Subversion Repositories pentevo

Rev

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

  1. /* code96c141.c */
  2. /*****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
  4. /*                                                                           */
  5. /* AS-Portierung                                                             */
  6. /*                                                                           */
  7. /* Codegenerator TLCS-900(L)                                                 */
  8. /*                                                                           */
  9. /* Historie: 27. 6.1996 Grundsteinlegung                                     */
  10. /*                                                                           */
  11. /*****************************************************************************/
  12.  
  13. #include "stdinc.h"
  14. #include <string.h>
  15. #include <ctype.h>
  16.  
  17. #include "nls.h"
  18. #include "bpemu.h"
  19. #include "strutil.h"
  20.  
  21. #include "asmdef.h"
  22. #include "asmsub.h"
  23. #include "asmpars.h"
  24. #include "asmallg.h"
  25. #include "onoff_common.h"
  26. #include "errmsg.h"
  27. #include "codepseudo.h"
  28. #include "intpseudo.h"
  29. #include "asmitree.h"
  30. #include "asmcode.h"
  31. #include "codevars.h"
  32. #include "errmsg.h"
  33. #include "operator.h"
  34.  
  35. #include "code96c141.h"
  36.  
  37. /*-------------------------------------------------------------------------*/
  38. /* Daten */
  39.  
  40. typedef struct
  41. {
  42.   Word Code;
  43.   Byte CPUFlag;
  44.   Boolean InSup;
  45. } FixedOrder;
  46.  
  47. typedef struct
  48. {
  49.   Word Code;
  50.   Boolean InSup;
  51.   Byte MinMax,MaxMax;
  52.   ShortInt Default;
  53. } ImmOrder;
  54.  
  55. typedef struct
  56. {
  57.   Word Code;
  58.   Byte OpMask;
  59. } RegOrder;
  60.  
  61. typedef struct
  62. {
  63.   const char *Name;
  64.   Byte Code;
  65. } Condition;
  66.  
  67. #define ModNone (-1)
  68. #define ModReg 0
  69. #define MModReg (1  << ModReg)
  70. #define ModXReg 1
  71. #define MModXReg (1 << ModXReg)
  72. #define ModMem 2
  73. #define MModMem (1  << ModMem)
  74. #define ModImm 3
  75. #define MModImm (1  << ModImm)
  76. #define ModCReg 4
  77. #define MModCReg (1 << ModCReg)
  78.  
  79. #define COND_CODE_TRUE 8
  80.  
  81. static FixedOrder *FixedOrders;
  82. static RegOrder *RegOrders;
  83. static ImmOrder *ImmOrders;
  84. static Condition *Conditions;
  85.  
  86. static ShortInt AdrType;
  87. static ShortInt OpSize;        /* -1/0/1/2 = nix/Byte/Word/Long */
  88. static Byte AdrMode;
  89. static Byte AdrVals[10];
  90. static Boolean MinOneIs0, AutoIncSizeNeeded;
  91.  
  92. static CPUVar CPU96C141,CPU93C141;
  93.  
  94. /*---------------------------------------------------------------------------*/
  95. /* Adressparser */
  96.  
  97. static Boolean IsRegBase(Byte No, tSymbolSize Size)
  98. {
  99.   return ((Size == eSymbolSize32Bit)
  100.        || ((Size == eSymbolSize16Bit) && (No < 0xf0) && (!MaxMode) && ((No & 3) == 0)));
  101. }
  102.  
  103. static void ChkMaxMode(Boolean MustMax, tRegEvalResult *Result)
  104. {
  105.   if (MaxMode != MustMax)
  106.   {
  107.     *Result = eRegAbort;
  108.     WrError((MustMax) ? ErrNum_OnlyInMaxmode : ErrNum_NotInMaxmode);
  109.   }
  110. }
  111.  
  112. static Boolean IsQuot(char Ch)
  113. {
  114.   return ((Ch == '\'') || (Ch == '`'));
  115. }
  116.  
  117. static tRegEvalResult CodeEReg(char *Asc, Byte *ErgNo, tSymbolSize *ErgSize)
  118. {
  119. #define RegCnt 8
  120.   static const char Reg8Names[RegCnt + 1] = "AWCBEDLH";
  121.   static const char Reg16Names[RegCnt][3] =
  122.   {
  123.     "WA" ,"BC" ,"DE" ,"HL" ,"IX" ,"IY" ,"IZ" ,"SP"
  124.   };
  125.   static const char Reg32Names[RegCnt][4] =
  126.   {
  127.     "XWA","XBC","XDE","XHL","XIX","XIY","XIZ","XSP"
  128.   };
  129.  
  130.   int z, l = strlen(Asc);
  131.   const char *pos;
  132.   String HAsc, Asc_N;
  133.   tRegEvalResult Result;
  134.  
  135.   strmaxcpy(Asc_N, Asc, STRINGSIZE);
  136.   NLS_UpString(Asc_N);
  137.   Asc = Asc_N;
  138.  
  139.   Result = eIsReg;
  140.  
  141.   /* mom. Bank ? */
  142.  
  143.   if (l == 1)
  144.   {
  145.     pos = strchr(Reg8Names, *Asc);
  146.     if (pos)
  147.     {
  148.      z = pos - Reg8Names;
  149.      *ErgNo = 0xe0 + ((z & 6) << 1) + (z & 1);
  150.      *ErgSize = eSymbolSize8Bit;
  151.      return Result;
  152.     }
  153.   }
  154.   for (z = 0; z < RegCnt; z++)
  155.   {
  156.     if (!strcmp(Asc, Reg16Names[z]))
  157.     {
  158.       *ErgNo = 0xe0 + (z << 2);
  159.       *ErgSize = eSymbolSize16Bit;
  160.       return Result;
  161.     }
  162.     if (!strcmp(Asc, Reg32Names[z]))
  163.     {
  164.       *ErgNo = 0xe0 + (z << 2);
  165.       *ErgSize = eSymbolSize32Bit;
  166.       if (z < 4)
  167.         ChkMaxMode(True, &Result);
  168.       return Result;
  169.     }
  170.   }
  171.  
  172.   /* Bankregister, 8 Bit ? */
  173.  
  174.   if ((l == 3) && ((*Asc == 'Q') || (*Asc == 'R')) && ((Asc[2] >= '0') && (Asc[2] <= '7')))
  175.   {
  176.     for (z = 0; z < RegCnt; z++)
  177.       if (Asc[1] == Reg8Names[z])
  178.       {
  179.         *ErgNo = ((Asc[2] - '0') << 4) + ((z & 6) << 1) + (z & 1);
  180.         if (*Asc == 'Q')
  181.         {
  182.           *ErgNo |= 2;
  183.           ChkMaxMode(True, &Result);
  184.         }
  185.         if (((*Asc == 'Q') || (MaxMode)) && (Asc[2] > '3'))
  186.         {
  187.           WrError(ErrNum_OverRange);
  188.           Result = eRegAbort;
  189.         }
  190.         *ErgSize = eSymbolSize8Bit;
  191.         return Result;
  192.       }
  193.   }
  194.  
  195.   /* Bankregister, 16 Bit ? */
  196.  
  197.   if ((l == 4) && ((*Asc == 'Q') || (*Asc == 'R')) && ((Asc[3] >= '0') && (Asc[3] <= '7')))
  198.   {
  199.     strcpy(HAsc, Asc + 1);
  200.     HAsc[2] = '\0';
  201.     for (z = 0; z < RegCnt >> 1; z++)
  202.       if (!strcmp(HAsc, Reg16Names[z]))
  203.       {
  204.         *ErgNo = ((Asc[3] - '0') << 4) + (z << 2);
  205.         if (*Asc == 'Q')
  206.         {
  207.           *ErgNo |= 2;
  208.           ChkMaxMode(True, &Result);
  209.         }
  210.         if (((*Asc == 'Q') || (MaxMode)) && (Asc[3] > '3'))
  211.         {
  212.           WrError(ErrNum_OverRange);
  213.           Result = eRegAbort;
  214.         }
  215.         *ErgSize = eSymbolSize16Bit;
  216.         return Result;
  217.       }
  218.   }
  219.  
  220.   /* Bankregister, 32 Bit ? */
  221.  
  222.   if ((l == 4) && ((Asc[3] >= '0') && (Asc[3] <= '7')))
  223.   {
  224.     for (z = 0; z < RegCnt >> 1; z++)
  225.      if (strncmp(Asc, Reg32Names[z], 3) == 0)
  226.      {
  227.        *ErgNo = ((Asc[3] - '0') << 4) + (z << 2);
  228.        ChkMaxMode(True, &Result);
  229.        if (Asc[3] > '3')
  230.        {
  231.          WrError(ErrNum_OverRange);
  232.          Result = eRegAbort;
  233.        }
  234.        *ErgSize = eSymbolSize32Bit;
  235.        return Result;
  236.      }
  237.   }
  238.  
  239.   /* obere 8-Bit-Haelften momentaner Bank ? */
  240.  
  241.   if ((l == 2) && (*Asc == 'Q'))
  242.    for (z = 0; z < RegCnt; z++)
  243.     if (Asc[1] == Reg8Names[z])
  244.     {
  245.       *ErgNo = 0xe2 + ((z & 6) << 1) + (z & 1);
  246.       ChkMaxMode(True, &Result);
  247.       *ErgSize = eSymbolSize8Bit;
  248.       return Result;
  249.     }
  250.  
  251.   /* obere 16-Bit-Haelften momentaner Bank und von XIX..XSP ? */
  252.  
  253.   if ((l == 3) && (*Asc == 'Q'))
  254.   {
  255.     for (z = 0; z < RegCnt; z++)
  256.       if (!strcmp(Asc + 1, Reg16Names[z]))
  257.       {
  258.         *ErgNo = 0xe2 + (z << 2);
  259.         if (z < 4) ChkMaxMode(True, &Result);
  260.         *ErgSize = eSymbolSize16Bit;
  261.         return Result;
  262.       }
  263.   }
  264.  
  265.   /* 8-Bit-Teile von XIX..XSP ? */
  266.  
  267.   if (((l == 3) || ((l == 4) && (*Asc == 'Q')))
  268.   && ((Asc[l - 1] == 'L') || (Asc[l - 1] == 'H')))
  269.   {
  270.     strcpy(HAsc, Asc + (l - 3)); HAsc[2] = '\0';
  271.     for (z = 0; z < RegCnt >> 1; z++)
  272.       if (!strcmp(HAsc, Reg16Names[z + 4]))
  273.       {
  274.         *ErgNo = 0xf0 + (z << 2) + ((l - 3) << 1) + (Ord(Asc[l - 1] == 'H'));
  275.         *ErgSize = eSymbolSize8Bit;
  276.         return Result;
  277.       }
  278.   }
  279.  
  280.   /* 8-Bit-Teile vorheriger Bank ? */
  281.  
  282.   if (((l == 2) || ((l == 3) && (*Asc == 'Q'))) && (IsQuot(Asc[l - 1])))
  283.    for (z = 0; z < RegCnt; z++)
  284.      if (Asc[l - 2] == Reg8Names[z])
  285.      {
  286.        *ErgNo = 0xd0 + ((z & 6) << 1) + ((strlen(Asc) - 2) << 1) + (z & 1);
  287.        if (l == 3) ChkMaxMode(True, &Result);
  288.        *ErgSize = eSymbolSize8Bit;
  289.        return Result;
  290.      }
  291.  
  292.   /* 16-Bit-Teile vorheriger Bank ? */
  293.  
  294.   if (((l == 3) || ((l == 4) && (*Asc == 'Q'))) && (IsQuot(Asc[l - 1])))
  295.   {
  296.     strcpy(HAsc, Asc + 1);
  297.     HAsc[l - 2] = '\0';
  298.     for (z = 0; z < RegCnt >> 1; z++)
  299.       if (!strcmp(HAsc, Reg16Names[z]))
  300.       {
  301.         *ErgNo = 0xd0 + (z << 2) + ((strlen(Asc) - 3) << 1);
  302.         if (l == 4) ChkMaxMode(True, &Result);
  303.         *ErgSize = eSymbolSize16Bit;
  304.         return Result;
  305.       }
  306.   }
  307.  
  308.   /* 32-Bit-Register vorheriger Bank ? */
  309.  
  310.   if ((l == 4) && (IsQuot(Asc[3])))
  311.   {
  312.     strcpy(HAsc, Asc); HAsc[3] = '\0';
  313.     for (z = 0; z < RegCnt >> 1; z++)
  314.       if (!strcmp(HAsc, Reg32Names[z]))
  315.       {
  316.         *ErgNo = 0xd0 + (z << 2);
  317.         ChkMaxMode(True, &Result);
  318.         *ErgSize = eSymbolSize32Bit;
  319.         return Result;
  320.       }
  321.   }
  322.  
  323.   return (Result = eIsNoReg);
  324. }
  325.  
  326. static void ChkL(CPUVar Must, tRegEvalResult *Result)
  327. {
  328.   if (MomCPU != Must)
  329.   {
  330.     WrError(ErrNum_InvCtrlReg);
  331.     *Result = eRegAbort;
  332.   }
  333. }
  334.  
  335. static tRegEvalResult CodeCReg(char *Asc, Byte *ErgNo, tSymbolSize *ErgSize)
  336. {
  337.   tRegEvalResult Result = eIsReg;
  338.  
  339.   if (!as_strcasecmp(Asc, "NSP"))
  340.   {
  341.     *ErgNo = 0x3c;
  342.     *ErgSize = eSymbolSize16Bit;
  343.     ChkL(CPU96C141, &Result);
  344.     return Result;
  345.   }
  346.   if (!as_strcasecmp(Asc, "XNSP"))
  347.   {
  348.     *ErgNo = 0x3c;
  349.     *ErgSize = eSymbolSize32Bit;
  350.     ChkL(CPU96C141, &Result);
  351.     return Result;
  352.   }
  353.   if (!as_strcasecmp(Asc,"INTNEST"))
  354.   {
  355.     *ErgNo = 0x3c;
  356.     *ErgSize = eSymbolSize16Bit;
  357.     ChkL(CPU93C141, &Result);
  358.     return Result;
  359.   }
  360.   if ((strlen(Asc) == 5)
  361.    && (!as_strncasecmp(Asc, "DMA", 3))
  362.    && (Asc[4] >= '0') && (Asc[4] <= '3'))
  363.   {
  364.     switch (as_toupper(Asc[3]))
  365.     {
  366.       case 'S':
  367.         *ErgNo = (Asc[4] - '0') * 4;
  368.         *ErgSize = eSymbolSize32Bit;
  369.         return Result;
  370.       case 'D':
  371.         *ErgNo = (Asc[4] - '0') * 4 + 0x10;
  372.         *ErgSize = eSymbolSize32Bit;
  373.         return Result;
  374.       case 'M':
  375.         *ErgNo = (Asc[4] - '0') * 4 + 0x22;
  376.         *ErgSize = eSymbolSize8Bit;
  377.         return Result;
  378.       case 'C':
  379.         *ErgNo = (Asc[4] - '0') * 4 + 0x20;
  380.         *ErgSize = eSymbolSize16Bit;
  381.         return Result;
  382.     }
  383.   }
  384.  
  385.   return (Result = eIsNoReg);
  386. }
  387.  
  388.  
  389. typedef struct
  390. {
  391.   char *Name;
  392.   Byte Num;
  393.   Boolean InMax, InMin;
  394. } RegDesc;
  395.  
  396.  
  397. static void SetOpSize(ShortInt NewSize)
  398. {
  399.   if (OpSize == -1)
  400.     OpSize = NewSize;
  401.   else if (OpSize != NewSize)
  402.   {
  403.     WrError(ErrNum_ConfOpSizes);
  404.     AdrType = ModNone;
  405.   }
  406. }
  407.  
  408. static Boolean IsRegCurrent(Byte No, tSymbolSize Size, Byte *Erg)
  409. {
  410.   switch (Size)
  411.   {
  412.     case eSymbolSize8Bit:
  413.       if ((No & 0xf2) == 0xe0)
  414.       {
  415.         *Erg = ((No & 0x0c) >> 1) + ((No & 1) ^ 1);
  416.         return True;
  417.       }
  418.       else
  419.         return False;
  420.     case eSymbolSize16Bit:
  421.     case eSymbolSize32Bit:
  422.       if ((No & 0xe3) == 0xe0)
  423.       {
  424.         *Erg = ((No & 0x1c) >> 2);
  425.         return True;
  426.       }
  427.       else
  428.         return False;
  429.     default:
  430.       return False;
  431.   }
  432. }
  433.  
  434. static const char Sizes[] = "124";
  435.  
  436. static Boolean GetPostInc(const char *pArg, int ArgLen, tSymbolSize *pOpSize, int *pCutoffRight)
  437. {
  438.   const char *pPos;
  439.  
  440.   /* <reg>+ */
  441.  
  442.   if ((ArgLen > 2) && (pArg[ArgLen - 1] == '+'))
  443.   {
  444.     *pOpSize = eSymbolSizeUnknown;
  445.     *pCutoffRight = 1;
  446.     return True;
  447.   }
  448.  
  449.   /* <reg>++n, <reg>+:n */
  450.  
  451.   if ((ArgLen > 4) && (pArg[ArgLen - 3] == '+') && strchr(":+", pArg[ArgLen - 2]))
  452.   {
  453.     pPos = strchr(Sizes, pArg[ArgLen - 1]);
  454.     if (pPos)
  455.     {
  456.       *pOpSize = (tSymbolSize)(pPos - Sizes);
  457.       *pCutoffRight = 3;
  458.       return True;
  459.     }
  460.   }
  461.   return False;
  462. }
  463.  
  464. static Boolean GetPreDec(const char *pArg, int ArgLen, tSymbolSize *pOpSize, int *pCutoffLeft, int *pCutoffRight)
  465. {
  466.   const char *pPos;
  467.  
  468.   /* n--<reg> */
  469.  
  470.   if ((ArgLen > 4) && (pArg[1] == '-') && (pArg[2] == '-'))
  471.   {
  472.     pPos = strchr(Sizes, pArg[0]);
  473.     if (pPos)
  474.     {
  475.       *pOpSize = (tSymbolSize)(pPos - Sizes);
  476.       *pCutoffLeft = 3;
  477.       *pCutoffRight = 0;
  478.       return True;
  479.     }
  480.   }
  481.  
  482.   if ((ArgLen > 2) && (pArg[0] == '-'))
  483.   {
  484.     *pCutoffLeft = 1;
  485.  
  486.     /* -<reg>:n */
  487.  
  488.     if ((ArgLen > 4) && (pArg[ArgLen - 2] == ':'))
  489.     {
  490.       pPos = strchr(Sizes, pArg[ArgLen - 1]);
  491.       if (pPos)
  492.       {
  493.         *pOpSize = (tSymbolSize)(pPos - Sizes);
  494.         *pCutoffRight = 2;
  495.         return True;
  496.       }
  497.     }
  498.  
  499.     /* -<reg> */
  500.  
  501.     else
  502.     {
  503.       *pOpSize = eSymbolSizeUnknown;
  504.       *pCutoffRight = 0;
  505.       return True;
  506.     }
  507.   }
  508.   return False;
  509. }
  510.  
  511. static void ChkAdr(Byte Erl)
  512. {
  513.   if (AdrType != ModNone)
  514.    if (!(Erl & (1 << AdrType)))
  515.    {
  516.      WrError(ErrNum_InvAddrMode);
  517.      AdrType = ModNone;
  518.    }
  519. }
  520.  
  521. typedef struct
  522. {
  523.   as_eval_cb_data_t cb_data;
  524.   Byte base_reg, index_reg, part_mask;
  525.   tSymbolSize base_size, index_size;
  526. } tlcs900_eval_cb_data_t;
  527.  
  528. DECLARE_AS_EVAL_CB(tlcs900_eval_cb)
  529. {
  530.   tlcs900_eval_cb_data_t *p_eval_cb_data = (tlcs900_eval_cb_data_t*)p_data;
  531.   Byte reg_num;
  532.   tSymbolSize reg_size;
  533.  
  534.   switch (CodeEReg(p_arg->str.p_str, &reg_num, &reg_size))
  535.   {
  536.     case eIsNoReg:
  537.     {
  538.       if ((as_eval_cb_data_stack_depth(p_data->p_stack) > 0)
  539.        && as_eval_cb_data_stack_plain_add(p_data->p_stack))
  540.         p_eval_cb_data->part_mask |= 1;
  541.       return e_eval_none;
  542.     }
  543.     case eRegAbort:
  544.       return e_eval_fail;
  545.     case eIsReg:
  546.       if (!as_eval_cb_data_stack_plain_add(p_data->p_stack))
  547.       {
  548.         WrError(ErrNum_InvAddrMode);
  549.         return e_eval_fail;
  550.       }
  551.       else
  552.       {
  553.         Boolean MustInd;
  554.  
  555.         if (reg_size == eSymbolSize8Bit)
  556.           MustInd = True;
  557.         else if (reg_size == eSymbolSize32Bit)
  558.           MustInd = False;
  559.         else if (!IsRegBase(reg_num, reg_size))
  560.           MustInd = True;
  561.         else if (p_eval_cb_data->part_mask & 4)
  562.           MustInd = True;
  563.         else
  564.           MustInd = False;
  565.         if (MustInd)
  566.         {
  567.           if (p_eval_cb_data->part_mask & 2)
  568.           {
  569.             WrError(ErrNum_InvAddrMode);
  570.             return e_eval_fail;
  571.           }
  572.           else
  573.           {
  574.             p_eval_cb_data->index_reg = reg_num;
  575.             p_eval_cb_data->part_mask |= 2;
  576.             p_eval_cb_data->index_size = reg_size;
  577.           }
  578.         }
  579.         else
  580.         {
  581.           if (p_eval_cb_data->part_mask & 4)
  582.           {
  583.             WrError(ErrNum_InvAddrMode);
  584.             return e_eval_fail;
  585.           }
  586.           else
  587.           {
  588.             p_eval_cb_data->base_reg = reg_num;
  589.             p_eval_cb_data->part_mask |= 4;
  590.             p_eval_cb_data->base_size = reg_size;
  591.           }
  592.         }
  593.       }
  594.       as_tempres_set_int(p_res, 0);
  595.       return e_eval_ok;
  596.     default:
  597.       return e_eval_none;
  598.   }
  599. }
  600.  
  601. static Boolean force_op_size(TempResult *pErg, TempResult *pLVal, TempResult *pRVal)
  602. {
  603.   tSymbolFlags add_flags = eSymbolFlag_None;
  604.  
  605.   if (!pLVal || !pRVal)
  606.     return False;
  607.  
  608.   switch (pRVal->Contents.Int)
  609.   {
  610.     case 8:
  611.       add_flags = eSymbolFlag_UserShort;
  612.       goto copy;
  613.     case 16:
  614.       add_flags = eSymbolFlag_UserMedium;
  615.       goto copy;
  616.     case 24:
  617.       add_flags = eSymbolFlag_UserLong;
  618.       goto copy;
  619.     default:
  620.       WrError(ErrNum_InvDispLen);
  621.       as_tempres_set_none(pErg);
  622.       break;
  623.     copy:
  624.       as_tempres_copy_value(pErg, pLVal);
  625.       pErg->Flags |= add_flags;
  626.       pErg->DataSize = pLVal->DataSize;
  627.   }
  628.   return True;
  629. }
  630.  
  631. static const as_operator_t tlcs900_operators[] =
  632. {
  633.   { ":" ,1 , e_op_dyadic , 1, { TempInt | (TempInt << 4), 0, 0, 0 }, force_op_size},
  634.   {NULL, 0 , e_op_monadic, 0, { 0, 0, 0, 0, 0 }, NULL}
  635. };
  636.  
  637. static void DecodeAdrMem(const tStrComp *pArg)
  638. {
  639.   LongInt DispAcc;
  640.   tStrComp Arg;
  641.   Byte HNum;
  642.   tSymbolSize HSize;
  643.   tEvalResult eval_result;
  644.   int CutoffLeft, CutoffRight, ArgLen = strlen(pArg->str.p_str);
  645.   tSymbolSize IncOpSize, disp_size;
  646.   tlcs900_eval_cb_data_t eval_cb_data;
  647.   Boolean FirstFlag;
  648.  
  649.   AdrType = ModNone;
  650.   AutoIncSizeNeeded = False;
  651.  
  652.   /* post-increment */
  653.  
  654.   if ((ArgLen > 2)
  655.    && GetPostInc(pArg->str.p_str, ArgLen, &IncOpSize, &CutoffRight))
  656.   {
  657.     String Reg;
  658.     tStrComp RegComp;
  659.  
  660.     StrCompMkTemp(&RegComp, Reg, sizeof(Reg));
  661.     StrCompCopy(&RegComp, pArg);
  662.     StrCompShorten(&RegComp, CutoffRight);
  663.     if (CodeEReg(RegComp.str.p_str, &HNum, &HSize) == eIsReg)
  664.     {
  665.       if (!IsRegBase(HNum, HSize)) WrStrErrorPos(ErrNum_InvAddrMode, &RegComp);
  666.       else
  667.       {
  668.         if (IncOpSize == eSymbolSizeUnknown)
  669.           IncOpSize = (tSymbolSize)OpSize;
  670.         AdrType = ModMem;
  671.         AdrMode = 0x45;
  672.         AdrCnt = 1;
  673.         AdrVals[0] = HNum;
  674.         if (IncOpSize == eSymbolSizeUnknown)
  675.           AutoIncSizeNeeded = True;
  676.         else
  677.           AdrVals[0] += IncOpSize;
  678.       }
  679.       return;
  680.     }
  681.   }
  682.  
  683.   /* pre-decrement ? */
  684.  
  685.   if ((ArgLen > 2)
  686.    && GetPreDec(pArg->str.p_str, ArgLen, &IncOpSize, &CutoffLeft, &CutoffRight))
  687.   {
  688.     String Reg;
  689.     tStrComp RegComp;
  690.  
  691.     StrCompMkTemp(&RegComp, Reg, sizeof(Reg));
  692.     StrCompCopySub(&RegComp, pArg, CutoffLeft, ArgLen - CutoffLeft - CutoffRight);
  693.     if (CodeEReg(RegComp.str.p_str, &HNum, &HSize) == eIsReg)
  694.     {
  695.       if (!IsRegBase(HNum, HSize)) WrError(ErrNum_InvAddrMode);
  696.       else
  697.       {
  698.         if (IncOpSize == eSymbolSizeUnknown)
  699.           IncOpSize = (tSymbolSize)OpSize;
  700.         AdrType = ModMem;
  701.         AdrMode = 0x44;
  702.         AdrCnt = 1;
  703.         AdrVals[0] = HNum;
  704.         if (IncOpSize == eSymbolSizeUnknown)
  705.           AutoIncSizeNeeded = True;
  706.         else
  707.           AdrVals[0] += IncOpSize;
  708.       }
  709.       return;
  710.     }
  711.   }
  712.  
  713.   Arg = *pArg;
  714.   as_eval_cb_data_ini(&eval_cb_data.cb_data, tlcs900_eval_cb);
  715.   eval_cb_data.cb_data.p_operators = tlcs900_operators;
  716.   eval_cb_data.base_reg = eval_cb_data.index_reg = 0xff;
  717.   eval_cb_data.base_size = eval_cb_data.index_size = eSymbolSizeUnknown;
  718.   eval_cb_data.part_mask = 0;
  719.   DispAcc = EvalStrIntExprWithResultAndCallback(&Arg, Int32, &eval_result, &eval_cb_data.cb_data);
  720.   if (!eval_result.OK)
  721.     return;
  722.   if (!eval_cb_data.part_mask || DispAcc)
  723.     eval_cb_data.part_mask |= 1;
  724.   FirstFlag = mFirstPassUnknownOrQuestionable(eval_result.Flags);
  725.  
  726.   /* auto-deduce address/displacement size? */
  727.  
  728.   if (eval_result.Flags & eSymbolFlag_UserLong)
  729.     disp_size = eSymbolSize24Bit;
  730.   else if (eval_result.Flags & eSymbolFlag_UserMedium)
  731.     disp_size = eSymbolSize16Bit;
  732.   else if (eval_result.Flags & eSymbolFlag_UserShort)
  733.     disp_size = eSymbolSize8Bit;
  734.   else
  735.     switch (eval_cb_data.part_mask)
  736.     {
  737.       case 1:
  738.         if (DispAcc <= 0xff)
  739.           disp_size = eSymbolSize8Bit;
  740.         else if (DispAcc < 0xffff)
  741.           disp_size = eSymbolSize16Bit;
  742.         else
  743.           disp_size = eSymbolSize24Bit;
  744.         break;
  745.       case 5:
  746.         if (!DispAcc)
  747.         {
  748.           eval_cb_data.part_mask &= ~1;
  749.           goto other;
  750.         }
  751.         if (RangeCheck(DispAcc, SInt8) && IsRegCurrent(eval_cb_data.base_reg, eval_cb_data.base_size, &AdrMode))
  752.           disp_size = eSymbolSize8Bit;
  753.         else
  754.           disp_size = eSymbolSize16Bit;
  755.         break;
  756.       other:
  757.       default:
  758.         disp_size = eSymbolSizeUnknown;
  759.     }
  760.  
  761.   switch (eval_cb_data.part_mask)
  762.   {
  763.     case 0:
  764.     case 2:
  765.     case 3:
  766.     case 7:
  767.       WrError(ErrNum_InvAddrMode);
  768.       break;
  769.     case 1:
  770.       switch (disp_size)
  771.       {
  772.         case eSymbolSize8Bit:
  773.           if (FirstFlag)
  774.             DispAcc &= 0xff;
  775.           if (DispAcc > 0xff) WrError(ErrNum_AdrOverflow);
  776.           else
  777.           {
  778.             AdrType = ModMem;
  779.             AdrMode = 0x40;
  780.             AdrCnt = 1;
  781.             AdrVals[0] = DispAcc;
  782.           }
  783.           break;
  784.         case eSymbolSize16Bit:
  785.           if (FirstFlag)
  786.             DispAcc &= 0xffff;
  787.           if (DispAcc > 0xffff) WrError(ErrNum_AdrOverflow);
  788.           else
  789.           {
  790.             AdrType = ModMem;
  791.             AdrMode = 0x41;
  792.             AdrCnt = 2;
  793.             AdrVals[0] = Lo(DispAcc);
  794.             AdrVals[1] = Hi(DispAcc);
  795.           }
  796.           break;
  797.         case eSymbolSize24Bit:
  798.           if (FirstFlag)
  799.             DispAcc &= 0xffffff;
  800.           if (DispAcc > 0xffffff) WrError(ErrNum_AdrOverflow);
  801.           else
  802.           {
  803.             AdrType = ModMem;
  804.             AdrMode = 0x42;
  805.             AdrCnt = 3;
  806.             AdrVals[0] = DispAcc         & 0xff;
  807.             AdrVals[1] = (DispAcc >>  8) & 0xff;
  808.             AdrVals[2] = (DispAcc >> 16) & 0xff;
  809.           }
  810.           break;
  811.         default:
  812.           break; /* assert(0)? */
  813.       }
  814.       break;
  815.     case 4:
  816.       if (IsRegCurrent(eval_cb_data.base_reg, eval_cb_data.base_size, &AdrMode))
  817.       {
  818.         AdrType = ModMem;
  819.         AdrCnt = 0;
  820.       }
  821.       else
  822.       {
  823.         AdrType = ModMem;
  824.         AdrMode = 0x43;
  825.         AdrCnt = 1;
  826.         AdrVals[0] = eval_cb_data.base_reg;
  827.       }
  828.       break;
  829.     case 5:
  830.       switch (disp_size)
  831.       {
  832.         case eSymbolSize8Bit:
  833.           if (FirstFlag)
  834.             DispAcc &= 0x7f;
  835.           if (!IsRegCurrent(eval_cb_data.base_reg, eval_cb_data.base_size, &AdrMode)) WrError(ErrNum_InvAddrMode);
  836.           else if (ChkRange(DispAcc, -128, 127))
  837.           {
  838.             AdrType = ModMem;
  839.             AdrMode += 8;
  840.             AdrCnt = 1;
  841.             AdrVals[0] = DispAcc & 0xff;
  842.           }
  843.           break;
  844.         case eSymbolSize16Bit:
  845.           if (FirstFlag)
  846.             DispAcc &= 0x7fff;
  847.           if (ChkRange(DispAcc, -32768, 32767))
  848.           {
  849.             AdrType = ModMem;
  850.             AdrMode = 0x43;
  851.             AdrCnt = 3;
  852.             AdrVals[0] = eval_cb_data.base_reg + 1;
  853.             AdrVals[1] = DispAcc & 0xff;
  854.             AdrVals[2] = (DispAcc >> 8) & 0xff;
  855.           }
  856.           break;
  857.         case eSymbolSize24Bit:
  858.           WrError(ErrNum_InvDispLen);
  859.           break;
  860.         default:
  861.           break; /* assert(0)? */
  862.       }
  863.       break;
  864.     case 6:
  865.       AdrType = ModMem;
  866.       AdrMode = 0x43;
  867.       AdrCnt = 3;
  868.       AdrVals[0] = 3 + (eval_cb_data.index_size << 2);
  869.       AdrVals[1] = eval_cb_data.base_reg;
  870.       AdrVals[2] = eval_cb_data.index_reg;
  871.       break;
  872.   }
  873. }
  874.  
  875. static void DecodeAdr(const tStrComp *pArg, Byte Erl)
  876. {
  877.   Byte HNum;
  878.   tSymbolSize HSize;
  879.   LongInt DispAcc;
  880.   Boolean OK;
  881.  
  882.   AdrType = ModNone;
  883.   AutoIncSizeNeeded = False;
  884.  
  885.   /* Register ? */
  886.  
  887.   switch (CodeEReg(pArg->str.p_str, &HNum, &HSize))
  888.   {
  889.     case eRegAbort:
  890.       ChkAdr(Erl);
  891.       return;
  892.     case eIsReg:
  893.       if (IsRegCurrent(HNum, HSize, &AdrMode))
  894.         AdrType = ModReg;
  895.       else
  896.       {
  897.        AdrType = ModXReg;
  898.        AdrMode = HNum;
  899.       }
  900.       SetOpSize(HSize);
  901.       ChkAdr(Erl);
  902.       return;
  903.     default:
  904.       break;
  905.   }
  906.  
  907.   /* Steuerregister ? */
  908.  
  909.   switch (CodeCReg(pArg->str.p_str, &HNum, &HSize))
  910.   {
  911.     case eRegAbort:
  912.       ChkAdr(Erl);
  913.       return;
  914.     case eIsReg:
  915.       AdrType = ModCReg;
  916.       AdrMode = HNum;
  917.       SetOpSize(HSize);
  918.       ChkAdr(Erl);
  919.       return;
  920.     default:
  921.       break;
  922.   }
  923.  
  924.   /* Speicheroperand ? */
  925.  
  926.   if (IsIndirect(pArg->str.p_str))
  927.   {
  928.     tStrComp Arg;
  929.  
  930.     StrCompRefRight(&Arg, pArg, 1);
  931.     StrCompShorten(&Arg, 1);
  932.     KillPrefBlanksStrCompRef(&Arg);
  933.     KillPostBlanksStrComp(&Arg);
  934.     DecodeAdrMem(&Arg);
  935.     ChkAdr(Erl); return;
  936.   }
  937.  
  938.   /* bleibt nur noch immediate... */
  939.  
  940.   if ((MinOneIs0) && (OpSize == -1))
  941.     OpSize = 0;
  942.   switch (OpSize)
  943.   {
  944.     case -1:
  945.       WrError(ErrNum_UndefOpSizes);
  946.       break;
  947.     case 0:
  948.       AdrVals[0] = EvalStrIntExpression(pArg, Int8, &OK);
  949.       if (OK)
  950.       {
  951.         AdrType = ModImm;
  952.         AdrCnt = 1;
  953.       }
  954.       break;
  955.     case 1:
  956.       DispAcc = EvalStrIntExpression(pArg, Int16, &OK);
  957.       if (OK)
  958.       {
  959.         AdrType = ModImm;
  960.         AdrCnt = 2;
  961.         AdrVals[0] = Lo(DispAcc);
  962.         AdrVals[1] = Hi(DispAcc);
  963.       }
  964.       break;
  965.     case 2:
  966.       DispAcc = EvalStrIntExpression(pArg, Int32, &OK);
  967.       if (OK)
  968.       {
  969.         AdrType = ModImm;
  970.         AdrCnt = 4;
  971.         AdrVals[0] = Lo(DispAcc);
  972.         AdrVals[1] = Hi(DispAcc);
  973.         AdrVals[2] = Lo(DispAcc >> 16);
  974.         AdrVals[3] = Hi(DispAcc >> 16);
  975.       }
  976.       break;
  977.   }
  978. }
  979.  
  980. /*---------------------------------------------------------------------------*/
  981.  
  982. static void SetAutoIncSize(Byte AdrModePos, Byte FixupPos)
  983. {
  984.   if ((BAsmCode[AdrModePos] & 0x4e) == 0x44)
  985.     BAsmCode[FixupPos] = (BAsmCode[FixupPos] & 0xfc) | OpSize;
  986. }
  987.  
  988. static Boolean ArgPair(const char *Val1, const char *Val2)
  989. {
  990.   return  (((!as_strcasecmp(ArgStr[1].str.p_str, Val1)) && (!as_strcasecmp(ArgStr[2].str.p_str, Val2)))
  991.         || ((!as_strcasecmp(ArgStr[1].str.p_str, Val2)) && (!as_strcasecmp(ArgStr[2].str.p_str, Val1))));
  992. }
  993.  
  994. static LongInt ImmVal(void)
  995. {
  996.   LongInt tmp;
  997.  
  998.   tmp = AdrVals[0];
  999.   if (OpSize >= 1)
  1000.     tmp += ((LongInt)AdrVals[1]) << 8;
  1001.   if (OpSize == 2)
  1002.   {
  1003.     tmp += ((LongInt)AdrVals[2]) << 16;
  1004.     tmp += ((LongInt)AdrVals[3]) << 24;
  1005.   }
  1006.   return tmp;
  1007. }
  1008.  
  1009. static Boolean IsPwr2(LongInt Inp, Byte *Erg)
  1010. {
  1011.   LongInt Shift;
  1012.  
  1013.   Shift = 1;
  1014.   *Erg = 0;
  1015.   do
  1016.   {
  1017.     if (Inp == Shift)
  1018.       return True;
  1019.     Shift += Shift;
  1020.     (*Erg)++;
  1021.   }
  1022.   while (Shift != 0);
  1023.   return False;
  1024. }
  1025.  
  1026. static Boolean IsShort(Byte Code)
  1027. {
  1028.   return ((Code & 0x4e) == 0x40);
  1029. }
  1030.  
  1031. static void CheckSup(void)
  1032. {
  1033.   if ((MomCPU == CPU96C141)
  1034.    && (!SupAllowed))
  1035.     WrError(ErrNum_PrivOrder);
  1036. }
  1037.  
  1038. /*!------------------------------------------------------------------------
  1039.  * \fn     decode_condition(const char *p_asc, Byte *p_condition)
  1040.  * \brief  decode condition code identifier
  1041.  * \param  p_asc source argument
  1042.  * \param  p_condition resulting code if found
  1043.  * \return True if found
  1044.  * ------------------------------------------------------------------------ */
  1045.  
  1046. static Boolean decode_condition(const char *p_asc, Byte *p_condition)
  1047. {
  1048.   int z;
  1049.  
  1050.   for (z = 0; Conditions[z].Name; z++)
  1051.     if (!as_strcasecmp(p_asc, Conditions[z].Name))
  1052.     {
  1053.       *p_condition = Conditions[z].Code;
  1054.       return True;
  1055.     }
  1056.   return False;
  1057. }
  1058.  
  1059. static void SetInstrOpSize(Byte Size)
  1060. {
  1061.   if (Size != 255)
  1062.     OpSize = Size;
  1063. }
  1064.  
  1065. /*---------------------------------------------------------------------------*/
  1066.  
  1067. static void DecodeMULA(Word Index)
  1068. {
  1069.   UNUSED(Index);
  1070.  
  1071.   if (ChkArgCnt(1, 1))
  1072.   {
  1073.     DecodeAdr(&ArgStr[1], MModReg | MModXReg);
  1074.     if ((AdrType != ModNone) && (OpSize != 2)) WrError(ErrNum_InvOpSize);
  1075.     else switch (AdrType)
  1076.     {
  1077.       case ModReg:
  1078.         CodeLen = 2;
  1079.         BAsmCode[0] = 0xd8 + AdrMode;
  1080.         BAsmCode[1] = 0x19;
  1081.         break;
  1082.       case ModXReg:
  1083.         CodeLen = 3;
  1084.         BAsmCode[0] = 0xd7;
  1085.         BAsmCode[1] = AdrMode;
  1086.         BAsmCode[2] = 0x19;
  1087.         break;
  1088.     }
  1089.   }
  1090. }
  1091.  
  1092. static void DecodeJPCALL(Word Index)
  1093. {
  1094.   if (ChkArgCnt(1, 2))
  1095.   {
  1096.     Byte cond_code;
  1097.  
  1098.     if (ArgCnt == 1)
  1099.       cond_code = COND_CODE_TRUE;
  1100.     else if (!decode_condition(ArgStr[1].str.p_str, &cond_code))
  1101.     {
  1102.       WrStrErrorPos(ErrNum_UndefCond, &ArgStr[1]);
  1103.       return;
  1104.     }
  1105.  
  1106.     if (IsIndirect(ArgStr[ArgCnt].str.p_str))
  1107.       DecodeAdr(&ArgStr[ArgCnt], MModMem);
  1108.     else
  1109.       DecodeAdrMem(&ArgStr[ArgCnt]);
  1110.     if (AdrType == ModMem)
  1111.     {
  1112.       if ((cond_code == COND_CODE_TRUE) && ((AdrMode == 0x41) || (AdrMode == 0x42)))
  1113.       {
  1114.         CodeLen = 1 + AdrCnt;
  1115.         BAsmCode[0] = 0x1a + 2 * Index + (AdrCnt - 2);
  1116.         memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  1117.       }
  1118.       else
  1119.       {
  1120.         CodeLen = 2 + AdrCnt;
  1121.         BAsmCode[0] = 0xb0 + AdrMode;
  1122.         memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  1123.         BAsmCode[1 + AdrCnt] = 0xd0 + (Index << 4) + cond_code;
  1124.       }
  1125.     }
  1126.   }
  1127. }
  1128.  
  1129. static void DecodeJR(Word Index)
  1130. {
  1131.   if (ChkArgCnt(1, 2))
  1132.   {
  1133.     Byte cond_code;
  1134.     Boolean OK;
  1135.     LongInt AdrLong;
  1136.     tSymbolFlags Flags;
  1137.  
  1138.     if (1 == ArgCnt)
  1139.       cond_code = COND_CODE_TRUE;
  1140.     else if (!decode_condition(ArgStr[1].str.p_str, &cond_code))
  1141.     {
  1142.       WrStrErrorPos(ErrNum_UndefCond, &ArgStr[1]);
  1143.       return;
  1144.     }
  1145.  
  1146.     AdrLong = EvalStrIntExpressionWithFlags(&ArgStr[ArgCnt], Int32, &OK, &Flags);
  1147.     if (OK)
  1148.     {
  1149.       if (Index==1)
  1150.       {
  1151.         AdrLong -= EProgCounter() + 3;
  1152.         if (((AdrLong > 0x7fffl) || (AdrLong < -0x8000l)) && !mSymbolQuestionable(Flags)) WrError(ErrNum_DistTooBig);
  1153.         else
  1154.         {
  1155.           CodeLen = 3;
  1156.           BAsmCode[0] = 0x70 + cond_code;
  1157.           BAsmCode[1] = Lo(AdrLong);
  1158.           BAsmCode[2] = Hi(AdrLong);
  1159.           if (!mFirstPassUnknown(Flags))
  1160.           {
  1161.             AdrLong++;
  1162.             if ((AdrLong >= -128) && (AdrLong <= 127)) WrError(ErrNum_ShortJumpPossible);
  1163.           }
  1164.         }
  1165.       }
  1166.       else
  1167.       {
  1168.         AdrLong -= EProgCounter() + 2;
  1169.         if (((AdrLong > 127) || (AdrLong < -128)) && !mSymbolQuestionable(Flags)) WrError(ErrNum_DistTooBig);
  1170.         else
  1171.         {
  1172.           CodeLen = 2;
  1173.           BAsmCode[0] = 0x60 + cond_code;
  1174.           BAsmCode[1] = Lo(AdrLong);
  1175.         }
  1176.       }
  1177.     }
  1178.   }
  1179. }
  1180.  
  1181. static void DecodeCALR(Word Index)
  1182. {
  1183.   LongInt AdrLong;
  1184.   Boolean OK;
  1185.   tSymbolFlags Flags;
  1186.  
  1187.   UNUSED(Index);
  1188.  
  1189.   if (ChkArgCnt(1, 1))
  1190.   {
  1191.     AdrLong = EvalStrIntExpressionWithFlags(&ArgStr[1], Int32, &OK, &Flags) - (EProgCounter() + 3);
  1192.     if (OK)
  1193.     {
  1194.       if (((AdrLong < -32768) || (AdrLong > 32767)) && !mSymbolQuestionable(Flags)) WrError(ErrNum_DistTooBig);
  1195.       else
  1196.       {
  1197.         CodeLen = 3;
  1198.         BAsmCode[0] = 0x1e;
  1199.         BAsmCode[1] = Lo(AdrLong);
  1200.         BAsmCode[2] = Hi(AdrLong);
  1201.       }
  1202.     }
  1203.   }
  1204. }
  1205.  
  1206. static void DecodeRET(Word Index)
  1207. {
  1208.   UNUSED(Index);
  1209.  
  1210.   if (ChkArgCnt(0, 1))
  1211.   {
  1212.     Byte cond_code;
  1213.  
  1214.     if (ArgCnt == 0)
  1215.       cond_code = COND_CODE_TRUE;
  1216.     else if (!decode_condition(ArgStr[1].str.p_str, &cond_code))
  1217.     {
  1218.       WrStrErrorPos(ErrNum_UndefCond, &ArgStr[1]);
  1219.       return;
  1220.     }
  1221.  
  1222.     if (cond_code == COND_CODE_TRUE)
  1223.     {
  1224.       CodeLen = 1;
  1225.       BAsmCode[0] = 0x0e;
  1226.     }
  1227.     else
  1228.     {
  1229.       CodeLen = 2;
  1230.       BAsmCode[0] = 0xb0;
  1231.       BAsmCode[1] = 0xf0 + cond_code;
  1232.     }
  1233.   }
  1234. }
  1235.  
  1236. static void DecodeRETD(Word Index)
  1237. {
  1238.   Word AdrWord;
  1239.   Boolean OK;
  1240.   UNUSED(Index);
  1241.  
  1242.   if (ChkArgCnt(1, 1))
  1243.   {
  1244.     AdrWord = EvalStrIntExpression(&ArgStr[1], Int16, &OK);
  1245.     if (OK)
  1246.     {
  1247.       CodeLen = 3;
  1248.       BAsmCode[0] = 0x0f;
  1249.       BAsmCode[1] = Lo(AdrWord);
  1250.       BAsmCode[2] = Hi(AdrWord);
  1251.     }
  1252.   }
  1253. }
  1254.  
  1255. static void DecodeDJNZ(Word Index)
  1256. {
  1257.   LongInt AdrLong;
  1258.   Boolean OK;
  1259.   tSymbolFlags Flags;
  1260.  
  1261.   UNUSED(Index);
  1262.  
  1263.   if (ChkArgCnt(1, 2))
  1264.   {
  1265.     if (ArgCnt == 1)
  1266.     {
  1267.       AdrType = ModReg;
  1268.       AdrMode = 2;
  1269.       OpSize = 0;
  1270.     }
  1271.     else
  1272.       DecodeAdr(&ArgStr[1], MModReg | MModXReg);
  1273.     if (AdrType != ModNone)
  1274.     {
  1275.       if (OpSize == 2) WrError(ErrNum_InvOpSize);
  1276.       else
  1277.       {
  1278.         AdrLong = EvalStrIntExpressionWithFlags(&ArgStr[ArgCnt], Int32, &OK, &Flags) - (EProgCounter() + 3 + Ord(AdrType == ModXReg));
  1279.         if (OK)
  1280.         {
  1281.           if (((AdrLong < -128) || (AdrLong > 127)) && !mSymbolQuestionable(Flags)) WrError(ErrNum_JmpDistTooBig);
  1282.           else
  1283.            switch (AdrType)
  1284.            {
  1285.              case ModReg:
  1286.                CodeLen = 3;
  1287.                BAsmCode[0] = 0xc8 + (OpSize << 4) + AdrMode;
  1288.                BAsmCode[1] = 0x1c;
  1289.                BAsmCode[2] = AdrLong & 0xff;
  1290.                break;
  1291.              case ModXReg:
  1292.                CodeLen = 4;
  1293.                BAsmCode[0] = 0xc7 + (OpSize << 4);
  1294.                BAsmCode[1] = AdrMode;
  1295.                BAsmCode[2] = 0x1c;
  1296.                BAsmCode[3] = AdrLong & 0xff;
  1297.                break;
  1298.            }
  1299.         }
  1300.       }
  1301.     }
  1302.   }
  1303. }
  1304.  
  1305. static void DecodeEX(Word Index)
  1306. {
  1307.   Byte HReg;
  1308.   UNUSED(Index);
  1309.  
  1310.   /* work around the parser problem related to the ' character */
  1311.  
  1312.   if (!as_strncasecmp(ArgStr[2].str.p_str, "F\'", 2))
  1313.     ArgStr[2].str.p_str[2] = '\0';
  1314.  
  1315.   if (!ChkArgCnt(2, 2));
  1316.   else if ((ArgPair("F", "F\'")) || (ArgPair("F`", "F")))
  1317.   {
  1318.     CodeLen = 1;
  1319.     BAsmCode[0] = 0x16;
  1320.   }
  1321.   else
  1322.   {
  1323.     DecodeAdr(&ArgStr[1], MModReg | MModXReg | MModMem);
  1324.     if (OpSize == 2) WrError(ErrNum_InvOpSize);
  1325.     else
  1326.     {
  1327.       switch (AdrType)
  1328.       {
  1329.         case ModReg:
  1330.           HReg = AdrMode;
  1331.           DecodeAdr(&ArgStr[2], MModReg | MModXReg | MModMem);
  1332.           switch (AdrType)
  1333.           {
  1334.             case ModReg:
  1335.               CodeLen = 2;
  1336.               BAsmCode[0] = 0xc8 + (OpSize << 4) + AdrMode;
  1337.               BAsmCode[1] = 0xb8 + HReg;
  1338.               break;
  1339.             case ModXReg:
  1340.               CodeLen = 3;
  1341.               BAsmCode[0] = 0xc7 + (OpSize << 4);
  1342.               BAsmCode[1] = AdrMode;
  1343.               BAsmCode[2] = 0xb8 + HReg;
  1344.               break;
  1345.             case ModMem:
  1346.               CodeLen = 2 + AdrCnt;
  1347.               BAsmCode[0] = 0x80 + (OpSize << 4) + AdrMode;
  1348.               memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  1349.               BAsmCode[1 + AdrCnt] = 0x30 + HReg;
  1350.               break;
  1351.           }
  1352.           break;
  1353.         case ModXReg:
  1354.           HReg = AdrMode;
  1355.           DecodeAdr(&ArgStr[2], MModReg);
  1356.           if (AdrType == ModReg)
  1357.           {
  1358.             CodeLen = 3;
  1359.             BAsmCode[0] = 0xc7 + (OpSize << 4);
  1360.             BAsmCode[1] = HReg;
  1361.             BAsmCode[2] = 0xb8 + AdrMode;
  1362.           }
  1363.           break;
  1364.         case ModMem:
  1365.         {
  1366.           Boolean FixupAutoIncSize = AutoIncSizeNeeded;
  1367.  
  1368.           MinOneIs0 = True;
  1369.           HReg = AdrCnt;
  1370.           BAsmCode[0] = AdrMode;
  1371.           memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  1372.           DecodeAdr(&ArgStr[2], MModReg);
  1373.           if (AdrType == ModReg)
  1374.           {
  1375.             CodeLen = 2 + HReg;
  1376.             if (FixupAutoIncSize)
  1377.               SetAutoIncSize(0, 1);
  1378.             BAsmCode[0] += 0x80 + (OpSize << 4);
  1379.             BAsmCode[1 + HReg] = 0x30 + AdrMode;
  1380.           }
  1381.           break;
  1382.         }
  1383.       }
  1384.     }
  1385.   }
  1386. }
  1387.  
  1388. static void DecodeBS1x(Word Index)
  1389. {
  1390.   if (!ChkArgCnt(2, 2));
  1391.   else if (as_strcasecmp(ArgStr[1].str.p_str, "A")) WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[1]);
  1392.   else
  1393.   {
  1394.     DecodeAdr(&ArgStr[2], MModReg | MModXReg);
  1395.     if (OpSize != 1) WrError(ErrNum_InvOpSize);
  1396.     else switch (AdrType)
  1397.     {
  1398.       case ModReg:
  1399.         CodeLen = 2;
  1400.         BAsmCode[0] = 0xd8 + AdrMode;
  1401.         BAsmCode[1] = 0x0e + Index; /* ANSI */
  1402.         break;
  1403.       case ModXReg:
  1404.         CodeLen = 3;
  1405.         BAsmCode[0] = 0xd7;
  1406.         BAsmCode[1] = AdrMode;
  1407.         BAsmCode[2] = 0x0e +Index; /* ANSI */
  1408.         break;
  1409.     }
  1410.   }
  1411. }
  1412.  
  1413. static void DecodeLDA(Word Index)
  1414. {
  1415.   Byte HReg;
  1416.   UNUSED(Index);
  1417.  
  1418.   if (ChkArgCnt(2, 2))
  1419.   {
  1420.     DecodeAdr(&ArgStr[1], MModReg);
  1421.     if (AdrType != ModNone)
  1422.     {
  1423.       if (OpSize < 1) WrError(ErrNum_InvOpSize);
  1424.       else
  1425.       {
  1426.         HReg = AdrMode;
  1427.         if (IsIndirect(ArgStr[2].str.p_str))
  1428.           DecodeAdr(&ArgStr[2], MModMem);
  1429.         else
  1430.           DecodeAdrMem(&ArgStr[2]);
  1431.         if (AdrType != ModNone)
  1432.         {
  1433.           CodeLen = 2 + AdrCnt;
  1434.           BAsmCode[0] = 0xb0 + AdrMode;
  1435.           memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  1436.           BAsmCode[1 + AdrCnt] = 0x20 + ((OpSize - 1) << 4) + HReg;
  1437.         }
  1438.       }
  1439.     }
  1440.   }
  1441. }
  1442.  
  1443. static void DecodeLDAR(Word Index)
  1444. {
  1445.   LongInt AdrLong;
  1446.   Boolean OK;
  1447.   tSymbolFlags Flags;
  1448.  
  1449.   UNUSED(Index);
  1450.  
  1451.   if (ChkArgCnt(2, 2))
  1452.   {
  1453.     AdrLong = EvalStrIntExpressionWithFlags(&ArgStr[2], Int32, &OK, &Flags) - (EProgCounter() + 4);
  1454.     if (OK)
  1455.     {
  1456.       if (((AdrLong < -32768) || (AdrLong > 32767)) && !mSymbolQuestionable(Flags)) WrError(ErrNum_DistTooBig);
  1457.       else
  1458.       {
  1459.         DecodeAdr(&ArgStr[1], MModReg);
  1460.         if (AdrType != ModNone)
  1461.         {
  1462.           if (OpSize < 1) WrError(ErrNum_InvOpSize);
  1463.           else
  1464.           {
  1465.             CodeLen = 5;
  1466.             BAsmCode[0] = 0xf3;
  1467.             BAsmCode[1] = 0x13;
  1468.             BAsmCode[2] = Lo(AdrLong);
  1469.             BAsmCode[3] = Hi(AdrLong);
  1470.             BAsmCode[4] = 0x20 + ((OpSize - 1) << 4) + AdrMode;
  1471.           }
  1472.         }
  1473.       }
  1474.     }
  1475.   }
  1476. }
  1477.  
  1478. static void DecodeLDC(Word Index)
  1479. {
  1480.   Byte HReg;
  1481.   UNUSED(Index);
  1482.  
  1483.   if (ChkArgCnt(2, 2))
  1484.   {
  1485.     DecodeAdr(&ArgStr[1], MModReg | MModXReg| MModCReg);
  1486.     HReg = AdrMode;
  1487.     switch (AdrType)
  1488.     {
  1489.       case ModReg:
  1490.         DecodeAdr(&ArgStr[2], MModCReg);
  1491.         if (AdrType != ModNone)
  1492.         {
  1493.           CodeLen = 3;
  1494.           BAsmCode[0] = 0xc8 + (OpSize << 4) + HReg;
  1495.           BAsmCode[1] = 0x2f;
  1496.           BAsmCode[2] = AdrMode;
  1497.         }
  1498.         break;
  1499.       case ModXReg:
  1500.         DecodeAdr(&ArgStr[2], MModCReg);
  1501.         if (AdrType != ModNone)
  1502.         {
  1503.           CodeLen = 4;
  1504.           BAsmCode[0] = 0xc7 + (OpSize << 4);
  1505.           BAsmCode[1] = HReg;
  1506.           BAsmCode[2] = 0x2f;
  1507.           BAsmCode[3] = AdrMode;
  1508.         };
  1509.         break;
  1510.       case ModCReg:
  1511.         DecodeAdr(&ArgStr[2], MModReg | MModXReg);
  1512.         switch (AdrType)
  1513.         {
  1514.           case ModReg:
  1515.             CodeLen = 3;
  1516.             BAsmCode[0] = 0xc8 + (OpSize << 4) + AdrMode;
  1517.             BAsmCode[1] = 0x2e;
  1518.             BAsmCode[2] = HReg;
  1519.             break;
  1520.           case ModXReg:
  1521.             CodeLen = 4;
  1522.             BAsmCode[0] = 0xc7 + (OpSize << 4);
  1523.             BAsmCode[1] = AdrMode;
  1524.             BAsmCode[2] = 0x2e;
  1525.             BAsmCode[3] = HReg;
  1526.             break;
  1527.         }
  1528.         break;
  1529.     }
  1530.   }
  1531. }
  1532.  
  1533. static void DecodeLDX(Word Index)
  1534. {
  1535.   Boolean OK;
  1536.   UNUSED(Index);
  1537.  
  1538.   if (ChkArgCnt(2, 2))
  1539.   {
  1540.     DecodeAdr(&ArgStr[1], MModMem);
  1541.     if (AdrType != ModNone)
  1542.     {
  1543.       if (AdrMode != 0x40) WrError(ErrNum_InvAddrMode);
  1544.       else
  1545.       {
  1546.         BAsmCode[4] = EvalStrIntExpression(&ArgStr[2], Int8, &OK);
  1547.         if (OK)
  1548.         {
  1549.           CodeLen = 6;
  1550.           BAsmCode[0] = 0xf7;
  1551.           BAsmCode[1] = 0;
  1552.           BAsmCode[2] = AdrVals[0];
  1553.           BAsmCode[3] = 0;
  1554.           BAsmCode[5] = 0;
  1555.         }
  1556.       }
  1557.     }
  1558.   }
  1559. }
  1560.  
  1561. static void DecodeLINK(Word Index)
  1562. {
  1563.   Word AdrWord;
  1564.   Boolean OK;
  1565.   UNUSED(Index);
  1566.  
  1567.   if (ChkArgCnt(2, 2))
  1568.   {
  1569.     AdrWord = EvalStrIntExpression(&ArgStr[2], Int16, &OK);
  1570.     if (OK)
  1571.     {
  1572.       DecodeAdr(&ArgStr[1], MModReg | MModXReg);
  1573.       if ((AdrType != ModNone) && (OpSize != 2)) WrError(ErrNum_InvOpSize);
  1574.       else
  1575.        switch (AdrType)
  1576.        {
  1577.          case ModReg:
  1578.            CodeLen = 4;
  1579.            BAsmCode[0] = 0xe8 + AdrMode;
  1580.            BAsmCode[1] = 0x0c;
  1581.            BAsmCode[2] = Lo(AdrWord);
  1582.            BAsmCode[3] = Hi(AdrWord);
  1583.            break;
  1584.          case ModXReg:
  1585.            CodeLen = 5;
  1586.            BAsmCode[0] = 0xe7;
  1587.            BAsmCode[1] = AdrMode;
  1588.            BAsmCode[2] = 0x0c;
  1589.            BAsmCode[3] = Lo(AdrWord);
  1590.            BAsmCode[4] = Hi(AdrWord);
  1591.            break;
  1592.        }
  1593.     }
  1594.   }
  1595. }
  1596.  
  1597. static void DecodeLD(Word Code)
  1598. {
  1599.   Byte HReg;
  1600.   Boolean ShDest, ShSrc, OK;
  1601.  
  1602.   SetInstrOpSize(Hi(Code));
  1603.  
  1604.   if (ChkArgCnt(2, 2))
  1605.   {
  1606.     DecodeAdr(&ArgStr[1], MModReg | MModXReg | MModMem);
  1607.     switch (AdrType)
  1608.     {
  1609.       case ModReg:
  1610.         HReg = AdrMode;
  1611.         DecodeAdr(&ArgStr[2], MModReg | MModXReg| MModMem| MModImm);
  1612.         switch (AdrType)
  1613.         {
  1614.           case ModReg:
  1615.             CodeLen = 2;
  1616.             BAsmCode[0] = 0xc8 + (OpSize << 4) + AdrMode;
  1617.             BAsmCode[1] = 0x88 + HReg;
  1618.             break;
  1619.           case ModXReg:
  1620.             CodeLen = 3;
  1621.             BAsmCode[0] = 0xc7 + (OpSize << 4);
  1622.             BAsmCode[1] = AdrMode;
  1623.             BAsmCode[2] = 0x88 + HReg;
  1624.             break;
  1625.           case ModMem:
  1626.             CodeLen = 2 + AdrCnt;
  1627.             BAsmCode[0] = 0x80 + (OpSize << 4) + AdrMode;
  1628.             memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  1629.             BAsmCode[1 + AdrCnt] = 0x20 + HReg;
  1630.             break;
  1631.           case ModImm:
  1632.           {
  1633.             LongInt ImmValue = ImmVal();
  1634.  
  1635.             if ((ImmValue <= 7) && (ImmValue >= 0))
  1636.             {
  1637.               CodeLen = 2;
  1638.               BAsmCode[0] = 0xc8 + (OpSize << 4) + HReg;
  1639.               BAsmCode[1] = 0xa8 + AdrVals[0];
  1640.             }
  1641.             else
  1642.             {
  1643.               CodeLen = 1 + AdrCnt;
  1644.               BAsmCode[0] = ((OpSize + 2) << 4) + HReg;
  1645.               memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  1646.             }
  1647.             break;
  1648.           }
  1649.         }
  1650.         break;
  1651.       case ModXReg:
  1652.         HReg = AdrMode;
  1653.         DecodeAdr(&ArgStr[2], MModReg + MModImm);
  1654.         switch (AdrType)
  1655.         {
  1656.           case ModReg:
  1657.             CodeLen = 3;
  1658.             BAsmCode[0] = 0xc7 + (OpSize << 4);
  1659.             BAsmCode[1] = HReg;
  1660.             BAsmCode[2] = 0x98 + AdrMode;
  1661.             break;
  1662.           case ModImm:
  1663.           {
  1664.             LongInt ImmValue = ImmVal();
  1665.  
  1666.             if ((ImmValue <= 7) && (ImmValue >= 0))
  1667.             {
  1668.               CodeLen = 3;
  1669.               BAsmCode[0] = 0xc7 + (OpSize << 4);
  1670.               BAsmCode[1] = HReg;
  1671.               BAsmCode[2] = 0xa8 + AdrVals[0];
  1672.             }
  1673.             else
  1674.             {
  1675.               CodeLen = 3 + AdrCnt;
  1676.               BAsmCode[0] = 0xc7 + (OpSize << 4);
  1677.               BAsmCode[1] = HReg;
  1678.               BAsmCode[2] = 3;
  1679.               memcpy(BAsmCode + 3, AdrVals, AdrCnt);
  1680.             }
  1681.             break;
  1682.           }
  1683.         }
  1684.         break;
  1685.       case ModMem:
  1686.       {
  1687.         Boolean FixupAutoIncSize = AutoIncSizeNeeded;
  1688.  
  1689.         BAsmCode[0] = AdrMode;
  1690.         HReg = AdrCnt;
  1691.         MinOneIs0 = True;
  1692.         memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  1693.         DecodeAdr(&ArgStr[2], MModReg | MModMem | MModImm);
  1694.         switch (AdrType)
  1695.         {
  1696.          case ModReg:
  1697.            CodeLen = 2 + HReg;
  1698.            BAsmCode[0] += 0xb0;
  1699.            if (FixupAutoIncSize)
  1700.              SetAutoIncSize(0, 1);
  1701.            BAsmCode[1 + HReg] = 0x40 + (OpSize << 4) + AdrMode;
  1702.            break;
  1703.          case ModMem:
  1704.            if (OpSize == -1) OpSize = 0;
  1705.            ShDest = IsShort(BAsmCode[0]);
  1706.            ShSrc = IsShort(AdrMode);
  1707.            if (!(ShDest || ShSrc)) WrError(ErrNum_InvAddrMode);
  1708.            else
  1709.            {
  1710.              if ((ShDest && (!ShSrc))) OK = True;
  1711.              else if (ShSrc && (!ShDest)) OK = False;
  1712.              else if (AdrMode == 0x40) OK = True;
  1713.              else OK = False;
  1714.              if (OK)  /* dest=(dir8/16) */
  1715.              {
  1716.                CodeLen = 4 + AdrCnt;
  1717.                HReg = BAsmCode[0];
  1718.                BAsmCode[3 + AdrCnt] = (BAsmCode[0] == 0x40) ? 0 : BAsmCode[2];
  1719.                BAsmCode[2 + AdrCnt] = BAsmCode[1];
  1720.                BAsmCode[0] = 0x80 + (OpSize << 4) + AdrMode;
  1721.                AdrMode = HReg;
  1722.                if (FixupAutoIncSize)
  1723.                  SetAutoIncSize(0, 1);
  1724.                memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  1725.                BAsmCode[1 + AdrCnt] = 0x19;
  1726.              }
  1727.              else
  1728.              {
  1729.                CodeLen = 4 + HReg;
  1730.                BAsmCode[2 + HReg] = AdrVals[0];
  1731.                BAsmCode[3 + HReg] = (AdrMode == 0x40) ? 0 : AdrVals[1];
  1732.                BAsmCode[0] += 0xb0;
  1733.                if (FixupAutoIncSize)
  1734.                  SetAutoIncSize(0, 1);
  1735.                BAsmCode[1 + HReg] = 0x14 + (OpSize << 1);
  1736.              }
  1737.            }
  1738.            break;
  1739.          case ModImm:
  1740.           if (BAsmCode[0] == 0x40)
  1741.           {
  1742.             CodeLen = 2 + AdrCnt;
  1743.             BAsmCode[0] = 0x08 + (OpSize << 1);
  1744.             memcpy(BAsmCode + 2, AdrVals, AdrCnt);
  1745.           }
  1746.           else
  1747.           {
  1748.             CodeLen = 2 + HReg + AdrCnt;
  1749.             BAsmCode[0] += 0xb0;
  1750.             BAsmCode[1 + HReg] = OpSize << 1;
  1751.             memcpy(BAsmCode + 2 + HReg, AdrVals, AdrCnt);
  1752.           }
  1753.           break;
  1754.         }
  1755.         break;
  1756.       }
  1757.     }
  1758.   }
  1759. }
  1760.  
  1761. static void DecodeFixed(Word Index)
  1762. {
  1763.   FixedOrder *FixedZ = FixedOrders + Index;
  1764.  
  1765.   if (ChkArgCnt(0, 0)
  1766.    && (ChkExactCPUMask(FixedZ->CPUFlag, CPU96C141) >= 0))
  1767.   {
  1768.     if (Hi(FixedZ->Code) == 0)
  1769.     {
  1770.       CodeLen = 1;
  1771.       BAsmCode[0] = Lo(FixedZ->Code);
  1772.     }
  1773.     else
  1774.     {
  1775.       CodeLen = 2;
  1776.       BAsmCode[0] = Hi(FixedZ->Code);
  1777.       BAsmCode[1] = Lo(FixedZ->Code);
  1778.     }
  1779.     if (FixedZ->InSup)
  1780.       CheckSup();
  1781.   }
  1782. }
  1783.  
  1784. static void DecodeImm(Word Index)
  1785. {
  1786.   ImmOrder *ImmZ = ImmOrders + Index;
  1787.   Word AdrWord;
  1788.   Boolean OK;
  1789.  
  1790.   if (ChkArgCnt((ImmZ->Default == -1) ? 1 : 0, 1))
  1791.   {
  1792.     if (ArgCnt == 0)
  1793.     {
  1794.       AdrWord = ImmZ->Default;
  1795.       OK = True;
  1796.     }
  1797.     else
  1798.       AdrWord = EvalStrIntExpression(&ArgStr[1], Int8, &OK);
  1799.     if (OK)
  1800.     {
  1801.       if (((MaxMode) && (AdrWord > ImmZ->MaxMax)) || ((!MaxMode) && (AdrWord > ImmZ->MinMax))) WrError(ErrNum_OverRange);
  1802.       else if (Hi(ImmZ->Code) == 0)
  1803.       {
  1804.         CodeLen = 1;
  1805.         BAsmCode[0] = Lo(ImmZ->Code) + AdrWord;
  1806.       }
  1807.       else
  1808.       {
  1809.         CodeLen = 2;
  1810.         BAsmCode[0] = Hi(ImmZ->Code);
  1811.         BAsmCode[1] = Lo(ImmZ->Code) + AdrWord;
  1812.       }
  1813.     }
  1814.     if (ImmZ->InSup)
  1815.       CheckSup();
  1816.   }
  1817. }
  1818.  
  1819. static void DecodeALU2(Word Code);
  1820.  
  1821. static void DecodeReg(Word Index)
  1822. {
  1823.   RegOrder *RegZ = RegOrders + Index;
  1824.  
  1825.   /* dispatch to CPL as compare-long with two args: */
  1826.  
  1827.   if ((Memo("CPL")) && (ArgCnt >= 2))
  1828.   {
  1829.     DecodeALU2(0x0207);
  1830.     return;
  1831.   }
  1832.  
  1833.   if (ChkArgCnt(1, 1))
  1834.   {
  1835.     DecodeAdr(&ArgStr[1], MModReg | MModXReg);
  1836.     if (AdrType != ModNone)
  1837.     {
  1838.       if (((1 << OpSize) & RegZ->OpMask) == 0) WrError(ErrNum_InvOpSize);
  1839.       else if (AdrType == ModReg)
  1840.       {
  1841.         BAsmCode[0] = Hi(RegZ->Code) + 8 + (OpSize << 4) + AdrMode;
  1842.         BAsmCode[1] = Lo(RegZ->Code);
  1843.         CodeLen = 2;
  1844.       }
  1845.       else
  1846.       {
  1847.         BAsmCode[0] = Hi(RegZ->Code) + 7 + (OpSize << 4);
  1848.         BAsmCode[1] = AdrMode;
  1849.         BAsmCode[2] = Lo(RegZ->Code);
  1850.         CodeLen = 3;
  1851.       }
  1852.     }
  1853.   }
  1854. }
  1855.  
  1856. static void DecodeALU2(Word Code)
  1857. {
  1858.   Byte HReg;
  1859.  
  1860.   SetInstrOpSize(Hi(Code));
  1861.   if (ChkArgCnt(2, 2))
  1862.   {
  1863.     DecodeAdr(&ArgStr[1], MModReg | MModXReg | MModMem);
  1864.     switch (AdrType)
  1865.     {
  1866.       case ModReg:
  1867.         HReg=AdrMode;
  1868.         DecodeAdr(&ArgStr[2], MModReg | MModXReg | MModMem | MModImm);
  1869.         switch (AdrType)
  1870.         {
  1871.           case ModReg:
  1872.             CodeLen = 2;
  1873.             BAsmCode[0] = 0xc8 + (OpSize << 4) + AdrMode;
  1874.             BAsmCode[1] = 0x80 + (Lo(Code) << 4) + HReg;
  1875.             break;
  1876.           case ModXReg:
  1877.             CodeLen = 3;
  1878.             BAsmCode[0] = 0xc7 + (OpSize << 4);
  1879.             BAsmCode[1] = AdrMode;
  1880.             BAsmCode[2] = 0x80 + (Lo(Code) << 4) + HReg;
  1881.             break;
  1882.           case ModMem:
  1883.             CodeLen = 2 + AdrCnt;
  1884.             BAsmCode[0] = 0x80 + AdrMode + (OpSize << 4);
  1885.             memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  1886.             BAsmCode[1 + AdrCnt] = 0x80 + HReg + (Lo(Code) << 4);
  1887.             break;
  1888.           case ModImm:
  1889.             if ((Lo(Code) == 7) && (OpSize != 2) && (ImmVal() <= 7) && (ImmVal() >= 0))
  1890.             {
  1891.               CodeLen = 2;
  1892.               BAsmCode[0] = 0xc8 + (OpSize << 4) + HReg;
  1893.               BAsmCode[1] = 0xd8 + AdrVals[0];
  1894.             }
  1895.             else
  1896.             {
  1897.               CodeLen = 2 + AdrCnt;
  1898.               BAsmCode[0] = 0xc8 + (OpSize << 4) + HReg;
  1899.               BAsmCode[1] = 0xc8 + Lo(Code);
  1900.               memcpy(BAsmCode + 2, AdrVals, AdrCnt);
  1901.             }
  1902.             break;
  1903.         }
  1904.         break;
  1905.       case ModXReg:
  1906.         HReg = AdrMode;
  1907.         DecodeAdr(&ArgStr[2], MModImm);
  1908.         switch (AdrType)
  1909.         {
  1910.           case ModImm:
  1911.             if ((Lo(Code) == 7) && (OpSize != 2) && (ImmVal() <= 7) && (ImmVal() >= 0))
  1912.             {
  1913.               CodeLen = 3;
  1914.               BAsmCode[0] = 0xc7 + (OpSize << 4);
  1915.               BAsmCode[1] = HReg;
  1916.               BAsmCode[2] = 0xd8 + AdrVals[0];
  1917.             }
  1918.             else
  1919.             {
  1920.               CodeLen = 3 + AdrCnt;
  1921.               BAsmCode[0] = 0xc7 + (OpSize << 4);
  1922.               BAsmCode[1] = HReg;
  1923.               BAsmCode[2] = 0xc8 + Lo(Code);
  1924.               memcpy(BAsmCode + 3, AdrVals, AdrCnt);
  1925.             }
  1926.             break;
  1927.         }
  1928.         break;
  1929.       case ModMem:
  1930.       {
  1931.         Boolean FixupAutoIncSize = AutoIncSizeNeeded;
  1932.  
  1933.         MinOneIs0 = True;
  1934.         HReg = AdrCnt;
  1935.         BAsmCode[0] = AdrMode;
  1936.         memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  1937.         DecodeAdr(&ArgStr[2], MModReg | MModImm);
  1938.         switch (AdrType)
  1939.         {
  1940.           case ModReg:
  1941.             CodeLen = 2 + HReg;
  1942.             if (FixupAutoIncSize)
  1943.               SetAutoIncSize(0, 1);
  1944.             BAsmCode[0] += 0x80 + (OpSize << 4);
  1945.             BAsmCode[1 + HReg] = 0x88 + (Lo(Code) << 4) + AdrMode;
  1946.             break;
  1947.           case ModImm:
  1948.             CodeLen = 2 + HReg + AdrCnt;
  1949.             BAsmCode[0] += 0x80 + (OpSize << 4);
  1950.             BAsmCode[1 + HReg] = 0x38 + Lo(Code);
  1951.             memcpy(BAsmCode + 2 + HReg, AdrVals, AdrCnt);
  1952.             break;
  1953.         };
  1954.         break;
  1955.       }
  1956.     }
  1957.   }
  1958. }
  1959.  
  1960. static void DecodePUSH_POP(Word Code)
  1961. {
  1962.   SetInstrOpSize(Hi(Code));
  1963.  
  1964.   if (!ChkArgCnt(1, 1));
  1965.   else if (!as_strcasecmp(ArgStr[1].str.p_str, "F"))
  1966.   {
  1967.     CodeLen = 1;
  1968.     BAsmCode[0] = 0x18 + Lo(Code);
  1969.   }
  1970.   else if (!as_strcasecmp(ArgStr[1].str.p_str, "A"))
  1971.   {
  1972.     CodeLen = 1;
  1973.     BAsmCode[0] = 0x14 + Lo(Code);
  1974.   }
  1975.   else if (!as_strcasecmp(ArgStr[1].str.p_str, "SR"))
  1976.   {
  1977.     CodeLen = 1;
  1978.     BAsmCode[0] = 0x02 + Lo(Code);
  1979.     CheckSup();
  1980.   }
  1981.   else
  1982.   {
  1983.     MinOneIs0 = True;
  1984.     DecodeAdr(&ArgStr[1], MModReg | MModXReg | MModMem | (Lo(Code) ? 0 : MModImm));
  1985.     switch (AdrType)
  1986.     {
  1987.       case ModReg:
  1988.         if (OpSize == 0)
  1989.         {
  1990.           CodeLen = 2;
  1991.           BAsmCode[0] = 0xc8 + (OpSize << 4) + AdrMode;
  1992.           BAsmCode[1] = 0x04 + Lo(Code);
  1993.         }
  1994.         else
  1995.         {
  1996.           CodeLen = 1;
  1997.           BAsmCode[0] = 0x28 + (Lo(Code) << 5) + ((OpSize - 1) << 4) + AdrMode;
  1998.         }
  1999.         break;
  2000.       case ModXReg:
  2001.         CodeLen = 3;
  2002.         BAsmCode[0] = 0xc7 + (OpSize << 4);
  2003.         BAsmCode[1] = AdrMode;
  2004.         BAsmCode[2] = 0x04 + Lo(Code);
  2005.         break;
  2006.       case ModMem:
  2007.         if (OpSize == -1)
  2008.           OpSize=0;
  2009.         CodeLen = 2 + AdrCnt;
  2010.         if (Lo(Code))
  2011.           BAsmCode[0] = 0xb0 + AdrMode;
  2012.         else
  2013.           BAsmCode[0] = 0x80 + (OpSize << 4) + AdrMode;
  2014.         memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  2015.         if (Lo(Code))
  2016.           BAsmCode[1 + AdrCnt] = 0x04 + (OpSize << 1);
  2017.         else
  2018.           BAsmCode[1 + AdrCnt] = 0x04;
  2019.         break;
  2020.       case ModImm:
  2021.         if (OpSize == -1)
  2022.           OpSize = 0;
  2023.         BAsmCode[0] = 9 + (OpSize << 1);
  2024.         memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  2025.         CodeLen = 1 + AdrCnt;
  2026.         break;
  2027.     }
  2028.   }
  2029. }
  2030.  
  2031. static void DecodeShift(Word Code)
  2032. {
  2033.   Boolean OK;
  2034.   tSymbolFlags Flags;
  2035.   Byte HReg;
  2036.  
  2037.   SetInstrOpSize(Hi(Code));
  2038.  
  2039.   if (ChkArgCnt(1, 2))
  2040.   {
  2041.     OK = True;
  2042.     if (ArgCnt == 1)
  2043.       HReg = 1;
  2044.     else if (!as_strcasecmp(ArgStr[1].str.p_str, "A"))
  2045.       HReg = 0xff;
  2046.     else
  2047.     {
  2048.       HReg = EvalStrIntExpressionWithFlags(&ArgStr[1], Int8, &OK, &Flags);
  2049.       if (OK)
  2050.       {
  2051.         if (mFirstPassUnknown(Flags))
  2052.           HReg &= 0x0f;
  2053.         else
  2054.         {
  2055.           if ((HReg == 0) || (HReg > 16))
  2056.           {
  2057.             WrError(ErrNum_OverRange);
  2058.             OK = False;
  2059.           }
  2060.           else
  2061.             HReg &= 0x0f;
  2062.         }
  2063.       }
  2064.     }
  2065.     if (OK)
  2066.     {
  2067.       DecodeAdr(&ArgStr[ArgCnt], MModReg | MModXReg | ((HReg == 0xff) ? 0 : MModMem));
  2068.       switch (AdrType)
  2069.       {
  2070.         case ModReg:
  2071.           CodeLen = 2 + Ord(HReg != 0xff);
  2072.           BAsmCode[0] = 0xc8 + (OpSize << 4) + AdrMode;
  2073.           BAsmCode[1] = 0xe8 + Lo(Code);
  2074.           CodeLen = 2;
  2075.           if (HReg == 0xff)
  2076.             BAsmCode[1] += 0x10;
  2077.           else
  2078.             BAsmCode[CodeLen++] = HReg;
  2079.           break;
  2080.         case ModXReg:
  2081.           BAsmCode[0] = 0xc7+(OpSize << 4);
  2082.           BAsmCode[1] = AdrMode;
  2083.           BAsmCode[2] = 0xe8 + Lo(Code);
  2084.           CodeLen = 3;
  2085.           if (HReg == 0xff)
  2086.             BAsmCode[2] += 0x10;
  2087.           else
  2088.             BAsmCode[CodeLen++] = HReg;
  2089.           break;
  2090.         case ModMem:
  2091.           if (HReg != 1) WrError(ErrNum_InvAddrMode);
  2092.           else
  2093.           {
  2094.             if (OpSize == -1)
  2095.               OpSize = 0;
  2096.             CodeLen = 2 + AdrCnt;
  2097.             BAsmCode[0] = 0x80 + (OpSize << 4) + AdrMode;
  2098.             memcpy(BAsmCode + 1 , AdrVals, AdrCnt);
  2099.             BAsmCode[1 + AdrCnt] = 0x78 + Lo(Code);
  2100.           }
  2101.           break;
  2102.       }
  2103.     }
  2104.   }
  2105. }
  2106.  
  2107. static void DecodeMulDiv(Word Code)
  2108. {
  2109.   Byte HReg;
  2110.  
  2111.   if (ChkArgCnt(2, 2))
  2112.   {
  2113.     DecodeAdr(&ArgStr[1], MModReg | MModXReg);
  2114.     if (OpSize == 0) WrError(ErrNum_InvOpSize);
  2115.     else
  2116.     {
  2117.       if ((AdrType == ModReg) && (OpSize == 1))
  2118.       {
  2119.         if (AdrMode > 3)
  2120.         {
  2121.           AdrType = ModXReg;
  2122.           AdrMode = 0xe0 + (AdrMode << 2);
  2123.         }
  2124.         else
  2125.           AdrMode += 1 + AdrMode;
  2126.       }
  2127.       OpSize--;
  2128.       HReg = AdrMode;
  2129.       switch (AdrType)
  2130.       {
  2131.         case ModReg:
  2132.           DecodeAdr(&ArgStr[2], MModReg | MModXReg | MModMem | MModImm);
  2133.           switch (AdrType)
  2134.           {
  2135.             case ModReg:
  2136.               CodeLen = 2;
  2137.               BAsmCode[0] = 0xc8 + (OpSize << 4) + AdrMode;
  2138.               BAsmCode[1] = 0x40 + (Code << 3) + HReg;
  2139.               break;
  2140.             case ModXReg:
  2141.               CodeLen = 3;
  2142.               BAsmCode[0] = 0xc7 + (OpSize << 4);
  2143.               BAsmCode[1] = AdrMode;
  2144.               BAsmCode[2] = 0x40 + (Code << 3) + HReg;
  2145.               break;
  2146.             case ModMem:
  2147.               CodeLen = 2 + AdrCnt;
  2148.               BAsmCode[0] = 0x80 + (OpSize << 4) + AdrMode;
  2149.               memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  2150.               BAsmCode[1 + AdrCnt] = 0x40 + (Code << 3) + HReg;
  2151.               break;
  2152.             case ModImm:
  2153.               CodeLen = 2 + AdrCnt;
  2154.               BAsmCode[0] = 0xc8 + (OpSize << 4) + HReg;
  2155.               BAsmCode[1] = 0x08 + Code;
  2156.               memcpy(BAsmCode + 2, AdrVals, AdrCnt);
  2157.               break;
  2158.           }
  2159.           break;
  2160.         case ModXReg:
  2161.           DecodeAdr(&ArgStr[2], MModImm);
  2162.           if (AdrType == ModImm)
  2163.           {
  2164.             CodeLen = 3 + AdrCnt;
  2165.             BAsmCode[0] = 0xc7 + (OpSize << 4);
  2166.             BAsmCode[1] = HReg;
  2167.             BAsmCode[2] = 0x08 + Code;
  2168.             memcpy(BAsmCode + 3, AdrVals, AdrCnt);
  2169.           }
  2170.           break;
  2171.       }
  2172.     }
  2173.   }
  2174. }
  2175.  
  2176. static void DecodeBitCF(Word Code)
  2177. {
  2178.   Boolean OK;
  2179.   Byte BitPos;
  2180.  
  2181.   if (ChkArgCnt(2, 2))
  2182.   {
  2183.     DecodeAdr(&ArgStr[2], MModReg | MModXReg | MModMem);
  2184.     if (AdrType!=ModNone)
  2185.     {
  2186.       if (OpSize == 2) WrError(ErrNum_InvOpSize);
  2187.       else
  2188.       {
  2189.         if (AdrType == ModMem)
  2190.           OpSize = 0;
  2191.         if (!as_strcasecmp(ArgStr[1].str.p_str, "A"))
  2192.         {
  2193.           BitPos = 0xff;
  2194.           OK = True;
  2195.         }
  2196.         else
  2197.           BitPos = EvalStrIntExpression(&ArgStr[1], (OpSize == 0) ? UInt3 : Int4, &OK);
  2198.         if (OK)
  2199.          switch (AdrType)
  2200.          {
  2201.            case ModReg:
  2202.              BAsmCode[0] = 0xc8 + (OpSize << 4) + AdrMode;
  2203.              BAsmCode[1] = 0x20 + Code;
  2204.              CodeLen = 2;
  2205.              if (BitPos == 0xff)
  2206.                BAsmCode[1] |= 0x08;
  2207.              else
  2208.                BAsmCode[CodeLen++] = BitPos;
  2209.              break;
  2210.            case ModXReg:
  2211.              BAsmCode[0] = 0xc7 + (OpSize << 4);
  2212.              BAsmCode[1] = AdrMode;
  2213.              BAsmCode[2] = 0x20 + Code;
  2214.              CodeLen = 3;
  2215.              if (BitPos == 0xff)
  2216.                BAsmCode[2] |= 0x08;
  2217.              else
  2218.                BAsmCode[CodeLen++] = BitPos;
  2219.              break;
  2220.            case ModMem:
  2221.              CodeLen = 2 + AdrCnt;
  2222.              BAsmCode[0] = 0xb0 + AdrMode;
  2223.              memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  2224.              BAsmCode[1 + AdrCnt] = (BitPos == 0xff)
  2225.                                   ? 0x28 + Code
  2226.                                   : 0x80 + (Code << 3) + BitPos;
  2227.              break;
  2228.          }
  2229.       }
  2230.     }
  2231.   }
  2232. }
  2233.  
  2234. static void DecodeBit(Word Code)
  2235. {
  2236.   Boolean OK;
  2237.   Byte BitPos;
  2238.  
  2239.   if (ChkArgCnt(2, 2))
  2240.   {
  2241.     DecodeAdr(&ArgStr[2], MModReg | MModXReg | MModMem);
  2242.     if (AdrType == ModMem)
  2243.       OpSize = 0;
  2244.     if (AdrType != ModNone)
  2245.     {
  2246.       if (OpSize == 2) WrError(ErrNum_InvOpSize);
  2247.       else
  2248.       {
  2249.         BitPos = EvalStrIntExpression(&ArgStr[1], (OpSize == 0) ? UInt3 : Int4, &OK);
  2250.         if (OK)
  2251.         {
  2252.           switch (AdrType)
  2253.           {
  2254.             case ModReg:
  2255.               CodeLen = 3;
  2256.               BAsmCode[0] = 0xc8 + (OpSize << 4) + AdrMode;
  2257.               BAsmCode[1] = 0x30 + Code;
  2258.               BAsmCode[2] = BitPos;
  2259.               break;
  2260.             case ModXReg:
  2261.               CodeLen = 4;
  2262.               BAsmCode[0] = 0xc7 + (OpSize << 4);
  2263.               BAsmCode[1] = AdrMode;
  2264.               BAsmCode[2] = 0x30 + Code;
  2265.               BAsmCode[3] = BitPos;
  2266.               break;
  2267.             case ModMem:
  2268.               CodeLen = 2 + AdrCnt;
  2269.               Code = (Code == 4) ? 0 : Code + 1;
  2270.               BAsmCode[0] = 0xb0 + AdrMode;
  2271.               memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  2272.               BAsmCode[1 + AdrCnt] = 0xa8 + (Code << 3) + BitPos;
  2273.               break;
  2274.           }
  2275.         }
  2276.       }
  2277.     }
  2278.   }
  2279. }
  2280.  
  2281. static void DecodeINC_DEC(Word Code)
  2282. {
  2283.   Boolean OK;
  2284.   Byte Incr;
  2285.   tSymbolFlags Flags;
  2286.  
  2287.   SetInstrOpSize(Hi(Code));
  2288.  
  2289.   if (ChkArgCnt(1, 2))
  2290.   {
  2291.     if (ArgCnt == 1)
  2292.     {
  2293.       Incr = 1;
  2294.       OK = True;
  2295.       Flags = eSymbolFlag_None;
  2296.     }
  2297.     else
  2298.       Incr = EvalStrIntExpressionWithFlags(&ArgStr[1], Int4, &OK, &Flags);
  2299.     if (OK)
  2300.     {
  2301.       if (mFirstPassUnknown(Flags))
  2302.         Incr &= 7;
  2303.       else if ((Incr < 1) || (Incr > 8))
  2304.       {
  2305.         WrError(ErrNum_OverRange);
  2306.         OK = False;
  2307.       }
  2308.     }
  2309.     if (OK)
  2310.     {
  2311.       Incr &= 7;    /* 8-->0 */
  2312.       DecodeAdr(&ArgStr[ArgCnt], MModReg | MModXReg | MModMem);
  2313.       switch (AdrType)
  2314.       {
  2315.         case ModReg:
  2316.           CodeLen = 2;
  2317.           BAsmCode[0] = 0xc8 + (OpSize << 4) + AdrMode;
  2318.           BAsmCode[1] = 0x60 + (Lo(Code) << 3) + Incr;
  2319.           break;
  2320.         case ModXReg:
  2321.           CodeLen = 3;
  2322.           BAsmCode[0] = 0xc7 + (OpSize << 4);
  2323.           BAsmCode[1] = AdrMode;
  2324.           BAsmCode[2] = 0x60 + (Lo(Code) << 3) + Incr;
  2325.           break;
  2326.         case ModMem:
  2327.           if (OpSize == -1)
  2328.             OpSize = 0;
  2329.           CodeLen = 2 + AdrCnt;
  2330.           BAsmCode[0] = 0x80 + AdrMode + (OpSize << 4);
  2331.           memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  2332.           BAsmCode[1 + AdrCnt] = 0x60 + (Lo(Code) << 3) + Incr;
  2333.           break;
  2334.       }
  2335.     }
  2336.   }
  2337. }
  2338.  
  2339. static void DecodeCPxx(Word Code)
  2340. {
  2341.   Boolean OK;
  2342.  
  2343.   if (ChkArgCntExtEitherOr(ArgCnt, 0, 2))
  2344.   {
  2345.     OK = True;
  2346.     if (ArgCnt == 0)
  2347.     {
  2348.       OpSize = 0;
  2349.       AdrMode = 3;
  2350.     }
  2351.     else
  2352.     {
  2353.       tSymbolSize HSize;
  2354.       int l = strlen(ArgStr[2].str.p_str);
  2355.       const char *CmpStr;
  2356.  
  2357.       if (!as_strcasecmp(ArgStr[1].str.p_str, "A"))
  2358.         OpSize = 0;
  2359.       else if (!as_strcasecmp(ArgStr[1].str.p_str, "WA"))
  2360.         OpSize = 1;
  2361.       CmpStr = (Code & 0x02) ? "-)" : "+)";
  2362.       if (OpSize == -1) OK = False;
  2363.       else if ((l < 2) || (*ArgStr[2].str.p_str != '(') || (as_strcasecmp(ArgStr[2].str.p_str + l - 2, CmpStr))) OK = False;
  2364.       else
  2365.       {
  2366.         ArgStr[2].str.p_str[l - 2] = '\0';
  2367.         if (CodeEReg(ArgStr[2].str.p_str + 1, &AdrMode, &HSize) != eIsReg) OK = False;
  2368.         else if (!IsRegBase(AdrMode, HSize)) OK = False;
  2369.         else if (!IsRegCurrent(AdrMode, HSize, &AdrMode)) OK = False;
  2370.       }
  2371.       if (!OK)
  2372.         WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[2]);
  2373.     }
  2374.     if (OK)
  2375.     {
  2376.       CodeLen = 2;
  2377.       BAsmCode[0] = 0x80 + (OpSize << 4) + AdrMode;
  2378.       BAsmCode[1] = Code;
  2379.     }
  2380.   }
  2381. }
  2382.  
  2383. static void DecodeLDxx(Word Code)
  2384. {
  2385.   SetInstrOpSize(Hi(Code));
  2386.  
  2387.   if (OpSize == -1)
  2388.     OpSize = 0;
  2389.   if (OpSize == 2) WrError(ErrNum_InvOpSize);
  2390.   else if (ChkArgCntExtEitherOr(ArgCnt, 0, 2))
  2391.   {
  2392.     Boolean OK;
  2393.     Byte HReg = 0;
  2394.  
  2395.     if (ArgCnt == 0)
  2396.     {
  2397.       OK = True;
  2398.     }
  2399.     else
  2400.     {
  2401.       const char *CmpStr;
  2402.       int l1 = strlen(ArgStr[1].str.p_str),
  2403.           l2 = strlen(ArgStr[2].str.p_str);
  2404.  
  2405.       OK = True;
  2406.       CmpStr = (Code & 0x02) ? "-)" : "+)";
  2407.       if ((*ArgStr[1].str.p_str != '(') || (*ArgStr[2].str.p_str != '(')
  2408.        || (l1 < 3) || (l2 < 3)
  2409.        || (as_strcasecmp(ArgStr[1].str.p_str + l1 - 2, CmpStr))
  2410.        || (as_strcasecmp(ArgStr[2].str.p_str + l2 - 2, CmpStr)))
  2411.         OK = False;
  2412.       else
  2413.       {
  2414.         ArgStr[1].str.p_str[l1 - 2] = '\0';
  2415.         ArgStr[2].str.p_str[l2 - 2] = '\0';
  2416.         if ((!as_strcasecmp(ArgStr[1].str.p_str + 1,"XIX")) && (!as_strcasecmp(ArgStr[2].str.p_str + 1, "XIY")))
  2417.           HReg = 2;
  2418.         else if ((MaxMode) && (!as_strcasecmp(ArgStr[1].str.p_str + 1, "XDE")) && (!as_strcasecmp(ArgStr[2].str.p_str + 1 , "XHL")));
  2419.         else if ((!MaxMode) && (!as_strcasecmp(ArgStr[1].str.p_str + 1, "DE")) && (!as_strcasecmp(ArgStr[2].str.p_str + 1 , "HL")));
  2420.         else
  2421.           OK = False;
  2422.       }
  2423.     }
  2424.     if (!OK) WrError(ErrNum_InvAddrMode);
  2425.     else
  2426.     {
  2427.       CodeLen = 2;
  2428.       BAsmCode[0] = 0x83 + (OpSize << 4) + HReg;
  2429.       BAsmCode[1] = Lo(Code);
  2430.     }
  2431.   }
  2432. }
  2433.  
  2434. static void DecodeMINC_MDEC(Word Code)
  2435. {
  2436.   if (ChkArgCnt(2, 2))
  2437.   {
  2438.     Word AdrWord;
  2439.     Boolean OK;
  2440.  
  2441.     AdrWord = EvalStrIntExpression(&ArgStr[1], Int16, &OK);
  2442.     if (OK)
  2443.     {
  2444.       Byte Pwr;
  2445.       Byte ByteSizeLg2 = Code & 3, ByteSize = 1 << ByteSizeLg2;
  2446.  
  2447.       if (!IsPwr2(AdrWord, &Pwr)) WrStrErrorPos(ErrNum_NotPwr2, &ArgStr[1]);
  2448.       else if (Pwr <= ByteSizeLg2) WrStrErrorPos(ErrNum_UnderRange, &ArgStr[1]);
  2449.       else
  2450.       {
  2451.         AdrWord -= ByteSize;
  2452.         DecodeAdr(&ArgStr[2], MModReg | MModXReg);
  2453.         if ((AdrType != ModNone) && (OpSize != 1)) WrError(ErrNum_InvOpSize);
  2454.         else
  2455.          switch (AdrType)
  2456.          {
  2457.            case ModReg:
  2458.              CodeLen = 4;
  2459.              BAsmCode[0] = 0xd8 + AdrMode;
  2460.              BAsmCode[1] = Code;
  2461.              BAsmCode[2] = Lo(AdrWord);
  2462.              BAsmCode[3] = Hi(AdrWord);
  2463.              break;
  2464.            case ModXReg:
  2465.              CodeLen = 5;
  2466.              BAsmCode[0] = 0xd7;
  2467.              BAsmCode[1] = AdrMode;
  2468.              BAsmCode[2] = Code;
  2469.              BAsmCode[3] = Lo(AdrWord);
  2470.              BAsmCode[4] = Hi(AdrWord);
  2471.              break;
  2472.          }
  2473.       }
  2474.     }
  2475.   }
  2476. }
  2477.  
  2478. static void DecodeRLD_RRD(Word Code)
  2479. {
  2480.   if (!ChkArgCnt(1, 2));
  2481.   else if ((ArgCnt == 2) && (as_strcasecmp(ArgStr[1].str.p_str, "A"))) WrError(ErrNum_InvAddrMode);
  2482.   else
  2483.   {
  2484.     DecodeAdr(&ArgStr[ArgCnt], MModMem);
  2485.     if (AdrType != ModNone)
  2486.     {
  2487.       CodeLen = 2 + AdrCnt;
  2488.       BAsmCode[0] = 0x80 + AdrMode;
  2489.       memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  2490.       BAsmCode[1 + AdrCnt] = Code;
  2491.     }
  2492.   }
  2493. }
  2494.  
  2495. static void DecodeSCC(Word Code)
  2496. {
  2497.   UNUSED(Code);
  2498.  
  2499.   if (ChkArgCnt(2, 2))
  2500.   {
  2501.     Byte cond_code;
  2502.  
  2503.     if (!decode_condition(ArgStr[1].str.p_str, &cond_code)) WrStrErrorPos(ErrNum_UndefCond, &ArgStr[1]);
  2504.     else
  2505.     {
  2506.       DecodeAdr(&ArgStr[2], MModReg | MModXReg);
  2507.       if (OpSize > 1) WrError(ErrNum_UndefOpSizes);
  2508.       else
  2509.       {
  2510.          switch (AdrType)
  2511.          {
  2512.            case ModReg:
  2513.              CodeLen = 2;
  2514.              BAsmCode[0] = 0xc8 + (OpSize << 4) + AdrMode;
  2515.              BAsmCode[1] = 0x70 + cond_code;
  2516.              break;
  2517.            case ModXReg:
  2518.              CodeLen = 3;
  2519.              BAsmCode[0] = 0xc7 + (OpSize << 4);
  2520.              BAsmCode[1] = AdrMode;
  2521.              BAsmCode[2] = 0x70 + cond_code;
  2522.              break;
  2523.          }
  2524.       }
  2525.     }
  2526.   }
  2527.   return;
  2528. }
  2529.  
  2530. /*---------------------------------------------------------------------------*/
  2531.  
  2532. static void AddSize(const char *NName, Byte NCode, InstProc Proc, Word SizeMask)
  2533. {
  2534.   int l;
  2535.   char SizeName[20];
  2536.  
  2537.   AddInstTable(InstTable, NName, 0xff00 | NCode, Proc);
  2538.   l = as_snprintf(SizeName, sizeof(SizeName), "%sB", NName);
  2539.   if (SizeMask & 1)
  2540.     AddInstTable(InstTable, SizeName, 0x0000 | NCode, Proc);
  2541.   if (SizeMask & 2)
  2542.   {
  2543.     SizeName[l - 1] = 'W';
  2544.     AddInstTable(InstTable, SizeName, 0x0100 | NCode, Proc);
  2545.   }
  2546.  
  2547.   /* CP(L) would generate conflict with CPL instruction - dispatch
  2548.      it from CPL single-op instruction if ArgCnt >= 2! */
  2549.  
  2550.   if ((SizeMask & 4) && (strcmp(NName, "CP")))
  2551.   {
  2552.     SizeName[l - 1] = 'L';
  2553.     AddInstTable(InstTable, SizeName, 0x0200 | NCode, Proc);
  2554.   }
  2555. }
  2556.  
  2557. static void AddMod(const char *NName, Byte NCode)
  2558. {
  2559.   int l;
  2560.   char SizeName[20];
  2561.  
  2562.   l = as_snprintf(SizeName, sizeof(SizeName), "%s1", NName);
  2563.   AddInstTable(InstTable, SizeName, NCode, DecodeMINC_MDEC);
  2564.   SizeName[l - 1] = '2';
  2565.   AddInstTable(InstTable, SizeName, NCode | 1, DecodeMINC_MDEC);
  2566.   SizeName[l - 1] = '4';
  2567.   AddInstTable(InstTable, SizeName, NCode | 2, DecodeMINC_MDEC);
  2568. }
  2569.  
  2570. static void AddFixed(const char *NName, Word NCode, Byte NFlag, Boolean NSup)
  2571. {
  2572.   order_array_rsv_end(FixedOrders, FixedOrder);
  2573.   FixedOrders[InstrZ].Code = NCode;
  2574.   FixedOrders[InstrZ].CPUFlag = NFlag;
  2575.   FixedOrders[InstrZ].InSup = NSup;
  2576.   AddInstTable(InstTable, NName, InstrZ++, DecodeFixed);
  2577. }
  2578.  
  2579. static void AddReg(const char *NName, Word NCode, Byte NMask)
  2580. {
  2581.   order_array_rsv_end(RegOrders, RegOrder);
  2582.   RegOrders[InstrZ].Code = NCode;
  2583.   RegOrders[InstrZ].OpMask = NMask;
  2584.   AddInstTable(InstTable, NName, InstrZ++, DecodeReg);
  2585. }
  2586.  
  2587. static void AddImm(const char *NName, Word NCode, Boolean NInSup,
  2588.                    Byte NMinMax, Byte NMaxMax, ShortInt NDefault)
  2589. {
  2590.   order_array_rsv_end(ImmOrders, ImmOrder);
  2591.   ImmOrders[InstrZ].Code = NCode;
  2592.   ImmOrders[InstrZ].InSup = NInSup;
  2593.   ImmOrders[InstrZ].MinMax = NMinMax;
  2594.   ImmOrders[InstrZ].MaxMax = NMaxMax;
  2595.   ImmOrders[InstrZ].Default = NDefault;
  2596.   AddInstTable(InstTable, NName, InstrZ++, DecodeImm);
  2597. }
  2598.  
  2599. static void AddALU2(const char *NName, Byte NCode)
  2600. {
  2601.   AddSize(NName, NCode, DecodeALU2, 7);
  2602. }
  2603.  
  2604. static void AddShift(const char *NName)
  2605. {
  2606.   AddSize(NName, InstrZ++, DecodeShift, 7);
  2607. }
  2608.  
  2609. static void AddMulDiv(const char *NName)
  2610. {
  2611.   AddInstTable(InstTable, NName, InstrZ++, DecodeMulDiv);
  2612. }
  2613.  
  2614. static void AddBitCF(const char *NName, Byte NCode)
  2615. {
  2616.   AddInstTable(InstTable, NName, NCode, DecodeBitCF);
  2617. }
  2618.  
  2619. static void AddBit(const char *NName)
  2620. {
  2621.   AddInstTable(InstTable, NName, InstrZ++, DecodeBit);
  2622. }
  2623.  
  2624. static void AddCondition(const char *NName, Byte NCode)
  2625. {
  2626.   order_array_rsv_end(Conditions, Condition);
  2627.   Conditions[InstrZ].Name = NName;
  2628.   Conditions[InstrZ++].Code = NCode;
  2629. }
  2630.  
  2631. static void InitFields(void)
  2632. {
  2633.   InstTable = CreateInstTable(301);
  2634.   SetDynamicInstTable(InstTable);
  2635.  
  2636.   add_null_pseudo(InstTable);
  2637.  
  2638.   AddInstTable(InstTable, "MULA"  , 0, DecodeMULA);
  2639.   AddInstTable(InstTable, "JP"    , 0, DecodeJPCALL);
  2640.   AddInstTable(InstTable, "CALL"  , 1, DecodeJPCALL);
  2641.   AddInstTable(InstTable, "JR"    , 0, DecodeJR);
  2642.   AddInstTable(InstTable, "JRL"   , 1, DecodeJR);
  2643.   AddInstTable(InstTable, "CALR"  , 0, DecodeCALR);
  2644.   AddInstTable(InstTable, "RET"   , 0, DecodeRET);
  2645.   AddInstTable(InstTable, "RETD"  , 0, DecodeRETD);
  2646.   AddInstTable(InstTable, "DJNZ"  , 0, DecodeDJNZ);
  2647.   AddInstTable(InstTable, "EX"    , 0, DecodeEX);
  2648.   AddInstTable(InstTable, "BS1F"  , 0, DecodeBS1x);
  2649.   AddInstTable(InstTable, "BS1B"  , 1, DecodeBS1x);
  2650.   AddInstTable(InstTable, "LDA"   , 0, DecodeLDA);
  2651.   AddInstTable(InstTable, "LDAR"  , 0, DecodeLDAR);
  2652.   AddInstTable(InstTable, "LDC"   , 0, DecodeLDC);
  2653.   AddInstTable(InstTable, "LDX"   , 0, DecodeLDX);
  2654.   AddInstTable(InstTable, "LINK"  , 0, DecodeLINK);
  2655.   AddSize("LD", 0, DecodeLD, 7);
  2656.   AddSize("PUSH", 0, DecodePUSH_POP, 7);
  2657.   AddSize("POP" , 1, DecodePUSH_POP, 7);
  2658.   AddSize("INC" , 0, DecodeINC_DEC, 7);
  2659.   AddSize("DEC" , 1, DecodeINC_DEC, 7);
  2660.   AddInstTable(InstTable, "CPI"  , 0x14, DecodeCPxx);
  2661.   AddInstTable(InstTable, "CPIR" , 0x15, DecodeCPxx);
  2662.   AddInstTable(InstTable, "CPD"  , 0x16, DecodeCPxx);
  2663.   AddInstTable(InstTable, "CPDR" , 0x17, DecodeCPxx);
  2664.   AddSize("LDI", 0x10 , DecodeLDxx, 3);
  2665.   AddSize("LDIR", 0x11, DecodeLDxx, 3);
  2666.   AddSize("LDD", 0x12 , DecodeLDxx, 3);
  2667.   AddSize("LDDR", 0x13, DecodeLDxx, 3);
  2668.   AddMod("MINC", 0x38);
  2669.   AddMod("MDEC", 0x3c);
  2670.   AddInstTable(InstTable, "RLD", 0x06, DecodeRLD_RRD);
  2671.   AddInstTable(InstTable, "RRD", 0x07, DecodeRLD_RRD);
  2672.   AddInstTable(InstTable, "SCC", 0, DecodeSCC);
  2673.  
  2674.   InstrZ = 0;
  2675.   AddFixed("CCF"   , 0x0012, 3, False);
  2676.   AddFixed("DECF"  , 0x000d, 3, False);
  2677.   AddFixed("DI"    , 0x0607, 3, True );
  2678.   AddFixed("HALT"  , 0x0005, 3, True );
  2679.   AddFixed("INCF"  , 0x000c, 3, False);
  2680.   AddFixed("MAX"   , 0x0004, 1, True );
  2681.   AddFixed("MIN"   , 0x0004, 2, True );
  2682.   AddFixed("NOP"   , 0x0000, 3, False);
  2683.   AddFixed("NORMAL", 0x0001, 1, True );
  2684.   AddFixed("RCF"   , 0x0010, 3, False);
  2685.   AddFixed("RETI"  , 0x0007, 3, True );
  2686.   AddFixed("SCF"   , 0x0011, 3, False);
  2687.   AddFixed("ZCF"   , 0x0013, 3, False);
  2688.  
  2689.   InstrZ = 0;
  2690.   AddReg("CPL" , 0xc006, 3);
  2691.   AddReg("DAA" , 0xc010, 1);
  2692.   AddReg("EXTS", 0xc013, 6);
  2693.   AddReg("EXTZ", 0xc012, 6);
  2694.   AddReg("MIRR", 0xc016, 2);
  2695.   AddReg("NEG" , 0xc007, 3);
  2696.   AddReg("PAA" , 0xc014, 6);
  2697.   AddReg("UNLK", 0xc00d, 4);
  2698.  
  2699.   InstrZ = 0;
  2700.   AddImm("EI"  , 0x0600, True,  7, 7,  0);
  2701.   AddImm("LDF" , 0x1700, False, 7, 3, -1);
  2702.   AddImm("SWI" , 0x00f8, False, 7, 7,  7);
  2703.  
  2704.   AddALU2("ADC", 1);
  2705.   AddALU2("ADD", 0);
  2706.   AddALU2("AND", 4);
  2707.   AddALU2("OR" , 6);
  2708.   AddALU2("SBC", 3);
  2709.   AddALU2("SUB", 2);
  2710.   AddALU2("XOR", 5);
  2711.   AddALU2("CP" , 7);
  2712.  
  2713.   InstrZ = 0;
  2714.   AddShift("RLC");
  2715.   AddShift("RRC");
  2716.   AddShift("RL");
  2717.   AddShift("RR");
  2718.   AddShift("SLA");
  2719.   AddShift("SRA");
  2720.   AddShift("SLL");
  2721.   AddShift("SRL");
  2722.  
  2723.   InstrZ = 0;
  2724.   AddMulDiv("MUL");
  2725.   AddMulDiv("MULS");
  2726.   AddMulDiv("DIV");
  2727.   AddMulDiv("DIVS");
  2728.  
  2729.   AddBitCF("ANDCF" , 0);
  2730.   AddBitCF("LDCF"  , 3);
  2731.   AddBitCF("ORCF"  , 1);
  2732.   AddBitCF("STCF"  , 4);
  2733.   AddBitCF("XORCF" , 2);
  2734.  
  2735.   InstrZ = 0;
  2736.   AddBit("RES");
  2737.   AddBit("SET");
  2738.   AddBit("CHG");
  2739.   AddBit("BIT");
  2740.   AddBit("TSET");
  2741.  
  2742.   InstrZ = 0;
  2743.   AddCondition("F"   ,  0); AddCondition("T"   , COND_CODE_TRUE);
  2744.   AddCondition("Z"   ,  6); AddCondition("NZ"  , 14);
  2745.   AddCondition("C"   ,  7); AddCondition("NC"  , 15);
  2746.   AddCondition("PL"  , 13); AddCondition("MI"  ,  5);
  2747.   AddCondition("P"   , 13); AddCondition("M"   ,  5);
  2748.   AddCondition("NE"  , 14); AddCondition("EQ"  ,  6);
  2749.   AddCondition("OV"  ,  4); AddCondition("NOV" , 12);
  2750.   AddCondition("PE"  ,  4); AddCondition("PO"  , 12);
  2751.   AddCondition("GE"  ,  9); AddCondition("LT"  ,  1);
  2752.   AddCondition("GT"  , 10); AddCondition("LE"  ,  2);
  2753.   AddCondition("UGE" , 15); AddCondition("ULT" ,  7);
  2754.   AddCondition("UGT" , 11); AddCondition("ULE" ,  3);
  2755.   AddCondition(NULL  ,  0);
  2756.  
  2757.   AddIntelPseudo(InstTable, eIntPseudoFlag_LittleEndian);
  2758. }
  2759.  
  2760. static void DeinitFields(void)
  2761. {
  2762.   DestroyInstTable(InstTable);
  2763.   order_array_free(FixedOrders);
  2764.   order_array_free(RegOrders);
  2765.   order_array_free(ImmOrders);
  2766.   order_array_free(Conditions);
  2767. }
  2768.  
  2769. static void MakeCode_96C141(void)
  2770. {
  2771.   OpSize = eSymbolSizeUnknown;
  2772.   MinOneIs0 = False;
  2773.  
  2774.   /* vermischt */
  2775.  
  2776.   if (!LookupInstTable(InstTable, OpPart.str.p_str))
  2777.     WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
  2778. }
  2779.  
  2780. static Boolean ChkPC_96C141(LargeWord Addr)
  2781. {
  2782.   Boolean ok;
  2783.  
  2784.   switch (ActPC)
  2785.   {
  2786.     case SegCode:
  2787.       if (MaxMode) ok = (Addr <= 0xffffff);
  2788.               else ok = (Addr <= 0xffff);
  2789.       break;
  2790.     default:
  2791.       ok = False;
  2792.   }
  2793.   return (ok);
  2794. }
  2795.  
  2796.  
  2797. static Boolean IsDef_96C141(void)
  2798. {
  2799.   return False;
  2800. }
  2801.  
  2802. static Boolean ChkMoreOneArg(void)
  2803. {
  2804.   return (ArgCnt > 1);
  2805. }
  2806.  
  2807. static void SwitchTo_96C141(void)
  2808. {
  2809.   TurnWords = False;
  2810.   SetIntConstMode(eIntConstModeIntel);
  2811.   SetIsOccupiedFnc = ChkMoreOneArg;
  2812.  
  2813.   PCSymbol = "$";
  2814.   HeaderID = 0x52;
  2815.   NOPCode = 0x00;
  2816.   DivideChars = ",";
  2817.   HasAttrs = False;
  2818.  
  2819.   ValidSegs = (1 << SegCode);
  2820.   Grans[SegCode] = 1;
  2821.   ListGrans[SegCode] = 1;
  2822.   SegInits[SegCode] = 0;
  2823.   SegLimits[SegCode] = 0xfffffful;
  2824.  
  2825.   MakeCode = MakeCode_96C141;
  2826.   ChkPC = ChkPC_96C141;
  2827.   IsDef = IsDef_96C141;
  2828.   SwitchFrom = DeinitFields;
  2829.   onoff_maxmode_add();
  2830.   onoff_supmode_add();
  2831.  
  2832.   InitFields();
  2833. }
  2834.  
  2835. void code96c141_init(void)
  2836. {
  2837.   CPU96C141 = AddCPU("96C141", SwitchTo_96C141);
  2838.   CPU93C141 = AddCPU("93C141", SwitchTo_96C141);
  2839. }
  2840.