Subversion Repositories pentevo

Rev

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

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