Subversion Repositories pentevo

Rev

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

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