Subversion Repositories pentevo

Rev

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

  1. /* code3254x.c */
  2. /*****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
  4. /*                                                                           */
  5. /* Macro Assembler AS                                                        */
  6. /*                                                                           */
  7. /* Code Generator for TI C54x DSP devices                                    */
  8. /*                                                                           */
  9. /*****************************************************************************/
  10.  
  11. /*-------------------------------------------------------------------------*/
  12. /* Includes */
  13.  
  14. #include "stdinc.h"
  15. #include <string.h>
  16. #include <ctype.h>
  17.  
  18. #include "bpemu.h"
  19. #include "strutil.h"
  20. #include "chunks.h"
  21. #include "asmdef.h"
  22. #include "asmsub.h"
  23. #include "asmpars.h"
  24. #include "asmallg.h"
  25. #include "asmrelocs.h"
  26. #include "asmcode.h"
  27. #include "codepseudo.h"
  28. #include "tipseudo.h"
  29. #include "asmitree.h"
  30. #include "codevars.h"
  31. #include "fileformat.h"
  32. #include "headids.h"
  33. #include "errmsg.h"
  34.  
  35. #include "code3254x.h"
  36.  
  37. /*-------------------------------------------------------------------------*/
  38. /* Data Structures */
  39.  
  40. #define FixedOrderCnt 12
  41. #define AccOrderCnt 16
  42. #define Acc2OrderCnt 5
  43. #define MemOrderCnt 9
  44. #define XYOrderCnt 4
  45. #define MemAccOrderCnt 17
  46. #define MemConstOrderCnt 5
  47. #define MacOrderCnt 3
  48. #define ConditionCnt 23
  49.  
  50. typedef struct
  51. {
  52.   Word Code;
  53.   Boolean IsRepeatable;
  54. } FixedOrder;
  55.  
  56. typedef struct
  57. {
  58.   Word Code;
  59.   Boolean IsRepeatable, Swap;
  60.   IntType ConstType;
  61. } MemConstOrder;
  62.  
  63. typedef struct
  64. {
  65.   const char *Name;
  66.   Word Class, Code, Mask;
  67. } Condition;
  68.  
  69. typedef enum {ModNone = - 1, ModAcc, ModMem, ModImm, ModAReg} ModType;
  70. #define MModAcc  (1 << ModAcc)
  71. #define MModMem  (1 << ModMem)
  72. #define MModImm  (1 << ModImm)
  73. #define MModAReg (1 << ModAReg)
  74.  
  75. static LongInt Reg_CPL, Reg_DP, Reg_SP;
  76.  
  77. static Boolean ThisRep, LastRep, ForcePageZero;
  78.  
  79. static FixedOrder *FixedOrders, *AccOrders, *Acc2Orders, *MemOrders, *XYOrders,
  80.                   *MemAccOrders, *MacOrders;
  81. static MemConstOrder *MemConstOrders;
  82. static Condition *Conditions;
  83.  
  84. static CPUVar CPU320C541;
  85.  
  86. static IntType OpSize;
  87. static ShortInt AdrMode;
  88. static Word AdrVals[3];
  89.  
  90. static Boolean ThisPar;
  91. static Word LastOpCode;
  92.  
  93. /*-------------------------------------------------------------------------*/
  94. /* Address Decoder */
  95.  
  96. static const char ShortConds[4][4] =
  97. {
  98.   "EQ", "LT", "GT", "NEQ"
  99. };
  100.  
  101. static Boolean IsAcc(char *Asc)
  102. {
  103.   return ((Asc[1] == '\0') && (as_toupper(*Asc) >= 'A') && (as_toupper(*Asc) <= 'B'));
  104. }
  105.  
  106. static Boolean DecodeAdr(const tStrComp *pArg, int Mask)
  107. {
  108. #define IndirCnt 16
  109.   static const char Patterns[IndirCnt][9] = /* leading asterisk is omitted since constant */
  110.   {
  111.     "ARx",      "ARx-",     "ARx+",      "+ARx",
  112.     "ARx-0B",   "ARx-0",    "ARx+0",     "ARx+0B",
  113.     "ARx-%",    "ARx-0%",   "ARx+%",     "ARx+0%",
  114.     "ARx(n)",   "+ARx(n)",  "+ARx(n)%",  "(n)"
  115.   };
  116.   Boolean OK;
  117.  
  118.   AdrMode = ModNone;
  119.   AdrCnt = 0;
  120.  
  121.   /* accumulators */
  122.  
  123.   if (IsAcc(pArg->str.p_str))
  124.   {
  125.     AdrMode = ModAcc;
  126.     *AdrVals = as_toupper(*pArg->str.p_str) - 'A';
  127.     goto done;
  128.   }
  129.  
  130.   /* aux registers */
  131.  
  132.   if ((strlen(pArg->str.p_str) == 3) && (!as_strncasecmp(pArg->str.p_str, "AR", 2)) && (pArg->str.p_str[2] >= '0') && (pArg->str.p_str[2] <= '7'))
  133.   {
  134.     AdrMode = ModAReg;
  135.     *AdrVals = pArg->str.p_str[2] - '0';
  136.     goto done;
  137.   }
  138.  
  139.   /* immediate */
  140.  
  141.   if (*pArg->str.p_str == '#')
  142.   {
  143.     *AdrVals = EvalStrIntExpressionOffs(pArg, 1, OpSize, &OK);
  144.     if (OK)
  145.       AdrMode = ModImm;
  146.     goto done;
  147.   }
  148.  
  149.   /* indirect */
  150.  
  151.   if (*pArg->str.p_str == '*')
  152.   {
  153.     int z;
  154.     Word RegNum;
  155.     char *pConstStart, *pConstEnd;
  156.  
  157.     /* check all possible patterns */
  158.  
  159.     for (z = 0; z < IndirCnt; z++)
  160.     {
  161.       const char *pPattern = Patterns[z];
  162.       char *pComp = pArg->str.p_str + 1;
  163.  
  164.       /* pattern comparison */
  165.  
  166.       RegNum = 0;
  167.       pConstStart = pConstEnd = NULL;
  168.       OK = TRUE;
  169.       while ((*pPattern) && (*pComp) && (OK))
  170.       {
  171.         switch (*pPattern)
  172.         {
  173.           case 'x': /* embedded number */
  174.             RegNum = *pComp - '0';
  175.             OK = RegNum < 8;
  176.             break;
  177.           case 'n': /* constant */
  178.             pConstStart = pComp;
  179.             pConstEnd = QuotPos(pComp, pPattern[1]);
  180.             if (pConstEnd)
  181.               pComp = pConstEnd - 1;
  182.             else
  183.               OK = False;
  184.             break;
  185.           default:  /* compare verbatim */
  186.             if (as_toupper(*pPattern) != as_toupper(*pComp))
  187.               OK = False;
  188.         }
  189.         if (OK)
  190.         {
  191.           pPattern++;
  192.           pComp++;
  193.         }
  194.       }
  195.  
  196.       /* for a successful comparison, we must have reached the end of both strings
  197.          simultaneously. */
  198.  
  199.       OK = OK && (!*pPattern) && (!*pComp);
  200.       if (OK)
  201.         break;
  202.     }
  203.  
  204.     if (!OK) WrError(ErrNum_InvAddrMode);
  205.     else
  206.     {
  207.       /* decode offset ? pConst... /must/ be set if such a pattern was successfully
  208.          decoded! */
  209.  
  210.       if (strchr(Patterns[z], 'n'))
  211.       {
  212.         /* MMR-style instructions do not allow an extension word */
  213.  
  214.         if (ForcePageZero)
  215.         {
  216.           WrError(ErrNum_InvAddrMode);
  217.           OK = False;
  218.         }
  219.         else
  220.         {
  221.           tStrComp Start, Remainder;
  222.           char Save;
  223.  
  224.           StrCompRefRight(&Start, pArg, pConstStart - pArg->str.p_str);
  225.           Save = StrCompSplitRef(&Start, &Remainder, &Start, pConstEnd);
  226.           AdrVals[1] = EvalStrIntExpression(&Start, Int16, &OK);
  227.           *pConstEnd = Save;
  228.           if (OK)
  229.             AdrCnt = 1;
  230.         }
  231.       }
  232.  
  233.       /* all fine until now? Then do the rest... */
  234.  
  235.       if (OK)
  236.       {
  237.         AdrMode = ModMem;
  238.         AdrVals[0] = 0x80 | (z << 3) | RegNum;
  239.       }
  240.     }
  241.  
  242.     goto done;
  243.   }
  244.  
  245.   /* then try absolute resp. immediate if absolute not allowed */
  246.  
  247.   if (Mask & MModMem)
  248.   {
  249.     tSymbolFlags Flags;
  250.  
  251.     *AdrVals = EvalStrIntExpressionWithFlags(pArg, UInt16, &OK, &Flags);
  252.     if (OK)
  253.     {
  254.       if (Reg_CPL) /* short address rel. to SP? */
  255.       {
  256.         *AdrVals -= Reg_SP;
  257.         if (!mFirstPassUnknown(Flags) && (*AdrVals > 127))
  258.           WrError(ErrNum_InAccPage);
  259.       }
  260.       else         /* on DP page ? */
  261.       {
  262.         if (!mFirstPassUnknown(Flags) && ((*AdrVals >> 7) != (Reg_DP)))
  263.           WrError(ErrNum_InAccPage);
  264.       }
  265.       AdrVals[0] &= 127;
  266.       AdrMode = ModMem;
  267.     }
  268.   }
  269.   else
  270.   {
  271.     *AdrVals = EvalStrIntExpression(pArg, OpSize, &OK);
  272.     if (OK)
  273.       AdrMode = ModImm;
  274.   }
  275.  
  276. done:
  277.   if ((AdrMode != ModNone) && (!(Mask & (1 << AdrMode))))
  278.   {
  279.     AdrMode = ModNone; AdrCnt = 0;
  280.     WrError(ErrNum_InvAddrMode);
  281.   }
  282.   return (AdrMode != ModNone);
  283. }
  284.  
  285. static Boolean MakeXY(Word *Dest, Boolean Quarrel)
  286. {
  287.   Boolean Result = False;
  288.  
  289.   if (AdrMode != ModMem);  /* should never occur, if address mask specified correctly before */
  290.   else
  291.   {
  292.     Word Mode = (*AdrVals >> 3) & 15, Reg = *AdrVals & 7;
  293.  
  294.     if ((Reg < 2) || (Reg > 5));
  295.     else if ((Mode != 0) && (Mode != 1) && (Mode != 2) && (Mode != 11));
  296.     else
  297.     {
  298.       *Dest = (Reg - 2) | ((Mode & 3) << 2);
  299.       Result = True;
  300.     }
  301.   }
  302.  
  303.   if ((Quarrel) && (!Result))
  304.     WrError(ErrNum_InvAddrMode);
  305.  
  306.   return Result;
  307. }
  308.  
  309. static Boolean DecodeCondition(int StartIndex, Word *Result, int *errindex, Boolean *ErrUnknown)
  310. {
  311.   int z, z2;
  312.   Word CurrClass, CurrMask;
  313.  
  314.   *Result = CurrMask = 0; CurrClass = 0xffff; *ErrUnknown = False;
  315.  
  316.   for (z = StartIndex; z <= ArgCnt; z++)
  317.   {
  318.     for (z2 = 0; z2 < ConditionCnt; z2++)
  319.       if (!as_strcasecmp(ArgStr[z].str.p_str, Conditions[z2].Name))
  320.         break;
  321.     if (z2 >= ConditionCnt)
  322.     {
  323.       *ErrUnknown = True;
  324.       break;
  325.     }
  326.  
  327.     if (CurrClass == 0xffff)
  328.       CurrClass = Conditions[z2].Class;
  329.     else if (CurrClass != Conditions[z2].Class)
  330.       break;
  331.  
  332.     if (Conditions[z2].Mask & CurrMask)
  333.       break;
  334.  
  335.     CurrMask |= Conditions[z2].Mask;
  336.     *Result |= Conditions[z2].Code;
  337.   }
  338.  
  339.   *errindex = z;
  340.   return (CurrClass != 0xffff) && (z > ArgCnt);
  341. }
  342.  
  343. /*-------------------------------------------------------------------------*/
  344. /* Decoders */
  345.  
  346. static void DecodeFixed(Word Index)
  347. {
  348.   const FixedOrder *POrder = FixedOrders + Index;
  349.  
  350.   if (!ChkArgCnt(0, 0));
  351.   else if (ThisPar) WrError(ErrNum_ParNotPossible);
  352.   else if ((LastRep) && (!POrder->IsRepeatable)) WrError(ErrNum_NotRepeatable);
  353.   else
  354.   {
  355.     WAsmCode[0] = POrder->Code;
  356.     CodeLen = 1;
  357.   }
  358. }
  359.  
  360. static void DecodeAcc(Word Index)
  361. {
  362.   const FixedOrder *POrder = AccOrders + Index;
  363.  
  364.   if (!ChkArgCnt(1, 1));
  365.   else if (ThisPar) WrError(ErrNum_ParNotPossible);
  366.   else if ((LastRep) && (!POrder->IsRepeatable)) WrError(ErrNum_NotRepeatable);
  367.   else
  368.   {
  369.     if (DecodeAdr(&ArgStr[1], MModAcc))
  370.     {
  371.       WAsmCode[0] = POrder->Code | (AdrVals[0] << 8);
  372.       CodeLen = 1;
  373.     }
  374.   }
  375. }
  376.  
  377. static void DecodeAcc2(Word Index)
  378. {
  379.   const FixedOrder *POrder = Acc2Orders + Index;
  380.   Boolean OK;
  381.  
  382.   if (!ChkArgCnt(1, 2));
  383.   else if (ThisPar) WrError(ErrNum_ParNotPossible);
  384.   else if ((LastRep) && (!POrder->IsRepeatable)) WrError(ErrNum_NotRepeatable);
  385.   else
  386.   {
  387.     OK = DecodeAdr(&ArgStr[1], MModAcc);
  388.     if (OK)
  389.     {
  390.       WAsmCode[0] = POrder->Code | (AdrVals[0] << 9);
  391.       if (ArgCnt == 2)
  392.         OK = DecodeAdr(&ArgStr[2], MModAcc);
  393.       if (OK)
  394.       {
  395.         WAsmCode[0] |= (AdrVals[0] << 8);
  396.         CodeLen = 1;
  397.       }
  398.     }
  399.   }
  400. }
  401.  
  402. static void DecodeMem(Word Index)
  403. {
  404.   const FixedOrder *POrder = MemOrders + Index;
  405.  
  406.   if (!ChkArgCnt(1, 1));
  407.   else if (ThisPar) WrError(ErrNum_ParNotPossible);
  408.   else if ((LastRep) && (!POrder->IsRepeatable)) WrError(ErrNum_NotRepeatable);
  409.   else if (DecodeAdr(&ArgStr[1], MModMem))
  410.   {
  411.     memcpy(WAsmCode, AdrVals, (AdrCnt + 1) << 1);
  412.     WAsmCode[0] |= POrder->Code;
  413.     CodeLen = 1 + AdrCnt;
  414.   }
  415. }
  416.  
  417. static void DecodeXY(Word Index)
  418. {
  419.   const FixedOrder *POrder = XYOrders + Index;
  420.   Word TmpX, TmpY;
  421.  
  422.   if (ArgCnt != 2) WrError(ErrNum_InvAddrMode);
  423.   else if (ThisPar) WrError(ErrNum_ParNotPossible);
  424.   else if ((LastRep) && (!POrder->IsRepeatable)) WrError(ErrNum_NotRepeatable);
  425.   else
  426.   {
  427.     if (DecodeAdr(&ArgStr[1], MModMem))
  428.       if (MakeXY(&TmpX, True))
  429.         if (DecodeAdr(&ArgStr[2], MModMem))
  430.           if (MakeXY(&TmpY, True))
  431.           {
  432.             WAsmCode[0] = POrder->Code | (TmpX << 4) | TmpY;
  433.             CodeLen = 1;
  434.           }
  435.   }
  436. }
  437.  
  438. static void DecodeADDSUB(Word Index)
  439. {
  440.   Boolean OK;
  441.   Integer Shift;
  442.   Word DestAcc;
  443.  
  444.   if (ChkArgCnt(2, 4))
  445.   {
  446.     OpSize = SInt16;
  447.     DecodeAdr(&ArgStr[1], MModAcc | MModMem | MModImm);
  448.     switch (AdrMode)
  449.     {
  450.       case ModAcc:  /* ADD src, SHIFT|ASM [,dst] */
  451.         if (!ChkArgCnt(2, 3));
  452.         else if (ThisPar) WrError(ErrNum_ParNotPossible);
  453.         else
  454.         {
  455.           Word SrcAcc = *AdrVals;
  456.  
  457.           /* SrcAcc remains in AdrVals[0] if no 3rd operand, therefore
  458.              no extra assignment needed! */
  459.  
  460.           if (ArgCnt == 3)
  461.           {
  462.             if (!DecodeAdr(&ArgStr[3], MModAcc))
  463.               break;
  464.           }
  465.  
  466.           /* distinguish variants of shift specification: */
  467.  
  468.           if (!as_strcasecmp(ArgStr[2].str.p_str, "ASM"))
  469.           {
  470.             WAsmCode[0] = 0xf480 | Index | (SrcAcc << 9) | (*AdrVals << 8);
  471.             CodeLen = 1;
  472.           }
  473.           else
  474.           {
  475.             WAsmCode[0] = EvalStrIntExpression(&ArgStr[2], SInt5, &OK);
  476.             if (OK)
  477.             {
  478.               WAsmCode[0] = (WAsmCode[0] & 0x1f) | 0xf400 | (Index << 5) | (SrcAcc << 9) | (*AdrVals << 8);
  479.               CodeLen = 1;
  480.             }
  481.           }
  482.         }
  483.         break;
  484.  
  485.       case ModMem: /* ADD mem[, TS | SHIFT | Ymem], src[, dst] */
  486.       {
  487.         int HCnt;
  488.  
  489.         /* rescue decoded address values */
  490.  
  491.         memcpy(WAsmCode, AdrVals, (AdrCnt + 1) << 1);
  492.         HCnt = AdrCnt;
  493.  
  494.         /* no shift? this is the case for two operands or three operands and the second is an accumulator */
  495.  
  496.         if (ArgCnt == 2)
  497.           Shift = 0;
  498.         else if ((ArgCnt == 3) && (IsAcc(ArgStr[2].str.p_str)))
  499.           Shift = 0;
  500.  
  501.         /* special shift value ? */
  502.  
  503.         else if (!as_strcasecmp(ArgStr[2].str.p_str, "TS"))
  504.           Shift = 255;
  505.  
  506.         /* shift address operand ? */
  507.  
  508.         else if (*ArgStr[2].str.p_str == '*')
  509.         {
  510.           Word Tmp;
  511.  
  512.           /* break down source operand to reduced variant */
  513.  
  514.           if (!MakeXY(WAsmCode, True))
  515.             break;
  516.           WAsmCode[0] = WAsmCode[0] << 4;
  517.  
  518.           /* merge in second operand */
  519.  
  520.           if (!DecodeAdr(&ArgStr[2], MModMem))
  521.             break;
  522.           if (!MakeXY(&Tmp, True))
  523.             break;
  524.           WAsmCode[0] |= Tmp;
  525.           Shift = 254;
  526.         }
  527.  
  528.         /* normal immediate shift */
  529.  
  530.         else
  531.         {
  532.           tSymbolFlags Flags;
  533.  
  534.           Shift = EvalStrIntExpressionWithFlags(&ArgStr[2], SInt6, &OK, &Flags);
  535.           if (!OK)
  536.             break;
  537.           if (mFirstPassUnknown(Flags) && (Shift > 16))
  538.             Shift &= 15;
  539.           if (!ChkRange(Shift, -16 ,16))
  540.             break;
  541.         }
  542.  
  543.         /* decode destination accumulator */
  544.  
  545.         if (!DecodeAdr(&ArgStr[ArgCnt], MModAcc))
  546.           break;
  547.         DestAcc = *AdrVals;
  548.  
  549.         /* optionally decode source accumulator.  If no second accumulator, result
  550.            again remains in AdrVals */
  551.  
  552.         if ((ArgCnt == 4) || ((ArgCnt == 3) && (IsAcc(ArgStr[2].str.p_str))))
  553.         {
  554.           if (!DecodeAdr(&ArgStr[ArgCnt - 1], MModAcc))
  555.             break;
  556.         }
  557.  
  558.         /* now start applying the variants */
  559.  
  560.         if (Shift == 255) /* TS case */
  561.         {
  562.           if (*AdrVals != DestAcc) WrError(ErrNum_InvAddrMode);
  563.           else if (ThisPar) WrError(ErrNum_ParNotPossible);
  564.           else
  565.           {
  566.             WAsmCode[0] |= 0x0400 | (Index << 11) | (DestAcc << 8);
  567.             CodeLen = 1 + HCnt;
  568.           }
  569.         }
  570.  
  571.         else if (Shift == 254) /* XY case */
  572.         {
  573.           if (*AdrVals != DestAcc) WrError(ErrNum_InvAddrMode);
  574.           else if (ThisPar) WrError(ErrNum_ParNotPossible);
  575.           else
  576.           {
  577.             WAsmCode[0] |= 0xa000 | (Index << 9) | (DestAcc << 8);
  578.             CodeLen = 1;
  579.           }
  580.         }
  581.  
  582.         else if (Shift == 16) /* optimization for 16 shifts */
  583.         {
  584.           if (ThisPar) WrError(ErrNum_ParNotPossible);
  585.           else
  586.           {
  587.             WAsmCode[0] |= (0x3c00 + (Index << 10)) | (*AdrVals << 9) | (DestAcc << 8);
  588.             CodeLen = 1 + HCnt;
  589.           }
  590.         }
  591.  
  592.         else if ((DestAcc == *AdrVals) && (Shift == 0)) /* shortform without shift and with one accu only */
  593.         {
  594.           if (ThisPar)
  595.           {
  596.             AdrMode = ModMem; AdrVals[0] = WAsmCode[0];
  597.             if (MakeXY(AdrVals, True))
  598.             {
  599.               /* prev. operation must be STH src,0,Xmem */
  600.               if ((LastOpCode & 0xfe0f) != 0x9a00) WrError(ErrNum_ParNotPossible);
  601.               else
  602.               {
  603.                 RetractWords(1);
  604.                 WAsmCode[0] = 0xc000 | (Index << 10) | (DestAcc << 8) | ((LastOpCode & 0x0100) << 1) | ((LastOpCode & 0x00f0) >> 4) | (*AdrVals << 4);
  605.                 CodeLen = 1;
  606.               }
  607.             }
  608.           }
  609.           else
  610.           {
  611.             WAsmCode[0] |= 0x0000 | (Index << 11) | (DestAcc << 8);
  612.             CodeLen = 1 + HCnt;
  613.           }
  614.         }
  615.  
  616.         else if (ThisPar) WrError(ErrNum_ParNotPossible);
  617.         else
  618.         {
  619.           Word SrcAcc = *AdrVals;
  620.  
  621.           /* fool MakeXY a bit */
  622.  
  623.           AdrMode = ModMem; AdrVals[0] = WAsmCode[0];
  624.  
  625.           if ((Shift >= 0) && (DestAcc == SrcAcc) && (MakeXY(WAsmCode, False))) /* X-Addr and positive shift */
  626.           {
  627.             WAsmCode[0] = 0x9000 | (Index << 9) | (WAsmCode[0] << 4) | (DestAcc << 8) | Shift;
  628.             CodeLen = 1;
  629.           }
  630.           else /* last resort... */
  631.           {
  632.             WAsmCode[0] |= 0x6f00;
  633.             WAsmCode[2] = WAsmCode[1]; /* shift optional address offset */
  634.             WAsmCode[1] = 0x0c00 | (Index << 5) | (SrcAcc << 9) | (DestAcc << 8) | (Shift & 0x1f);
  635.             CodeLen = 2 + HCnt;
  636.           }
  637.         }
  638.  
  639.         break;
  640.       }
  641.  
  642.       case ModImm:  /* ADD #lk[, SHIFT|16], src[, dst] */
  643.       {
  644.         if (ThisPar) WrError(ErrNum_ParNotPossible);
  645.         {
  646.           /* store away constant */
  647.  
  648.           WAsmCode[1] = *AdrVals;
  649.  
  650.           /* no shift? this is the case for two operands or three operands and the second is an accumulator */
  651.  
  652.           if (ArgCnt == 2)
  653.             Shift = 0;
  654.           else if ((ArgCnt == 3) && (IsAcc(ArgStr[2].str.p_str)))
  655.             Shift = 0;
  656.  
  657.           /* otherwise shift is second argument */
  658.  
  659.           else
  660.           {
  661.             tSymbolFlags Flags;
  662.  
  663.             Shift = EvalStrIntExpressionWithFlags(&ArgStr[2], UInt5, &OK, &Flags);
  664.             if (!OK)
  665.               break;
  666.             if (mFirstPassUnknown(Flags) && (Shift > 16))
  667.               Shift &= 15;
  668.             if (!ChkRange(Shift, 0 ,16))
  669.               break;
  670.           }
  671.  
  672.           /* decode destination accumulator */
  673.  
  674.           if (!DecodeAdr(&ArgStr[ArgCnt], MModAcc))
  675.             break;
  676.           DestAcc = *AdrVals;
  677.  
  678.           /* optionally decode source accumulator.  If no second accumulator, result
  679.              again remains in AdrVals */
  680.  
  681.           if ((ArgCnt == 4) || ((ArgCnt == 3) && (IsAcc(ArgStr[2].str.p_str))))
  682.           {
  683.             if (!DecodeAdr(&ArgStr[ArgCnt - 1], MModAcc))
  684.               break;
  685.           }
  686.  
  687.           /* distinguish according to shift count */
  688.  
  689.           if (Shift == 16)
  690.           {
  691.             WAsmCode[0] = 0xf060 | Index | (DestAcc << 8) | (*AdrVals << 9);
  692.             CodeLen = 2;
  693.           }
  694.           else
  695.           {
  696.             WAsmCode[0] = 0xf000 | (Index << 5) | (DestAcc << 8) | (*AdrVals << 9) | (Shift & 15);
  697.             CodeLen = 2;
  698.           }
  699.         }
  700.         break;
  701.       }
  702.     }
  703.   }
  704. }
  705.  
  706. static void DecodeMemAcc(Word Index)
  707. {
  708.   FixedOrder *POrder = MemAccOrders + Index;
  709.  
  710.   if (!ChkArgCnt(2, 2));
  711.   else if (ThisPar) WrError(ErrNum_ParNotPossible);
  712.   else if ((LastRep) && (!POrder->IsRepeatable)) WrError(ErrNum_NotRepeatable);
  713.   else if (DecodeAdr(&ArgStr[2], MModAcc))
  714.   {
  715.     WAsmCode[0] = POrder->Code | (AdrVals[0] << 8);
  716.     if (DecodeAdr(&ArgStr[1], MModMem))
  717.     {
  718.       WAsmCode[0] |= *AdrVals;
  719.       if (AdrCnt)
  720.         WAsmCode[1] = AdrVals[1];
  721.       CodeLen = 1 + AdrCnt;
  722.     }
  723.   }
  724. }
  725.  
  726. static void DecodeMemConst(Word Index)
  727. {
  728.   MemConstOrder *POrder = MemConstOrders + Index;
  729.   int HCnt;
  730.  
  731.   if (!ChkArgCnt(2, 2));
  732.   else if (ThisPar) WrError(ErrNum_ParNotPossible);
  733.   else if ((LastRep) && (!POrder->IsRepeatable)) WrError(ErrNum_NotRepeatable);
  734.   else if (DecodeAdr(&ArgStr[2 - POrder->Swap], MModMem))
  735.   {
  736.     WAsmCode[0] = POrder->Code | 0[AdrVals];
  737.     HCnt = AdrCnt;
  738.     if (HCnt)
  739.       WAsmCode[1] = AdrVals[1];
  740.     OpSize = POrder->ConstType;
  741.     if (DecodeAdr(&ArgStr[1 +  POrder->Swap], MModImm))
  742.     {
  743.       WAsmCode[1 + HCnt] = *AdrVals;
  744.       CodeLen = 2 + HCnt;
  745.     }
  746.   }
  747. }
  748.  
  749. static void DecodeMPY(Word Index)
  750. {
  751.   Word DestAcc;
  752.  
  753.   (void)Index;
  754.  
  755.   if (!ChkArgCnt(2, 3));
  756.   else if (DecodeAdr(&ArgStr[ArgCnt], MModAcc))
  757.   {
  758.     DestAcc = (*AdrVals) << 8;
  759.     if (ArgCnt == 3)
  760.     {
  761.       Word XMode;
  762.  
  763.       if (ThisPar) WrError(ErrNum_ParNotPossible);
  764.       else if (DecodeAdr(&ArgStr[1], MModMem))
  765.         if (MakeXY(&XMode, True))
  766.           if (DecodeAdr(&ArgStr[2], MModMem))
  767.             if (MakeXY(WAsmCode, True))
  768.             {
  769.               *WAsmCode |= 0xa400 | DestAcc | (XMode << 4);
  770.               CodeLen = 1;
  771.             }
  772.     }
  773.     else
  774.     {
  775.       OpSize = SInt16;
  776.       DecodeAdr(&ArgStr[1], MModImm | MModMem);
  777.       switch (AdrMode)
  778.       {
  779.         case ModImm:
  780.           if (ThisPar) WrError(ErrNum_ParNotPossible);
  781.           else
  782.           {
  783.             WAsmCode[0] = 0xf066 | DestAcc;
  784.             WAsmCode[1] = *AdrVals;
  785.             CodeLen = 2;
  786.           }
  787.           break;
  788.         case ModMem:
  789.           if (ThisPar)
  790.           {
  791.             if (MakeXY(AdrVals, True))
  792.             {
  793.               /* previous op ST src, Ym */
  794.               if ((LastOpCode & 0xfe0f) != 0x9a00) WrError(ErrNum_ParNotPossible);
  795.               else
  796.               {
  797.                 RetractWords(1);
  798.                 *WAsmCode = 0xcc00 | DestAcc | ((LastOpCode & 0x0100) << 1) | ((LastOpCode & 0x00f0) >> 4) | (*AdrVals);
  799.                 CodeLen = 1;
  800.               }
  801.             }
  802.           }
  803.           else
  804.           {
  805.             WAsmCode[0] = 0x2000 | DestAcc | 0[AdrVals];
  806.             if (AdrCnt)
  807.               WAsmCode[1] = AdrVals[1];
  808.             CodeLen = 1 + AdrCnt;
  809.           }
  810.           break;
  811.       }
  812.     }
  813.   }
  814. }
  815.  
  816. static void DecodeMPYA(Word Index)
  817. {
  818.   (void) Index;
  819.  
  820.   if (!ChkArgCnt(1, 1));
  821.   else if (ThisPar) WrError(ErrNum_ParNotPossible);
  822.   else
  823.   {
  824.     DecodeAdr(&ArgStr[1], MModAcc | MModMem);
  825.     switch (AdrMode)
  826.     {
  827.       case ModMem:
  828.         WAsmCode[0] = 0x3100 | AdrVals[0];
  829.         if (AdrCnt)
  830.           WAsmCode[1] = AdrVals[1];
  831.         CodeLen = 1 + AdrCnt;
  832.         break;
  833.       case ModAcc:
  834.         WAsmCode[0] = 0xf48c | (*AdrVals << 8);
  835.         CodeLen = 1;
  836.         break;
  837.     }
  838.   }
  839. }
  840.  
  841. static void DecodeSQUR(Word Index)
  842. {
  843.   (void)Index;
  844.  
  845.   if (!ChkArgCnt(2, 2));
  846.   else if (ThisPar) WrError(ErrNum_ParNotPossible);
  847.   else if (DecodeAdr(&ArgStr[2], MModAcc))
  848.   {
  849.     0[WAsmCode] = *AdrVals << 8;
  850.     DecodeAdr(&ArgStr[1], MModAcc | MModMem);
  851.     switch (AdrMode)
  852.     {
  853.       case ModAcc:
  854.         if (*AdrVals) WrError(ErrNum_InvAddrMode);
  855.         else
  856.         {
  857.           WAsmCode[0] |= 0xf48d;
  858.           CodeLen = 1;
  859.         }
  860.         break;
  861.       case ModMem:
  862.         WAsmCode[0] |= 0x2600 | *AdrVals;
  863.         if (AdrCnt)
  864.           WAsmCode[1] = AdrVals[1];
  865.         CodeLen = 1 + AdrCnt;
  866.         break;
  867.     }
  868.   }
  869. }
  870.  
  871. static void DecodeMAC(Word Index)
  872. {
  873.   (void) Index;
  874.  
  875.   if (!ChkArgCnt(2, 4));
  876.   else if (DecodeAdr(&ArgStr[ArgCnt], MModAcc))
  877.   {
  878.     *WAsmCode = (*AdrVals) << 8;
  879.     OpSize = SInt16;
  880.     DecodeAdr(&ArgStr[1], MModImm | MModMem);
  881.  
  882.     /* handle syntax 3: immediate op first */
  883.  
  884.     if (AdrMode == ModImm)
  885.     {
  886.       if (!ChkArgCnt(2, 3));
  887.       else if (ThisPar) WrError(ErrNum_ParNotPossible);
  888.       else
  889.       {
  890.         *WAsmCode |= 0xf067; WAsmCode[1] = *AdrVals;
  891.         if (ArgCnt == 2)
  892.         {
  893.           *WAsmCode |= ((*WAsmCode & 0x100) << 1);
  894.           CodeLen = 2;
  895.         }
  896.         else if (DecodeAdr(&ArgStr[2], MModAcc))
  897.         {
  898.           *WAsmCode |= ((*AdrVals) << 9);
  899.           CodeLen = 2;
  900.         }
  901.       }
  902.     }
  903.  
  904.     /* syntax 1/2/4 have memory operand in front */
  905.  
  906.     else if (AdrMode == ModMem)
  907.     {
  908.       /* save [first] memory operand */
  909.  
  910.       Word HMode = *AdrVals, HCnt = AdrCnt;
  911.       if (AdrCnt)
  912.         WAsmCode[1] = AdrVals[1];
  913.  
  914.       /* syntax 2+4 have at least 3 operands, handle syntax 1 */
  915.  
  916.       if (ArgCnt == 2)
  917.       {
  918.         if (ThisPar)
  919.         {
  920.           if (MakeXY(AdrVals, True))
  921.           {
  922.             if ((LastOpCode & 0xfe0f) == 0x9400) /* previous op LD Xmem, src */
  923.             {
  924.               if ((LastOpCode & 0x0100) == (*WAsmCode & 0x0100)) WrError(ErrNum_ParNotPossible);
  925.               else
  926.               {
  927.                 RetractWords(1);
  928.                 *WAsmCode = 0xa800 | (LastOpCode & 0x01f0) | (*AdrVals);
  929.                 CodeLen = 1;
  930.               }
  931.             }
  932.             else if ((LastOpCode & 0xfe0f) == 0x9a00) /* previous op ST src, Ymem */
  933.             {
  934.               RetractWords(1);
  935.               *WAsmCode |= 0xd000 | ((LastOpCode & 0x0100) << 1) | ((LastOpCode & 0x00f0) >> 4) | (*AdrVals << 4);
  936.               CodeLen = 1;
  937.             }
  938.             else WrError(ErrNum_ParNotPossible);
  939.           }
  940.         }
  941.         else
  942.         {
  943.           *WAsmCode |= 0x2800 | HMode;
  944.           CodeLen = 1 + AdrCnt;
  945.         }
  946.       }
  947.       else if (ThisPar) WrError(ErrNum_ParNotPossible);
  948.       else
  949.       {
  950.         /* both syntax 2+4 have optional second accumulator */
  951.  
  952.         if (ArgCnt == 3)
  953.           *WAsmCode |= ((*WAsmCode & 0x100) << 1);
  954.         else if (DecodeAdr(&ArgStr[3], MModAcc))
  955.           *WAsmCode |= ((*AdrVals) << 9);
  956.  
  957.         /* if no second accu, AdrMode is still set from previous decode */
  958.  
  959.         if (AdrMode != ModNone)
  960.         {
  961.           /* differentiate & handle syntax 2 & 4. OpSize still set from above! */
  962.  
  963.           DecodeAdr(&ArgStr[2], MModMem | MModImm);
  964.           switch (AdrMode)
  965.           {
  966.             case ModMem:
  967.               if (MakeXY(AdrVals, TRUE))
  968.               {
  969.                 WAsmCode[0] |= (*AdrVals);
  970.                 *AdrVals = HMode;
  971.                 if (MakeXY(&HMode, TRUE))
  972.                 {
  973.                   WAsmCode[0] |= 0xb000 | (HMode << 4);
  974.                   CodeLen = 1;
  975.                 }
  976.               }
  977.               break;
  978.             case ModImm:
  979.               WAsmCode[1 + HCnt] = *AdrVals;
  980.               WAsmCode[0] |= 0x6400 | HMode;
  981.               CodeLen = 2 + HCnt;
  982.               break;
  983.           }
  984.         }
  985.       }
  986.     }
  987.   }
  988. }
  989.  
  990. static void DecodeMACDP(Word Index)
  991. {
  992.   if (!ChkArgCnt(3, 3));
  993.   else if (ThisPar) WrError(ErrNum_ParNotPossible);
  994.   else if (DecodeAdr(&ArgStr[3], MModAcc))
  995.   {
  996.     *WAsmCode = Index | (0[AdrVals] << 8);
  997.     if (DecodeAdr(&ArgStr[1], MModMem))
  998.     {
  999.       tEvalResult EvalResult;
  1000.  
  1001.       *WAsmCode |= *AdrVals;
  1002.       if (AdrCnt)
  1003.         WAsmCode[1] = AdrVals[1];
  1004.       WAsmCode[1 + AdrCnt] = EvalStrIntExpressionWithResult(&ArgStr[2], UInt16, &EvalResult);
  1005.       if (EvalResult.OK)
  1006.       {
  1007.         ChkSpace(Index & 0x200 ? SegData : SegCode, EvalResult.AddrSpaceMask);
  1008.         CodeLen = 2 + AdrCnt;
  1009.       }
  1010.     }
  1011.   }
  1012. }
  1013.  
  1014. static void DecodeFIRS(Word Index)
  1015. {
  1016.   (void)Index;
  1017.  
  1018.   if (!ChkArgCnt(3, 3));
  1019.   else if (ThisPar) WrError(ErrNum_ParNotPossible);
  1020.   else if (DecodeAdr(&ArgStr[1], MModMem))
  1021.     if (MakeXY(WAsmCode, TRUE))
  1022.     {
  1023.       0[WAsmCode] = 0xe000 | ((*WAsmCode) << 4);
  1024.       if (DecodeAdr(&ArgStr[2], MModMem))
  1025.         if (MakeXY(AdrVals, TRUE))
  1026.         {
  1027.           tEvalResult EvalResult;
  1028.  
  1029.           0[WAsmCode] |= *AdrVals;
  1030.           WAsmCode[1] = EvalStrIntExpressionWithResult(&ArgStr[3], UInt16, &EvalResult);
  1031.           if (EvalResult.OK)
  1032.           {
  1033.             ChkSpace(SegCode, EvalResult.AddrSpaceMask);
  1034.             CodeLen = 2;
  1035.           }
  1036.         }
  1037.     }
  1038. }
  1039.  
  1040. static void DecodeBIT(Word Index)
  1041. {
  1042.   Boolean OK;
  1043.  
  1044.   (void)Index;
  1045.  
  1046.   if (!ChkArgCnt(2, 2));
  1047.   else if (ThisPar) WrError(ErrNum_ParNotPossible);
  1048.   else if (DecodeAdr(&ArgStr[1], MModMem))
  1049.     if (MakeXY(AdrVals, TRUE))
  1050.     {
  1051.       WAsmCode[0] = EvalStrIntExpression(&ArgStr[2], UInt4, &OK);
  1052.       if (OK)
  1053.       {
  1054.         WAsmCode[0] |= 0x9600 | (AdrVals[0] << 4);
  1055.         CodeLen = 1;
  1056.       }
  1057.     }
  1058. }
  1059.  
  1060. static void DecodeBITF(Word Index)
  1061. {
  1062.   UNUSED(Index);
  1063.  
  1064.   if (!ChkArgCnt(2, 2));
  1065.   else if (ThisPar) WrError(ErrNum_ParNotPossible);
  1066.   else
  1067.   {
  1068.     OpSize = UInt16;
  1069.     if (DecodeAdr(&ArgStr[2], MModImm))
  1070.     {
  1071.       WAsmCode[1] = *AdrVals;
  1072.       if (DecodeAdr(&ArgStr[1], MModMem))
  1073.       {
  1074.         *WAsmCode = 0x6100 | *AdrVals;
  1075.         if (AdrCnt)
  1076.         {
  1077.           WAsmCode[2] = WAsmCode[1];
  1078.           WAsmCode[1] = AdrVals[1];
  1079.         }
  1080.         CodeLen = 2 + AdrCnt;
  1081.       }
  1082.     }
  1083.   }
  1084. }
  1085.  
  1086. static void DecodeMACR(Word Index)
  1087. {
  1088.   (void) Index;
  1089.  
  1090.   if (!ChkArgCnt(2, 4));
  1091.   else if (DecodeAdr(&ArgStr[ArgCnt], MModAcc))
  1092.   {
  1093.     *WAsmCode = *AdrVals << 8;
  1094.     if (DecodeAdr(&ArgStr[1], MModMem))
  1095.     {
  1096.       if (ArgCnt == 2)
  1097.       {
  1098.         if (ThisPar)
  1099.         {
  1100.           if (MakeXY(AdrVals, True))
  1101.           {
  1102.             if ((LastOpCode & 0xfe0f) == 0x9400) /* previous op LD Xmem, src */
  1103.             {
  1104.               if ((LastOpCode & 0x0100) == (*WAsmCode & 0x0100)) WrError(ErrNum_ParNotPossible);
  1105.               else
  1106.               {
  1107.                 RetractWords(1);
  1108.                 *WAsmCode = 0xaa00 | (LastOpCode & 0x01f0) | (*AdrVals);
  1109.                 CodeLen = 1;
  1110.               }
  1111.             }
  1112.             else if ((LastOpCode & 0xfe0f) == 0x9a00) /* previous op ST src, Ymem */
  1113.             {
  1114.               RetractWords(1);
  1115.               *WAsmCode |= 0xd400 | ((LastOpCode & 0x0100) << 1) | ((LastOpCode & 0x00f0) >> 4) | (*AdrVals << 4);
  1116.               CodeLen = 1;
  1117.             }
  1118.             else WrError(ErrNum_ParNotPossible);
  1119.           }
  1120.         }
  1121.         else
  1122.         {
  1123.           WAsmCode[0] |= 0x2a00 | *AdrVals;
  1124.           if (AdrCnt)
  1125.             WAsmCode[1] = AdrVals[1];
  1126.           CodeLen = 1 + AdrCnt;
  1127.         }
  1128.       }
  1129.       else if (ThisPar) WrError(ErrNum_ParNotPossible);
  1130.       else
  1131.       {
  1132.         if (MakeXY(AdrVals, True))
  1133.         {
  1134.           WAsmCode[0] |= 0xb400 | ((*AdrVals) << 4);
  1135.           if (DecodeAdr(&ArgStr[2], MModMem))
  1136.             if (MakeXY(AdrVals, True))
  1137.             {
  1138.               WAsmCode[0] |= *AdrVals;
  1139.               if (ArgCnt == 4)
  1140.               {
  1141.                 if (DecodeAdr(&ArgStr[3], MModAcc))
  1142.                   WAsmCode[0] |= (*AdrVals) << 9;
  1143.               }
  1144.               else
  1145.                 *WAsmCode |= ((*WAsmCode & 0x100) << 1);
  1146.               if (AdrMode != ModNone)
  1147.                 CodeLen = 1;
  1148.             }
  1149.         }
  1150.       }
  1151.     }
  1152.   }
  1153. }
  1154.  
  1155. static void DecodeMac(Word Index)
  1156. {
  1157.   FixedOrder *POrder = MacOrders + Index;
  1158.  
  1159.   if (!ChkArgCnt(1, ArgCntMax));
  1160.   else if (ThisPar) WrError(ErrNum_ParNotPossible);
  1161.   else if (!as_strcasecmp(ArgStr[1].str.p_str, "T"))
  1162.   {
  1163.     if (!ChkArgCnt(1, 3));
  1164.     else if (DecodeAdr(&ArgStr[ArgCnt], MModAcc))
  1165.     {
  1166.       WAsmCode[0] = 0xf480 | (POrder->Code & 0xff) | ((*AdrVals) << 8);
  1167.       if (ArgCnt == 3)
  1168.         DecodeAdr(&ArgStr[2], MModAcc);
  1169.       if (AdrMode != ModNone)
  1170.       {
  1171.         WAsmCode[0] |= ((*AdrVals) << 9);
  1172.         CodeLen = 1;
  1173.       }
  1174.     }
  1175.   }
  1176.   else if (!ChkArgCnt(1, 2));
  1177.   else
  1178.   {
  1179.     if ((ArgCnt == 2) && (as_strcasecmp(ArgStr[2].str.p_str, "B"))) WrError(ErrNum_InvAddrMode);
  1180.     else if (DecodeAdr(&ArgStr[1], MModMem))
  1181.     {
  1182.       WAsmCode[0] = (POrder->Code & 0xff00) | (*AdrVals);
  1183.       if (AdrCnt)
  1184.         WAsmCode[1] = AdrVals[1];
  1185.       CodeLen = 1 + AdrCnt;
  1186.     }
  1187.   }
  1188. }
  1189.  
  1190. static void DecodeMACSU(Word Index)
  1191. {
  1192.   (void)Index;
  1193.  
  1194.   if (!ChkArgCnt(3, 3));
  1195.   else if (ThisPar) WrError(ErrNum_ParNotPossible);
  1196.   else if (DecodeAdr(&ArgStr[3], MModAcc))
  1197.   {
  1198.     *WAsmCode = 0xa600 | ((*AdrVals) << 8);
  1199.     if ((DecodeAdr(&ArgStr[1], MModMem))
  1200.      && (MakeXY(AdrVals, TRUE)))
  1201.     {
  1202.       *WAsmCode |= ((*AdrVals) << 4);
  1203.       if ((DecodeAdr(&ArgStr[2], MModMem))
  1204.        && (MakeXY(AdrVals, TRUE)))
  1205.       {
  1206.         *WAsmCode |= *AdrVals;
  1207.         CodeLen = 1;
  1208.       }
  1209.     }
  1210.   }
  1211. }
  1212.  
  1213. static void DecodeMAS(Word Index)
  1214. {
  1215.   if (!ChkArgCnt(2, 4));
  1216.   else if (DecodeAdr(&ArgStr[ArgCnt], MModAcc))
  1217.   {
  1218.     *WAsmCode = ((*AdrVals) << 8);
  1219.     if (DecodeAdr(&ArgStr[1], MModMem))
  1220.     {
  1221.       if (ArgCnt == 2)
  1222.       {
  1223.         if (ThisPar)
  1224.         {
  1225.           if (MakeXY(AdrVals, True))
  1226.           {
  1227.             if ((LastOpCode & 0xfe0f) == 0x9400) /* previous op LD Xmem, src */
  1228.             {
  1229.               if ((LastOpCode & 0x0100) == (*WAsmCode & 0x0100)) WrError(ErrNum_ParNotPossible);
  1230.               else
  1231.               {
  1232.                 RetractWords(1);
  1233.                 *WAsmCode = 0xac00 | Index | (LastOpCode & 0x01f0) | (*AdrVals);
  1234.                 CodeLen = 1;
  1235.               }
  1236.             }
  1237.             else if ((LastOpCode & 0xfe0f) == 0x9a00) /* previous op ST src, Ymem */
  1238.             {
  1239.               RetractWords(1);
  1240.               *WAsmCode |= 0xd800 | (Index << 1) | ((LastOpCode & 0x0100) << 1) | ((LastOpCode & 0x00f0) >> 4) | (*AdrVals << 4);
  1241.               CodeLen = 1;
  1242.             }
  1243.             else WrError(ErrNum_ParNotPossible);
  1244.           }
  1245.         }
  1246.         else
  1247.         {
  1248.           *WAsmCode |= 0x2c00 | Index | *AdrVals;
  1249.           if (AdrCnt)
  1250.             1[WAsmCode] = AdrVals[1];
  1251.           CodeLen = 1 + AdrCnt;
  1252.         }
  1253.       }
  1254.       else if (ThisPar) WrError(ErrNum_ParNotPossible);
  1255.       else if (MakeXY(AdrVals, TRUE))
  1256.       {
  1257.         *WAsmCode |= 0xb800 | (Index << 1) | ((*AdrVals) << 4);
  1258.         if (DecodeAdr(&ArgStr[2], MModMem))
  1259.           if (MakeXY(AdrVals, TRUE))
  1260.           {
  1261.             *WAsmCode |= *AdrVals;
  1262.             if (ArgCnt == 4)
  1263.             {
  1264.               if (DecodeAdr(&ArgStr[3], MModAcc))
  1265.                 *WAsmCode |= ((*AdrVals) << 9);
  1266.             }
  1267.             else
  1268.               *WAsmCode |= ((*WAsmCode & 0x100) << 1);
  1269.             if (AdrMode != ModNone)
  1270.               CodeLen = 1;
  1271.           }
  1272.       }
  1273.     }
  1274.   }
  1275. }
  1276.  
  1277. static void DecodeMASAR(Word Index)
  1278. {
  1279.   (void)Index;
  1280.  
  1281.   if (!ChkArgCnt(2, 3));
  1282.   else if (ThisPar) WrError(ErrNum_ParNotPossible);
  1283.   else if (as_strcasecmp(ArgStr[1].str.p_str, "T")) WrError(ErrNum_InvAddrMode);
  1284.   else if (DecodeAdr(&ArgStr[ArgCnt], MModAcc))
  1285.   {
  1286.     WAsmCode[0] = (*AdrVals << 8);
  1287.     if (ArgCnt == 3)
  1288.       DecodeAdr(&ArgStr[2], MModAcc);
  1289.     if (AdrMode != ModNone)
  1290.     {
  1291.       *WAsmCode |= 0xf48b | ((*AdrVals) << 9);
  1292.       CodeLen = 1;
  1293.     }
  1294.   }
  1295. }
  1296.  
  1297. static void DecodeDADD(Word Index)
  1298. {
  1299.   (void)Index;
  1300.  
  1301.   if (!ChkArgCnt(2, 3));
  1302.   else if (ThisPar) WrError(ErrNum_ParNotPossible);
  1303.   else if (DecodeAdr(&ArgStr[ArgCnt], MModAcc))
  1304.   {
  1305.     WAsmCode[0] = 0x5000 | (AdrVals[0] << 8);
  1306.     if (ArgCnt == 3)
  1307.       DecodeAdr(&ArgStr[2], MModAcc);
  1308.     if (AdrMode != ModNone)
  1309.     {
  1310.       WAsmCode[0] |= (AdrVals[0] << 9);
  1311.       if (DecodeAdr(&ArgStr[1], MModMem))
  1312.       {
  1313.         WAsmCode[0] |= AdrVals[0];
  1314.         if (AdrCnt)
  1315.           WAsmCode[1] = AdrVals[1];
  1316.         CodeLen = 1 + AdrCnt;
  1317.       }
  1318.     }
  1319.   }
  1320. }
  1321.  
  1322. static void DecodeLog(Word Index)
  1323. {
  1324.   Word Acc, Shift;
  1325.   Boolean OK;
  1326.  
  1327.   if (!ChkArgCnt(1, 4));
  1328.   else if (ThisPar) WrError(ErrNum_ParNotPossible);
  1329.   else
  1330.   {
  1331.     OpSize = UInt16;
  1332.     DecodeAdr(&ArgStr[1], MModAcc | MModMem | MModImm);
  1333.     switch (AdrMode)
  1334.     {
  1335.       case ModAcc:  /* Variant 4 */
  1336.         if (ChkArgCnt(1, 3))
  1337.         {
  1338.           Acc = *AdrVals << 9;
  1339.           *WAsmCode = 0xf080 | Acc | (Index << 5);
  1340.           Shift = 0; OK = True;
  1341.           if (((ArgCnt == 2) && IsAcc(ArgStr[2].str.p_str)) || (ArgCnt == 3))
  1342.           {
  1343.             OK = DecodeAdr(&ArgStr[ArgCnt], MModAcc);
  1344.             if (OK)
  1345.               Acc = *AdrVals << 8;
  1346.           }
  1347.           else
  1348.             Acc = Acc >> 1;
  1349.           if (OK)
  1350.             if (((ArgCnt == 2) && (!IsAcc(ArgStr[2].str.p_str))) || (ArgCnt == 3))
  1351.             {
  1352.               Shift = EvalStrIntExpression(&ArgStr[2], SInt5, &OK);
  1353.             }
  1354.           if (OK)
  1355.           {
  1356.             *WAsmCode |= Acc | (Shift & 0x1f);
  1357.             CodeLen = 1;
  1358.           }
  1359.         }
  1360.         break;
  1361.  
  1362.       case ModMem:  /* Variant 1 */
  1363.         if (ChkArgCnt(2, 2))
  1364.         {
  1365.           *WAsmCode = 0x1800 | (*AdrVals) | (Index << 9);
  1366.           if (AdrCnt)
  1367.             WAsmCode[1] = AdrVals[1];
  1368.           CodeLen = AdrCnt + 1;
  1369.           if (DecodeAdr(&ArgStr[2], MModAcc))
  1370.             *WAsmCode |= (*AdrVals) << 8;
  1371.           else
  1372.             CodeLen = 0;
  1373.         }
  1374.         break;
  1375.  
  1376.       case ModImm:  /* Variant 2,3 */
  1377.         if (ChkArgCnt(2, 4))
  1378.         {
  1379.           WAsmCode[1] = *AdrVals;
  1380.           if (DecodeAdr(&ArgStr[ArgCnt], MModAcc))
  1381.           {
  1382.             *WAsmCode = Acc = *AdrVals << 8;
  1383.             Shift = 0;
  1384.             OK = True;
  1385.             if (((ArgCnt == 3) && IsAcc(ArgStr[2].str.p_str)) || (ArgCnt == 4))
  1386.             {
  1387.               OK = DecodeAdr(&ArgStr[ArgCnt - 1], MModAcc);
  1388.               if (OK)
  1389.                 Acc = (*AdrVals) << 9;
  1390.             }
  1391.             else
  1392.               Acc = Acc << 1;
  1393.             if (OK)
  1394.             {
  1395.               if (((ArgCnt == 3) && (!IsAcc(ArgStr[2].str.p_str))) || (ArgCnt == 4))
  1396.               {
  1397.                 tSymbolFlags Flags;
  1398.  
  1399.                 Shift = EvalStrIntExpressionWithFlags(&ArgStr[2], UInt5, &OK, &Flags);
  1400.                 if (mFirstPassUnknown(Flags))
  1401.                   Shift &= 15;
  1402.                 OK = ChkRange(Shift, 0, 16);
  1403.               }
  1404.             }
  1405.             if (OK)
  1406.             {
  1407.               *WAsmCode |= Acc;
  1408.               if (Shift == 16) /* Variant 3 */
  1409.               {
  1410.                 *WAsmCode |= 0xf063 + Index;
  1411.               }
  1412.               else             /* Variant 2 */
  1413.               {
  1414.                 *WAsmCode |= 0xf000 | ((Index + 3) << 4) | Shift;
  1415.               }
  1416.               CodeLen = 2;
  1417.             }
  1418.           }
  1419.         }
  1420.         break;
  1421.     }
  1422.   }
  1423. }
  1424.  
  1425. static void DecodeSFT(Word Index)
  1426. {
  1427.   Boolean OK;
  1428.   int Shift;
  1429.  
  1430.   if (!ChkArgCnt(2, 3));
  1431.   else if (ThisPar) WrError(ErrNum_ParNotPossible);
  1432.   else if (DecodeAdr(&ArgStr[1], MModAcc))
  1433.   {
  1434.     0[WAsmCode] = Index | ((*AdrVals) << 9);
  1435.     if (ArgCnt == 3)
  1436.       DecodeAdr(&ArgStr[3], MModAcc);
  1437.     if (AdrMode != ModNone)
  1438.     {
  1439.       0[WAsmCode] |= ((*AdrVals) << 8);
  1440.       Shift = EvalStrIntExpression(&ArgStr[2], SInt5, &OK);
  1441.       if (OK)
  1442.       {
  1443.         0[WAsmCode] |= (Shift & 0x1f);
  1444.         CodeLen = 1;
  1445.       }
  1446.     }
  1447.   }
  1448. }
  1449.  
  1450. static void DecodeCMPR(Word Index)
  1451. {
  1452.   Word z;
  1453.   Boolean OK;
  1454.  
  1455.   (void) Index;
  1456.  
  1457.   if (!ChkArgCnt(2, 2));
  1458.   else if (ThisPar) WrError(ErrNum_ParNotPossible);
  1459.   else if (DecodeAdr(&ArgStr[2], MModAReg))
  1460.   {
  1461.     OK = False;
  1462.     for (z = 0; z < 4; z++)
  1463.       if (!as_strcasecmp(ArgStr[1].str.p_str, ShortConds[z]))
  1464.       {
  1465.         OK = True;
  1466.         break;
  1467.       }
  1468.     if (!OK)
  1469.       z = EvalStrIntExpression(&ArgStr[1], UInt2, &OK);
  1470.     if (OK)
  1471.     {
  1472.       0[WAsmCode] = 0xf4a8 | (*AdrVals) | (z << 8);
  1473.       CodeLen = 1;
  1474.     }
  1475.   }
  1476. }
  1477.  
  1478. static void DecodePMAD(Word Index)
  1479. {
  1480.   if (!ChkArgCnt(1, 1));
  1481.   else if (ThisPar) WrError(ErrNum_ParNotPossible);
  1482.   else if (LastRep) WrError(ErrNum_NotRepeatable);
  1483.   else
  1484.   {
  1485.     tEvalResult EvalResult;
  1486.  
  1487.     WAsmCode[1] = EvalStrIntExpressionWithResult(&ArgStr[1], UInt16, &EvalResult);
  1488.     if (EvalResult.OK)
  1489.     {
  1490.       ChkSpace(SegCode, EvalResult.AddrSpaceMask);
  1491.       0[WAsmCode] = Index;
  1492.       CodeLen = 2;
  1493.     }
  1494.   }
  1495. }
  1496.  
  1497. static void DecodeBANZ(Word Index)
  1498. {
  1499.   if (!ChkArgCnt(2, 2));
  1500.   else if (ThisPar) WrError(ErrNum_ParNotPossible);
  1501.   else if (LastRep) WrError(ErrNum_NotRepeatable);
  1502.   else if (DecodeAdr(&ArgStr[2], MModMem))
  1503.   {
  1504.     tEvalResult EvalResult;
  1505.  
  1506.     if (CodeLen)
  1507.       WAsmCode[1] = 1[AdrVals];
  1508.     WAsmCode[1 + CodeLen] = EvalStrIntExpressionWithResult(&ArgStr[1], UInt16, &EvalResult);
  1509.     if (EvalResult.OK)
  1510.     {
  1511.       ChkSpace(SegCode, EvalResult.AddrSpaceMask);
  1512.       0[WAsmCode] = Index | (*AdrVals);
  1513.       CodeLen = 2 + AdrCnt;
  1514.     }
  1515.   }
  1516. }
  1517.  
  1518. static void DecodePMADCond(Word Index)
  1519. {
  1520.   int index;
  1521.   Boolean OK;
  1522.  
  1523.   if (!ChkArgCnt(2, ArgCntMax));
  1524.   else if (ThisPar) WrError(ErrNum_ParNotPossible);
  1525.   else if (LastRep) WrError(ErrNum_NotRepeatable);
  1526.   else if (!DecodeCondition(2, WAsmCode, &index, &OK))
  1527.     WrStrErrorPos(OK ? ErrNum_UndefCond : ErrNum_IncompCond, &ArgStr[index]);
  1528.   else
  1529.   {
  1530.     tEvalResult EvalResult;
  1531.  
  1532.     WAsmCode[1] = EvalStrIntExpressionWithResult(&ArgStr[1], UInt16, &EvalResult);
  1533.     if (EvalResult.OK)
  1534.     {
  1535.       ChkSpace(SegCode, EvalResult.AddrSpaceMask);
  1536.       0[WAsmCode] |= Index;
  1537.       CodeLen = 2;
  1538.     }
  1539.   }
  1540. }
  1541.  
  1542. static void DecodeFPMAD(Word Index)
  1543. {
  1544.   if (!ChkArgCnt(1, 1));
  1545.   else if (ThisPar) WrError(ErrNum_ParNotPossible);
  1546.   else if (LastRep) WrError(ErrNum_NotRepeatable);
  1547.   else
  1548.   {
  1549.     tEvalResult EvalResult;
  1550.     LongWord Addr = EvalStrIntExpressionWithResult(&ArgStr[1], UInt23, &EvalResult);
  1551.     if (EvalResult.OK)
  1552.     {
  1553.       ChkSpace(SegCode, EvalResult.AddrSpaceMask);
  1554.       0[WAsmCode] = Index | (Addr >> 16);
  1555.       1[WAsmCode] = Addr & 0xffff;
  1556.       CodeLen = 2;
  1557.     }
  1558.   }
  1559. }
  1560.  
  1561. static void DecodeINTR(Word Index)
  1562. {
  1563.   Boolean OK;
  1564.  
  1565.   if (!ChkArgCnt(1, 1));
  1566.   else if (ThisPar) WrError(ErrNum_ParNotPossible);
  1567.   else if (LastRep) WrError(ErrNum_NotRepeatable);
  1568.   else
  1569.   {
  1570.     *WAsmCode = Index | EvalStrIntExpression(&ArgStr[1], UInt5, &OK);
  1571.     if (OK)
  1572.       CodeLen = 1;
  1573.   }
  1574. }
  1575.  
  1576. static void DecodeRPT(Word Index)
  1577. {
  1578.   UNUSED(Index);
  1579.  
  1580.   if (!ChkArgCnt(1, 1));
  1581.   else if (ThisPar) WrError(ErrNum_ParNotPossible);
  1582.   else if (LastRep) WrError(ErrNum_NotRepeatable);
  1583.   else
  1584.   {
  1585.     OpSize = UInt16;
  1586.     DecodeAdr(&ArgStr[1], MModImm | MModMem);
  1587.     switch (AdrMode)
  1588.     {
  1589.       case ModImm:
  1590.         if (!Hi(*AdrVals))
  1591.         {
  1592.           *WAsmCode = 0xec00 | (*AdrVals);
  1593.           CodeLen = 1;
  1594.         }
  1595.         else
  1596.         {
  1597.           *WAsmCode = 0xf070;
  1598.           WAsmCode[1] = *AdrVals;
  1599.           CodeLen = 2;
  1600.         }
  1601.         ThisRep = True;
  1602.         break;
  1603.       case ModMem:
  1604.         WAsmCode[0] = 0x4700 | (*AdrVals);
  1605.         if (AdrCnt)
  1606.           WAsmCode[1] = AdrVals[1];
  1607.         CodeLen = 1 + AdrCnt;
  1608.         ThisRep = True;
  1609.         break;
  1610.     }
  1611.   }
  1612. }
  1613.  
  1614. static void DecodeRPTZ(Word Index)
  1615. {
  1616.   UNUSED(Index);
  1617.  
  1618.   if (!ChkArgCnt(2, 2));
  1619.   else if (ThisPar) WrError(ErrNum_ParNotPossible);
  1620.   else if (LastRep) WrError(ErrNum_NotRepeatable);
  1621.   else if (DecodeAdr(&ArgStr[1], MModAcc))
  1622.   {
  1623.     *WAsmCode = 0xf071 | (AdrVals[0] << 8);
  1624.     OpSize = UInt16;
  1625.     if (DecodeAdr(&ArgStr[2], MModImm))
  1626.     {
  1627.       WAsmCode[1] = *AdrVals;
  1628.       CodeLen = 2;
  1629.       ThisRep = True;
  1630.     }
  1631.   }
  1632. }
  1633.  
  1634. static void DecodeFRAME(Word Index)
  1635. {
  1636.   Boolean OK;
  1637.  
  1638.   UNUSED(Index);
  1639.  
  1640.   if (!ChkArgCnt(1, 1));
  1641.   else if (ThisPar) WrError(ErrNum_ParNotPossible);
  1642.   else
  1643.   {
  1644.     *WAsmCode = 0xee00 | (EvalStrIntExpression(&ArgStr[1], SInt8, &OK) & 0xff);
  1645.     if (OK)
  1646.       CodeLen = 1;
  1647.   }
  1648. }
  1649.  
  1650. static void DecodeIDLE(Word Index)
  1651. {
  1652.   Boolean OK;
  1653.  
  1654.   UNUSED(Index);
  1655.  
  1656.   if (!ChkArgCnt(1, 1));
  1657.   else if (ThisPar) WrError(ErrNum_ParNotPossible);
  1658.   else if (LastRep) WrError(ErrNum_NotRepeatable);
  1659.   else
  1660.   {
  1661.     tSymbolFlags Flags;
  1662.  
  1663.     *WAsmCode = EvalStrIntExpressionWithFlags(&ArgStr[1], UInt2, &OK, &Flags);
  1664.     if (mFirstPassUnknown(Flags))
  1665.       *WAsmCode = 1;
  1666.     if ((OK) && (ChkRange(*WAsmCode, 1, 3)))
  1667.     {
  1668.       if (*WAsmCode != 2)
  1669.         *WAsmCode = (*WAsmCode) >> 1;
  1670.       *WAsmCode = 0xf4e1 | (*WAsmCode << 8);
  1671.       CodeLen = 1;
  1672.     }
  1673.   }
  1674. }
  1675.  
  1676. static void DecodeSBIT(Word Index)
  1677. {
  1678.   Boolean OK;
  1679.   Word Bit;
  1680.  
  1681.   if (!ChkArgCnt(1, 2));
  1682.   else if (ThisPar) WrError(ErrNum_ParNotPossible);
  1683.   else if (LastRep) WrError(ErrNum_NotRepeatable);
  1684.   else
  1685.   {
  1686.     if (ArgCnt == 1)
  1687.       Bit = EvalStrIntExpression(&ArgStr[1], UInt5, &OK);
  1688.     else
  1689.     {
  1690.       Bit = EvalStrIntExpression(&ArgStr[1], UInt1, &OK) << 4;
  1691.       if (OK)
  1692.         Bit |= EvalStrIntExpression(&ArgStr[2], UInt4, &OK);
  1693.     }
  1694.     if (OK)
  1695.     {
  1696.       *WAsmCode = Index | ((Bit & 16) << 5) | (Bit & 15);
  1697.       CodeLen = 1;
  1698.     }
  1699.   }
  1700. }
  1701.  
  1702. static void DecodeXC(Word Index)
  1703. {
  1704.   Boolean OK;
  1705.   int errindex;
  1706.  
  1707.   UNUSED(Index);
  1708.  
  1709.   if (!ChkArgCnt(2, ArgCntMax));
  1710.   else if (ThisPar) WrError(ErrNum_ParNotPossible);
  1711.   else if (LastRep) WrError(ErrNum_NotRepeatable);
  1712.   else if (!DecodeCondition(2, WAsmCode, &errindex, &OK))
  1713.     WrStrErrorPos(OK ? ErrNum_UndefCond : ErrNum_IncompCond, &ArgStr[errindex]);
  1714.   else
  1715.   {
  1716.     tSymbolFlags Flags;
  1717.  
  1718.     errindex = EvalStrIntExpressionWithFlags(&ArgStr[1], UInt2, &OK, &Flags);
  1719.     if (mFirstPassUnknown(Flags))
  1720.       errindex = 1;
  1721.     if ((OK) && (ChkRange(errindex, 1, 2)))
  1722.     {
  1723.       errindex--;
  1724.       0[WAsmCode] |= 0xfd00 | (errindex << 9);
  1725.       CodeLen = 1;
  1726.     }
  1727.   }
  1728. }
  1729.  
  1730. static void DecodeLD(Word Index)
  1731. {
  1732.   Integer Shift;
  1733.   Boolean OK;
  1734.  
  1735.   UNUSED(Index);
  1736.  
  1737.   if (!ChkArgCnt(2, 3));
  1738.  
  1739.   else if (!as_strcasecmp(ArgStr[ArgCnt].str.p_str, "T"))
  1740.   {
  1741.     if (!ChkArgCnt(2, 2));
  1742.     else if (DecodeAdr(&ArgStr[1], MModMem))
  1743.     {
  1744.       if (ThisPar)
  1745.       {
  1746.         if (MakeXY(AdrVals, TRUE))
  1747.         {
  1748.           /* prev. operation must be STH src,0,Xmem */
  1749.           if ((LastOpCode & 0xfe0f) != 0x9a00) WrError(ErrNum_ParNotPossible);
  1750.           else
  1751.           {
  1752.             RetractWords(1);
  1753.             *WAsmCode = 0xe400 | ((LastOpCode & 0x0100) << 1)
  1754.                         | ((LastOpCode & 0x00f0) >> 4) | ((*AdrVals) << 4);
  1755.             CodeLen = 1;
  1756.           }
  1757.         }
  1758.       }
  1759.       else
  1760.       {
  1761.         WAsmCode[0] = 0x3000 | AdrVals[0];
  1762.         if (AdrCnt)
  1763.           WAsmCode[1] = AdrVals[1];
  1764.         CodeLen = 1 + AdrCnt;
  1765.       }
  1766.     }
  1767.   }
  1768.  
  1769.   else if (!as_strcasecmp(ArgStr[ArgCnt].str.p_str, "DP"))
  1770.   {
  1771.     if (!ChkArgCnt(2, 2));
  1772.     else if (ThisPar) WrError(ErrNum_ParNotPossible);
  1773.     else
  1774.     {
  1775.       OpSize = UInt9;
  1776.       DecodeAdr(&ArgStr[1], MModMem | MModImm);
  1777.       switch (AdrMode)
  1778.       {
  1779.         case ModMem:
  1780.           WAsmCode[0] = 0x2600 | AdrVals[0];
  1781.           if (AdrCnt)
  1782.             WAsmCode[1] = AdrVals[1];
  1783.           CodeLen = 1 + AdrCnt;
  1784.           break;
  1785.         case ModImm:
  1786.           WAsmCode[0] = 0xea00 | (AdrVals[0] & 0x1ff);
  1787.           CodeLen = 1;
  1788.           break;
  1789.       }
  1790.     }
  1791.   }
  1792.  
  1793.   else if (!as_strcasecmp(ArgStr[ArgCnt].str.p_str, "ARP"))
  1794.   {
  1795.     if (!ChkArgCnt(2, 2));
  1796.     else if (ThisPar) WrError(ErrNum_ParNotPossible);
  1797.     else
  1798.     {
  1799.       OpSize = UInt3;
  1800.       if (DecodeAdr(&ArgStr[1], MModImm))
  1801.       {
  1802.         WAsmCode[0] = 0xf4a0 | (AdrVals[0] & 7);
  1803.         CodeLen = 1;
  1804.       }
  1805.     }
  1806.   }
  1807.  
  1808.   else if (!as_strcasecmp(ArgStr[2].str.p_str, "ASM"))
  1809.   {
  1810.     if (ThisPar) WrError(ErrNum_ParNotPossible);
  1811.     else
  1812.     {
  1813.       OpSize = SInt5;
  1814.       DecodeAdr(&ArgStr[1], MModAcc | MModMem | MModImm);
  1815.       switch (AdrMode)
  1816.       {
  1817.         case ModAcc:
  1818.           WAsmCode[0] = *AdrVals << 9;
  1819.           if (ArgCnt == 3)
  1820.             DecodeAdr(&ArgStr[3], MModAcc);
  1821.           if (AdrMode == ModAcc)
  1822.           {
  1823.             WAsmCode[0] |= 0xf482 | (AdrVals[0] << 8);
  1824.             CodeLen = 1;
  1825.           }
  1826.           break;
  1827.         case ModMem:
  1828.           if (ChkArgCnt(2, 2))
  1829.           {
  1830.             WAsmCode[0] = 0x3200 | AdrVals[0];
  1831.             if (AdrCnt)
  1832.               WAsmCode[1] = AdrVals[1];
  1833.             CodeLen = 1 + AdrCnt;
  1834.           }
  1835.           break;
  1836.         case ModImm:
  1837.           if (ChkArgCnt(2, 2))
  1838.           {
  1839.             WAsmCode[0] = 0xed00 | (AdrVals[0] & 0x1f);
  1840.             CodeLen = 1;
  1841.           }
  1842.           break;
  1843.       }
  1844.     }
  1845.   }
  1846.  
  1847.   else if (DecodeAdr(&ArgStr[ArgCnt], MModAcc))
  1848.   {
  1849.     *WAsmCode = *AdrVals << 8;
  1850.     if (ArgCnt == 3)
  1851.     {
  1852.       if (!as_strcasecmp(ArgStr[2].str.p_str, "TS"))
  1853.       {
  1854.         Shift = 0xff;
  1855.         OK = True;
  1856.       }
  1857.       else
  1858.       {
  1859.         tSymbolFlags Flags;
  1860.  
  1861.         Shift = EvalStrIntExpressionWithFlags(&ArgStr[2], SInt6, &OK, &Flags);
  1862.         if (mFirstPassUnknown(Flags))
  1863.           Shift = 0;
  1864.         if (OK)
  1865.           OK = ChkRange(Shift, -16, 16);
  1866.       }
  1867.     }
  1868.     else
  1869.     {
  1870.       Shift = 0;
  1871.       OK = True;
  1872.     }
  1873.     if (OK)
  1874.     {
  1875.       OpSize = UInt16;
  1876.       DecodeAdr(&ArgStr[1], MModAcc | MModMem | MModImm);
  1877.       switch (AdrMode)
  1878.       {
  1879.         case ModAcc:
  1880.           if (ThisPar) WrError(ErrNum_ParNotPossible);
  1881.           else if (ChkRange(Shift, -16, 15))
  1882.           {
  1883.             *WAsmCode |= 0xf440 | (AdrVals[0] << 9) | (Shift & 0x1f);
  1884.             CodeLen = 1;
  1885.           }
  1886.           break;
  1887.         case ModMem:
  1888.           if (Shift == 0xff) /* TS ? */
  1889.           {
  1890.             if (ThisPar) WrError(ErrNum_ParNotPossible);
  1891.             else
  1892.             {
  1893.               *WAsmCode |= 0x1400 | AdrVals[0];
  1894.               if (AdrCnt)
  1895.                 WAsmCode[1] = AdrVals[1];
  1896.               CodeLen = 1 + AdrCnt;
  1897.             }
  1898.           }
  1899.           else if ((Shift >= 0) && (MakeXY(WAsmCode + 1, False)))
  1900.           {
  1901.             if (ThisPar)
  1902.             {
  1903.               if (Shift) WrError(ErrNum_ParNotPossible);
  1904.               /* prev. operation must be STH src,0,Xmem */
  1905.               else if ((LastOpCode & 0xfe0f) != 0x9a00) WrError(ErrNum_ParNotPossible);
  1906.               else
  1907.               {
  1908.                 RetractWords(1);
  1909.                 *WAsmCode |= 0xc800 | ((LastOpCode & 0x0100) << 1)
  1910.                              | ((LastOpCode & 0x00f0) >> 4) | (WAsmCode[1] << 4);
  1911.                 CodeLen = 1;
  1912.               }
  1913.             }
  1914.             else
  1915.             {
  1916.               WAsmCode[0] |= 0x9400 | (WAsmCode[1] << 4) | Shift;
  1917.               CodeLen = 1;
  1918.             }
  1919.           }
  1920.           else if (Shift == 16)
  1921.           {
  1922.             if (ThisPar) WrError(ErrNum_ParNotPossible);
  1923.             else
  1924.             {
  1925.               WAsmCode[0] |= 0x4400 | AdrVals[0];
  1926.               if (AdrCnt)
  1927.                 WAsmCode[1] = AdrVals[1];
  1928.               CodeLen = 1 + AdrCnt;
  1929.             }
  1930.           }
  1931.           else if (!Shift)
  1932.           {
  1933.             if (ThisPar) WrError(ErrNum_ParNotPossible);
  1934.             else
  1935.             {
  1936.               WAsmCode[0] |= 0x1000 | AdrVals[0];
  1937.               if (AdrCnt)
  1938.                 WAsmCode[1] = AdrVals[1];
  1939.               CodeLen = 1 + AdrCnt;
  1940.             }
  1941.           }
  1942.           else
  1943.           {
  1944.             if (ThisPar) WrError(ErrNum_ParNotPossible);
  1945.             else
  1946.             {
  1947.               WAsmCode[1 + AdrCnt] = 0x0c40 | WAsmCode[0] | (Shift & 0x1f);
  1948.               WAsmCode[0] = 0x6f00 | AdrVals[0];
  1949.               if (AdrCnt)
  1950.                 WAsmCode[1] = AdrVals[1];
  1951.               CodeLen = 2 + AdrCnt;
  1952.             }
  1953.           }
  1954.           break;
  1955.         case ModImm:
  1956.           if (Shift == 0xff) WrError(ErrNum_InvAddrMode);
  1957.           else if (ThisPar) WrError(ErrNum_ParNotPossible);
  1958.           else if (ChkRange(Shift, 0, 16))
  1959.           {
  1960.             if ((Hi(AdrVals[0]) == 0) && (!Shift))
  1961.             {
  1962.               WAsmCode[0] |= 0xe800 | Lo(AdrVals[0]);
  1963.               CodeLen = 1;
  1964.             }
  1965.             else if (Shift == 16)
  1966.             {
  1967.               WAsmCode[0] |= 0xf062;
  1968.               WAsmCode[1] = AdrVals[0];
  1969.               CodeLen = 2;
  1970.             }
  1971.             else
  1972.             {
  1973.               WAsmCode[0] |= 0xf020 | (Shift & 15);
  1974.               WAsmCode[1] = AdrVals[0];
  1975.               CodeLen = 2;
  1976.             }
  1977.           }
  1978.           break;
  1979.       }
  1980.     }
  1981.   }
  1982. }
  1983.  
  1984. static void DecodePSHM(Word Index)
  1985. {
  1986.   UNUSED(Index);
  1987.  
  1988.   if (!ChkArgCnt(1, 1));
  1989.   else if (ThisPar) WrError(ErrNum_ParNotPossible);
  1990.   else
  1991.   {
  1992.     ForcePageZero = True;
  1993.     if (DecodeAdr(&ArgStr[1], MModMem))
  1994.     {
  1995.       *WAsmCode = 0x4a00 | (*AdrVals);
  1996.       CodeLen = 1;
  1997.     }
  1998.   }
  1999. }
  2000.  
  2001. static void DecodeLDM(Word Index)
  2002. {
  2003.   UNUSED(Index);
  2004.  
  2005.   if (!ChkArgCnt(2, 2));
  2006.   else if (ThisPar) WrError(ErrNum_ParNotPossible);
  2007.   else if (DecodeAdr(&ArgStr[2], MModAcc))
  2008.   {
  2009.     *WAsmCode = 0x4800 | (*AdrVals << 8);
  2010.     ForcePageZero = True;
  2011.     if (DecodeAdr(&ArgStr[1], MModMem))
  2012.     {
  2013.       *WAsmCode |= *AdrVals;
  2014.       CodeLen = 1;
  2015.     }
  2016.   }
  2017. }
  2018.  
  2019. static void DecodeSTLM(Word Index)
  2020. {
  2021.   UNUSED(Index);
  2022.  
  2023.   if (!ChkArgCnt(2, 2));
  2024.   else if (ThisPar) WrError(ErrNum_ParNotPossible);
  2025.   else if (DecodeAdr(&ArgStr[1], MModAcc))
  2026.   {
  2027.     *WAsmCode = 0x8800 | (*AdrVals << 8);
  2028.     ForcePageZero = True;
  2029.     if (DecodeAdr(&ArgStr[2], MModMem))
  2030.     {
  2031.       *WAsmCode |= *AdrVals;
  2032.       CodeLen = 1;
  2033.     }
  2034.   }
  2035. }
  2036.  
  2037. static void DecodeSTM(Word Index)
  2038. {
  2039.   UNUSED(Index);
  2040.  
  2041.   if (!ChkArgCnt(2, 2));
  2042.   else if (ThisPar) WrError(ErrNum_ParNotPossible);
  2043.   else if (DecodeAdr(&ArgStr[1], MModImm))
  2044.   {
  2045.     WAsmCode[1] = *AdrVals;
  2046.     ForcePageZero = True;
  2047.     if (DecodeAdr(&ArgStr[2], MModMem))
  2048.     {
  2049.       *WAsmCode = 0x7700 | (*AdrVals);
  2050.       CodeLen = 2;
  2051.     }
  2052.   }
  2053. }
  2054.  
  2055. static void DecodeDST(Word Index)
  2056. {
  2057.   UNUSED(Index);
  2058.  
  2059.   if (!ChkArgCnt(2, 2));
  2060.   else if (ThisPar) WrError(ErrNum_ParNotPossible);
  2061.   else if (DecodeAdr(&ArgStr[1], MModAcc))
  2062.   {
  2063.     *WAsmCode = 0x4e00 | (*AdrVals << 8);
  2064.     if (DecodeAdr(&ArgStr[2], MModMem))
  2065.     {
  2066.       *WAsmCode |= *AdrVals;
  2067.       if (AdrCnt)
  2068.        1[WAsmCode] = 1[AdrVals];
  2069.       CodeLen = 1 + AdrCnt;
  2070.     }
  2071.   }
  2072. }
  2073.  
  2074. static void DecodeST(Word Index)
  2075. {
  2076.   Word Acc;
  2077.  
  2078.   UNUSED(Index);
  2079.  
  2080.   /* NOTE: we also allow the form 'ST src,Xmem' as an alias
  2081.      for 'STH src,Ymem' since the first form is used in parallel
  2082.      load-store instructions. */
  2083.  
  2084.   if (!ChkArgCnt(2, 2));
  2085.   else if (ThisPar) WrError(ErrNum_ParNotPossible);
  2086.   else if (DecodeAdr(&ArgStr[2], MModMem))
  2087.   {
  2088.     *WAsmCode = *AdrVals;
  2089.     if (AdrCnt)
  2090.       1[WAsmCode] = 1[AdrVals];
  2091.     CodeLen = 1 + AdrCnt;
  2092.     OpSize = SInt16;
  2093.     if (!as_strcasecmp(ArgStr[1].str.p_str, "T"))
  2094.       *WAsmCode |= 0x8c00;
  2095.     else if (!as_strcasecmp(ArgStr[1].str.p_str, "TRN"))
  2096.       *WAsmCode |= 0x8d00;
  2097.     else
  2098.     {
  2099.       DecodeAdr(&ArgStr[1], MModImm | MModAcc);
  2100.       switch (AdrMode)
  2101.       {
  2102.         case ModImm:
  2103.           *WAsmCode |= 0x7600;
  2104.           (CodeLen++)[WAsmCode] = *AdrVals;
  2105.           break;
  2106.         case ModAcc:
  2107.           Acc = *AdrVals;
  2108.           *AdrVals = *WAsmCode;
  2109.           AdrMode = ModMem;
  2110.           if (MakeXY(AdrVals, True))
  2111.           {
  2112.             *WAsmCode = 0x9a00 | (Acc << 8) | (*AdrVals << 4);
  2113.             CodeLen = 1;
  2114.           }
  2115.           else
  2116.             CodeLen = 0;
  2117.           break;
  2118.         default:
  2119.           CodeLen = 0;
  2120.       }
  2121.     }
  2122.   }
  2123. }
  2124.  
  2125. static void DecodeSTLH(Word Index)
  2126. {
  2127.   Integer Shift;
  2128.   Boolean OK;
  2129.  
  2130.   if (!ChkArgCnt(2, 3));
  2131.   else if (ThisPar) WrError(ErrNum_ParNotPossible);
  2132.   else if (DecodeAdr(&ArgStr[1], MModAcc))
  2133.   {
  2134.     *WAsmCode = Index | (*AdrVals << 8);
  2135.     OK = True;
  2136.     if (ArgCnt == 2)
  2137.       Shift = 0;
  2138.     else if (!as_strcasecmp(ArgStr[2].str.p_str, "ASM"))
  2139.       Shift = 0xff;
  2140.     else
  2141.       Shift = EvalStrIntExpression(&ArgStr[2], SInt5, &OK);
  2142.     if ((OK) && (DecodeAdr(&ArgStr[ArgCnt], MModMem)))
  2143.     {
  2144.       if (AdrCnt)
  2145.         1[WAsmCode] = 1[AdrVals];
  2146.       CodeLen = 1 + AdrCnt;
  2147.       if (!Shift)
  2148.         *WAsmCode |= 0x8000 | *AdrVals;
  2149.       else if (Shift == 0xff)
  2150.         *WAsmCode |= 0x8400 | *AdrVals;
  2151.       else if ((MakeXY(WAsmCode + 2, False)) && (Shift > 0))
  2152.         *WAsmCode |= 0x9800 | (2[WAsmCode] << 4) | Shift;
  2153.       else
  2154.       {
  2155.         CodeLen[WAsmCode] = (0x0c80 | ((*WAsmCode) & 0x100) | (Shift & 0x1f)) - (Index >> 4);
  2156.         *WAsmCode = 0x6f00 | *AdrVals;
  2157.         CodeLen++;
  2158.       }
  2159.     }
  2160.   }
  2161. }
  2162.  
  2163. static void DecodeCMPS(Word Index)
  2164. {
  2165.   UNUSED(Index);
  2166.  
  2167.   if (!ChkArgCnt(2, 2));
  2168.   else if (ThisPar) WrError(ErrNum_ParNotPossible);
  2169.   else if (DecodeAdr(&ArgStr[1], MModAcc))
  2170.   {
  2171.     *WAsmCode = 0x8e00 | (*AdrVals << 8);
  2172.     if (DecodeAdr(&ArgStr[2], MModMem))
  2173.     {
  2174.       *WAsmCode |= *AdrVals;
  2175.       if (AdrCnt)
  2176.        1[WAsmCode] = 1[AdrVals];
  2177.       CodeLen = 1 + AdrCnt;
  2178.     }
  2179.   }
  2180. }
  2181.  
  2182. static void DecodeSACCD(Word Index)
  2183. {
  2184.   int index;
  2185.   Boolean OK;
  2186.  
  2187.   UNUSED(Index);
  2188.  
  2189.   if (!ChkArgCnt(3, 3));
  2190.   else if (ThisPar) WrError(ErrNum_ParNotPossible);
  2191.   else if (DecodeAdr(&ArgStr[1], MModAcc))
  2192.   {
  2193.     *WAsmCode = 0x9e00 | ((*AdrVals) << 8);
  2194.     if ((DecodeAdr(&ArgStr[2], MModMem))
  2195.      && (MakeXY(AdrVals, True)))
  2196.     {
  2197.       *WAsmCode |= ((*AdrVals) << 4);
  2198.       if (!DecodeCondition(3, WAsmCode + 1, &index, &OK)) WrStrErrorPos(ErrNum_UndefCond, &ArgStr[index]);
  2199.       else if ((WAsmCode[1] & 0xf0) != 0x40) WrStrErrorPos(ErrNum_UndefCond, &ArgStr[index]);
  2200.       else
  2201.       {
  2202.         *WAsmCode |= WAsmCode[1] & 15;
  2203.         CodeLen = 1;
  2204.       }
  2205.     }
  2206.   }
  2207. }
  2208.  
  2209. static void DecodeStoreCC(Word Index)
  2210. {
  2211.   int index;
  2212.   Boolean OK;
  2213.  
  2214.   UNUSED(Index);
  2215.  
  2216.   if (!ChkArgCnt(2, 2));
  2217.   else if (ThisPar) WrError(ErrNum_ParNotPossible);
  2218.   else if ((DecodeAdr(&ArgStr[1], MModMem)) && (MakeXY(AdrVals, True)))
  2219.   {
  2220.     *WAsmCode = Index | ((*AdrVals) << 4);
  2221.     if (!DecodeCondition(2, WAsmCode + 1, &index, &OK)) WrStrErrorPos(ErrNum_UndefCond, &ArgStr[index]);
  2222.     else if ((WAsmCode[1] & 0xf0) != 0x40) WrStrErrorPos(ErrNum_UndefCond, &ArgStr[index]);
  2223.     else
  2224.     {
  2225.       *WAsmCode |= WAsmCode[1] & 15;
  2226.       CodeLen = 1;
  2227.     }
  2228.   }
  2229. }
  2230.  
  2231. static void DecodeMVDabs(Word Index)
  2232. {
  2233.   if (!ChkArgCnt(2, 2));
  2234.   else if (ThisPar) WrError(ErrNum_ParNotPossible);
  2235.   else if (DecodeAdr(&ArgStr[1], MModMem))
  2236.   {
  2237.     tEvalResult EvalResult;
  2238.  
  2239.     *WAsmCode = Index | *AdrVals;
  2240.     if (AdrCnt)
  2241.       1[WAsmCode] = 1[AdrVals];
  2242.     WAsmCode[1 + AdrCnt] = EvalStrIntExpressionWithResult(&ArgStr[2], UInt16, &EvalResult);
  2243.     if (EvalResult.OK)
  2244.     {
  2245.       ChkSpace((Index == 0x7100) ? SegData : SegCode, EvalResult.AddrSpaceMask);
  2246.       CodeLen = 2 + AdrCnt;
  2247.     }
  2248.   }
  2249. }
  2250.  
  2251. static void DecodeMVabsD(Word Index)
  2252. {
  2253.   if (!ChkArgCnt(2, 2));
  2254.   else if (ThisPar) WrError(ErrNum_ParNotPossible);
  2255.   else if (DecodeAdr(&ArgStr[2], MModMem))
  2256.   {
  2257.     tEvalResult EvalResult;
  2258.  
  2259.     *WAsmCode = Index | *AdrVals;
  2260.     if (AdrCnt)
  2261.       1[WAsmCode] = 1[AdrVals];
  2262.     WAsmCode[1 + AdrCnt] = EvalStrIntExpressionWithResult(&ArgStr[1], UInt16, &EvalResult);
  2263.     if (EvalResult.OK)
  2264.     {
  2265.       ChkSpace((Index == 0x7000) ? SegData : SegCode, EvalResult.AddrSpaceMask);
  2266.       CodeLen = 2 + AdrCnt;
  2267.     }
  2268.   }
  2269. }
  2270.  
  2271. static void DecodeMVdmadmmr(Word Index)
  2272. {
  2273.   if (!ChkArgCnt(2, 2));
  2274.   else if (ThisPar) WrError(ErrNum_ParNotPossible);
  2275.   else
  2276.   {
  2277.     const tStrComp *pArg1 = (Index & 0x0100) ? &ArgStr[2] : &ArgStr[1],
  2278.                    *pArg2 = (Index & 0x0100) ? &ArgStr[1] : &ArgStr[2];
  2279.  
  2280.     ForcePageZero = True;
  2281.     if (DecodeAdr(pArg2, MModMem))
  2282.     {
  2283.       tEvalResult EvalResult;
  2284.  
  2285.       *WAsmCode = Index | *AdrVals;
  2286.       WAsmCode[1] = EvalStrIntExpressionWithResult(pArg1, UInt16, &EvalResult);
  2287.       if (EvalResult.OK)
  2288.       {
  2289.         ChkSpace(SegData, EvalResult.AddrSpaceMask);
  2290.         CodeLen = 2;
  2291.       }
  2292.     }
  2293.   }
  2294. }
  2295.  
  2296. static Boolean GetReg(const tStrComp *pArg, Word *Res)
  2297. {
  2298.   tEvalResult EvalResult;
  2299.  
  2300.   *Res = EvalStrIntExpressionWithResult(pArg, UInt8, &EvalResult);
  2301.   if (EvalResult.OK)
  2302.   {
  2303.     if (mFirstPassUnknown(EvalResult.Flags))
  2304.       *Res = 0x10;
  2305.     ChkSpace(SegData, EvalResult.AddrSpaceMask);
  2306.     EvalResult.OK = ChkRange(*Res, 0x10, 0x1f);
  2307.     if (EvalResult.OK)
  2308.       *Res -= 0x10;
  2309.   }
  2310.   return EvalResult.OK;
  2311. }
  2312.  
  2313. static void DecodeMVMM(Word Index)
  2314. {
  2315.   Word XReg, YReg;
  2316.   UNUSED(Index);
  2317.  
  2318.   if (!ChkArgCnt(2, 2));
  2319.   else if (ThisPar) WrError(ErrNum_ParNotPossible);
  2320.   else if ((GetReg(&ArgStr[1], &XReg)) && (GetReg(&ArgStr[2], &YReg)))
  2321.   {
  2322.     *WAsmCode = 0xe700 | (XReg << 4) | YReg;
  2323.     CodeLen = 1;
  2324.   }
  2325. }
  2326.  
  2327. static void DecodePort(Word Index)
  2328. {
  2329.   if (!ChkArgCnt(2, 2));
  2330.   else if (ThisPar) WrError(ErrNum_ParNotPossible);
  2331.   else
  2332.   {
  2333.     const tStrComp *pArg1 = (Index & 0x0100) ? &ArgStr[2] : &ArgStr[1],
  2334.                    *pArg2 = (Index & 0x0100) ? &ArgStr[1] : &ArgStr[2];
  2335.  
  2336.     if (DecodeAdr(pArg2, MModMem))
  2337.     {
  2338.       tEvalResult EvalResult;
  2339.  
  2340.       *WAsmCode = Index | *AdrVals;
  2341.       if (AdrCnt)
  2342.         1[WAsmCode] = 1[AdrVals];
  2343.       WAsmCode[1 + AdrCnt] = EvalStrIntExpressionWithResult(pArg1, UInt16, &EvalResult);
  2344.       if (EvalResult.OK)
  2345.       {
  2346.         ChkSpace(SegIO, EvalResult.AddrSpaceMask);
  2347.         CodeLen = 2 + AdrCnt;
  2348.       }
  2349.     }
  2350.   }
  2351. }
  2352.  
  2353. /*-------------------------------------------------------------------------*/
  2354. /* Pseudo Instructions */
  2355.  
  2356. static Boolean DecodePseudo(void)
  2357. {
  2358.   if (Memo("PORT"))
  2359.   {
  2360.     CodeEquate(SegIO, 0, 65535);
  2361.     return True;
  2362.   }
  2363.  
  2364.   return False;
  2365. }
  2366.  
  2367. /*-------------------------------------------------------------------------*/
  2368. /* Code Table Handling */
  2369.  
  2370. static void AddFixed(const char *Name, Word Code, Boolean IsRepeatable)
  2371. {
  2372.   if (InstrZ >= FixedOrderCnt)
  2373.     exit(0);
  2374.  
  2375.   FixedOrders[InstrZ].Code         = Code;
  2376.   FixedOrders[InstrZ].IsRepeatable = IsRepeatable;
  2377.   AddInstTable(InstTable, Name, InstrZ++, DecodeFixed);
  2378. }
  2379.  
  2380. static void AddAcc(const char *Name, Word Code, Boolean IsRepeatable)
  2381. {
  2382.   if (InstrZ >= AccOrderCnt)
  2383.     exit(0);
  2384.  
  2385.   AccOrders[InstrZ].Code         = Code;
  2386.   AccOrders[InstrZ].IsRepeatable = IsRepeatable;
  2387.   AddInstTable(InstTable, Name, InstrZ++, DecodeAcc);
  2388. }
  2389.  
  2390. static void AddAcc2(const char *Name, Word Code, Boolean IsRepeatable)
  2391. {
  2392.   if (InstrZ >= Acc2OrderCnt)
  2393.     exit(0);
  2394.  
  2395.   Acc2Orders[InstrZ].Code         = Code;
  2396.   Acc2Orders[InstrZ].IsRepeatable = IsRepeatable;
  2397.   AddInstTable(InstTable, Name, InstrZ++, DecodeAcc2);
  2398. }
  2399.  
  2400. static void AddMem(const char *Name, Word Code, Boolean IsRepeatable)
  2401. {
  2402.   if (InstrZ >= MemOrderCnt)
  2403.     exit(0);
  2404.  
  2405.   MemOrders[InstrZ].Code         = Code;
  2406.   MemOrders[InstrZ].IsRepeatable = IsRepeatable;
  2407.   AddInstTable(InstTable, Name, InstrZ++, DecodeMem);
  2408. }
  2409.  
  2410. static void AddXY(const char *Name, Word Code, Boolean IsRepeatable)
  2411. {
  2412.   if (InstrZ >= XYOrderCnt)
  2413.     exit(0);
  2414.  
  2415.   XYOrders[InstrZ].Code         = Code;
  2416.   XYOrders[InstrZ].IsRepeatable = IsRepeatable;
  2417.   AddInstTable(InstTable, Name, InstrZ++, DecodeXY);
  2418. }
  2419.  
  2420. static void AddMemAcc(const char *Name, Word Code, Boolean IsRepeatable)
  2421. {
  2422.   if (InstrZ >= MemAccOrderCnt)
  2423.     exit(0);
  2424.  
  2425.   MemAccOrders[InstrZ].Code         = Code;
  2426.   MemAccOrders[InstrZ].IsRepeatable = IsRepeatable;
  2427.   AddInstTable(InstTable, Name, InstrZ++, DecodeMemAcc);
  2428. }
  2429.  
  2430. static void AddMemConst(const char *Name, Word Code, Boolean IsRepeatable, Boolean Swap, IntType ConstType)
  2431. {
  2432.   if (InstrZ >= MemConstOrderCnt)
  2433.     exit(0);
  2434.  
  2435.   MemConstOrders[InstrZ].Code         = Code;
  2436.   MemConstOrders[InstrZ].IsRepeatable = IsRepeatable;
  2437.   MemConstOrders[InstrZ].Swap         = Swap;
  2438.   MemConstOrders[InstrZ].ConstType    = ConstType;
  2439.   AddInstTable(InstTable, Name, InstrZ++, DecodeMemConst);
  2440. }
  2441.  
  2442. static void AddMac(const char *Name, Word Code, Boolean IsRepeatable)
  2443. {
  2444.   if (InstrZ >= MacOrderCnt)
  2445.     exit(0);
  2446.  
  2447.   MacOrders[InstrZ].Code         = Code;
  2448.   MacOrders[InstrZ].IsRepeatable = IsRepeatable;
  2449.   AddInstTable(InstTable, Name, InstrZ++, DecodeMac);
  2450. }
  2451.  
  2452. static void AddCondition(const char *NName, Word NClass, Word NCode, Word NMask)
  2453. {
  2454.   if (InstrZ >= ConditionCnt)
  2455.     exit(0);
  2456.   Conditions[InstrZ  ].Name  = NName;
  2457.   Conditions[InstrZ  ].Class = NClass;
  2458.   Conditions[InstrZ  ].Code  = NCode;
  2459.   Conditions[InstrZ++].Mask  = NMask;
  2460. }
  2461.  
  2462. static void InitFields(void)
  2463. {
  2464.   InstTable = CreateInstTable(203);
  2465.  
  2466.   AddInstTable(InstTable, "LD", 0, DecodeLD);
  2467.   AddInstTable(InstTable, "ST", 0, DecodeST);
  2468.   AddInstTable(InstTable, "STH", 0x200, DecodeSTLH);
  2469.   AddInstTable(InstTable, "STL", 0x000, DecodeSTLH);
  2470.  
  2471.   FixedOrders = (FixedOrder*) malloc(sizeof(FixedOrder) * FixedOrderCnt); InstrZ = 0;
  2472.   AddFixed("FRET"  , 0xf4e4, FALSE);
  2473.   AddFixed("FRETD" , 0xf6e4, FALSE);
  2474.   AddFixed("FRETE" , 0xf4e5, FALSE);
  2475.   AddFixed("FRETED", 0xf6e5, FALSE);
  2476.   AddFixed("NOP"   , NOPCode, TRUE);
  2477.   AddFixed("RESET" , 0xf7e0, FALSE);
  2478.   AddFixed("RET"   , 0xfc00, FALSE);
  2479.   AddFixed("RETD"  , 0xfe00, FALSE);
  2480.   AddFixed("RETE"  , 0xf4eb, FALSE);
  2481.   AddFixed("RETED" , 0xf6eb, FALSE);
  2482.   AddFixed("RETF"  , 0xf49b, FALSE);
  2483.   AddFixed("RETFD" , 0xf69b, FALSE);
  2484.  
  2485.   AccOrders = (FixedOrder*) malloc(sizeof(FixedOrder) * AccOrderCnt); InstrZ = 0;
  2486.   AddAcc  ("EXP"   , 0xf48e, TRUE );
  2487.   AddAcc  ("MAX"   , 0xf486, TRUE );
  2488.   AddAcc  ("MIN"   , 0xf487, TRUE );
  2489.   AddAcc  ("SAT"   , 0xf483, TRUE );
  2490.   AddAcc  ("ROL"   , 0xf491, TRUE );
  2491.   AddAcc  ("ROLTC" , 0xf492, TRUE );
  2492.   AddAcc  ("ROR"   , 0xf490, TRUE );
  2493.   AddAcc  ("SFTC"  , 0xf494, TRUE );
  2494.   AddAcc  ("CALA"  , 0xf4e3, FALSE);
  2495.   AddAcc  ("CALAD" , 0xf6e3, FALSE);
  2496.   AddAcc  ("FCALA" , 0xf4e7, FALSE);
  2497.   AddAcc  ("FCALAD", 0xf6e7, FALSE);
  2498.   AddAcc  ("BACC"  , 0xf4e2, FALSE);
  2499.   AddAcc  ("BACCD" , 0xf6e2, FALSE);
  2500.   AddAcc  ("FBACC" , 0xf4e6, FALSE);
  2501.   AddAcc  ("FBACCD", 0xf6e6, FALSE);
  2502.  
  2503.   Acc2Orders = (FixedOrder*) malloc(sizeof(FixedOrder) * Acc2OrderCnt); InstrZ = 0;
  2504.   AddAcc2 ("NEG"   , 0xf484, TRUE );
  2505.   AddAcc2 ("NORM"  , 0xf48f, TRUE );
  2506.   AddAcc2 ("RND"   , 0xf49f, TRUE );
  2507.   AddAcc2 ("ABS"   , 0xf485, TRUE );
  2508.   AddAcc2 ("CMPL"  , 0xf493, TRUE );
  2509.  
  2510.   MemOrders = (FixedOrder*) malloc(sizeof(FixedOrder) * MemOrderCnt); InstrZ = 0;
  2511.   AddMem  ("DELAY" , 0x4d00, TRUE );
  2512.   AddMem  ("POLY"  , 0x3600, TRUE );
  2513.   AddMem  ("BITT"  , 0x3400, TRUE );
  2514.   AddMem  ("POPD"  , 0x8b00, TRUE );
  2515.   AddMem  ("PSHD"  , 0x4b00, TRUE );
  2516.   AddMem  ("MAR"   , 0x6d00, TRUE );
  2517.   AddMem  ("LTD"   , 0x4c00, TRUE );
  2518.   AddMem  ("READA" , 0x7e00, TRUE );
  2519.   AddMem  ("WRITA" , 0x7f00, TRUE );
  2520.  
  2521.   XYOrders = (FixedOrder*) malloc(sizeof(FixedOrder) * XYOrderCnt); InstrZ = 0;
  2522.   AddXY   ("ABDST" , 0xe300, TRUE );
  2523.   AddXY   ("LMS"   , 0xe100, TRUE );
  2524.   AddXY   ("SQDST" , 0xe200, TRUE );
  2525.   AddXY   ("MVDD"  , 0xe500, TRUE );
  2526.  
  2527.   AddInstTable(InstTable, "ADD", 0, DecodeADDSUB);
  2528.   AddInstTable(InstTable, "SUB", 1, DecodeADDSUB);
  2529.  
  2530.   MemAccOrders = (FixedOrder*) malloc(sizeof(FixedOrder) * MemAccOrderCnt); InstrZ = 0;
  2531.   AddMemAcc("ADDC" , 0x0600, TRUE );
  2532.   AddMemAcc("ADDS" , 0x0200, TRUE );
  2533.   AddMemAcc("SUBB" , 0x0e00, TRUE );
  2534.   AddMemAcc("SUBC" , 0x1e00, TRUE );
  2535.   AddMemAcc("SUBS" , 0x0a00, TRUE );
  2536.   AddMemAcc("MPYR" , 0x2200, TRUE );
  2537.   AddMemAcc("MPYU" , 0x2400, TRUE );
  2538.   AddMemAcc("SQURA", 0x3800, TRUE );
  2539.   AddMemAcc("SQURS", 0x3a00, TRUE );
  2540.   AddMemAcc("DADST", 0x5a00, TRUE );
  2541.   AddMemAcc("DRSUB", 0x5800, TRUE );
  2542.   AddMemAcc("DSADT", 0x5e00, TRUE );
  2543.   AddMemAcc("DSUB" , 0x5400, TRUE );
  2544.   AddMemAcc("DSUBT", 0x5c00, TRUE );
  2545.   AddMemAcc("DLD"  , 0x5600, TRUE );
  2546.   AddMemAcc("LDR"  , 0x1600, TRUE );
  2547.   AddMemAcc("LDU"  , 0x1200, TRUE );
  2548.  
  2549.   MacOrders = (FixedOrder*) malloc(sizeof(FixedOrder) * MacOrderCnt); InstrZ = 0;
  2550.   AddMac("MACA"  , 0x3508, TRUE );
  2551.   AddMac("MACAR" , 0x3709, TRUE );
  2552.   AddMac("MASA"  , 0x330a, TRUE );
  2553.  
  2554.   MemConstOrders = (MemConstOrder*) malloc(sizeof(MemConstOrder) * MemConstOrderCnt); InstrZ = 0;
  2555.   AddMemConst("ADDM", 0x6b00, FALSE, FALSE, SInt16);
  2556.   AddMemConst("ANDM", 0x6800, FALSE, FALSE, UInt16);
  2557.   AddMemConst("CMPM", 0x6000, TRUE , TRUE , SInt16);
  2558.   AddMemConst("ORM" , 0x6900, FALSE, FALSE, UInt16);
  2559.   AddMemConst("XORM", 0x6a00, FALSE, FALSE, UInt16);
  2560.  
  2561.   AddInstTable(InstTable, "AND"  , 0, DecodeLog);
  2562.   AddInstTable(InstTable, "OR"   , 1, DecodeLog);
  2563.   AddInstTable(InstTable, "XOR"  , 2, DecodeLog);
  2564.   AddInstTable(InstTable, "MPY"  , 0, DecodeMPY);
  2565.   AddInstTable(InstTable, "MPYA" , 0, DecodeMPYA);
  2566.   AddInstTable(InstTable, "SQUR" , 0, DecodeSQUR);
  2567.   AddInstTable(InstTable, "MAC"  , 0, DecodeMAC);
  2568.   AddInstTable(InstTable, "MACR" , 0, DecodeMACR);
  2569.   AddInstTable(InstTable, "MACD" , 0x7a00, DecodeMACDP);
  2570.   AddInstTable(InstTable, "MACP" , 0x7800, DecodeMACDP);
  2571.   AddInstTable(InstTable, "MACSU", 0, DecodeMACSU);
  2572.   AddInstTable(InstTable, "MAS"  , 0x000, DecodeMAS);
  2573.   AddInstTable(InstTable, "MASR" , 0x200, DecodeMAS);
  2574.   AddInstTable(InstTable, "MASAR", 0, DecodeMASAR);
  2575.   AddInstTable(InstTable, "DADD" , 0, DecodeDADD);
  2576.   AddInstTable(InstTable, "FIRS" , 0, DecodeFIRS);
  2577.   AddInstTable(InstTable, "SFTA" , 0xf460, DecodeSFT);
  2578.   AddInstTable(InstTable, "SFTL" , 0xf0e0, DecodeSFT);
  2579.   AddInstTable(InstTable, "BIT"  , 0, DecodeBIT);
  2580.   AddInstTable(InstTable, "BITF" , 0, DecodeBITF);
  2581.   AddInstTable(InstTable, "CMPR" , 0, DecodeCMPR);
  2582.  
  2583.   AddInstTable(InstTable, "B"    , 0xf073, DecodePMAD);
  2584.   AddInstTable(InstTable, "BD"   , 0xf273, DecodePMAD);
  2585.   AddInstTable(InstTable, "CALL" , 0xf074, DecodePMAD);
  2586.   AddInstTable(InstTable, "CALLD", 0xf274, DecodePMAD);
  2587.   AddInstTable(InstTable, "RPTB" , 0xf072, DecodePMAD);
  2588.   AddInstTable(InstTable, "RPTBD", 0xf272, DecodePMAD);
  2589.  
  2590.   AddInstTable(InstTable, "BC"   , 0xf800, DecodePMADCond);
  2591.   AddInstTable(InstTable, "BCD"  , 0xfa00, DecodePMADCond);
  2592.   AddInstTable(InstTable, "CC"   , 0xf900, DecodePMADCond);
  2593.   AddInstTable(InstTable, "CCD"  , 0xfb00, DecodePMADCond);
  2594.  
  2595.   AddInstTable(InstTable, "FB"    , 0xf880, DecodeFPMAD);
  2596.   AddInstTable(InstTable, "FBD"   , 0xfa80, DecodeFPMAD);
  2597.   AddInstTable(InstTable, "FCALL" , 0xf980, DecodeFPMAD);
  2598.   AddInstTable(InstTable, "FCALLD", 0xfb80, DecodeFPMAD);
  2599.  
  2600.   AddInstTable(InstTable, "BANZ" , 0x6c00, DecodeBANZ);
  2601.   AddInstTable(InstTable, "BANZD", 0x6e00, DecodeBANZ);
  2602.  
  2603.   AddInstTable(InstTable, "INTR" , 0xf7c0, DecodeINTR);
  2604.   AddInstTable(InstTable, "TRAP" , 0xf4c0, DecodeINTR);
  2605.   AddInstTable(InstTable, "PSHM" , 0     , DecodePSHM);
  2606.   AddInstTable(InstTable, "LDM"  , 0     , DecodeLDM);
  2607.   AddInstTable(InstTable, "STLM" , 0     , DecodeSTLM);
  2608.   AddInstTable(InstTable, "STM"  , 0     , DecodeSTM);
  2609.   AddInstTable(InstTable, "CMPS" , 0     , DecodeCMPS);
  2610.  
  2611.   AddInstTable(InstTable, "RPT"  , 0     , DecodeRPT);
  2612.   AddInstTable(InstTable, "RPTZ" , 0     , DecodeRPTZ);
  2613.  
  2614.   AddInstTable(InstTable, "FRAME", 0     , DecodeFRAME);
  2615.   AddInstTable(InstTable, "IDLE" , 0     , DecodeIDLE);
  2616.  
  2617.   AddInstTable(InstTable, "RSBX" , 0xf4b0, DecodeSBIT);
  2618.   AddInstTable(InstTable, "SSBX" , 0xf5b0, DecodeSBIT);
  2619.  
  2620.   AddInstTable(InstTable, "XC"   , 0     , DecodeXC);
  2621.  
  2622.   AddInstTable(InstTable, "DST"  , 0     , DecodeDST);
  2623.  
  2624.   AddInstTable(InstTable, "SACCD", 0     , DecodeSACCD);
  2625.  
  2626.   AddInstTable(InstTable, "SRCCD", 0x9d00, DecodeStoreCC);
  2627.   AddInstTable(InstTable, "STRCD", 0x9c00, DecodeStoreCC);
  2628.  
  2629.   AddInstTable(InstTable, "MVDK" , 0x7100, DecodeMVDabs);
  2630.   AddInstTable(InstTable, "MVDP" , 0x7d00, DecodeMVDabs);
  2631.   AddInstTable(InstTable, "MVKD" , 0x7000, DecodeMVabsD);
  2632.   AddInstTable(InstTable, "MVPD" , 0x7c00, DecodeMVabsD);
  2633.   AddInstTable(InstTable, "MVDM" , 0x7200, DecodeMVdmadmmr);
  2634.   AddInstTable(InstTable, "MVMD" , 0x7300, DecodeMVdmadmmr);
  2635.   AddInstTable(InstTable, "MVMM" , 0x7300, DecodeMVMM);
  2636.  
  2637.   AddInstTable(InstTable, "PORTR", 0x7400, DecodePort);
  2638.   AddInstTable(InstTable, "PORTW", 0x7500, DecodePort);
  2639.  
  2640.   Conditions = (Condition*) malloc(sizeof(Condition) * ConditionCnt); InstrZ = 0;
  2641.   AddCondition("BIO"  , 0, 0x0003, 0x0003);
  2642.   AddCondition("NBIO" , 0, 0x0002, 0x0003);
  2643.   AddCondition("C"    , 0, 0x000c, 0x000c);
  2644.   AddCondition("NC"   , 0, 0x0008, 0x000c);
  2645.   AddCondition("TC"   , 0, 0x0030, 0x0030);
  2646.   AddCondition("NTC"  , 0, 0x0020, 0x0030);
  2647.   AddCondition("AEQ"  , 1, 0x0045, 0x000f);
  2648.   AddCondition("ANEQ" , 1, 0x0044, 0x000f);
  2649.   AddCondition("AGT"  , 1, 0x0046, 0x000f);
  2650.   AddCondition("AGEQ" , 1, 0x0042, 0x000f);
  2651.   AddCondition("ALT"  , 1, 0x0043, 0x000f);
  2652.   AddCondition("ALEQ" , 1, 0x0047, 0x000f);
  2653.   AddCondition("AOV"  , 1, 0x0070, 0x00f0);
  2654.   AddCondition("ANOV" , 1, 0x0060, 0x00f0);
  2655.   AddCondition("BEQ"  , 2, 0x004d, 0x000f);
  2656.   AddCondition("BNEQ" , 2, 0x004c, 0x000f);
  2657.   AddCondition("BGT"  , 2, 0x004e, 0x000f);
  2658.   AddCondition("BGEQ" , 2, 0x004a, 0x000f);
  2659.   AddCondition("BLT"  , 2, 0x004b, 0x000f);
  2660.   AddCondition("BLEQ" , 2, 0x004f, 0x000f);
  2661.   AddCondition("BOV"  , 2, 0x0078, 0x00f0);
  2662.   AddCondition("BNOV" , 2, 0x0068, 0x00f0);
  2663.   AddCondition("UNC"  , 3, 0x0000, 0x00ff);
  2664. }
  2665.  
  2666. static void DeinitFields(void)
  2667. {
  2668.   DestroyInstTable(InstTable);
  2669.   free(FixedOrders);
  2670.   free(AccOrders);
  2671.   free(Acc2Orders);
  2672.   free(MemOrders);
  2673.   free(XYOrders);
  2674.   free(MemAccOrders);
  2675.   free(MemConstOrders);
  2676.   free(MacOrders);
  2677.   free(Conditions);
  2678. }
  2679.  
  2680. /*-------------------------------------------------------------------------*/
  2681. /* Linking Routines */
  2682.  
  2683. static void MakeCode_32054x(void)
  2684. {
  2685.   CodeLen = 0;
  2686.   DontPrint = False;
  2687.  
  2688.   ThisPar = !strcmp(LabPart.str.p_str, "||");
  2689.   if ((strlen(OpPart.str.p_str) > 2) && (!strncmp(OpPart.str.p_str, "||", 2)))
  2690.   {
  2691.     ThisPar = True; strmov(OpPart.str.p_str, OpPart.str.p_str + 2);
  2692.   }
  2693.  
  2694.   /* zu ignorierendes */
  2695.  
  2696.   if (*OpPart.str.p_str == '\0')
  2697.     return;
  2698.  
  2699.   if (DecodePseudo())
  2700.     return;
  2701.  
  2702.   if (DecodeTIPseudo())
  2703.     return;
  2704.  
  2705.   /* search */
  2706.  
  2707.   ThisRep = False;
  2708.   ForcePageZero = False;
  2709.   if (!LookupInstTable(InstTable, OpPart.str.p_str))
  2710.     WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
  2711.   else
  2712.     LastOpCode = *WAsmCode;
  2713.   LastRep = ThisRep;
  2714. }
  2715.  
  2716. static void InitCode_32054x(void)
  2717. {
  2718.   Reg_CPL = 0;
  2719.   Reg_DP = 0;
  2720.   Reg_SP = 0;
  2721. }
  2722.  
  2723. static Boolean IsDef_32054x(void)
  2724. {
  2725.   return (!strcmp(LabPart.str.p_str, "||"));
  2726. }
  2727.  
  2728. static void SwitchFrom_32054x(void)
  2729. {
  2730.   DeinitFields();
  2731. }
  2732.  
  2733. static void SwitchTo_32054x(void)
  2734. {
  2735. #define ASSUME3254xCount (sizeof(ASSUME3254xs) / sizeof(*ASSUME3254xs))
  2736.   static ASSUMERec ASSUME3254xs[] =
  2737.   {
  2738.     {"CPL", &Reg_CPL, 0,      1,       0, NULL},
  2739.     {"DP" , &Reg_DP , 0,  0x1ff,   0x200, NULL},
  2740.     {"SP" , &Reg_SP , 0, 0xffff, 0x10000, NULL}
  2741.   };
  2742.  
  2743.   const TFamilyDescr *FoundDescr;
  2744.  
  2745.   FoundDescr = FindFamilyByName("TMS320C54x");
  2746.  
  2747.   TurnWords = False;
  2748.   SetIntConstMode(eIntConstModeIntel);
  2749.  
  2750.   PCSymbol = "$";
  2751.   HeaderID = FoundDescr->Id;
  2752.   NOPCode = 0xf495;
  2753.   DivideChars = ",";
  2754.   HasAttrs = False;
  2755.  
  2756.   ValidSegs = (1 << SegCode) | (1 << SegData) | (1 << SegIO);
  2757.   Grans[SegCode] = 2; ListGrans[SegCode] = 2; SegInits[SegCode] = 2; SegLimits[SegCode] = 0xffff;
  2758.   Grans[SegData] = 2; ListGrans[SegData] = 2; SegInits[SegData] = 2; SegLimits[SegData] = 0xffff;
  2759.   Grans[SegIO  ] = 2; ListGrans[SegIO  ] = 2; SegInits[SegIO  ] = 2; SegLimits[SegIO  ] = 0xffff;
  2760.  
  2761.   MakeCode = MakeCode_32054x;
  2762.   IsDef = IsDef_32054x;
  2763.  
  2764.   pASSUMERecs = ASSUME3254xs;
  2765.   ASSUMERecCnt = ASSUME3254xCount;
  2766.  
  2767.   InitFields();
  2768.   SwitchFrom = SwitchFrom_32054x;
  2769.   ThisRep = LastRep = False;
  2770.   LastOpCode = 0;
  2771. }
  2772.  
  2773. /*-------------------------------------------------------------------------*/
  2774. /* Global Interface */
  2775.  
  2776. void code32054x_init(void)
  2777. {
  2778.   CPU320C541 = AddCPU("320C541", SwitchTo_32054x);
  2779.  
  2780.   AddInitPassProc(InitCode_32054x);
  2781. }
  2782.