Subversion Repositories pentevo

Rev

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

  1. /* code166.c */
  2. /*****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
  4. /*                                                                           */
  5. /* AS-Portierung                                                             */
  6. /*                                                                           */
  7. /* AS-Codegenerator Siemens 80C16x                                           */
  8. /*                                                                           */
  9. /*****************************************************************************/
  10.  
  11. #include "stdinc.h"
  12. #include <string.h>
  13. #include <ctype.h>
  14.  
  15. #include "nls.h"
  16. #include "strutil.h"
  17. #include "bpemu.h"
  18. #include "asmdef.h"
  19. #include "asmsub.h"
  20. #include "asmpars.h"
  21. #include "asmitree.h"
  22. #include "asmcode.h"
  23. #include "asmallg.h"
  24. #include "codepseudo.h"
  25. #include "intpseudo.h"
  26. #include "codevars.h"
  27. #include "errmsg.h"
  28.  
  29. #include "code166.h"
  30.  
  31. typedef struct
  32. {
  33.   CPUVar MinCPU;
  34.   Word Code1, Code2;
  35. } BaseOrder;
  36.  
  37. typedef struct
  38. {
  39.   const char *Name;
  40.   Byte Code;
  41. } Condition;
  42.  
  43. #define COND_CODE_TRUE 0x0
  44.  
  45. #define DPPCount 4
  46. static const char RegNames[6][5] = { "DPP0", "DPP1", "DPP2", "DPP3", "CP", "SP" };
  47.  
  48. static CPUVar CPU80C166, CPU80C167, CPU80C167CS;
  49.  
  50. static BaseOrder *FixedOrders;
  51. static Condition *Conditions;
  52. static int TrueCond;
  53.  
  54. static LongInt DPPAssumes[DPPCount];
  55. static IntType MemInt, MemInt2;
  56. static tSymbolSize OpSize;
  57.  
  58. static Boolean DPPChanged[DPPCount], N_DPPChanged[DPPCount];
  59. static Boolean SPChanged, CPChanged, N_SPChanged, N_CPChanged;
  60.  
  61. static ShortInt ExtCounter;
  62. static enum
  63. {
  64.   MemModeStd,       /* normal */
  65.   MemModeNoCheck,   /* EXTS Rn */
  66.   MemModeZeroPage,  /* EXTP Rn */
  67.   MemModeFixedBank, /* EXTS nn */
  68.   MemModeFixedPage  /* EXTP nn */
  69. } MemMode;
  70. static Word MemPage;
  71. static Boolean ExtSFRs;
  72.  
  73. #define ASSUME166Count 4
  74. static ASSUMERec ASSUME166s[ASSUME166Count] =
  75. {
  76.   { "DPP0", DPPAssumes + 0, 0, 15, -1, NULL },
  77.   { "DPP1", DPPAssumes + 1, 0, 15, -1, NULL },
  78.   { "DPP2", DPPAssumes + 2, 0, 15, -1, NULL },
  79.   { "DPP3", DPPAssumes + 3, 0, 15, -1, NULL }
  80. };
  81.  
  82. /*-------------------------------------------------------------------------*/
  83.  
  84. enum
  85. {
  86.   ModNone = -1,
  87.   ModReg = 0,
  88.   ModImm = 1,
  89.   ModIReg = 2,
  90.   ModPreDec = 3,
  91.   ModPostInc = 4,
  92.   ModIndex = 5,
  93.   ModAbs = 6,
  94.   ModMReg = 7,
  95.   ModLAbs = 8
  96. };
  97.  
  98. typedef enum
  99. {
  100.   eForceNone = 0,
  101.   eForceShort = 1,
  102.   eForceLong = 2
  103. } tForceSize;
  104.  
  105. #define MModReg (1 << ModReg)
  106. #define MModImm (1 << ModImm)
  107. #define MModIReg (1 << ModIReg)
  108. #define MModPreDec (1 << ModPreDec)
  109. #define MModPostInc (1 << ModPostInc)
  110. #define MModIndex (1 << ModIndex)
  111. #define MModAbs (1 << ModAbs)
  112. #define MModMReg (1 << ModMReg)
  113. #define MModLAbs (1 << ModLAbs)
  114.  
  115. #define M_InCode (1 << 14)
  116. #define M_Dest (1 << 13)
  117.  
  118. typedef struct
  119. {
  120.   Byte Mode;
  121.   Byte Vals[2];
  122.   ShortInt Type;
  123.   tSymbolFlags SymFlags;
  124.   tForceSize ForceSize;
  125.   int Cnt;
  126. } tAdrResult;
  127.  
  128. /*!------------------------------------------------------------------------
  129.  * \fn     IsRegCore(const char *pArg, tRegInt *pValue, tSymbolSize *pSize)
  130.  * \brief  check whether argument describes a CPU (general purpose) register
  131.  * \param  pArg argument
  132.  * \param  pValue resulting register # if yes
  133.  * \param  pSize resulting register size if yes
  134.  * \return true if yes
  135.  * ------------------------------------------------------------------------ */
  136.  
  137. static Boolean IsRegCore(const char *pArg, tRegInt *pValue, tSymbolSize *pSize)
  138. {
  139.   int l = strlen(pArg);
  140.   Boolean OK;
  141.  
  142.   if ((l < 2) || (as_toupper(*pArg) != 'R'))
  143.     return False;
  144.   else if ((l > 2) && (as_toupper(pArg[1]) == 'L'))
  145.   {
  146.     *pValue = ConstLongInt(pArg + 2, &OK, 10) << 1;
  147.     *pSize = eSymbolSize8Bit;
  148.     return (OK && (*pValue <= 15));
  149.   }
  150.   else if ((l > 2) && (as_toupper(pArg[1]) == 'H'))
  151.   {
  152.     *pValue = (ConstLongInt(pArg + 2, &OK, 10) << 1) + 1;
  153.     *pSize = eSymbolSize8Bit;
  154.     return (OK && (*pValue <= 15));
  155.   }
  156.   else
  157.   {
  158.     *pValue = ConstLongInt(pArg + 1, &OK, 10);
  159.     *pSize = eSymbolSize16Bit;
  160.     return (OK && (*pValue <= 15));
  161.   }
  162. }
  163.  
  164. /*!------------------------------------------------------------------------
  165.  * \fn     DissectReg_166(char *pDest, size_t DestSize, tRegInt Value, tSymbolSize InpSize)
  166.  * \brief  dissect register symbols - C16x variant
  167.  * \param  pDest destination buffer
  168.  * \param  DestSize destination buffer size
  169.  * \param  Value numeric register value
  170.  * \param  InpSize register size
  171.  * ------------------------------------------------------------------------ */
  172.  
  173. static void DissectReg_166(char *pDest, size_t DestSize, tRegInt Value, tSymbolSize InpSize)
  174. {
  175.   switch (InpSize)
  176.   {
  177.     case eSymbolSize8Bit:
  178.       as_snprintf(pDest, DestSize, "R%c%u", Value & 1 ? 'H' : 'L', (unsigned)(Value >> 1));
  179.       break;
  180.     case eSymbolSize16Bit:
  181.       as_snprintf(pDest, DestSize, "R%u", (unsigned)Value);
  182.       break;
  183.     default:
  184.       as_snprintf(pDest, DestSize, "%d-%u", (int)InpSize, (unsigned)Value);
  185.   }
  186. }
  187.  
  188. /*!------------------------------------------------------------------------
  189.  * \fn     IsReg(const tStrComp *pArg, Byte *pValue, tSymbolSize *pSize, tSymbolSize ReqSize, Boolean MustBeReg)
  190.  * \brief  check whether argument is a CPU register or user-defined register alias
  191.  * \param  pArg argument
  192.  * \param  pValue resulting register # if yes
  193.  * \param  pSize resulting register size if yes
  194.  * \param  ReqSize requested register size
  195.  * \param  MustBeReg expecting register or maybe not?
  196.  * \return reg eval result
  197.  * ------------------------------------------------------------------------ */
  198.  
  199. /* NOTE: If requester register size is 8 bits, R0..R15 is allowed as
  200.    alias for R0L,R0H,R1L,...,R7H: */
  201.  
  202. static Boolean ChkRegSize(tSymbolSize ReqSize, tSymbolSize ActSize)
  203. {
  204.   return (ReqSize == eSymbolSizeUnknown)
  205.       || (ReqSize == ActSize)
  206.       || ((ReqSize == eSymbolSize8Bit) && (ActSize == eSymbolSize16Bit));
  207. }
  208.  
  209. static tRegEvalResult IsReg(const tStrComp *pArg, Byte *pValue, tSymbolSize *pSize, tSymbolSize ReqSize, Boolean MustBeReg)
  210. {
  211.   tRegDescr RegDescr;
  212.   tEvalResult EvalResult;
  213.   tRegEvalResult RegEvalResult;
  214.  
  215.   if (IsRegCore(pArg->str.p_str, &RegDescr.Reg, &EvalResult.DataSize))
  216.     RegEvalResult = eIsReg;
  217.   else
  218.     RegEvalResult = EvalStrRegExpressionAsOperand(pArg, &RegDescr, &EvalResult, eSymbolSizeUnknown, MustBeReg);
  219.  
  220.   if (RegEvalResult == eIsReg)
  221.   {
  222.     if (!ChkRegSize(ReqSize, EvalResult.DataSize))
  223.     {
  224.       WrStrErrorPos(ErrNum_InvOpSize, pArg);
  225.       RegEvalResult = MustBeReg ? eIsNoReg : eRegAbort;
  226.     }
  227.   }
  228.  
  229.   *pValue = RegDescr.Reg;
  230.   if (pSize) *pSize = EvalResult.DataSize;
  231.   return RegEvalResult;
  232. }
  233.  
  234. static tRegEvalResult IsRegM1(const tStrComp *pArg, Byte *pValue, tSymbolSize ReqSize, Boolean MustBeReg)
  235. {
  236.   if (*pArg->str.p_str)
  237.   {
  238.     int l;
  239.     char tmp = pArg->str.p_str[l = (strlen(pArg->str.p_str) - 1)];
  240.     tRegEvalResult b;
  241.  
  242.     pArg->str.p_str[l] = '\0';
  243.     b = IsReg(pArg, pValue, NULL, ReqSize, MustBeReg);
  244.     pArg->str.p_str[l] = tmp;
  245.     return b;
  246.   }
  247.   else
  248.     return eIsNoReg;
  249. }
  250.  
  251. static tRegEvalResult IsRegP1(const tStrComp *pArg, Byte *pValue, tSymbolSize ReqSize, Boolean MustBeReg)
  252. {
  253.   tStrComp Arg;
  254.  
  255.   StrCompRefRight(&Arg, pArg, 1);
  256.   return IsReg(&Arg, pValue, NULL, ReqSize, MustBeReg);
  257. }
  258.  
  259. static LongInt SFRStart(void)
  260. {
  261.   return (ExtSFRs) ? 0xf000 : 0xfe00;
  262. }
  263.  
  264. static LongInt SFREnd(void)
  265. {
  266.   return (ExtSFRs) ? 0xf1de : 0xffde;
  267. }
  268.  
  269. static Boolean CalcPage(LongInt *Adr, Boolean DoAnyway)
  270. {
  271.   int z;
  272.   Word Bank;
  273.  
  274.   switch (MemMode)
  275.   {
  276.     case MemModeStd:
  277.       z = 0;
  278.       while ((z <= 3) && (((*Adr) >> 14) != DPPAssumes[z]))
  279.         z++;
  280.       if (z > 3)
  281.       {
  282.         WrError(ErrNum_InAccPage);
  283.         (*Adr) &= 0xffff;
  284.         return DoAnyway;
  285.       }
  286.       else
  287.       {
  288.         *Adr = ((*Adr) & 0x3fff) + (z << 14);
  289.         if (DPPChanged[z])
  290.           WrXError(ErrNum_Pipeline, RegNames[z]);
  291.         return True;
  292.       }
  293.     case MemModeZeroPage:
  294.       (*Adr) &= 0x3fff;
  295.       return True;
  296.     case MemModeFixedPage:
  297.       Bank = (*Adr) >> 14;
  298.       (*Adr) &= 0x3fff;
  299.       if (Bank != MemPage)
  300.       {
  301.         WrError(ErrNum_InAccPage);
  302.         return (DoAnyway);
  303.       }
  304.       else
  305.         return True;
  306.     case MemModeNoCheck:
  307.       (*Adr) &= 0xffff;
  308.       return True;
  309.     case MemModeFixedBank:
  310.       Bank = (*Adr) >> 16; (*Adr) &= 0xffff;
  311.       if (Bank != MemPage)
  312.       {
  313.         WrError(ErrNum_InAccPage);
  314.         return (DoAnyway);
  315.       }
  316.       else
  317.         return True;
  318.     default:
  319.       return False;
  320.   }
  321. }
  322.  
  323. static void DecideAbsolute(LongInt DispAcc, Word Mask, tAdrResult *pResult)
  324. {
  325. #define DPPAdr 0xfe00
  326. #define SPAdr 0xfe12
  327. #define CPAdr 0xfe10
  328.  
  329.   int z;
  330.  
  331.   if (Mask & M_InCode)
  332.   {
  333.     if ((HiWord(EProgCounter()) == HiWord(DispAcc)) && (Mask & MModAbs))
  334.     {
  335.       pResult->Type = ModAbs;
  336.       pResult->Cnt = 2;
  337.       pResult->Vals[0] = Lo(DispAcc);
  338.       pResult->Vals[1] = Hi(DispAcc);
  339.     }
  340.     else
  341.     {
  342.       pResult->Type = ModLAbs;
  343.       pResult->Cnt = 2;
  344.       pResult->Mode = DispAcc >> 16;
  345.       pResult->Vals[0] = Lo(DispAcc);
  346.       pResult->Vals[1] = Hi(DispAcc);
  347.     }
  348.   }
  349.   else if (((Mask & MModMReg) != 0) && (DispAcc >= SFRStart()) && (DispAcc <= SFREnd()) && (!(DispAcc & 1)))
  350.   {
  351.     pResult->Type = ModMReg;
  352.     pResult->Cnt = 1;
  353.     pResult->Vals[0] = (DispAcc - SFRStart()) >> 1;
  354.   }
  355.   else switch (MemMode)
  356.   {
  357.     case MemModeStd:
  358.       z = 0;
  359.       while ((z <= 3) && ((DispAcc >> 14) != DPPAssumes[z]))
  360.         z++;
  361.       if (z > 3)
  362.       {
  363.         WrError(ErrNum_InAccPage);
  364.         z = (DispAcc >> 14) & 3;
  365.       }
  366.       pResult->Type = ModAbs;
  367.       pResult->Cnt = 2;
  368.       pResult->Vals[0] = Lo(DispAcc);
  369.       pResult->Vals[1] = (Hi(DispAcc) & 0x3f) + (z << 6);
  370.       if (DPPChanged[z])
  371.         WrXError(ErrNum_Pipeline, RegNames[z]);
  372.       break;
  373.     case MemModeZeroPage:
  374.       pResult->Type = ModAbs;
  375.       pResult->Cnt = 2;
  376.       pResult->Vals[0] = Lo(DispAcc);
  377.       pResult->Vals[1] = Hi(DispAcc) & 0x3f;
  378.       break;
  379.     case MemModeFixedPage:
  380.       if ((DispAcc >> 14) != MemPage)
  381.         WrError(ErrNum_InAccPage);
  382.       pResult->Type = ModAbs;
  383.       pResult->Cnt = 2;
  384.       pResult->Vals[0] = Lo(DispAcc);
  385.       pResult->Vals[1] = Hi(DispAcc) & 0x3f;
  386.       break;
  387.     case MemModeNoCheck:
  388.       pResult->Type = ModAbs;
  389.       pResult->Cnt = 2;
  390.       pResult->Vals[0] = Lo(DispAcc);
  391.       pResult->Vals[1] = Hi(DispAcc);
  392.       break;
  393.     case MemModeFixedBank:
  394.       if ((DispAcc >> 16) != MemPage)
  395.         WrError(ErrNum_InAccPage);
  396.       pResult->Type = ModAbs;
  397.       pResult->Cnt = 2;
  398.       pResult->Vals[0] = Lo(DispAcc);
  399.       pResult->Vals[1] = Hi(DispAcc);
  400.       break;
  401.   }
  402.  
  403.   if ((pResult->Type != ModNone) && (Mask & M_Dest))
  404.   {
  405.     switch ((Word)DispAcc)
  406.     {
  407.       case SPAdr    : N_SPChanged = True; break;
  408.       case CPAdr    : N_CPChanged = True; break;
  409.       case DPPAdr   :
  410.       case DPPAdr + 1 : N_DPPChanged[0] = True; break;
  411.       case DPPAdr + 2 :
  412.       case DPPAdr + 3 : N_DPPChanged[1] = True; break;
  413.       case DPPAdr + 4 :
  414.       case DPPAdr + 5 : N_DPPChanged[2] = True; break;
  415.       case DPPAdr + 6 :
  416.       case DPPAdr + 7 : N_DPPChanged[3] = True; break;
  417.     }
  418.   }
  419. }
  420.  
  421. static int SplitForceSize(const char *pArg, tForceSize *pForceSize)
  422. {
  423.   switch (*pArg)
  424.   {
  425.     case '>': *pForceSize = eForceLong; return 1;
  426.     case '<': *pForceSize = eForceShort; return 1;
  427.     default: return 0;
  428.   }
  429. }
  430.  
  431. static ShortInt DecodeAdr(const tStrComp *pArg, Word Mask, tAdrResult *pResult)
  432. {
  433.   LongInt HDisp, DispAcc;
  434.   Boolean OK, NegFlag, NNegFlag;
  435.   Byte HReg;
  436.   int Offs;
  437.   tRegEvalResult RegEvalResult;
  438.  
  439.   pResult->Type = ModNone;
  440.   pResult->Cnt = 0;
  441.   pResult->ForceSize = eForceNone;
  442.  
  443.   /* immediate ? */
  444.  
  445.   if (*pArg->str.p_str == '#')
  446.   {
  447.     Offs = SplitForceSize(pArg->str.p_str + 1, &pResult->ForceSize);
  448.     switch (OpSize)
  449.     {
  450.       case eSymbolSize8Bit:
  451.         pResult->Vals[0] = EvalStrIntExpressionOffsWithFlags(pArg, 1 + Offs, Int8, &OK, &pResult->SymFlags);
  452.         pResult->Vals[1] = 0;
  453.         break;
  454.       case eSymbolSize16Bit:
  455.         HDisp = EvalStrIntExpressionOffsWithFlags(pArg, 1 + Offs, Int16, &OK, &pResult->SymFlags);
  456.         pResult->Vals[0] = Lo(HDisp);
  457.         pResult->Vals[1] = Hi(HDisp);
  458.         break;
  459.       default:
  460.         OK = False;
  461.         break;
  462.     }
  463.     if (OK)
  464.     {
  465.       pResult->Type = ModImm;
  466.       AdrCnt = OpSize + 1;
  467.     }
  468.   }
  469.  
  470.   /* Register ? */
  471.  
  472.   else if ((RegEvalResult = IsReg(pArg, &pResult->Mode, NULL, OpSize, False)) != eIsNoReg)
  473.   {
  474.     if (RegEvalResult == eRegAbort)
  475.       return pResult->Type;
  476.     if ((Mask & MModReg) != 0)
  477.       pResult->Type = ModReg;
  478.     else
  479.     {
  480.       pResult->Type = ModMReg;
  481.       pResult->Vals[0] = 0xf0 + pResult->Mode;
  482.       AdrCnt = 1;
  483.     }
  484.     if (CPChanged)
  485.       WrXError(ErrNum_Pipeline, RegNames[4]);
  486.   }
  487.  
  488.   /* indirekt ? */
  489.  
  490.   else if ((*pArg->str.p_str == '[') && (pArg->str.p_str[strlen(pArg->str.p_str) - 1] == ']'))
  491.   {
  492.     tStrComp Arg;
  493.     int ArgLen;
  494.  
  495.     StrCompRefRight(&Arg, pArg, 1);
  496.     StrCompShorten(&Arg, 1);
  497.     KillPrefBlanksStrCompRef(&Arg);
  498.     KillPostBlanksStrComp(&Arg);
  499.     ArgLen = strlen(Arg.str.p_str);
  500.  
  501.     /* Predekrement ? */
  502.  
  503.     if ((ArgLen > 2) && (*Arg.str.p_str == '-') && ((RegEvalResult = IsRegP1(&Arg, &pResult->Mode, eSymbolSize16Bit, False)) != eIsNoReg))
  504.     {
  505.       if (eRegAbort == RegEvalResult)
  506.         return pResult->Type;
  507.       pResult->Type = ModPreDec;
  508.     }
  509.  
  510.     /* Postinkrement ? */
  511.  
  512.     else if ((ArgLen > 2) && (Arg.str.p_str[ArgLen - 1] == '+') && ((RegEvalResult = IsRegM1(&Arg, &pResult->Mode, eSymbolSize16Bit, False)) != eIsNoReg))
  513.     {
  514.       if (eRegAbort == RegEvalResult)
  515.         return pResult->Type;
  516.       pResult->Type = ModPostInc;
  517.     }
  518.  
  519.     /* indiziert ? */
  520.  
  521.     else
  522.     {
  523.       tStrComp Remainder;
  524.       char *pSplitPos;
  525.  
  526.       NNegFlag = NegFlag = False;
  527.       DispAcc = 0;
  528.       pResult->Mode = 0xff;
  529.       do
  530.       {
  531.         pSplitPos = indir_split_pos(Arg.str.p_str);
  532.         if (pSplitPos)
  533.         {
  534.           NNegFlag = *pSplitPos == '-';
  535.           StrCompSplitRef(&Arg, &Remainder, &Arg, pSplitPos);
  536.         }
  537.         if ((RegEvalResult = IsReg(&Arg, &HReg, NULL, eSymbolSize16Bit, False)) != eIsNoReg)
  538.         {
  539.           if (RegEvalResult == eRegAbort)
  540.             return pResult->Type;
  541.           if (NegFlag || (pResult->Mode != 0xff))
  542.             WrError(ErrNum_InvAddrMode);
  543.           else
  544.             pResult->Mode = HReg;
  545.         }
  546.         else
  547.         {
  548.           HDisp = EvalStrIntExpressionOffs(&Arg, !!(*Arg.str.p_str == '#'), Int32, &OK);
  549.           if (OK)
  550.             DispAcc = NegFlag ? DispAcc - HDisp : DispAcc + HDisp;
  551.         }
  552.         if (pSplitPos)
  553.         {
  554.           NegFlag = NNegFlag;
  555.           Arg = Remainder;
  556.         }
  557.       }
  558.       while (pSplitPos);
  559.       if (pResult->Mode == 0xff)
  560.         DecideAbsolute(DispAcc, Mask, pResult);
  561.       else if (DispAcc == 0)
  562.         pResult->Type = ModIReg;
  563.       else if (DispAcc > 0xffff)
  564.         WrError(ErrNum_OverRange);
  565.       else if (DispAcc < -0x8000l)
  566.         WrError(ErrNum_UnderRange);
  567.       else
  568.       {
  569.         pResult->Vals[0] = Lo(DispAcc);
  570.         pResult->Vals[1] = Hi(DispAcc);
  571.         pResult->Type = ModIndex;
  572.         pResult->Cnt = 2;
  573.       }
  574.     }
  575.   }
  576.   else
  577.   {
  578.     int Offset = SplitForceSize(pArg->str.p_str, &pResult->ForceSize);
  579.  
  580.     DispAcc = EvalStrIntExpressionOffsWithFlags(pArg, Offset, MemInt, &OK, &pResult->SymFlags);
  581.     if (OK)
  582.       DecideAbsolute(DispAcc, Mask, pResult);
  583.   }
  584.  
  585.   if ((pResult->Type != ModNone) && (!((1 << pResult->Type) & Mask)))
  586.   {
  587.     WrError(ErrNum_InvAddrMode);
  588.     pResult->Type = ModNone;
  589.     pResult->Cnt = 0;
  590.   }
  591.   return pResult->Type;
  592. }
  593.  
  594. static Boolean DecodeCondition(const char *Name, Byte *p_cond_code)
  595. {
  596.   int z;
  597.  
  598.   for (z = 0; Conditions[z].Name; z++)
  599.     if (!as_strcasecmp(Conditions[z].Name, Name))
  600.     {
  601.       *p_cond_code = Conditions[z].Code;
  602.       return True;
  603.     }
  604.   return False;
  605. }
  606.  
  607. static Boolean DecodeBitAddr(const tStrComp *pArg, Word *Adr, Byte *Bit, Boolean MayBeOut)
  608. {
  609.   char *p;
  610.   Word LAdr;
  611.   Byte Reg;
  612.   Boolean OK;
  613.  
  614.   p = QuotPos(pArg->str.p_str, '.');
  615.   if (!p)
  616.   {
  617.     LAdr = EvalStrIntExpression(pArg, UInt16, &OK) & 0x1fff;
  618.     if (OK)
  619.     {
  620.       if ((!MayBeOut) && ((LAdr >> 12) != Ord(ExtSFRs)))
  621.       {
  622.         WrError(ErrNum_InAccReg);
  623.         return False;
  624.       }
  625.       *Adr = LAdr >> 4;
  626.       *Bit = LAdr & 15;
  627.       if (!MayBeOut)
  628.         *Adr = Lo(*Adr);
  629.       return True;
  630.     }
  631.     else return False;
  632.   }
  633.   else if (p == pArg->str.p_str)
  634.   {
  635.     WrError(ErrNum_InvAddrMode);
  636.     return False;
  637.   }
  638.   else
  639.   {
  640.     tStrComp AddrComp, BitComp;
  641.  
  642.     StrCompSplitRef(&AddrComp, &BitComp, pArg, p);
  643.  
  644.     switch (IsReg(&AddrComp, &Reg, NULL, eSymbolSize16Bit, False))
  645.     {
  646.       case eIsReg:
  647.         *Adr = 0xf0 + Reg;
  648.         break;
  649.       case eRegAbort:
  650.         return False;
  651.       case eIsNoReg:
  652.       {
  653.         tSymbolFlags Flags;
  654.  
  655.         LAdr = EvalStrIntExpressionWithFlags(&AddrComp, UInt16, &OK, &Flags);
  656.         if (!OK)
  657.           return False;
  658.         if (mFirstPassUnknown(Flags))
  659.           LAdr = 0xfd00;
  660.  
  661.         /* full addresses must be even, since bitfields in memory are 16 bit: */
  662.  
  663.         if ((LAdr > 0xff) && (LAdr & 1))
  664.         {
  665.           WrStrErrorPos(ErrNum_NotAligned, &AddrComp);
  666.           return False;
  667.         }
  668.  
  669.         /* coded bit address: */
  670.  
  671.         if (LAdr <= 0xff)
  672.           *Adr = LAdr;
  673.  
  674.         /* 1st RAM bank: */
  675.  
  676.         else if ((LAdr >= 0xfd00) && (LAdr <= 0xfdfe))
  677.           *Adr = (LAdr - 0xfd00)/2;
  678.  
  679.         /* SFR space: */
  680.  
  681.         else if ((LAdr >= 0xff00) && (LAdr <= 0xffde))
  682.         {
  683.           if ((ExtSFRs) && (!MayBeOut))
  684.           {
  685.             WrStrErrorPos(ErrNum_InAccReg, &AddrComp);
  686.             return False;
  687.           }
  688.           *Adr = 0x80 + ((LAdr - 0xff00) / 2);
  689.         }
  690.  
  691.         /* extended SFR space: */
  692.  
  693.         else if ((LAdr >= 0xf100) && (LAdr <= 0xf1de))
  694.         {
  695.           if ((!ExtSFRs) && (!MayBeOut))
  696.           {
  697.             WrStrErrorPos(ErrNum_InAccReg, &AddrComp);
  698.             return False;
  699.           }
  700.           *Adr = 0x80 + ((LAdr - 0xf100) / 2);
  701.           if (MayBeOut)
  702.             (*Adr) += 0x100;
  703.         }
  704.         else
  705.         {
  706.           WrStrErrorPos(ErrNum_OverRange, &AddrComp);
  707.           return False;
  708.         }
  709.       }
  710.     }
  711.  
  712.     *Bit = EvalStrIntExpression(&BitComp, UInt4, &OK);
  713.     return OK;
  714.   }
  715. }
  716.  
  717. static Word WordVal(const tAdrResult *pResult)
  718. {
  719.   return pResult->Vals[0] + (((Word)pResult->Vals[1]) << 8);
  720. }
  721.  
  722. static Boolean DecodePref(const tStrComp *pArg, Byte *Erg)
  723. {
  724.   Boolean OK;
  725.   tSymbolFlags Flags;
  726.  
  727.   if (*pArg->str.p_str != '#')
  728.   {
  729.     WrError(ErrNum_InvAddrMode);
  730.     return False;
  731.   }
  732.   *Erg = EvalStrIntExpressionOffsWithFlags(pArg, 1, UInt3, &OK, &Flags);
  733.   if (mFirstPassUnknown(Flags))
  734.     *Erg = 1;
  735.   if (!OK)
  736.     return False;
  737.   if (*Erg < 1)
  738.     WrError(ErrNum_UnderRange);
  739.   else if (*Erg > 4)
  740.     WrError(ErrNum_OverRange);
  741.   else
  742.   {
  743.     (*Erg)--;
  744.     return True;
  745.   }
  746.   return False;
  747. }
  748.  
  749. /*-------------------------------------------------------------------------*/
  750.  
  751. static void DecodeFixed(Word Index)
  752. {
  753.   const BaseOrder *pOrder = FixedOrders + Index;
  754.  
  755.   if (ChkArgCnt(0, 0))
  756.   {
  757.     CodeLen = 2;
  758.     BAsmCode[0] = Lo(pOrder->Code1);
  759.     BAsmCode[1] = Hi(pOrder->Code1);
  760.     if (pOrder->Code2 != 0)
  761.     {
  762.       CodeLen = 4;
  763.       BAsmCode[2] = Lo(pOrder->Code2);
  764.       BAsmCode[3] = Hi(pOrder->Code2);
  765.       if ((!strncmp(OpPart.str.p_str, "RET", 3)) && (SPChanged))
  766.         WrXError(ErrNum_Pipeline, RegNames[5]);
  767.     }
  768.   }
  769. }
  770.  
  771. static void DecodeMOV(Word Code)
  772. {
  773.   LongInt AdrLong;
  774.  
  775.   OpSize = (tSymbolSize)Hi(Code);
  776.   Code = 1 - OpSize;
  777.  
  778.   if (ChkArgCnt(2, 2))
  779.   {
  780.     tAdrResult DestResult;
  781.  
  782.     switch (DecodeAdr(&ArgStr[1], MModReg | MModMReg | MModIReg | MModPreDec | MModPostInc | MModIndex | MModAbs | M_Dest, &DestResult))
  783.     {
  784.       case ModReg:
  785.       {
  786.         tAdrResult SrcResult;
  787.  
  788.         switch (DecodeAdr(&ArgStr[2], MModReg | MModImm | MModIReg | MModPostInc | MModIndex | MModAbs, &SrcResult))
  789.         {
  790.           case ModReg:
  791.             CodeLen = 2;
  792.              BAsmCode[0] = 0xf0 + Code;
  793.             BAsmCode[1] = (DestResult.Mode << 4) + SrcResult.Mode;
  794.             break;
  795.           case ModImm:
  796.           {
  797.             Boolean IsShort = WordVal(&SrcResult) <= 15;
  798.  
  799.             if (!SrcResult.ForceSize)
  800.               SrcResult.ForceSize = IsShort ? eForceShort : eForceLong;
  801.             if (SrcResult.ForceSize == eForceShort)
  802.             {
  803.               if (!IsShort && !mSymbolQuestionable(SrcResult.SymFlags)) WrStrErrorPos(ErrNum_OverRange, &ArgStr[2]);
  804.               else
  805.               {
  806.                 CodeLen = 2;
  807.                 BAsmCode[0] = 0xe0 + Code;
  808.                 BAsmCode[1] = (WordVal(&SrcResult) << 4) + DestResult.Mode;
  809.               }
  810.             }
  811.             else
  812.             {
  813.               CodeLen = 4;
  814.               BAsmCode[0] = 0xe6 + Code;
  815.               BAsmCode[1] = DestResult.Mode + 0xf0;
  816.               memcpy(BAsmCode + 2, SrcResult.Vals, 2);
  817.             }
  818.             break;
  819.           }
  820.           case ModIReg:
  821.             CodeLen = 2;
  822.             BAsmCode[0] = 0xa8 + Code;
  823.             BAsmCode[1] = (DestResult.Mode << 4) + SrcResult.Mode;
  824.             break;
  825.           case ModPostInc:
  826.             CodeLen = 2;
  827.             BAsmCode[0] = 0x98 + Code;
  828.             BAsmCode[1] = (DestResult.Mode << 4) + SrcResult.Mode;
  829.             break;
  830.           case ModIndex:
  831.             CodeLen = 2 + SrcResult.Cnt;
  832.             BAsmCode[0] = 0xd4 + (Code << 5);
  833.             BAsmCode[1] = (DestResult.Mode << 4) + SrcResult.Mode;
  834.             memcpy(BAsmCode + 2, SrcResult.Vals, SrcResult.Cnt);
  835.             break;
  836.           case ModAbs:
  837.             CodeLen = 2 + SrcResult.Cnt;
  838.             BAsmCode[0] = 0xf2 + Code;
  839.             BAsmCode[1] = 0xf0 + DestResult.Mode;
  840.             memcpy(BAsmCode + 2, SrcResult.Vals, SrcResult.Cnt);
  841.             break;
  842.         }
  843.         break;
  844.       }
  845.       case ModMReg:
  846.       {
  847.         tAdrResult SrcResult;
  848.  
  849.         BAsmCode[1] = DestResult.Vals[0];
  850.         switch (DecodeAdr(&ArgStr[2], MModImm | MModMReg | ((DPPAssumes[3] == 3) ? MModIReg : 0) | MModAbs, &SrcResult))
  851.         {
  852.           case ModImm:
  853.             CodeLen = 4;
  854.             BAsmCode[0] = 0xe6 + Code;
  855.             memcpy(BAsmCode + 2, SrcResult.Vals, 2);
  856.             break;
  857.           case ModMReg: /* BAsmCode[1] sicher absolut darstellbar, da Rn vorher */
  858.                         /* abgefangen wird! */
  859.             BAsmCode[0] = 0xf6 + Code;
  860.             AdrLong = SFRStart() + (((Word)BAsmCode[1]) << 1);
  861.             CalcPage(&AdrLong, True);
  862.             BAsmCode[2] = Lo(AdrLong);
  863.             BAsmCode[3] = Hi(AdrLong);
  864.             BAsmCode[1] = SrcResult.Vals[0];
  865.             CodeLen = 4;
  866.             break;
  867.           case ModIReg:
  868.             CodeLen = 4; BAsmCode[0] = 0x94 + (Code << 5);
  869.             BAsmCode[2] = BAsmCode[1] << 1;
  870.             BAsmCode[3] = 0xfe + (BAsmCode[1] >> 7); /* ANSI :-0 */
  871.             BAsmCode[1] = SrcResult.Mode;
  872.             break;
  873.           case ModAbs:
  874.             CodeLen = 2 + SrcResult.Cnt;
  875.             BAsmCode[0] = 0xf2 + Code;
  876.             memcpy(BAsmCode + 2, SrcResult.Vals, SrcResult.Cnt);
  877.             break;
  878.         }
  879.         break;
  880.       }
  881.       case ModIReg:
  882.       {
  883.         tAdrResult SrcResult;
  884.  
  885.         switch (DecodeAdr(&ArgStr[2], MModReg | MModIReg | MModPostInc | MModAbs, &SrcResult))
  886.         {
  887.           case ModReg:
  888.             CodeLen = 2;
  889.             BAsmCode[0] = 0xb8 + Code;
  890.             BAsmCode[1] = DestResult.Mode + (SrcResult.Mode << 4);
  891.             break;
  892.           case ModIReg:
  893.             CodeLen = 2;
  894.            BAsmCode[0] = 0xc8 + Code;
  895.             BAsmCode[1] = (DestResult.Mode << 4) + SrcResult.Mode;
  896.             break;
  897.           case ModPostInc:
  898.             CodeLen = 2;
  899.             BAsmCode[0] = 0xe8 + Code;
  900.             BAsmCode[1] = (DestResult.Mode << 4) + SrcResult.Mode;
  901.             break;
  902.           case ModAbs:
  903.             CodeLen = 2 + SrcResult.Cnt;
  904.             BAsmCode[0] = 0x84 + (Code << 5);
  905.             BAsmCode[1] = DestResult.Mode;
  906.             memcpy(BAsmCode + 2, SrcResult.Vals, SrcResult.Cnt);
  907.             break;
  908.         }
  909.         break;
  910.       }
  911.       case ModPreDec:
  912.       {
  913.         tAdrResult SrcResult;
  914.  
  915.         switch (DecodeAdr(&ArgStr[2], MModReg, &SrcResult))
  916.         {
  917.           case ModReg:
  918.             CodeLen = 2;
  919.             BAsmCode[0] = 0x88 + Code;
  920.             BAsmCode[1] = DestResult.Mode + (SrcResult.Mode << 4);
  921.             break;
  922.         }
  923.         break;
  924.       }
  925.       case ModPostInc:
  926.       {
  927.         tAdrResult SrcResult;
  928.  
  929.         switch (DecodeAdr(&ArgStr[2], MModIReg, &SrcResult))
  930.         {
  931.           case ModIReg:
  932.             CodeLen = 2;
  933.             BAsmCode[0] = 0xd8 + Code;
  934.             BAsmCode[1] = (DestResult.Mode << 4) + SrcResult.Mode;
  935.             break;
  936.         }
  937.         break;
  938.       }
  939.       case ModIndex:
  940.       {
  941.         tAdrResult SrcResult;
  942.  
  943.         BAsmCode[1] = DestResult.Mode;
  944.         memcpy(BAsmCode + 2, DestResult.Vals, DestResult.Cnt);
  945.         switch (DecodeAdr(&ArgStr[2], MModReg, &SrcResult))
  946.         {
  947.           case ModReg:
  948.             BAsmCode[0] = 0xc4 + (Code << 5);
  949.             CodeLen = 4;
  950.             BAsmCode[1] += SrcResult.Mode << 4;
  951.             break;
  952.         }
  953.         break;
  954.       }
  955.       case ModAbs:
  956.       {
  957.         tAdrResult SrcResult;
  958.  
  959.         memcpy(BAsmCode + 2, DestResult.Vals, DestResult.Cnt);
  960.         switch (DecodeAdr(&ArgStr[2], MModIReg | MModMReg, &SrcResult))
  961.         {
  962.           case ModIReg:
  963.             CodeLen = 4;
  964.             BAsmCode[0] = 0x94 + (Code << 5);
  965.             BAsmCode[1] = SrcResult.Mode;
  966.             break;
  967.           case ModMReg:
  968.             CodeLen = 4;
  969.             BAsmCode[0] = 0xf6 + Code;
  970.             BAsmCode[1] = SrcResult.Vals[0];
  971.             break;
  972.         }
  973.         break;
  974.       }
  975.     }
  976.   }
  977. }
  978.  
  979. static void DecodeMOVBS_MOVBZ(Word Code)
  980. {
  981.   LongInt AdrLong;
  982.  
  983.   if (ChkArgCnt(2, 2))
  984.   {
  985.     tAdrResult DestResult;
  986.  
  987.     OpSize = eSymbolSize16Bit;
  988.     switch (DecodeAdr(&ArgStr[1], MModReg | MModMReg | MModAbs | M_Dest, &DestResult))
  989.     {
  990.       case ModReg:
  991.       {
  992.         tAdrResult SrcResult;
  993.  
  994.         OpSize = eSymbolSize8Bit;
  995.         switch (DecodeAdr(&ArgStr[2], MModReg | MModAbs, &SrcResult))
  996.         {
  997.           case ModReg:
  998.             CodeLen = 2;
  999.             BAsmCode[0] = 0xc0 + Code;
  1000.             BAsmCode[1] = DestResult.Mode + (SrcResult.Mode << 4);
  1001.             break;
  1002.           case ModAbs:
  1003.             CodeLen = 4;
  1004.             BAsmCode[0] = 0xc2 + Code;
  1005.             BAsmCode[1] = 0xf0 + DestResult.Mode;
  1006.             memcpy(BAsmCode + 2, SrcResult.Vals, 2);
  1007.             break;
  1008.         }
  1009.         break;
  1010.       }
  1011.       case ModMReg:
  1012.       {
  1013.         tAdrResult SrcResult;
  1014.  
  1015.         BAsmCode[1] = DestResult.Vals[0];
  1016.         OpSize = eSymbolSize8Bit;
  1017.         switch (DecodeAdr(&ArgStr[2], MModAbs | MModMReg, &SrcResult))
  1018.         {
  1019.           case ModMReg: /* BAsmCode[1] sicher absolut darstellbar, da Rn vorher */
  1020.                         /* abgefangen wird! */
  1021.             BAsmCode[0] = 0xc5 + Code;
  1022.             AdrLong = SFRStart() + (((Word)BAsmCode[1]) << 1);
  1023.             CalcPage(&AdrLong, True);
  1024.             BAsmCode[2] = Lo(AdrLong);
  1025.             BAsmCode[3] = Hi(AdrLong);
  1026.             BAsmCode[1] = SrcResult.Vals[0];
  1027.             CodeLen = 4;
  1028.             break;
  1029.           case ModAbs:
  1030.             CodeLen = 2 + SrcResult.Cnt;
  1031.             BAsmCode[0] = 0xc2 + Code;
  1032.             memcpy(BAsmCode + 2, SrcResult.Vals, SrcResult.Cnt);
  1033.             break;
  1034.         }
  1035.         break;
  1036.       }
  1037.       case ModAbs:
  1038.       {
  1039.         tAdrResult SrcResult;
  1040.  
  1041.         OpSize = eSymbolSize8Bit;
  1042.         memcpy(BAsmCode + 2, DestResult.Vals, DestResult.Cnt);
  1043.         switch (DecodeAdr(&ArgStr[2], MModMReg, &SrcResult))
  1044.         {
  1045.           case ModMReg:
  1046.             CodeLen = 4;
  1047.             BAsmCode[0] = 0xc5 + Code;
  1048.             BAsmCode[1] = SrcResult.Vals[0];
  1049.             break;
  1050.         }
  1051.         break;
  1052.       }
  1053.     }
  1054.   }
  1055. }
  1056.  
  1057. static void DecodePUSH_POP(Word Code)
  1058. {
  1059.   if (ChkArgCnt(1, 1))
  1060.   {
  1061.     tAdrResult Result;
  1062.  
  1063.     switch (DecodeAdr(&ArgStr[1], MModMReg | ((Code & 0x10) ? M_Dest : 0), &Result))
  1064.     {
  1065.       case ModMReg:
  1066.         CodeLen = 2;
  1067.         BAsmCode[0] = Code;
  1068.         BAsmCode[1] = Result.Vals[0];
  1069.         if (SPChanged) WrXError(ErrNum_Pipeline, RegNames[5]);
  1070.         break;
  1071.     }
  1072.   }
  1073. }
  1074.  
  1075. static void DecodeSCXT(Word Code)
  1076. {
  1077.   UNUSED(Code);
  1078.  
  1079.   if (ChkArgCnt(2, 2))
  1080.   {
  1081.     tAdrResult Result;
  1082.  
  1083.     switch (DecodeAdr(&ArgStr[1], MModMReg | M_Dest, &Result))
  1084.     {
  1085.       case ModMReg:
  1086.         BAsmCode[1] = Result.Vals[0];
  1087.         if (DecodeAdr(&ArgStr[2], MModAbs | MModImm, &Result) != ModNone)
  1088.         {
  1089.           CodeLen = 4; BAsmCode[0] = 0xc6 + (Ord(Result.Type == ModAbs) << 4);
  1090.           memcpy(BAsmCode + 2, Result.Vals, 2);
  1091.         }
  1092.         break;
  1093.     }
  1094.   }
  1095. }
  1096.  
  1097. static void DecodeALU2(Word Code)
  1098. {
  1099.   LongInt AdrLong;
  1100.  
  1101.   OpSize = (tSymbolSize)Hi(Code);
  1102.   Code = (1 - OpSize) + (Lo(Code)  << 4);
  1103.  
  1104.   if (ChkArgCnt(2, 2))
  1105.   {
  1106.     tAdrResult DestResult;
  1107.  
  1108.     switch (DecodeAdr(&ArgStr[1], MModReg | MModMReg | MModAbs | M_Dest, &DestResult))
  1109.     {
  1110.       case ModReg:
  1111.       {
  1112.         tAdrResult SrcResult;
  1113.  
  1114.         switch (DecodeAdr(&ArgStr[2], MModReg | MModIReg | MModPostInc | MModAbs | MModImm, &SrcResult))
  1115.         {
  1116.           case ModReg:
  1117.             CodeLen = 2;
  1118.             BAsmCode[0] = Code;
  1119.             BAsmCode[1] = (DestResult.Mode << 4) + SrcResult.Mode;
  1120.             break;
  1121.           case ModIReg:
  1122.             if (SrcResult.Mode > 3) WrError(ErrNum_InvAddrMode);
  1123.             else
  1124.             {
  1125.               CodeLen = 2;
  1126.               BAsmCode[0] = 0x08 + Code;
  1127.               BAsmCode[1] = (DestResult.Mode << 4) + 8 + SrcResult.Mode;
  1128.             }
  1129.             break;
  1130.           case ModPostInc:
  1131.             if (SrcResult.Mode > 3) WrError(ErrNum_InvAddrMode);
  1132.             else
  1133.             {
  1134.               CodeLen = 2;
  1135.               BAsmCode[0] = 0x08 + Code;
  1136.               BAsmCode[1] = (DestResult.Mode << 4) + 12 + SrcResult.Mode;
  1137.             }
  1138.             break;
  1139.           case ModAbs:
  1140.             CodeLen = 4;
  1141.             BAsmCode[0] = 0x02 + Code;
  1142.             BAsmCode[1] = 0xf0 + DestResult.Mode;
  1143.             memcpy(BAsmCode + 2, SrcResult.Vals, SrcResult.Cnt);
  1144.             break;
  1145.           case ModImm:
  1146.           {
  1147.             Boolean IsShort = WordVal(&SrcResult) <= 7;
  1148.  
  1149.             if (!SrcResult.ForceSize)
  1150.               SrcResult.ForceSize = IsShort ? eForceShort : eForceLong;
  1151.             if (SrcResult.ForceSize == eForceShort)
  1152.             {
  1153.               if (!IsShort && !mSymbolQuestionable(SrcResult.SymFlags)) WrStrErrorPos(ErrNum_OverRange, &ArgStr[2]);
  1154.               else
  1155.               {
  1156.                 CodeLen = 2;
  1157.                 BAsmCode[0] = 0x08 + Code;
  1158.                 BAsmCode[1] = (DestResult.Mode << 4) + SrcResult.Vals[0];
  1159.               }
  1160.             }
  1161.             else
  1162.             {
  1163.               CodeLen = 4;
  1164.               BAsmCode[0] = 0x06 + Code;
  1165.               BAsmCode[1] = 0xf0 + DestResult.Mode;
  1166.               memcpy(BAsmCode + 2, SrcResult.Vals, 2);
  1167.             }
  1168.             break;
  1169.           }
  1170.         }
  1171.         break;
  1172.       }
  1173.       case ModMReg:
  1174.       {
  1175.         tAdrResult SrcResult;
  1176.  
  1177.         BAsmCode[1] = DestResult.Vals[0];
  1178.         switch (DecodeAdr(&ArgStr[2], MModAbs | MModMReg | MModImm, &SrcResult))
  1179.         {
  1180.           case ModAbs:
  1181.             CodeLen = 4;
  1182.             BAsmCode[0] = 0x02 + Code;
  1183.             memcpy(BAsmCode + 2, SrcResult.Vals, SrcResult.Cnt);
  1184.             break;
  1185.           case ModMReg: /* BAsmCode[1] sicher absolut darstellbar, da Rn vorher */
  1186.                         /* abgefangen wird! */
  1187.             BAsmCode[0] = 0x04 + Code;
  1188.             AdrLong = SFRStart() + (((Word)BAsmCode[1]) << 1);
  1189.             CalcPage(&AdrLong, True);
  1190.             BAsmCode[2] = Lo(AdrLong);
  1191.             BAsmCode[3] = Hi(AdrLong);
  1192.             BAsmCode[1] = SrcResult.Vals[0];
  1193.             CodeLen = 4;
  1194.             break;
  1195.           case ModImm:
  1196.             CodeLen = 4;
  1197.             BAsmCode[0] = 0x06 + Code;
  1198.             memcpy(BAsmCode + 2, SrcResult.Vals, 2);
  1199.             break;
  1200.         }
  1201.         break;
  1202.       }
  1203.       case ModAbs:
  1204.       {
  1205.         tAdrResult SrcResult;
  1206.  
  1207.         memcpy(BAsmCode + 2, DestResult.Vals, DestResult.Cnt);
  1208.         switch (DecodeAdr(&ArgStr[2], MModMReg, &SrcResult))
  1209.         {
  1210.           case ModMReg:
  1211.             CodeLen = 4;
  1212.             BAsmCode[0] = 0x04 + Code;
  1213.             BAsmCode[1] = SrcResult.Vals[0];
  1214.             break;
  1215.         }
  1216.         break;
  1217.       }
  1218.     }
  1219.   }
  1220. }
  1221.  
  1222. static void DecodeCPL_NEG(Word Code)
  1223. {
  1224.   OpSize = (tSymbolSize)Hi(Code);
  1225.  
  1226.   Code = Lo(Code) + ((1 - OpSize) << 5);
  1227.   if (ChkArgCnt(1, 1))
  1228.   {
  1229.     tAdrResult Result;
  1230.  
  1231.     if (DecodeAdr(&ArgStr[1], MModReg | M_Dest, &Result) == ModReg)
  1232.     {
  1233.       CodeLen = 2;
  1234.       BAsmCode[0] = Code;
  1235.       BAsmCode[1] = Result.Mode << 4;
  1236.     }
  1237.   }
  1238. }
  1239.  
  1240. static void DecodeDiv(Word Code)
  1241. {
  1242.   if (ChkArgCnt(1, 1))
  1243.   {
  1244.     tAdrResult Result;
  1245.  
  1246.     if (DecodeAdr(&ArgStr[1], MModReg, &Result) == ModReg)
  1247.     {
  1248.       CodeLen = 2;
  1249.       BAsmCode[0] = 0x4b + (Code << 4);
  1250.       BAsmCode[1] = Result.Mode * 0x11;
  1251.     }
  1252.   }
  1253. }
  1254.  
  1255. static void DecodeLoop(Word Code)
  1256. {
  1257.   if (ChkArgCnt(2, 2))
  1258.   {
  1259.     tAdrResult Result;
  1260.  
  1261.     if (DecodeAdr(&ArgStr[1], MModReg | M_Dest, &Result) == ModReg)
  1262.     {
  1263.       BAsmCode[1] = Result.Mode;
  1264.       switch (DecodeAdr(&ArgStr[2], MModAbs | MModImm, &Result))
  1265.       {
  1266.         case ModAbs:
  1267.           CodeLen = 4;
  1268.           BAsmCode[0] = Code + 2;
  1269.           BAsmCode[1] += 0xf0;
  1270.           memcpy(BAsmCode + 2, Result.Vals, 2);
  1271.           break;
  1272.         case ModImm:
  1273.         {
  1274.           Boolean IsShort = WordVal(&Result) < 16;
  1275.  
  1276.           if (!Result.ForceSize)
  1277.             Result.ForceSize = IsShort ? eForceShort : eForceLong;
  1278.           if (Result.ForceSize == eForceShort)
  1279.           {
  1280.             if (!IsShort && !mSymbolQuestionable(Result.SymFlags)) WrStrErrorPos(ErrNum_OverRange, &ArgStr[2]);
  1281.             else
  1282.             {
  1283.               CodeLen = 2;
  1284.               BAsmCode[0] = Code;
  1285.               BAsmCode[1] += (WordVal(&Result) << 4);
  1286.             }
  1287.           }
  1288.           else
  1289.           {
  1290.             CodeLen = 4;
  1291.             BAsmCode[0] = Code + 6;
  1292.             BAsmCode[1] += 0xf0;
  1293.             memcpy(BAsmCode + 2, Result.Vals, 2);
  1294.           }
  1295.           break;
  1296.         }
  1297.       }
  1298.     }
  1299.   }
  1300. }
  1301.  
  1302. static void DecodeMul(Word Code)
  1303. {
  1304.   if (ChkArgCnt(2, 2))
  1305.   {
  1306.     tAdrResult DestResult;
  1307.  
  1308.     switch (DecodeAdr(&ArgStr[1], MModReg, &DestResult))
  1309.     {
  1310.       case ModReg:
  1311.       {
  1312.         tAdrResult SrcResult;
  1313.  
  1314.         switch (DecodeAdr(&ArgStr[2], MModReg, &SrcResult))
  1315.         {
  1316.           case ModReg:
  1317.             CodeLen = 2;
  1318.             BAsmCode[0] = 0x0b + (Code << 4);
  1319.             BAsmCode[1] = (DestResult.Mode << 4) + SrcResult.Mode;
  1320.             break;
  1321.         }
  1322.         break;
  1323.       }
  1324.     }
  1325.   }
  1326. }
  1327.  
  1328. static void DecodeShift(Word Code)
  1329. {
  1330.   if (ChkArgCnt(2, 2))
  1331.   {
  1332.     tAdrResult DestResult;
  1333.  
  1334.     OpSize = eSymbolSize16Bit;
  1335.     switch (DecodeAdr(&ArgStr[1], MModReg | M_Dest, &DestResult))
  1336.     {
  1337.       case ModReg:
  1338.       {
  1339.         tAdrResult SrcResult;
  1340.  
  1341.         switch (DecodeAdr(&ArgStr[2], MModReg | MModImm | M_Dest, &SrcResult))
  1342.         {
  1343.           case ModReg:
  1344.             BAsmCode[0] = Code;
  1345.             BAsmCode[1] = SrcResult.Mode + (DestResult.Mode << 4);
  1346.             CodeLen = 2;
  1347.             break;
  1348.           case ModImm:
  1349.             if ((WordVal(&SrcResult) > 15) && !mSymbolQuestionable(SrcResult.SymFlags)) WrStrErrorPos(ErrNum_OverRange, &ArgStr[2]);
  1350.             else
  1351.             {
  1352.               BAsmCode[0] = Code + 0x10;
  1353.               BAsmCode[1] = (WordVal(&SrcResult) << 4) + DestResult.Mode;
  1354.               CodeLen = 2;
  1355.             }
  1356.             break;
  1357.         }
  1358.         break;
  1359.       }
  1360.     }
  1361.   }
  1362. }
  1363.  
  1364. static void DecodeBit2(Word Code)
  1365. {
  1366.   Byte BOfs1, BOfs2;
  1367.   Word BAdr1, BAdr2;
  1368.  
  1369.   if (ChkArgCnt(2, 2)
  1370.    && DecodeBitAddr(&ArgStr[1], &BAdr1, &BOfs1, False)
  1371.    && DecodeBitAddr(&ArgStr[2], &BAdr2, &BOfs2, False))
  1372.   {
  1373.     CodeLen = 4;
  1374.     BAsmCode[0] = Code;
  1375.     BAsmCode[1] = BAdr2;
  1376.     BAsmCode[2] = BAdr1;
  1377.     BAsmCode[3] = (BOfs2 << 4) + BOfs1;
  1378.   }
  1379. }
  1380.  
  1381. static void DecodeBCLR_BSET(Word Code)
  1382. {
  1383.   Byte BOfs;
  1384.   Word BAdr;
  1385.  
  1386.   if (ChkArgCnt(1, 1)
  1387.    && DecodeBitAddr(&ArgStr[1], &BAdr, &BOfs, False))
  1388.   {
  1389.     CodeLen = 2;
  1390.     BAsmCode[0] = (BOfs << 4) + Code;
  1391.     BAsmCode[1] = BAdr;
  1392.   }
  1393. }
  1394.  
  1395. static void DecodeBFLDH_BFLDL(Word Code)
  1396. {
  1397.   Byte BOfs;
  1398.   Word BAdr;
  1399.  
  1400.   if (ChkArgCnt(3, 3))
  1401.   {
  1402.     strmaxcat(ArgStr[1].str.p_str, ".0", STRINGSIZE);
  1403.     if (DecodeBitAddr(&ArgStr[1], &BAdr, &BOfs, False))
  1404.     {
  1405.       tAdrResult Result;
  1406.  
  1407.       OpSize = eSymbolSize8Bit;
  1408.       BAsmCode[1] = BAdr;
  1409.       if (DecodeAdr(&ArgStr[2], MModImm, &Result) == ModImm)
  1410.       {
  1411.         BAsmCode[2] = Result.Vals[0];
  1412.         if (DecodeAdr(&ArgStr[3], MModImm, &Result) == ModImm)
  1413.         {
  1414.           BAsmCode[3] = Result.Vals[0];
  1415.           CodeLen = 4;
  1416.           BAsmCode[0] = Code;
  1417.           if (Code & 0x10)
  1418.           {
  1419.             BAdr = BAsmCode[2];
  1420.             BAsmCode[2] = BAsmCode[3];
  1421.             BAsmCode[3] = BAdr;
  1422.           }
  1423.         }
  1424.       }
  1425.     }
  1426.   }
  1427. }
  1428.  
  1429. static void DecodeJMP(Word Code)
  1430. {
  1431.   UNUSED(Code);
  1432.  
  1433.   if (ChkArgCnt(1, 2))
  1434.   {
  1435.     Byte cond_code;
  1436.     tAdrResult Result;
  1437.  
  1438.     if (ArgCnt == 1)
  1439.       cond_code = TrueCond;
  1440.     else if (!DecodeCondition(ArgStr[1].str.p_str, &cond_code))
  1441.     {
  1442.       WrStrErrorPos(ErrNum_UndefCond, &ArgStr[1]);
  1443.       return;
  1444.     }
  1445.  
  1446.     switch (DecodeAdr(&ArgStr[ArgCnt], MModAbs | MModLAbs | MModIReg | M_InCode, &Result))
  1447.     {
  1448.       case ModLAbs:
  1449.         if (cond_code != COND_CODE_TRUE) WrStrErrorPos(ErrNum_UndefCond, &ArgStr[1]);
  1450.         else
  1451.         {
  1452.           CodeLen = 2 + Result.Cnt;
  1453.           BAsmCode[0] = 0xfa;
  1454.           BAsmCode[1] = Result.Mode;
  1455.           memcpy(BAsmCode + 2, Result.Vals, Result.Cnt);
  1456.         }
  1457.         break;
  1458.       case ModAbs:
  1459.       {
  1460.         LongInt AdrDist = WordVal(&Result) - (EProgCounter() + 2);
  1461.         Boolean IsShort = (AdrDist <= 254) && (AdrDist >= -256) && ((AdrDist & 1) == 0);
  1462.  
  1463.         if (!Result.ForceSize)
  1464.           Result.ForceSize = IsShort ? eForceShort : eForceLong;
  1465.         if (Result.ForceSize == eForceShort)
  1466.         {
  1467.           if (!IsShort && !mSymbolQuestionable(Result.SymFlags)) WrStrErrorPos(ErrNum_JmpDistTooBig, &ArgStr[ArgCnt]);
  1468.           else
  1469.           {
  1470.             CodeLen = 2;
  1471.             BAsmCode[0] = 0x0d + (cond_code << 4);
  1472.             BAsmCode[1] = (AdrDist / 2) & 0xff;
  1473.           }
  1474.         }
  1475.         else
  1476.         {
  1477.           CodeLen = 2 + Result.Cnt;
  1478.           BAsmCode[0] = 0xea;
  1479.           BAsmCode[1] = cond_code << 4;
  1480.           memcpy(BAsmCode + 2, Result.Vals, Result.Cnt);
  1481.         }
  1482.         break;
  1483.       }
  1484.       case ModIReg:
  1485.         CodeLen = 2; BAsmCode[0] = 0x9c;
  1486.         BAsmCode[1] = (cond_code << 4) + Result.Mode;
  1487.         break;
  1488.     }
  1489.   }
  1490. }
  1491.  
  1492. static void DecodeCALL(Word Code)
  1493. {
  1494.   UNUSED(Code);
  1495.  
  1496.   if (ChkArgCnt(1, 2))
  1497.   {
  1498.     Byte cond_code;
  1499.     tAdrResult Result;
  1500.  
  1501.     if (ArgCnt == 1)
  1502.       cond_code = COND_CODE_TRUE;
  1503.     else if (!DecodeCondition(ArgStr[1].str.p_str, &cond_code))
  1504.     {
  1505.       WrStrErrorPos(ErrNum_UndefCond, &ArgStr[1]);
  1506.       return;
  1507.     }
  1508.  
  1509.     switch (DecodeAdr(&ArgStr[ArgCnt], MModAbs | MModLAbs | MModIReg | M_InCode, &Result))
  1510.     {
  1511.       case ModLAbs:
  1512.         if (cond_code != COND_CODE_TRUE) WrStrErrorPos(ErrNum_UndefCond, &ArgStr[1]);
  1513.         else
  1514.         {
  1515.           CodeLen = 2 + Result.Cnt;
  1516.           BAsmCode[0] = 0xda;
  1517.           BAsmCode[1] = Result.Mode;
  1518.           memcpy(BAsmCode + 2, Result.Vals, Result.Cnt);
  1519.         }
  1520.         break;
  1521.       case ModAbs:
  1522.       {
  1523.         LongInt AdrLong = WordVal(&Result) - (EProgCounter() + 2);
  1524.         Boolean IsShort = (AdrLong <= 254) && (AdrLong >= -256) && ((AdrLong & 1) == 0);
  1525.  
  1526.         if (!Result.ForceSize && (cond_code == COND_CODE_TRUE))
  1527.           Result.ForceSize = IsShort ? eForceShort : eForceLong;
  1528.         if (Result.ForceSize == eForceShort)
  1529.         {
  1530.           if (!IsShort && !mSymbolQuestionable(Result.SymFlags)) WrStrErrorPos(ErrNum_JmpDistTooBig, &ArgStr[ArgCnt]);
  1531.           else
  1532.           {
  1533.             CodeLen = 2;
  1534.             BAsmCode[0] = 0xbb;
  1535.             BAsmCode[1] = (AdrLong / 2) & 0xff;
  1536.           }
  1537.         }
  1538.         else
  1539.         {
  1540.           CodeLen = 2 + Result.Cnt;
  1541.           BAsmCode[0] = 0xca;
  1542.           BAsmCode[1] = 0x00 + (cond_code << 4);
  1543.           memcpy(BAsmCode + 2, Result.Vals, Result.Cnt);
  1544.         }
  1545.         break;
  1546.       }
  1547.       case ModIReg:
  1548.         CodeLen = 2;
  1549.         BAsmCode[0] = 0xab;
  1550.         BAsmCode[1] = (cond_code << 4) + Result.Mode;
  1551.         break;
  1552.     }
  1553.   }
  1554. }
  1555.  
  1556. static void DecodeJMPR(Word Code)
  1557. {
  1558.   UNUSED(Code);
  1559.  
  1560.   if (ChkArgCnt(1, 2))
  1561.   {
  1562.     Byte cond_code;
  1563.     Boolean OK;
  1564.     tSymbolFlags Flags;
  1565.     LongInt AdrLong;
  1566.  
  1567.     if (ArgCnt == 1)
  1568.       cond_code = COND_CODE_TRUE;
  1569.     else if (!DecodeCondition(ArgStr[1].str.p_str, &cond_code))
  1570.     {
  1571.       WrStrErrorPos(ErrNum_UndefCond, &ArgStr[1]);
  1572.       return;
  1573.     }
  1574.  
  1575.     AdrLong = EvalStrIntExpressionWithFlags(&ArgStr[ArgCnt], MemInt, &OK, &Flags) - (EProgCounter() + 2);
  1576.     if (OK)
  1577.     {
  1578.       if (AdrLong & 1) WrError(ErrNum_DistIsOdd);
  1579.       else if (!mSymbolQuestionable(Flags) && ((AdrLong > 254) || (AdrLong < -256))) WrError(ErrNum_JmpDistTooBig);
  1580.       else
  1581.       {
  1582.         CodeLen = 2;
  1583.         BAsmCode[0] = 0x0d + (cond_code << 4);
  1584.         BAsmCode[1] = (AdrLong / 2) & 0xff;
  1585.       }
  1586.     }
  1587.   }
  1588. }
  1589.  
  1590. static void DecodeCALLR(Word Code)
  1591. {
  1592.   UNUSED(Code);
  1593.  
  1594.   if (ChkArgCnt(1, 1))
  1595.   {
  1596.     Boolean OK;
  1597.     tSymbolFlags Flags;
  1598.     LongInt AdrLong = EvalStrIntExpressionWithFlags(&ArgStr[ArgCnt], MemInt, &OK, &Flags) - (EProgCounter() + 2);
  1599.     if (OK)
  1600.     {
  1601.       if (AdrLong & 1) WrError(ErrNum_DistIsOdd);
  1602.       else if (!mSymbolQuestionable(Flags) && ((AdrLong > 254) || (AdrLong < -256))) WrError(ErrNum_JmpDistTooBig);
  1603.       else
  1604.       {
  1605.         CodeLen = 2;
  1606.         BAsmCode[0] = 0xbb;
  1607.         BAsmCode[1] = (AdrLong / 2) & 0xff;
  1608.       }
  1609.     }
  1610.   }
  1611. }
  1612.  
  1613. static void DecodeJMPA_CALLA(Word Code)
  1614. {
  1615.   if (ChkArgCnt(1, 2))
  1616.   {
  1617.     Byte cond_code;
  1618.     Boolean OK;
  1619.     LongInt AdrLong;
  1620.     tSymbolFlags Flags;
  1621.  
  1622.     if (ArgCnt == 1)
  1623.       cond_code = COND_CODE_TRUE;
  1624.     else if (!DecodeCondition(ArgStr[1].str.p_str, &cond_code))
  1625.     {
  1626.       WrStrErrorPos(ErrNum_UndefCond, &ArgStr[1]);
  1627.       return;
  1628.     }
  1629.  
  1630.     AdrLong = EvalStrIntExpressionWithFlags(&ArgStr[ArgCnt], MemInt, &OK, &Flags);
  1631.     if (OK && ChkSamePage(AdrLong, EProgCounter(), 16, Flags))
  1632.     {
  1633.       CodeLen = 4;
  1634.       BAsmCode[0] = Code;
  1635.       BAsmCode[1] = 0x00 + (cond_code << 4);
  1636.       BAsmCode[2] = Lo(AdrLong);
  1637.       BAsmCode[3] = Hi(AdrLong);
  1638.     }
  1639.   }
  1640. }
  1641.  
  1642. static void DecodeJMPS_CALLS(Word Code)
  1643. {
  1644.   if (ChkArgCnt(1, 2))
  1645.   {
  1646.     Boolean OK;
  1647.     Word AdrWord;
  1648.     Byte AdrBank;
  1649.     LongInt AdrLong;
  1650.  
  1651.     if (ArgCnt == 1)
  1652.     {
  1653.       AdrLong = EvalStrIntExpression(&ArgStr[1], MemInt, &OK);
  1654.       AdrWord = AdrLong & 0xffff;
  1655.       AdrBank = AdrLong >> 16;
  1656.     }
  1657.     else
  1658.     {
  1659.       AdrWord = EvalStrIntExpression(&ArgStr[2], UInt16, &OK);
  1660.       AdrBank = OK ? EvalStrIntExpression(&ArgStr[1], MemInt2, &OK) : 0;
  1661.     }
  1662.     if (OK)
  1663.     {
  1664.       CodeLen = 4;
  1665.       BAsmCode[0] = Code;
  1666.       BAsmCode[1] = AdrBank;
  1667.       BAsmCode[2] = Lo(AdrWord);
  1668.       BAsmCode[3] = Hi(AdrWord);
  1669.     }
  1670.   }
  1671. }
  1672.  
  1673. static void DecodeJMPI_CALLI(Word Code)
  1674. {
  1675.   if (ChkArgCnt(1, 2))
  1676.   {
  1677.     Byte cond_code;
  1678.     tAdrResult Result;
  1679.  
  1680.     if (ArgCnt == 1)
  1681.       cond_code = COND_CODE_TRUE;
  1682.     else if (!DecodeCondition(ArgStr[1].str.p_str, &cond_code))
  1683.     {
  1684.       WrStrErrorPos(ErrNum_UndefCond, &ArgStr[1]);
  1685.       return;
  1686.     }
  1687.  
  1688.     switch (DecodeAdr(&ArgStr[ArgCnt], MModIReg | M_InCode, &Result))
  1689.     {
  1690.       case ModIReg:
  1691.         CodeLen = 2;
  1692.         BAsmCode[0] = Code;
  1693.         BAsmCode[1] = Result.Mode + (cond_code << 4);
  1694.         break;
  1695.     }
  1696.   }
  1697. }
  1698.  
  1699. static void DecodeBJmp(Word Code)
  1700. {
  1701.   Byte BOfs;
  1702.   Word BAdr;
  1703.  
  1704.   if (ChkArgCnt(2, 2)
  1705.    && DecodeBitAddr(&ArgStr[1], &BAdr, &BOfs, False))
  1706.   {
  1707.     Boolean OK;
  1708.     tSymbolFlags Flags;
  1709.     LongInt AdrLong = EvalStrIntExpressionWithFlags(&ArgStr[2], MemInt, &OK, &Flags) - (EProgCounter() + 4);
  1710.     if (OK)
  1711.     {
  1712.       if (AdrLong & 1) WrError(ErrNum_DistIsOdd);
  1713.       else if (!mSymbolQuestionable(Flags) && ((AdrLong < -256) || (AdrLong > 254))) WrError(ErrNum_JmpDistTooBig);
  1714.       else
  1715.       {
  1716.         CodeLen = 4; BAsmCode[0] = 0x8a + (Code << 4);
  1717.         BAsmCode[1] = BAdr;
  1718.         BAsmCode[2] = (AdrLong / 2) & 0xff;
  1719.         BAsmCode[3] = BOfs << 4;
  1720.       }
  1721.     }
  1722.   }
  1723. }
  1724.  
  1725. static void DecodePCALL(Word Code)
  1726. {
  1727.   UNUSED(Code);
  1728.  
  1729.   if (ChkArgCnt(2, 2))
  1730.   {
  1731.     tAdrResult Result;
  1732.  
  1733.     switch (DecodeAdr(&ArgStr[1], MModMReg, &Result))
  1734.     {
  1735.       case ModMReg:
  1736.         BAsmCode[1] = Result.Vals[0];
  1737.         switch (DecodeAdr(&ArgStr[2], MModAbs | M_InCode, &Result))
  1738.         {
  1739.           case ModAbs:
  1740.             CodeLen = 4;
  1741.             BAsmCode[0] = 0xe2;
  1742.             memcpy(BAsmCode + 2, Result.Vals, 2);
  1743.             break;
  1744.         }
  1745.         break;
  1746.     }
  1747.   }
  1748. }
  1749.  
  1750. static void DecodeRETP(Word Code)
  1751. {
  1752.   UNUSED(Code);
  1753.  
  1754.   if (ChkArgCnt(1, 1))
  1755.   {
  1756.     tAdrResult Result;
  1757.  
  1758.     switch (DecodeAdr(&ArgStr[1], MModMReg, &Result))
  1759.     {
  1760.       case ModMReg:
  1761.         BAsmCode[1] = Result.Vals[0];
  1762.         BAsmCode[0] = 0xeb;
  1763.         CodeLen = 2;
  1764.         if (SPChanged)
  1765.           WrXError(ErrNum_Pipeline, RegNames[5]);
  1766.         break;
  1767.     }
  1768.   }
  1769. }
  1770.  
  1771. static void DecodeTRAP(Word Code)
  1772. {
  1773.   UNUSED(Code);
  1774.  
  1775.   if (!ChkArgCnt(1, 1));
  1776.   else if (*ArgStr[1].str.p_str != '#') WrError(ErrNum_InvAddrMode);
  1777.   else
  1778.   {
  1779.     Boolean OK;
  1780.  
  1781.     BAsmCode[1] = EvalStrIntExpressionOffs(&ArgStr[1], 1, UInt7, &OK) << 1;
  1782.     if (OK)
  1783.     {
  1784.       BAsmCode[0] = 0x9b;
  1785.       CodeLen = 2;
  1786.     }
  1787.   }
  1788. }
  1789.  
  1790. static void DecodeATOMIC(Word Code)
  1791. {
  1792.   Byte HReg;
  1793.  
  1794.   UNUSED(Code);
  1795.  
  1796.   if (ChkArgCnt(1, 1)
  1797.    && ChkMinCPU(CPU80C167)
  1798.    && DecodePref(&ArgStr[1], &HReg))
  1799.   {
  1800.     CodeLen = 2;
  1801.     BAsmCode[0] = 0xd1;
  1802.     BAsmCode[1] = HReg << 4;
  1803.   }
  1804. }
  1805.  
  1806. static void DecodeEXTR(Word Code)
  1807. {
  1808.   Byte HReg;
  1809.  
  1810.   UNUSED(Code);
  1811.  
  1812.   if (ChkArgCnt(1, 1)
  1813.    && ChkMinCPU(CPU80C167)
  1814.    && DecodePref(&ArgStr[1], &HReg))
  1815.   {
  1816.     CodeLen = 2;
  1817.     BAsmCode[0] = 0xd1;
  1818.     BAsmCode[1] = 0x80 + (HReg << 4);
  1819.     ExtCounter = HReg + 1;
  1820.     ExtSFRs = True;
  1821.   }
  1822. }
  1823.  
  1824. static void DecodeEXTP_EXTPR(Word Code)
  1825. {
  1826.   Byte HReg;
  1827.  
  1828.   if (ChkArgCnt(2, 2)
  1829.    && ChkMinCPU(CPU80C167)
  1830.    && DecodePref(&ArgStr[2], &HReg))
  1831.   {
  1832.     tAdrResult Result;
  1833.  
  1834.     switch (DecodeAdr(&ArgStr[1], MModReg | MModImm, &Result))
  1835.     {
  1836.       case ModReg:
  1837.         CodeLen = 2;
  1838.         BAsmCode[0] = 0xdc;
  1839.         BAsmCode[1] = Code + 0x40 + (HReg << 4) + Result.Mode;
  1840.         ExtCounter = HReg + 1;
  1841.         MemMode = MemModeZeroPage;
  1842.         break;
  1843.       case ModImm:
  1844.         CodeLen = 4;
  1845.         BAsmCode[0] = 0xd7;
  1846.         BAsmCode[1] = Code + 0x40 + (HReg << 4);
  1847.         BAsmCode[2] = WordVal(&Result) & 0xff;
  1848.         BAsmCode[3] = (WordVal(&Result) >> 8) & 3;
  1849.         ExtCounter = HReg + 1;
  1850.         MemMode = MemModeFixedPage;
  1851.         MemPage = WordVal(&Result) & 0x3ff;
  1852.         break;
  1853.     }
  1854.   }
  1855. }
  1856.  
  1857. static void DecodeEXTS_EXTSR(Word Code)
  1858. {
  1859.   Byte HReg;
  1860.  
  1861.   OpSize = eSymbolSize8Bit;
  1862.   if (ChkArgCnt(2, 2)
  1863.    && ChkMinCPU(CPU80C167)
  1864.    && DecodePref(&ArgStr[2], &HReg))
  1865.   {
  1866.     tAdrResult Result;
  1867.  
  1868.     switch (DecodeAdr(&ArgStr[1], MModReg | MModImm, &Result))
  1869.     {
  1870.       case ModReg:
  1871.         CodeLen = 2;
  1872.         BAsmCode[0] = 0xdc;
  1873.         BAsmCode[1] = Code + 0x00 + (HReg << 4) + Result.Mode;
  1874.         ExtCounter = HReg + 1;
  1875.         MemMode = MemModeNoCheck;
  1876.         break;
  1877.       case ModImm:
  1878.         CodeLen = 4;
  1879.         BAsmCode[0] = 0xd7;
  1880.         BAsmCode[1] = Code + 0x00 + (HReg << 4);
  1881.         BAsmCode[2] = Result.Vals[0];
  1882.         BAsmCode[3] = 0;
  1883.         ExtCounter = HReg + 1;
  1884.         MemMode = MemModeFixedBank;
  1885.         MemPage = Result.Vals[0];
  1886.         break;
  1887.     }
  1888.   }
  1889. }
  1890.  
  1891. static void DecodeBIT(Word Code)
  1892. {
  1893.   Word Adr;
  1894.   Byte Bit;
  1895.  
  1896.   UNUSED(Code);
  1897.  
  1898.  if (ChkArgCnt(1, 1)
  1899.   && DecodeBitAddr(&ArgStr[1], &Adr, &Bit, True))
  1900.  {
  1901.    PushLocHandle(-1);
  1902.    EnterIntSymbol(&LabPart, (Adr << 4) + Bit, SegNone, False);
  1903.    PopLocHandle();
  1904.    as_snprintf(ListLine, STRINGSIZE, "=%02xH.%1x", (unsigned)Adr, (unsigned)Bit);
  1905.  }
  1906. }
  1907.  
  1908. /*-------------------------------------------------------------------------*/
  1909.  
  1910. static void AddBInstTable(const char *NName, Word NCode, InstProc Proc)
  1911. {
  1912.   char BName[30];
  1913.  
  1914.   AddInstTable(InstTable, NName, NCode | (eSymbolSize16Bit << 8), Proc);
  1915.   as_snprintf(BName, sizeof(BName), "%sB", NName);
  1916.   AddInstTable(InstTable, BName, NCode | (eSymbolSize8Bit << 8), Proc);
  1917. }
  1918.  
  1919. static void AddFixed(const char *NName, CPUVar NMin, Word NCode1, Word NCode2)
  1920. {
  1921.   order_array_rsv_end(FixedOrders, BaseOrder);
  1922.   FixedOrders[InstrZ].MinCPU = NMin;
  1923.   FixedOrders[InstrZ].Code1 = NCode1;
  1924.   FixedOrders[InstrZ].Code2 = NCode2;
  1925.   AddInstTable(InstTable, NName, InstrZ++, DecodeFixed);
  1926. }
  1927.  
  1928. static void AddShift(const char *NName, Byte NCode)
  1929. {
  1930.   AddInstTable(InstTable, NName, NCode, DecodeShift);
  1931. }
  1932.  
  1933. static void AddBit2(const char *NName, Byte NCode)
  1934. {
  1935.   AddInstTable(InstTable, NName, NCode, DecodeBit2);
  1936. }
  1937.  
  1938. static void AddLoop(const char *NName, Byte NCode)
  1939. {
  1940.   AddInstTable(InstTable, NName, NCode, DecodeLoop);
  1941. }
  1942.  
  1943. static void AddCondition(const char *NName, Byte NCode)
  1944. {
  1945.   order_array_rsv_end(Conditions, Condition);
  1946.   Conditions[InstrZ].Name = NName;
  1947.   Conditions[InstrZ++].Code = NCode;
  1948. }
  1949.  
  1950. static void InitFields(void)
  1951. {
  1952.   InstTable = CreateInstTable(201);
  1953.   SetDynamicInstTable(InstTable);
  1954.   AddBInstTable("MOV", 0, DecodeMOV);
  1955.   AddInstTable(InstTable, "MOVBS", 0x10, DecodeMOVBS_MOVBZ);
  1956.   AddInstTable(InstTable, "MOVBZ", 0x00, DecodeMOVBS_MOVBZ);
  1957.   AddInstTable(InstTable, "PUSH", 0xec, DecodePUSH_POP);
  1958.   AddInstTable(InstTable, "POP", 0xfc, DecodePUSH_POP);
  1959.   AddInstTable(InstTable, "SCXT", 0, DecodeSCXT);
  1960.   AddBInstTable("CPL", 0x91, DecodeCPL_NEG);
  1961.   AddBInstTable("NEG", 0x81, DecodeCPL_NEG);
  1962.   AddInstTable(InstTable, "BCLR", 0x0e, DecodeBCLR_BSET);
  1963.   AddInstTable(InstTable, "BSET", 0x0f, DecodeBCLR_BSET);
  1964.   AddInstTable(InstTable, "BFLDL", 0x0a, DecodeBFLDH_BFLDL);
  1965.   AddInstTable(InstTable, "BFLDH", 0x1a, DecodeBFLDH_BFLDL);
  1966.   AddInstTable(InstTable, "JMP", 0, DecodeJMP);
  1967.   AddInstTable(InstTable, "CALL", 0, DecodeCALL);
  1968.   AddInstTable(InstTable, "JMPR", 0, DecodeJMPR);
  1969.   AddInstTable(InstTable, "CALLR", 0, DecodeCALLR);
  1970.   AddInstTable(InstTable, "JMPA", 0xea, DecodeJMPA_CALLA);
  1971.   AddInstTable(InstTable, "CALLA", 0xca, DecodeJMPA_CALLA);
  1972.   AddInstTable(InstTable, "JMPS", 0xfa, DecodeJMPS_CALLS);
  1973.   AddInstTable(InstTable, "CALLS", 0xda, DecodeJMPS_CALLS);
  1974.   AddInstTable(InstTable, "JMPI", 0x9c, DecodeJMPI_CALLI);
  1975.   AddInstTable(InstTable, "CALLI", 0xab, DecodeJMPI_CALLI);
  1976.   AddInstTable(InstTable, "PCALL", 0, DecodePCALL);
  1977.   AddInstTable(InstTable, "RETP", 0, DecodeRETP);
  1978.   AddInstTable(InstTable, "TRAP", 0, DecodeTRAP);
  1979.   AddInstTable(InstTable, "ATOMIC", 0, DecodeATOMIC);
  1980.   AddInstTable(InstTable, "EXTR", 0, DecodeEXTR);
  1981.   AddInstTable(InstTable, "EXTP", 0x00, DecodeEXTP_EXTPR);
  1982.   AddInstTable(InstTable, "EXTPR", 0x80, DecodeEXTP_EXTPR);
  1983.   AddInstTable(InstTable, "EXTS", 0x00, DecodeEXTS_EXTSR);
  1984.   AddInstTable(InstTable, "EXTSR", 0x80, DecodeEXTS_EXTSR);
  1985.  
  1986.   InstrZ = 0;
  1987.   AddFixed("DISWDT", CPU80C166, 0x5aa5, 0xa5a5);
  1988.   AddFixed("EINIT" , CPU80C166, 0x4ab5, 0xb5b5);
  1989.   AddFixed("IDLE"  , CPU80C166, 0x7887, 0x8787);
  1990.   AddFixed("NOP"   , CPU80C166, 0x00cc, 0x0000);
  1991.   AddFixed("PWRDN" , CPU80C166, 0x6897, 0x9797);
  1992.   AddFixed("RET"   , CPU80C166, 0x00cb, 0x0000);
  1993.   AddFixed("RETI"  , CPU80C166, 0x88fb, 0x0000);
  1994.   AddFixed("RETS"  , CPU80C166, 0x00db, 0x0000);
  1995.   AddFixed("SRST"  , CPU80C166, 0x48b7, 0xb7b7);
  1996.   AddFixed("SRVWDT", CPU80C166, 0x58a7, 0xa7a7);
  1997.  
  1998.   InstrZ = 0;
  1999.   AddCondition("UC" , COND_CODE_TRUE); AddCondition("Z"  , 0x2);
  2000.   AddCondition("NZ" , 0x3); AddCondition("V"  , 0x4);
  2001.   AddCondition("NV" , 0x5); AddCondition("N"  , 0x6);
  2002.   AddCondition("NN" , 0x7); AddCondition("C"  , 0x8);
  2003.   AddCondition("NC" , 0x9); AddCondition("EQ" , 0x2);
  2004.   AddCondition("NE" , 0x3); AddCondition("ULT", 0x8);
  2005.   AddCondition("ULE", 0xf); AddCondition("UGE", 0x9);
  2006.   AddCondition("UGT", 0xe); AddCondition("SLT", 0xc);
  2007.   AddCondition("SLE", 0xb); AddCondition("SGE", 0xd);
  2008.   AddCondition("SGT", 0xa); AddCondition("NET", 0x1);
  2009.   AddCondition(NULL, 0);
  2010.  
  2011.   InstrZ = 0;
  2012.   AddBInstTable("ADD" , InstrZ++, DecodeALU2);
  2013.   AddBInstTable("ADDC", InstrZ++, DecodeALU2);
  2014.   AddBInstTable("SUB" , InstrZ++, DecodeALU2);
  2015.   AddBInstTable("SUBC", InstrZ++, DecodeALU2);
  2016.   AddBInstTable("CMP" , InstrZ++, DecodeALU2);
  2017.   AddBInstTable("XOR" , InstrZ++, DecodeALU2);
  2018.   AddBInstTable("AND" , InstrZ++, DecodeALU2);
  2019.   AddBInstTable("OR"  , InstrZ++, DecodeALU2);
  2020.  
  2021.   AddShift("ASHR", 0xac); AddShift("ROL" , 0x0c);
  2022.   AddShift("ROR" , 0x2c); AddShift("SHL" , 0x4c);
  2023.   AddShift("SHR" , 0x6c);
  2024.  
  2025.   AddBit2("BAND", 0x6a); AddBit2("BCMP" , 0x2a);
  2026.   AddBit2("BMOV", 0x4a); AddBit2("BMOVN", 0x3a);
  2027.   AddBit2("BOR" , 0x5a); AddBit2("BXOR" , 0x7a);
  2028.  
  2029.   AddLoop("CMPD1", 0xa0); AddLoop("CMPD2", 0xb0);
  2030.   AddLoop("CMPI1", 0x80); AddLoop("CMPI2", 0x90);
  2031.  
  2032.   InstrZ = 0;
  2033.   AddInstTable(InstTable, "DIV"  , InstrZ++, DecodeDiv);
  2034.   AddInstTable(InstTable, "DIVU" , InstrZ++, DecodeDiv);
  2035.   AddInstTable(InstTable, "DIVL" , InstrZ++, DecodeDiv);
  2036.   AddInstTable(InstTable, "DIVLU", InstrZ++, DecodeDiv);
  2037.  
  2038.   InstrZ = 0;
  2039.   AddInstTable(InstTable, "JB"   , InstrZ++, DecodeBJmp);
  2040.   AddInstTable(InstTable, "JNB"  , InstrZ++, DecodeBJmp);
  2041.   AddInstTable(InstTable, "JBC"  , InstrZ++, DecodeBJmp);
  2042.   AddInstTable(InstTable, "JNBS" , InstrZ++, DecodeBJmp);
  2043.  
  2044.   InstrZ = 0;
  2045.   AddInstTable(InstTable, "MUL"  , InstrZ++, DecodeMul);
  2046.   AddInstTable(InstTable, "MULU" , InstrZ++, DecodeMul);
  2047.   AddInstTable(InstTable, "PRIOR", InstrZ++, DecodeMul);
  2048.  
  2049.   AddInstTable(InstTable, "BIT" , 0, DecodeBIT);
  2050.   AddInstTable(InstTable, "REG" , 0, CodeREG);
  2051. }
  2052.  
  2053. static void DeinitFields(void)
  2054. {
  2055.   DestroyInstTable(InstTable);
  2056.   order_array_free(FixedOrders);
  2057.   order_array_free(Conditions);
  2058. }
  2059.  
  2060. static void MakeCode_166(void)
  2061. {
  2062.   int z;
  2063.  
  2064.   CodeLen = 0;
  2065.   DontPrint = False;
  2066.   OpSize = eSymbolSize16Bit;
  2067.  
  2068.   /* zu ignorierendes */
  2069.  
  2070.   if (Memo(""))
  2071.     return;
  2072.  
  2073.   /* Pseudoanweisungen */
  2074.  
  2075.   if (DecodeIntelPseudo(False))
  2076.     return;
  2077.  
  2078.   /* Pipeline-Flags weiterschalten */
  2079.  
  2080.   SPChanged = N_SPChanged; N_SPChanged = False;
  2081.   CPChanged = N_CPChanged; N_CPChanged = False;
  2082.   for (z = 0; z < DPPCount; z++)
  2083.   {
  2084.     DPPChanged[z] = N_DPPChanged[z];
  2085.     N_DPPChanged[z] = False;
  2086.   }
  2087.  
  2088.   /* Praefixe herunterzaehlen */
  2089.  
  2090.   if (ExtCounter >= 0)
  2091.    if (--ExtCounter < 0)
  2092.    {
  2093.      MemMode = MemModeStd;
  2094.      ExtSFRs = False;
  2095.    }
  2096.  
  2097.   if (!LookupInstTable(InstTable, OpPart.str.p_str))
  2098.     WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
  2099. }
  2100.  
  2101. /*!------------------------------------------------------------------------
  2102.  * \fn     InternSymbol_166(char *pArg, TempResult *pResult)
  2103.  * \brief  handle built-in symbols on C16x
  2104.  * \param  pArg source argument
  2105.  * \param  pResult result buffer
  2106.  * ------------------------------------------------------------------------ */
  2107.  
  2108. static void InternSymbol_166(char *pArg, TempResult *pResult)
  2109. {
  2110.   tRegInt Erg;
  2111.   tSymbolSize Size;
  2112.  
  2113.   if (IsRegCore(pArg, &Erg, &Size))
  2114.   {
  2115.     pResult->Typ = TempReg;
  2116.     pResult->DataSize = Size;
  2117.     pResult->Contents.RegDescr.Reg = Erg;
  2118.     pResult->Contents.RegDescr.Dissect = DissectReg_166;
  2119.     pResult->Contents.RegDescr.compare = NULL;
  2120.   }
  2121. }
  2122.  
  2123. static void InitCode_166(void)
  2124. {
  2125.   int z;
  2126.  
  2127.   for (z = 0; z < DPPCount; z++)
  2128.   {
  2129.     DPPAssumes[z] = z;
  2130.     N_DPPChanged[z] = False;
  2131.   }
  2132.   N_CPChanged = False;
  2133.   N_SPChanged = False;
  2134.  
  2135.   MemMode = MemModeStd;
  2136.   ExtSFRs = False;
  2137.   ExtCounter = (-1);
  2138. }
  2139.  
  2140. static Boolean IsDef_166(void)
  2141. {
  2142.   return (Memo("BIT")) || (Memo("REG"));
  2143. }
  2144.  
  2145. static void SwitchFrom_166(void)
  2146. {
  2147.   DeinitFields();
  2148. }
  2149.  
  2150. static void SwitchTo_166(void)
  2151. {
  2152.   Byte z;
  2153.  
  2154.   TurnWords = False;
  2155.   SetIntConstMode(eIntConstModeIntel);
  2156.   OpSize = eSymbolSize16Bit;
  2157.  
  2158.   PCSymbol = "$";
  2159.   HeaderID = 0x4c;
  2160.   NOPCode = 0xcc00;
  2161.   DivideChars = ",";
  2162.   HasAttrs = False;
  2163.  
  2164.   ValidSegs = (1 << SegCode);
  2165.   Grans[SegCode] = 1; ListGrans[SegCode] = 1; SegInits[SegCode] = 0;
  2166.  
  2167.   MakeCode = MakeCode_166;
  2168.   IsDef = IsDef_166;
  2169.   InternSymbol = InternSymbol_166;
  2170.   DissectReg = DissectReg_166;
  2171.   SwitchFrom = SwitchFrom_166;
  2172.  
  2173.   if (MomCPU == CPU80C166)
  2174.   {
  2175.     MemInt = UInt18;
  2176.     MemInt2 = UInt2;
  2177.     ASSUME166s[0].Max = 15;
  2178.     SegLimits[SegCode] = 0x3ffffl;
  2179.   }
  2180.   else
  2181.   {
  2182.     MemInt = UInt24;
  2183.     MemInt2 = UInt8;
  2184.     ASSUME166s[0].Max = 1023;
  2185.     SegLimits[SegCode] = 0xffffffl;
  2186.   }
  2187.   for (z = 1; z < 4; z++)
  2188.     ASSUME166s[z].Max = ASSUME166s[0].Max;
  2189.  
  2190.   pASSUMERecs = ASSUME166s;
  2191.   ASSUMERecCnt = ASSUME166Count;
  2192.  
  2193.   InitFields();
  2194. }
  2195.  
  2196. void code166_init(void)
  2197. {
  2198.   CPU80C166 = AddCPU("80C166", SwitchTo_166);
  2199.   CPU80C167 = AddCPU("80C167", SwitchTo_166);
  2200.   CPU80C167CS = AddCPU("80C167CS", SwitchTo_166);
  2201.  
  2202.   AddInitPassProc(InitCode_166);
  2203. }
  2204.