Subversion Repositories pentevo

Rev

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

  1. /* code3206x.c */
  2. /*****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
  4. /*                                                                           */
  5. /* AS-Portierung                                                             */
  6. /*                                                                           */
  7. /* Codegenerator TMS320C6x                                                   */
  8. /*                                                                           */
  9. /*****************************************************************************/
  10.  
  11. #include "stdinc.h"
  12. #include <string.h>
  13. #include <ctype.h>
  14. #include "be_le.h"
  15.  
  16. #include "strutil.h"
  17. #include "bpemu.h"
  18. #include "nls.h"
  19. #include "asmdef.h"
  20. #include "asmsub.h"
  21. #include "asmpars.h"
  22. #include "asmcode.h"
  23. #include "errmsg.h"
  24. #include "ieeefloat.h"
  25. #include "codepseudo.h"
  26. #include "asmitree.h"
  27. #include "codevars.h"
  28. #include "onoff_common.h"
  29. #include "nlmessages.h"
  30. #include "chartrans.h"
  31. #include "as.rsc"
  32.  
  33. /*---------------------------------------------------------------------------*/
  34.  
  35. typedef enum
  36. {
  37.   NoUnit, L1, L2, S1, S2, M1, M2, D1, D2, LastUnit, UnitCnt
  38. } TUnit;
  39.  
  40. #ifdef __cplusplus
  41. # include "code3206x.hpp"
  42. #endif
  43.  
  44. typedef struct
  45. {
  46.   LongInt OpCode;
  47.   LongInt SrcMask, SrcMask2, DestMask;
  48.   Byte CrossUsed; /* Bit 0 -->X1 benutzt, Bit 1 -->X2 benutzt */
  49.   Byte AddrUsed;  /* Bit 0 -->Addr1 benutzt, Bit 1 -->Addr2 benutzt
  50.                   Bit 2 -->LdSt1 benutzt, Bit 3 -->LdSt2 benutzt */
  51.   Byte LongUsed;  /* Bit 0 -->lange Quelle, Bit 1-->langes Ziel */
  52.   Boolean AbsBranch;
  53.   Boolean StoreUsed, LongSrc, LongDest;
  54.   TUnit U;
  55. } InstrRec;
  56.  
  57. typedef struct
  58. {
  59.   LongInt Code;
  60. } FixedOrder;
  61.  
  62. typedef struct
  63. {
  64.   LongInt Code;
  65.   Boolean WithImm;
  66. } CmpOrder;
  67.  
  68. typedef struct
  69. {
  70.   LongInt Code;
  71.   LongInt Scale;
  72. } MemOrder;
  73.  
  74. typedef struct
  75. {
  76.   LongInt Code;
  77.   Boolean DSign,SSign1,SSign2;
  78.   Boolean MayImm;
  79. } MulOrder;
  80.  
  81. typedef struct
  82. {
  83.   const char *Name;
  84.   LongInt Code;
  85.   Boolean Rd,Wr;
  86. } CtrlReg;
  87.  
  88. static const char UnitNames[UnitCnt][3] =
  89. {
  90.   "  ", "L1", "L2", "S1", "S2", "M1", "M2", "D1", "D2", "  "
  91. };
  92.  
  93. #define MaxParCnt 8
  94. #define FirstUnit L1
  95.  
  96. enum
  97. {
  98.   ModNone = -1,
  99.   ModReg = 0,
  100.   ModLReg = 1,
  101.   ModImm = 2
  102. };
  103.  
  104. #define MModReg (1 << ModReg)
  105. #define MModLReg (1 << ModLReg)
  106. #define MModImm (1 << ModImm)
  107.  
  108. static ShortInt AdrMode;
  109.  
  110. static CPUVar CPU32060;
  111.  
  112. static Boolean ThisPar, ThisCross, ThisStore, ThisAbsBranch;
  113. static Byte ThisAddr, ThisLong;
  114. static LongInt ThisSrc, ThisSrc2, ThisDest;
  115. static LongInt Condition;
  116. static TUnit ThisUnit;
  117. static LongWord UnitFlag, ThisInst;
  118. static Integer ParCnt;
  119. static LongWord PacketAddr;
  120.  
  121. static InstrRec *ParRecs;
  122.  
  123. static FixedOrder *LinAddOrders;
  124. static CmpOrder *CmpOrders;
  125. static MemOrder *MemOrders;
  126. static MulOrder *MulOrders;
  127. static CtrlReg *CtrlRegs;
  128.  
  129. /*-------------------------------------------------------------------------*/
  130.  
  131. static Boolean CheckOpt(char *Asc)
  132. {
  133.   Boolean Flag, erg = True;
  134.   int l = strlen(Asc);
  135.  
  136.   if (!strcmp(Asc, "||"))
  137.     ThisPar = True;
  138.   else if ((*Asc == '[') && (Asc[l - 1] == ']'))
  139.   {
  140.     Asc++;
  141.     Asc[l - 2] = '\0';
  142.     l -= 2;
  143.     if (*Asc == '!')
  144.     {
  145.       Asc++;
  146.       l--;
  147.       Condition = 1;
  148.     }
  149.     else
  150.       Condition = 0;
  151.     Flag = True;
  152.     if (l != 2)
  153.       Flag = False;
  154.     else if (as_toupper(*Asc) == 'A')
  155.     {
  156.       if ((Asc[1] >= '1') && (Asc[1] <= '2'))
  157.         Condition += (Asc[1] - '0' + 3) << 1;
  158.       else
  159.         Flag = False;
  160.     }
  161.     else if (as_toupper(*Asc) == 'B')
  162.     {
  163.       if ((Asc[1] >= '0') && (Asc[1] <= '2'))
  164.         Condition += (Asc[1] - '0' + 1) << 1;
  165.       else
  166.         Flag = False;
  167.     }
  168.     if (!Flag)
  169.       WrXError(ErrNum_InvReg, Asc);
  170.     erg = Flag;
  171.   }
  172.   else
  173.     erg = False;
  174.  
  175.   return erg;
  176. }
  177.  
  178. static Boolean ReiterateOpPart(void)
  179. {
  180.   char *p;
  181.   int z;
  182.  
  183.   if (!CheckOpt(OpPart.str.p_str))
  184.     return False;
  185.  
  186.   if (ArgCnt<1)
  187.   {
  188.     WrError(ErrNum_WrongArgCnt);
  189.     return False;
  190.   }
  191.   p = FirstBlank(ArgStr[1].str.p_str);
  192.   if (!p)
  193.   {
  194.     StrCompCopy(&OpPart, &ArgStr[1]);
  195.     for (z = 2; z <= ArgCnt; z++)
  196.       StrCompCopy(&ArgStr[z - 1], &ArgStr[z]);
  197.     ArgCnt--;
  198.   }
  199.   else
  200.   {
  201.     StrCompSplitLeft(&ArgStr[1], &OpPart, p);
  202.     KillPrefBlanksStrComp(&ArgStr[1]);
  203.   }
  204.   NLS_UpString(OpPart.str.p_str);
  205.   p = strchr(OpPart.str.p_str, '.');
  206.   if (!p)
  207.     *AttrPart.str.p_str = '\0';
  208.   else
  209.   {
  210.     strcpy(AttrPart.str.p_str, p + 1);
  211.     *p = '\0';
  212.   }
  213.   return True;
  214. }
  215.  
  216. /*-------------------------------------------------------------------------*/
  217.  
  218. static void AddSrc(LongWord Reg)
  219. {
  220.   LongWord Mask = 1 << Reg;
  221.  
  222.   if (!(ThisSrc & Mask))
  223.     ThisSrc |= Mask;
  224.   else
  225.     ThisSrc2 |= Mask;
  226. }
  227.  
  228. static void AddLSrc(LongWord Reg)
  229. {
  230.   AddSrc(Reg);
  231.   AddSrc(Reg + 1);
  232.   ThisLong |= 1;
  233. }
  234.  
  235. static void AddDest(LongWord Reg)
  236. {
  237.   ThisDest |= (1 << Reg);
  238. }
  239.  
  240. static void AddLDest(LongWord Reg)
  241. {
  242.   ThisDest |= (3 << Reg);
  243.   ThisLong |= 2;
  244. }
  245.  
  246. static LongInt FindReg(LongInt Mask)
  247. {
  248.   int z;
  249.  
  250.   for (z = 0; z < 32; z++)
  251.   {
  252.     if (Mask & 1)
  253.       break;
  254.     Mask = Mask >> 1;
  255.   }
  256.   return z;
  257. }
  258.  
  259. static char *RegName(LongInt Num)
  260. {
  261.   static char s[5];
  262.  
  263.   Num &= 31;
  264.   as_snprintf(s, sizeof(s), "%c%ld", 'A' + (Num >> 4), (long) (Num & 15));
  265.   return s;
  266. }
  267.  
  268. static Boolean DecodeSReg(char *Asc, LongWord *Reg, Boolean Quarrel)
  269. {
  270.   char *end;
  271.   Byte RVal;
  272.   Boolean TFlag;
  273.  
  274.   TFlag = True;
  275.   switch (as_toupper(*Asc))
  276.   {
  277.     case 'A':
  278.       *Reg = 0; break;
  279.     case 'B':
  280.       *Reg = 16; break;
  281.     default:
  282.       TFlag = False;
  283.   }
  284.   if (TFlag)
  285.   {
  286.     RVal = strtol(Asc + 1, &end, 10);
  287.     if (*end != '\0')
  288.       TFlag = False;
  289.     else if
  290.       (RVal>15) TFlag = False;
  291.     else
  292.       *Reg += RVal;
  293.   }
  294.   if ((!TFlag) && (Quarrel))
  295.     WrXError(ErrNum_InvReg, Asc);
  296.   return TFlag;
  297. }
  298.  
  299. static Boolean DecodeReg(char *Asc, LongWord *Reg, Boolean *PFlag, Boolean Quarrel)
  300. {
  301.   char *p;
  302.   LongWord NextReg;
  303.  
  304.   p = strchr(Asc, ':');
  305.   if (p == 0)
  306.   {
  307.     *PFlag = False;
  308.     return DecodeSReg(Asc, Reg, Quarrel);
  309.   }
  310.   else
  311.   {
  312.     *PFlag = True;
  313.     *p = '\0';
  314.     if (!DecodeSReg(Asc, &NextReg, Quarrel))
  315.       return False;
  316.     else if (!DecodeSReg(p + 1, Reg, Quarrel))
  317.      return False;
  318.     else if ((Odd(*Reg)) || (NextReg != (*Reg) + 1) || ((((*Reg) ^ NextReg) & 0x10) != 0))
  319.     {
  320.       if (Quarrel)
  321.         WrXError(ErrNum_InvRegPair, Asc);
  322.       return False;
  323.     }
  324.     else
  325.       return True;
  326.   }
  327. }
  328.  
  329. static Boolean DecodeCtrlReg(char *Asc, LongWord *Erg, Boolean Write)
  330. {
  331.   int z;
  332.  
  333.   for (z = 0; CtrlRegs[z].Name; z++)
  334.     if (!as_strcasecmp(Asc, CtrlRegs[z].Name))
  335.     {
  336.       *Erg = CtrlRegs[z].Code;
  337.       return (Write && CtrlRegs[z].Wr) || ((!Write) && CtrlRegs[z].Rd);
  338.     }
  339.   return False;
  340. }
  341.  
  342. /* Was bedeutet das r-Feld im Adressoperanden mit kurzem Offset ???
  343.    und wie ist das genau mit der Skalierung gemeint ??? */
  344.  
  345. static Boolean DecodeMem(const tStrComp *pArg, LongWord *Erg, LongWord Scale)
  346. {
  347.   LongInt DispAcc, Mode;
  348.   LongWord BaseReg, IndReg;
  349.   int l;
  350.   char Counter;
  351.   char *p, EmptyStr[] = "";
  352.   Boolean OK;
  353.   tStrComp Arg, DispArg, RegArg;
  354.  
  355.   StrCompRefRight(&Arg, pArg, 0);
  356.  
  357.   /* das muss da sein */
  358.  
  359.   if (*pArg->str.p_str != '*')
  360.   {
  361.     WrError(ErrNum_InvAddrMode);
  362.     return False;
  363.   }
  364.   StrCompIncRefLeft(&Arg, 1);
  365.  
  366.   /* teilen */
  367.  
  368.   p = strchr(Arg.str.p_str, '[');
  369.   Counter = ']';
  370.   if (!p)
  371.   {
  372.     p = strchr(Arg.str.p_str, '(');
  373.     Counter = ')';
  374.   }
  375.   if (p)
  376.   {
  377.     if (Arg.str.p_str[strlen(Arg.str.p_str) - 1] != Counter)
  378.     {
  379.       WrError(ErrNum_InvAddrMode);
  380.       return False;
  381.     }
  382.     StrCompSplitRef(&RegArg, &DispArg, &Arg, p);
  383.     StrCompShorten(&DispArg, 1);
  384.   }
  385.   else
  386.   {
  387.     RegArg = Arg;
  388.     StrCompMkTemp(&DispArg, EmptyStr, 0);
  389.   }
  390.  
  391.   /* Registerfeld entschluesseln */
  392.  
  393.   l = strlen(RegArg.str.p_str);
  394.   Mode = 1; /* Default ist *+R */
  395.   if (*RegArg.str.p_str == '+')
  396.   {
  397.     StrCompIncRefLeft(&RegArg, 1);
  398.     Mode = 1;
  399.     if (*RegArg.str.p_str == '+')
  400.     {
  401.       StrCompIncRefLeft(&RegArg, 1);
  402.       Mode = 9;
  403.     }
  404.   }
  405.   else if (*RegArg.str.p_str == '-')
  406.   {
  407.     StrCompIncRefLeft(&RegArg, 1);
  408.     Mode = 0;
  409.     if (*RegArg.str.p_str == '-')
  410.     {
  411.       StrCompIncRefLeft(&RegArg, 1);
  412.       Mode = 8;
  413.     }
  414.   }
  415.   else if (RegArg.str.p_str[l - 1] == '+')
  416.   {
  417.     if (RegArg.str.p_str[l - 2] != '+')
  418.     {
  419.       WrError(ErrNum_InvAddrMode);
  420.       return False;
  421.     }
  422.     StrCompShorten(&RegArg, 2);
  423.     Mode = 11;
  424.   }
  425.   else if (RegArg.str.p_str[l - 1] == '-')
  426.   {
  427.     if (RegArg.str.p_str[l - 2] != '-')
  428.     {
  429.       WrError(ErrNum_InvAddrMode);
  430.       return False;
  431.     }
  432.     StrCompShorten(&RegArg, 2);
  433.     Mode = 10;
  434.   }
  435.   if (!DecodeSReg(RegArg.str.p_str, &BaseReg, False))
  436.   {
  437.     WrStrErrorPos(ErrNum_InvReg, &RegArg);
  438.     return False;
  439.   }
  440.   AddSrc(BaseReg);
  441.  
  442.   /* kein Offsetfeld ? --> Skalierungsgroesse bei Autoinkrement/De-
  443.      krement, sonst 0 */
  444.  
  445.   if (*DispArg.str.p_str == '\0')
  446.     DispAcc = (Mode < 2) ? 0 : Scale;
  447.  
  448.   /* Register als Offsetfeld? Dann Bit 2 in Modus setzen */
  449.  
  450.   else if (DecodeSReg(DispArg.str.p_str, &IndReg, False))
  451.   {
  452.     if ((IndReg ^ BaseReg) > 15)
  453.     {
  454.       WrError(ErrNum_InvAddrMode);
  455.       return False;
  456.     }
  457.     Mode += 4;
  458.     AddSrc(DispAcc = IndReg);
  459.   }
  460.  
  461.   /* ansonsten normaler Offset */
  462.  
  463.   else
  464.   {
  465.     tSymbolFlags Flags;
  466.  
  467.     DispAcc = EvalStrIntExpressionWithFlags(&DispArg, UInt15, &OK, &Flags);
  468.     if (!OK)
  469.       return False;
  470.     if (mFirstPassUnknown(Flags))
  471.       DispAcc &= 7;
  472.     if (Counter  ==  ')')
  473.     {
  474.       if (DispAcc % Scale != 0)
  475.       {
  476.         WrError(ErrNum_NotAligned);
  477.         return False;
  478.       }
  479.       else
  480.        DispAcc /= Scale;
  481.     }
  482.   }
  483.  
  484.   /* Benutzung des Adressierers markieren */
  485.  
  486.   ThisAddr |= (BaseReg > 15) ? 2 : 1;
  487.  
  488.   /* Wenn Offset>31, muessen wir Variante 2 benutzen */
  489.  
  490.   if (((Mode & 4) == 0) && (DispAcc > 31))
  491.   {
  492.     if ((BaseReg < 0x1e) || (Mode != 1)) WrError(ErrNum_InvAddrMode);
  493.     else
  494.     {
  495.       *Erg = ((DispAcc & 0x7fff) << 8) + ((BaseReg & 1) << 7) + 12;
  496.       return True;
  497.     }
  498.   }
  499.  
  500.   else
  501.   {
  502.     *Erg = (BaseReg << 18) + ((DispAcc & 0x1f) << 13) + (Mode << 9)
  503.          + ((BaseReg & 0x10) << 3) + 4;
  504.     return True;
  505.   }
  506.  
  507.   return False;
  508. }
  509.  
  510. static Boolean DecodeAdr(const tStrComp *pArg, Byte Mask, Boolean Signed, LongWord *AdrVal)
  511. {
  512.   Boolean OK;
  513.  
  514.   AdrMode = ModNone;
  515.  
  516.   if (DecodeReg(pArg->str.p_str, AdrVal, &OK, False))
  517.   {
  518.     AdrMode = (OK) ? ModLReg : ModReg;
  519.   }
  520.   else
  521.   {
  522.     *AdrVal = Signed ?
  523.               EvalStrIntExpression(pArg, SInt5, &OK) & 0x1f :
  524.               EvalStrIntExpression(pArg, UInt5, &OK);
  525.     if (OK)
  526.       AdrMode = ModImm;
  527.   }
  528.  
  529.   if ((AdrMode != ModNone) && (((1 << AdrMode) & Mask) == 0))
  530.   {
  531.     WrError(ErrNum_InvAddrMode);
  532.     AdrMode = ModNone;
  533.     return False;
  534.   }
  535.   else return True;
  536. }
  537.  
  538. static Boolean ChkUnit(LongWord Reg, TUnit U1, TUnit U2)
  539. {
  540.   UnitFlag = Ord(Reg>15);
  541.   if (ThisUnit == NoUnit)
  542.   {
  543.     ThisUnit = (Reg>15) ? U2 : U1;
  544.     return True;
  545.   }
  546.   else if (((ThisUnit == U1) && (Reg < 16)) || ((ThisUnit == U2) && (Reg>15)))
  547.     return True;
  548.   else
  549.   {
  550.     WrError(ErrNum_UndefAttr);
  551.     return False;
  552.   }
  553. }
  554.  
  555. static TUnit UnitCode(char c)
  556. {
  557.   switch (c)
  558.   {
  559.     case 'L': return L1;
  560.     case 'S': return S1;
  561.     case 'D': return D1;
  562.     case 'M': return M1;
  563.     default: return NoUnit;
  564.   }
  565. }
  566.  
  567. static Boolean UnitUsed(TUnit TestUnit)
  568. {
  569.   Integer z;
  570.  
  571.   for (z = 0; z < ParCnt; z++)
  572.     if (ParRecs[z].U == TestUnit)
  573.       return True;
  574.  
  575.   return False;
  576. }
  577.  
  578. static Boolean IsCross(LongWord Reg)
  579. {
  580.   return (Reg >> 4) != UnitFlag;
  581. }
  582.  
  583. static void SetCross(LongWord Reg)
  584. {
  585.   ThisCross = ((Reg >> 4) != UnitFlag);
  586. }
  587.  
  588. static Boolean DecideUnit(LongWord Reg, const char *Units)
  589. {
  590.   Integer z;
  591.   TUnit TestUnit;
  592.  
  593.   if (ThisUnit == NoUnit)
  594.   {
  595.     z = 0;
  596.     while ((Units[z] != '\0') && (ThisUnit == NoUnit))
  597.     {
  598.       TestUnit = UnitCode(Units[z]);
  599.       if (Reg >= 16) TestUnit++;
  600.       if (!UnitUsed(TestUnit))
  601.         ThisUnit = TestUnit;
  602.       z++;
  603.     }
  604.     if (ThisUnit == NoUnit)
  605.     {
  606.       ThisUnit = UnitCode(*Units);
  607.       if (Reg > 16)
  608.         TestUnit++;
  609.     }
  610.   }
  611.   UnitFlag = (ThisUnit - FirstUnit) & 1;
  612.   if (IsCross(Reg))
  613.   {
  614.     WrError(ErrNum_UndefAttr);
  615.     return False;
  616.   }
  617.   else
  618.     return True;
  619. }
  620.  
  621. static void SwapReg(LongWord *r1, LongWord *r2)
  622. {
  623.   LongWord tmp;
  624.  
  625.   tmp = (*r1);
  626.   *r1 = (*r2);
  627.   *r2 = tmp;
  628. }
  629.  
  630. static Boolean DecodePseudo(void)
  631. {
  632.   Boolean OK;
  633.   unsigned dword_index;
  634.   tStrComp *pArg;
  635.   LongInt Size;
  636.  
  637.   if (Memo("SINGLE"))
  638.   {
  639.     if (ChkArgCnt(1, ArgCntMax))
  640.     {
  641.       OK = True;
  642.       forallargs(pArg, OK)
  643.       {
  644.         as_float_t Float = EvalStrFloatExpression(pArg, &OK);
  645.  
  646.         if (OK)
  647.         {
  648.           int ret;
  649.  
  650.           dword_index = CodeLen >> 2;
  651.           if ((ret = as_float_2_ieee4(Float, (Byte *) (DAsmCode + dword_index), HostBigEndian)) < 0)
  652.           {
  653.             asmerr_check_fp_dispose_result(ret, pArg);
  654.             OK = False;
  655.           }
  656.         }
  657.         if (OK)
  658.           CodeLen += 4;
  659.       }
  660.       if (!OK) CodeLen = 0;
  661.     }
  662.     return True;
  663.   }
  664.  
  665.   if (Memo("DOUBLE"))
  666.   {
  667.     if (ChkArgCnt(1, ArgCntMax))
  668.     {
  669.       OK = True;
  670.       forallargs(pArg, OK)
  671.       {
  672.         as_float_t Float = EvalStrFloatExpression(pArg, &OK);
  673.         if (OK)
  674.         {
  675.           int ret;
  676.  
  677.           dword_index = CodeLen >> 2;
  678.           if ((ret = as_float_2_ieee8(Float, (Byte *) (DAsmCode + dword_index), HostBigEndian)) < 0)
  679.           {
  680.             asmerr_check_fp_dispose_result(ret, pArg);
  681.             OK = False;
  682.           }
  683.         }
  684.         if (OK)
  685.         {
  686.           if (!HostBigEndian)
  687.           {
  688.             LongWord swap;
  689.  
  690.             swap = DAsmCode[dword_index + 0];
  691.             DAsmCode[dword_index + 0] = DAsmCode[dword_index + 1];
  692.             DAsmCode[dword_index + 1] = swap;
  693.           }
  694.           CodeLen += 8;
  695.         }
  696.       }
  697.       if (!OK) CodeLen = 0;
  698.     }
  699.     return True;
  700.   }
  701.  
  702.   if (Memo("DATA"))
  703.   {
  704.     if (ChkArgCnt(1, ArgCntMax))
  705.     {
  706.       TempResult t;
  707.       int cnt = 0;
  708.  
  709.       as_tempres_ini(&t);
  710.       OK = True;
  711.       forallargs (pArg, OK)
  712.       {
  713.         EvalStrExpression(pArg, &t);
  714.         switch (t.Typ)
  715.         {
  716.           case TempString:
  717.           {
  718.             unsigned z2;
  719.             LongWord Trans;
  720.  
  721.             if (MultiCharToInt(&t, 4))
  722.               goto ToInt;
  723.  
  724.             if (as_chartrans_xlate_nonz_dynstr(CurrTransTable->p_table, &t.Contents.str, pArg))
  725.               OK = False;
  726.             else
  727.               for (z2 = 0; z2 < t.Contents.str.len; z2++)
  728.               {
  729.                 Trans = t.Contents.str.p_str[z2] & 0xff;
  730.                 if (Packing)
  731.                 {
  732.                   if ((z2 & 3) == 0) DAsmCode[cnt++] = 0;
  733.                   DAsmCode[cnt - 1] += Trans << (8 * (3 - (z2 & 3)));
  734.                 }
  735.                 else
  736.                   DAsmCode[cnt++] = Trans;
  737.               }
  738.             break;
  739.           }
  740.           case TempInt:
  741.           ToInt:
  742. #ifdef HAS64
  743.             if (!RangeCheck(t.Contents.Int, Int32))
  744.             {
  745.               OK = False;
  746.               WrStrErrorPos(ErrNum_OverRange, pArg);
  747.             }
  748.             else
  749. #endif
  750.               DAsmCode[cnt++] = t.Contents.Int;
  751.             break;
  752.           case TempFloat:
  753.           {
  754.             int ret;
  755.  
  756.             if ((ret = as_float_2_ieee4(t.Contents.Float, (Byte *) (DAsmCode + cnt), HostBigEndian)) < 0)
  757.             {
  758.               asmerr_check_fp_dispose_result(ret, pArg);
  759.               OK = False;
  760.             }
  761.             else
  762.               cnt++;
  763.             break;
  764.           }
  765.           default:
  766.             OK = False;
  767.         }
  768.       }
  769.       if (OK)
  770.         CodeLen = cnt << 2;
  771.       as_tempres_free(&t);
  772.     }
  773.     return True;
  774.   }
  775.  
  776.   if (Memo("BSS"))
  777.   {
  778.     if (ChkArgCnt(1, 1))
  779.     {
  780.       tSymbolFlags Flags;
  781.  
  782.       Size = EvalStrIntExpressionWithFlags(&ArgStr[1], UInt24, &OK, &Flags);
  783.       if (mFirstPassUnknown(Flags)) WrError(ErrNum_FirstPassCalc);
  784.       if (OK && !mFirstPassUnknown(Flags))
  785.       {
  786.         DontPrint = True;
  787.         if (!Size) WrError(ErrNum_NullResMem);
  788.         CodeLen = Size;
  789.         BookKeeping();
  790.       }
  791.     }
  792.     return True;
  793.   }
  794.  
  795.   return False;
  796. }
  797.  
  798.  
  799. static Boolean CodeL(LongWord OpCode, LongWord Dest, LongWord Src1, LongWord Src2)
  800. {
  801.   ThisInst = 0x18 + (OpCode << 5) + (UnitFlag << 1) + (Ord(ThisCross) << 12)
  802.                   + (Dest << 23) + (Src2 << 18) + (Src1 << 13);
  803.   return True;
  804. }
  805.  
  806. static Boolean CodeM(LongWord OpCode, LongWord Dest, LongWord Src1, LongWord Src2)
  807. {
  808.   ThisInst = 0x00 + (OpCode << 7) + (UnitFlag << 1) + (Ord(ThisCross) << 12)
  809.                   + (Dest << 23) + (Src2 << 18) + (Src1 << 13);
  810.   return True;
  811. }
  812.  
  813. static Boolean CodeS(LongWord OpCode, LongWord Dest, LongWord Src1, LongWord Src2)
  814. {
  815.   ThisInst = 0x20 + (OpCode << 6) + (UnitFlag << 1) + (Ord(ThisCross) << 12)
  816.                   + (Dest << 23) + (Src2 << 18) + (Src1 << 13);
  817.   return True;
  818. }
  819.  
  820. static Boolean CodeD(LongWord OpCode, LongWord Dest, LongWord Src1, LongWord Src2)
  821. {
  822.   ThisInst = 0x40 + (OpCode << 7) + (UnitFlag << 1)
  823.                   + (Dest << 23) + (Src2 << 18) + (Src1 << 13);
  824.   return True;
  825. }
  826.  
  827. /*-------------------------------------------------------------------------*/
  828.  
  829. static Boolean __erg;
  830.  
  831. static void DecodeIDLE(Word Index)
  832. {
  833.   UNUSED(Index);
  834.  
  835.   if (!ChkArgCnt(0, 0));
  836.   else if ((ThisCross) || (ThisUnit != NoUnit)) WrError(ErrNum_UndefAttr);
  837.   else
  838.   {
  839.     ThisInst = 0x0001e000;
  840.     __erg = True;
  841.   }
  842. }
  843.  
  844. static void DecodeNOP(Word Index)
  845. {
  846.   LongInt Count;
  847.   Boolean OK;
  848.   UNUSED(Index);
  849.  
  850.   if (!ChkArgCnt(0, 1));
  851.   else if ((ThisCross) || (ThisUnit != NoUnit)) WrError(ErrNum_UndefAttr);
  852.   else
  853.   {
  854.     if (ArgCnt == 0)
  855.     {
  856.       OK = True;
  857.       Count = 0;
  858.     }
  859.     else
  860.     {
  861.       tSymbolFlags Flags;
  862.  
  863.       Count = EvalStrIntExpressionWithFlags(&ArgStr[1], UInt4, &OK, &Flags);
  864.       Count = mFirstPassUnknown(Flags) ? 0 : Count - 1;
  865.       OK = ChkRange(Count, 0, 8);
  866.     }
  867.     if (OK)
  868.     {
  869.       ThisInst = Count << 13;
  870.       __erg = True;
  871.     }
  872.   }
  873. }
  874.  
  875. static void DecodeMul(Word Index)
  876. {
  877.   LongWord DReg, S1Reg, S2Reg;
  878.   MulOrder *POrder = MulOrders + Index;
  879.  
  880.   if (ChkArgCnt(3, 3))
  881.   {
  882.     if ((DecodeAdr(&ArgStr[3], MModReg, POrder->DSign, &DReg))
  883.      && (ChkUnit(DReg, M1, M2)))
  884.     {
  885.       if (DecodeAdr(&ArgStr[2], MModReg, POrder->SSign2, &S2Reg))
  886.       {
  887.         AddSrc(S2Reg);
  888.         DecodeAdr(&ArgStr[1], (POrder->MayImm ? MModImm : 0) + MModReg, POrder->SSign1, &S1Reg);
  889.         switch (AdrMode)
  890.         {
  891.           case ModReg:
  892.             if ((ThisCross) && (!IsCross(S2Reg)) && (!IsCross(S1Reg))) WrError(ErrNum_InvAddrMode);
  893.             else if ((IsCross(S2Reg)) && (IsCross(S1Reg))) WrError(ErrNum_InvAddrMode);
  894.             else
  895.             {
  896.               if (IsCross(S1Reg))
  897.                 SwapReg(&S1Reg, &S2Reg);
  898.               SetCross(S2Reg);
  899.               AddSrc(S1Reg);
  900.               __erg = CodeM(POrder->Code, DReg, S1Reg, S2Reg);
  901.             }
  902.             break;
  903.           case ModImm:
  904.             __erg = Memo("MPY") ?
  905.                     CodeM(POrder->Code - 1, DReg, S1Reg, S2Reg) :
  906.                     CodeM(POrder->Code + 3, DReg, S1Reg, S2Reg);
  907.             break;
  908.         }
  909.       }
  910.     }
  911.   }
  912. }
  913.  
  914. static void DecodeMemO(Word Index)
  915. {
  916.   LongWord DReg, S1Reg;
  917.   MemOrder *POrder = MemOrders + Index;
  918.   Boolean OK, IsStore;
  919.  
  920.   if (ChkArgCnt(2, 2))
  921.   {
  922.     const tStrComp *pArg1, *pArg2;
  923.  
  924.     IsStore = (*OpPart.str.p_str) == 'S';
  925.     pArg1 = IsStore ? &ArgStr[2] : &ArgStr[1];
  926.     pArg2 = IsStore ? &ArgStr[1] : &ArgStr[2];
  927.     if (IsStore)
  928.       ThisStore = True;
  929.     if (DecodeAdr(pArg2, MModReg, False, &DReg))
  930.     {
  931.       if (IsStore)
  932.         AddSrc(DReg);
  933.       ThisAddr |= (DReg > 15) ? 8 : 4;
  934.       /* Zielregister 4 Takte verzoegert, nicht als Dest eintragen */
  935.       OK = DecodeMem(pArg1, &S1Reg, POrder->Scale);
  936.       if (OK)
  937.       {
  938.         OK = (S1Reg & 8) ?
  939.              ChkUnit(0x1e, D1, D2) :
  940.              ChkUnit((S1Reg >> 18) & 31, D1, D2);
  941.       }
  942.       if (OK)
  943.       {
  944.         ThisInst = S1Reg + (DReg << 23) + (POrder->Code << 4)
  945.                  + ((DReg & 16) >> 3);
  946.         __erg = True;
  947.       }
  948.     }
  949.   }
  950. }
  951.  
  952. static void DecodeSTP(Word Index)
  953. {
  954.   LongWord S2Reg;
  955.   UNUSED(Index);
  956.  
  957.   if (ChkArgCnt(1, 1)
  958.    && ChkUnit(0x10, S1, S2))
  959.   {
  960.     if (DecodeAdr(&ArgStr[1], MModReg, False, &S2Reg))
  961.     {
  962.       if ((ThisCross) || (S2Reg < 16)) WrError(ErrNum_InvAddrMode);
  963.       else
  964.       {
  965.         AddSrc(S2Reg);
  966.         __erg = CodeS(0x0c, 0, 0, S2Reg);
  967.       }
  968.     }
  969.   }
  970. }
  971.  
  972. static void DecodeABS(Word Index)
  973. {
  974.   Boolean DPFlag, S1Flag;
  975.   LongWord DReg, S1Reg;
  976.   UNUSED(Index);
  977.  
  978.   if (ChkArgCnt(2, 2)
  979.    && DecodeReg(ArgStr[2].str.p_str, &DReg, &DPFlag, True)
  980.    && ChkUnit(DReg, L1, L2)
  981.    && DecodeReg(ArgStr[1].str.p_str, &S1Reg, &S1Flag, True))
  982.   {
  983.     if (DPFlag != S1Flag) WrError(ErrNum_InvAddrMode);
  984.     else if ((ThisCross) && ((S1Reg >> 4) == UnitFlag)) WrError(ErrNum_InvAddrMode);
  985.     else
  986.     {
  987.       SetCross(S1Reg);
  988.       if (DPFlag)
  989.       {
  990.         __erg = CodeL(0x38, DReg, 0, S1Reg);
  991.         AddLSrc(S1Reg);
  992.         AddLDest(DReg);
  993.       }
  994.       else
  995.       {
  996.         __erg = CodeL(0x1a, DReg, 0, S1Reg);
  997.         AddSrc(S1Reg);
  998.         AddDest(DReg);
  999.       }
  1000.     }
  1001.   }
  1002. }
  1003.  
  1004. static void DecodeADD(Word Index)
  1005. {
  1006.   LongWord S1Reg, S2Reg, DReg;
  1007.   Boolean OK;
  1008.   UNUSED(Index);
  1009.  
  1010.   if (ChkArgCnt(3, 3))
  1011.   {
  1012.     DecodeAdr(&ArgStr[3], MModReg + MModLReg, True, &DReg);
  1013.     UnitFlag = DReg >> 4;
  1014.     switch (AdrMode)
  1015.     {
  1016.       case ModLReg:      /* ADD ?,?,long */
  1017.         AddLDest(DReg);
  1018.         DecodeAdr(&ArgStr[1], MModReg + MModLReg + MModImm, True, &S1Reg);
  1019.         switch (AdrMode)
  1020.         {
  1021.           case ModReg:    /* ADD int,?,long */
  1022.             AddSrc(S1Reg);
  1023.             DecodeAdr(&ArgStr[2], MModReg + MModLReg, True, &S2Reg);
  1024.             switch (AdrMode)
  1025.             {
  1026.               case ModReg: /* ADD int,int,long */
  1027.                 if (ChkUnit(DReg, L1, L2))
  1028.                 {
  1029.                   if ((ThisCross) && (!IsCross(S1Reg)) && (!IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
  1030.                   else if ((IsCross(S1Reg)) && (IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
  1031.                   else
  1032.                   {
  1033.                     AddSrc(S2Reg);
  1034.                     if (IsCross(S1Reg))
  1035.                       SwapReg(&S1Reg, &S2Reg);
  1036.                     SetCross(S2Reg);
  1037.                     __erg = CodeL(0x23, DReg, S1Reg, S2Reg);
  1038.                   }
  1039.                 }
  1040.                 break;
  1041.               case ModLReg:/* ADD int,long,long */
  1042.                 if (ChkUnit(DReg, L1, L2))
  1043.                 {
  1044.                   if (IsCross(S2Reg)) WrError(ErrNum_InvAddrMode);
  1045.                   else if ((ThisCross) && (!IsCross(S1Reg))) WrError(ErrNum_InvAddrMode);
  1046.                   else
  1047.                   {
  1048.                     AddLSrc(S2Reg);
  1049.                     SetCross(S1Reg);
  1050.                     __erg = CodeL(0x21, DReg, S1Reg, S2Reg);
  1051.                   }
  1052.                 }
  1053.                 break;
  1054.             }
  1055.             break;
  1056.           case ModLReg:   /* ADD long,?,long */
  1057.             AddLSrc(S1Reg);
  1058.             DecodeAdr(&ArgStr[2], MModReg + MModImm, True, &S2Reg);
  1059.             switch (AdrMode)
  1060.             {
  1061.               case ModReg: /* ADD long,int,long */
  1062.                 if (ChkUnit(DReg, L1, L2))
  1063.                 {
  1064.                   if (IsCross(S1Reg)) WrError(ErrNum_InvAddrMode);
  1065.                   else if ((ThisCross) && (!IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
  1066.                   else
  1067.                   {
  1068.                     AddSrc(S2Reg);
  1069.                     SetCross(S2Reg);
  1070.                     __erg = CodeL(0x21, DReg, S2Reg, S1Reg);
  1071.                   }
  1072.                 }
  1073.                 break;
  1074.               case ModImm: /* ADD long,imm,long */
  1075.                 if (ChkUnit(DReg, L1, L2))
  1076.                 {
  1077.                   if (IsCross(S1Reg)) WrError(ErrNum_InvAddrMode);
  1078.                   else if (ThisCross) WrError(ErrNum_InvAddrMode);
  1079.                   else
  1080.                     __erg = CodeL(0x20, DReg, S2Reg, S1Reg);
  1081.                 }
  1082.                 break;
  1083.              }
  1084.              break;
  1085.            case ModImm:    /* ADD imm,?,long */
  1086.              if (DecodeAdr(&ArgStr[2], MModLReg, True, &S2Reg))
  1087.              {         /* ADD imm,long,long */
  1088.                if (ChkUnit(DReg, L1, L2))
  1089.                {
  1090.                  if (IsCross(S2Reg)) WrError(ErrNum_InvAddrMode);
  1091.                  else if (ThisCross) WrError(ErrNum_InvAddrMode);
  1092.                  else
  1093.                  {
  1094.                    AddLSrc(S2Reg);
  1095.                    __erg = CodeL(0x20, DReg, S1Reg, S2Reg);
  1096.                  }
  1097.                }
  1098.              }
  1099.              break;
  1100.         }
  1101.         break;
  1102.       case ModReg:       /* ADD ?,?,int */
  1103.         AddDest(DReg);
  1104.         DecodeAdr(&ArgStr[1], MModReg + MModImm, True, &S1Reg);
  1105.         switch (AdrMode)
  1106.         {
  1107.           case ModReg:    /* ADD int,?,int */
  1108.             AddSrc(S1Reg);
  1109.             DecodeAdr(&ArgStr[2], MModReg + MModImm, True, &S2Reg);
  1110.             switch (AdrMode)
  1111.             {
  1112.               case ModReg: /* ADD int,int,int */
  1113.                 AddSrc(S2Reg);
  1114.                 if (((DReg ^ S1Reg) > 15) && ((DReg ^ S2Reg)>15)) WrError(ErrNum_InvAddrMode);
  1115.                 else if ((ThisCross) && ((DReg ^ S1Reg) < 16) && ((DReg ^ S2Reg) < 15)) WrError(ErrNum_InvAddrMode);
  1116.                 else
  1117.                 {
  1118.                   if ((S1Reg ^ DReg) > 15)
  1119.                     SwapReg(&S1Reg, &S2Reg);
  1120.                   OK = DecideUnit(DReg, ((S2Reg ^ DReg)>15) ? "LS" : "LSD");
  1121.                   if (OK)
  1122.                   {
  1123.                     switch (ThisUnit)
  1124.                     {
  1125.                       case L1: case L2: /* ADD.Lx int,int,int */
  1126.                         __erg = CodeL(0x03, DReg, S1Reg, S2Reg);
  1127.                         break;
  1128.                       case S1: case S2: /* ADD.Sx int,int,int */
  1129.                         __erg = CodeS(0x07, DReg, S1Reg, S2Reg);
  1130.                         break;
  1131.                       case D1: case D2: /* ADD.Dx int,int,int */
  1132.                         __erg = CodeD(0x10, DReg, S1Reg, S2Reg);
  1133.                         break;
  1134.                       default:
  1135.                         WrError(ErrNum_CannotUseUnit);
  1136.                     }
  1137.                   }
  1138.                 }
  1139.                 break;
  1140.               case ModImm: /* ADD int,imm,int */
  1141.                 if ((ThisCross) && ((S1Reg ^ DReg) < 16)) WrError(ErrNum_InvAddrMode);
  1142.                 else
  1143.                 {
  1144.                   SetCross(S1Reg);
  1145.                   if (DecideUnit(DReg, "LS"))
  1146.                     switch (ThisUnit)
  1147.                     {
  1148.                       case L1: case L2:
  1149.                         __erg = CodeL(0x02, DReg, S2Reg, S1Reg);
  1150.                         break;
  1151.                       case S1: case S2:
  1152.                         __erg = CodeS(0x06, DReg, S2Reg, S1Reg);
  1153.                         break;
  1154.                       default:
  1155.                         WrError(ErrNum_CannotUseUnit);
  1156.                     }
  1157.                 }
  1158.                 break;
  1159.             }
  1160.             break;
  1161.           case ModImm:   /* ADD imm,?,int */
  1162.             if (DecodeAdr(&ArgStr[2], MModReg, True, &S2Reg))
  1163.             {
  1164.               AddSrc(S2Reg);
  1165.               if ((ThisCross) && ((S2Reg ^ DReg) < 16)) WrError(ErrNum_InvAddrMode);
  1166.               else
  1167.               {
  1168.                 SetCross(S2Reg);
  1169.                 if (DecideUnit(DReg, "LS"))
  1170.                   switch (ThisUnit)
  1171.                   {
  1172.                     case L1: case L2:
  1173.                       __erg = CodeL(0x02, DReg, S1Reg, S2Reg);
  1174.                       break;
  1175.                     case S1: case S2:
  1176.                       __erg = CodeS(0x06, DReg, S1Reg, S2Reg);
  1177.                       break;
  1178.                     default:
  1179.                       WrError(ErrNum_CannotUseUnit);
  1180.                   }
  1181.               }
  1182.             }
  1183.             break;
  1184.         }
  1185.         break;
  1186.     }
  1187.   }
  1188. }
  1189.  
  1190. static void DecodeADDU(Word Index)
  1191. {
  1192.   LongWord DReg, S1Reg, S2Reg;
  1193.   UNUSED(Index);
  1194.  
  1195.   if (ChkArgCnt(3, 3))
  1196.   {
  1197.     DecodeAdr(&ArgStr[3], MModReg + MModLReg, False, &DReg);
  1198.     switch (AdrMode)
  1199.     {
  1200.       case ModReg:      /* ADDU ?,?,int */
  1201.         if (ChkUnit(DReg, D1, D2))
  1202.         {
  1203.           AddDest(DReg);
  1204.           DecodeAdr(&ArgStr[1], MModReg + MModImm, False, &S1Reg);
  1205.           switch (AdrMode)
  1206.           {
  1207.             case ModReg: /* ADDU int,?,int */
  1208.               if (IsCross(S1Reg)) WrError(ErrNum_InvAddrMode);
  1209.               else
  1210.               {
  1211.                 AddSrc(S1Reg);
  1212.                 if (DecodeAdr(&ArgStr[2], MModImm, False, &S2Reg))
  1213.                  __erg = CodeD(0x12, DReg, S2Reg, S1Reg);
  1214.               }
  1215.               break;
  1216.             case ModImm: /* ADDU imm,?,int */
  1217.               if (DecodeAdr(&ArgStr[2], MModReg, False, &S2Reg))
  1218.               {
  1219.                 if (IsCross(S2Reg)) WrError(ErrNum_InvAddrMode);
  1220.                 else
  1221.                 {
  1222.                   AddSrc(S2Reg);
  1223.                   __erg = CodeD(0x12, DReg, S1Reg, S2Reg);
  1224.                 }
  1225.               }
  1226.               break;
  1227.           }
  1228.         }
  1229.         break;
  1230.       case ModLReg:     /* ADDU ?,?,long */
  1231.         if (ChkUnit(DReg, L1, L2))
  1232.         {
  1233.           AddLDest(DReg);
  1234.           DecodeAdr(&ArgStr[1], MModReg + MModLReg, False, &S1Reg);
  1235.           switch (AdrMode)
  1236.           {
  1237.             case ModReg: /* ADDU int,?,long */
  1238.               AddSrc(S1Reg);
  1239.               DecodeAdr(&ArgStr[2], MModReg + MModLReg, False, &S2Reg);
  1240.               switch (AdrMode)
  1241.               {
  1242.                 case ModReg: /* ADDU int,int,long */
  1243.                   if ((IsCross(S1Reg)) && (IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
  1244.                   else if ((ThisCross) && (((S1Reg ^ DReg) < 16) && ((S2Reg ^ DReg) < 16))) WrError(ErrNum_InvAddrMode);
  1245.                   else
  1246.                   {
  1247.                     if ((S1Reg ^ DReg) > 15)
  1248.                       SwapReg(&S1Reg, &S2Reg);
  1249.                     SetCross(S2Reg);
  1250.                     __erg = CodeL(0x2b, DReg, S1Reg, S2Reg);
  1251.                   }
  1252.                   break;
  1253.                 case ModLReg: /* ADDU int,long,long */
  1254.                   if (IsCross(S2Reg)) WrError(ErrNum_InvAddrMode);
  1255.                   else if ((ThisCross) && ((S1Reg ^ DReg) < 16)) WrError(ErrNum_InvAddrMode);
  1256.                   else
  1257.                   {
  1258.                     AddLSrc(S2Reg);
  1259.                     SetCross(S1Reg);
  1260.                     __erg = CodeL(0x29, DReg, S1Reg, S2Reg);
  1261.                   }
  1262.                   break;
  1263.               }
  1264.               break;
  1265.             case ModLReg:
  1266.               if (IsCross(S1Reg)) WrError(ErrNum_InvAddrMode);
  1267.               else
  1268.               {
  1269.                 AddLSrc(S1Reg);
  1270.                 if (DecodeAdr(&ArgStr[2], MModReg, False, &S2Reg))
  1271.                 {
  1272.                   if ((ThisCross) && ((S2Reg ^ DReg) < 16)) WrError(ErrNum_InvAddrMode);
  1273.                   else
  1274.                   {
  1275.                     AddSrc(S2Reg); SetCross(S2Reg);
  1276.                     __erg = CodeL(0x29, DReg, S2Reg, S1Reg);
  1277.                   }
  1278.                 }
  1279.               }
  1280.               break;
  1281.           }
  1282.         }
  1283.         break;
  1284.     }
  1285.   }
  1286. }
  1287.  
  1288. static void DecodeSUB(Word Index)
  1289. {
  1290.   LongWord DReg, S1Reg, S2Reg;
  1291.   Boolean OK;
  1292.   UNUSED(Index);
  1293.  
  1294.   if (ChkArgCnt(3, 3))
  1295.   {
  1296.     DecodeAdr(&ArgStr[3], MModReg + MModLReg, True, &DReg);
  1297.     switch (AdrMode)
  1298.     {
  1299.       case ModReg:
  1300.         AddDest(DReg);
  1301.         DecodeAdr(&ArgStr[1], MModReg + MModImm, True, &S1Reg);
  1302.         switch (AdrMode)
  1303.         {
  1304.           case ModReg:
  1305.             AddSrc(S1Reg);
  1306.             DecodeAdr(&ArgStr[2], MModReg + MModImm, True, &S2Reg);
  1307.             switch (AdrMode)
  1308.             {
  1309.               case ModReg:
  1310.                if ((ThisCross) && ((S1Reg ^ DReg) < 16) && ((S2Reg ^ DReg) < 16)) WrError(ErrNum_InvAddrMode);
  1311.                else if (((S1Reg ^ DReg) > 15) && ((S2Reg ^ DReg) > 15)) WrError(ErrNum_InvAddrMode);
  1312.                else
  1313.                {
  1314.                  AddSrc(S2Reg);
  1315.                  ThisCross = ((S1Reg ^ DReg) > 15) || ((S2Reg ^ DReg) > 15);
  1316.                  if ((S1Reg ^ DReg) > 15) OK = DecideUnit(DReg, "L");
  1317.                  else if ((S2Reg ^ DReg) > 15) OK = DecideUnit(DReg, "LS");
  1318.                  else OK = DecideUnit(DReg, "LSD");
  1319.                  if (OK)
  1320.                    switch (ThisUnit)
  1321.                    {
  1322.                      case L1: case L2:
  1323.                        if ((S1Reg ^ DReg) > 15) __erg = CodeL(0x17, DReg, S1Reg, S2Reg);
  1324.                        else __erg = CodeL(0x07, DReg, S1Reg, S2Reg);
  1325.                        break;
  1326.                      case S1: case S2:
  1327.                        __erg = CodeS(0x17, DReg, S1Reg, S2Reg);
  1328.                        break;
  1329.                      case D1: case D2:
  1330.                        __erg = CodeD(0x11, DReg, S2Reg, S1Reg);
  1331.                        break;
  1332.                      default:
  1333.                        WrError(ErrNum_CannotUseUnit);
  1334.                    }
  1335.                }
  1336.                break;
  1337.               case ModImm:
  1338.                if (ChkUnit(DReg, D1, D2))
  1339.                {
  1340.                  if ((ThisCross) || ((S1Reg ^ DReg) > 15)) WrError(ErrNum_InvAddrMode);
  1341.                  else __erg = CodeD(0x13, DReg, S2Reg, S1Reg);
  1342.                }
  1343.                break;
  1344.             }
  1345.             break;
  1346.           case ModImm:
  1347.             if (DecodeAdr(&ArgStr[2], MModReg, True, &S2Reg))
  1348.             {
  1349.               if ((ThisCross) && ((S2Reg ^ DReg) < 16)) WrError(ErrNum_InvAddrMode);
  1350.               else
  1351.               {
  1352.                 AddSrc(S2Reg);
  1353.                 if (DecideUnit(DReg, "LS"))
  1354.                   switch (ThisUnit)
  1355.                   {
  1356.                     case L1: case L2:
  1357.                       __erg = CodeL(0x06, DReg, S1Reg, S2Reg);
  1358.                       break;
  1359.                     case S1: case S2:
  1360.                       __erg = CodeS(0x16, DReg, S1Reg, S2Reg);
  1361.                       break;
  1362.                     default:
  1363.                       WrError(ErrNum_CannotUseUnit);
  1364.                   }
  1365.               }
  1366.             }
  1367.             break;
  1368.         }
  1369.         break;
  1370.       case ModLReg:
  1371.         AddLDest(DReg);
  1372.         if (ChkUnit(DReg, L1, L2))
  1373.         {
  1374.           DecodeAdr(&ArgStr[1], MModImm + MModReg, True, &S1Reg);
  1375.           switch (AdrMode)
  1376.           {
  1377.             case ModImm:
  1378.               if (DecodeAdr(&ArgStr[2], MModLReg, True, &S2Reg))
  1379.               {
  1380.                 if ((ThisCross) || (/*NOT*/ IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
  1381.                 else
  1382.                 {
  1383.                   AddLSrc(S2Reg);
  1384.                   __erg = CodeL(0x24, DReg, S1Reg, S2Reg);
  1385.                 }
  1386.               }
  1387.               break;
  1388.             case ModReg:
  1389.               AddSrc(S1Reg);
  1390.               if (DecodeAdr(&ArgStr[2], MModReg, True, &S2Reg))
  1391.               {
  1392.                 if ((ThisCross) && (!IsCross(S1Reg)) && (!IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
  1393.                 else if ((IsCross(S1Reg)) && (IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
  1394.                 else
  1395.                 {
  1396.                   AddSrc(S2Reg);
  1397.                   ThisCross = (IsCross(S1Reg)) || (IsCross(S2Reg));
  1398.                   /* what did I do here? */
  1399.                   __erg = IsCross(S1Reg) ?
  1400.                           CodeL(0x37, DReg, S1Reg, S2Reg) :
  1401.                           CodeL(0x47, DReg, S1Reg, S2Reg);
  1402.                 }
  1403.               }
  1404.               break;
  1405.           }
  1406.         }
  1407.         break;
  1408.     }
  1409.   }
  1410. }
  1411.  
  1412. static void DecodeSUBU(Word Index)
  1413. {
  1414.   LongWord S1Reg, S2Reg, DReg;
  1415.   UNUSED(Index);
  1416.  
  1417.   if (ChkArgCnt(3, 3)
  1418.    && DecodeAdr(&ArgStr[3], MModLReg, False, &DReg)
  1419.    && ChkUnit(DReg, L1, L2))
  1420.   {
  1421.     AddLDest(DReg);
  1422.     if (DecodeAdr(&ArgStr[1], MModReg, False, &S1Reg))
  1423.     {
  1424.       AddSrc(S1Reg);
  1425.       if (DecodeAdr(&ArgStr[2], MModReg, False, &S2Reg))
  1426.       {
  1427.         if ((ThisCross) && (!IsCross(S1Reg)) && (!IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
  1428.         else if ((IsCross(S1Reg)) && (IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
  1429.         else
  1430.         {
  1431.           AddSrc(S2Reg);
  1432.           ThisCross = IsCross(S1Reg) || IsCross(S2Reg);
  1433.           __erg = IsCross(S1Reg) ?
  1434.                   CodeL(0x3f, DReg, S1Reg, S2Reg) :
  1435.                   CodeL(0x2f, DReg, S1Reg, S2Reg);
  1436.         }
  1437.       }
  1438.     }
  1439.   }
  1440. }
  1441.  
  1442. static void DecodeSUBC(Word Index)
  1443. {
  1444.   LongWord DReg, S1Reg, S2Reg;
  1445.   UNUSED(Index);
  1446.  
  1447.   if (ChkArgCnt(3, 3)
  1448.    && DecodeAdr(&ArgStr[3], MModReg, False, &DReg)
  1449.    && ChkUnit(DReg, L1, L2))
  1450.   {
  1451.     AddLDest(DReg);
  1452.     if (DecodeAdr(&ArgStr[1], MModReg, False, &S1Reg))
  1453.     {
  1454.       if (DecodeAdr(&ArgStr[2], MModReg, False, &S2Reg))
  1455.       {
  1456.         if ((ThisCross) && (!IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
  1457.         else if (IsCross(S1Reg)) WrError(ErrNum_InvAddrMode);
  1458.         else
  1459.         {
  1460.           AddSrc(S2Reg);
  1461.           SetCross(S2Reg);
  1462.           __erg = CodeL(0x4b, DReg, S1Reg, S2Reg);
  1463.         }
  1464.       }
  1465.     }
  1466.   }
  1467. }
  1468.  
  1469. static void DecodeLinAdd(Word Index)
  1470. {
  1471.   LongWord DReg, S1Reg, S2Reg;
  1472.   FixedOrder *POrder = LinAddOrders + Index;
  1473.  
  1474.   if (!ChkArgCnt(3, 3));
  1475.   else if (ThisCross) WrError(ErrNum_InvAddrMode);
  1476.   else
  1477.   {
  1478.     if ((DecodeAdr(&ArgStr[3], MModReg, True, &DReg))
  1479.      && (ChkUnit(DReg, D1, D2)))
  1480.     {
  1481.       AddDest(DReg);
  1482.       if (DecodeAdr(&ArgStr[1], MModReg, True, &S2Reg))
  1483.       {
  1484.         if (IsCross(S2Reg)) WrError(ErrNum_InvAddrMode);
  1485.         else
  1486.         {
  1487.           AddSrc(S2Reg);
  1488.           DecodeAdr(&ArgStr[2], MModReg + MModImm, False, &S1Reg);
  1489.           switch (AdrMode)
  1490.           {
  1491.             case ModReg:
  1492.               if (IsCross(S1Reg)) WrError(ErrNum_InvAddrMode);
  1493.               else
  1494.               {
  1495.                 AddSrc(S1Reg);
  1496.                 __erg = CodeD(POrder->Code, DReg, S1Reg, S2Reg);
  1497.               }
  1498.               break;
  1499.             case ModImm:
  1500.               __erg = CodeD(POrder->Code + 2, DReg, S1Reg, S2Reg);
  1501.               break;
  1502.           }
  1503.         }
  1504.       }
  1505.     }
  1506.   }
  1507. }
  1508.  
  1509. static void DecodeADDK(Word Index)
  1510. {
  1511.   LongInt Value;
  1512.   LongWord DReg;
  1513.   Boolean OK;
  1514.   UNUSED(Index);
  1515.  
  1516.   if (ChkArgCnt(2, 2)
  1517.    && DecodeAdr(&ArgStr[2], MModReg, False, &DReg)
  1518.    && ChkUnit(DReg, S1, S2))
  1519.   {
  1520.     AddDest(DReg);
  1521.     Value = EvalStrIntExpression(&ArgStr[1], SInt16, &OK);
  1522.     if (OK)
  1523.     {
  1524.       ThisInst = 0x50 + (UnitFlag << 1) + ((Value & 0xffff) << 7) + (DReg << 23);
  1525.       __erg = True;
  1526.     }
  1527.   }
  1528. }
  1529.  
  1530. static void DecodeADD2_SUB2(Word Index)
  1531. {
  1532.   LongWord DReg, S1Reg, S2Reg;
  1533.   Boolean OK;
  1534.  
  1535.   Index = (Index << 5) + 1;
  1536.   if (ChkArgCnt(3, 3)
  1537.    && DecodeAdr(&ArgStr[3], MModReg, True, &DReg)
  1538.    && ChkUnit(DReg, S1, S2))
  1539.   {
  1540.     AddDest(DReg);
  1541.     if (DecodeAdr(&ArgStr[1], MModReg, True, &S1Reg))
  1542.     {
  1543.       AddSrc(S1Reg);
  1544.       if (DecodeAdr(&ArgStr[2], MModReg, True, &S2Reg))
  1545.       {
  1546.         if ((ThisCross) && (!IsCross(S1Reg)) && (!IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
  1547.         else if ((IsCross(S1Reg)) && (IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
  1548.         else
  1549.         {
  1550.           OK = True; AddSrc(S2Reg);
  1551.           if (IsCross(S1Reg))
  1552.           {
  1553.             if (Index > 1)
  1554.             {
  1555.               WrError(ErrNum_InvAddrMode);
  1556.               OK = False;
  1557.             }
  1558.             else SwapReg(&S1Reg, &S2Reg);
  1559.           }
  1560.           if (OK)
  1561.           {
  1562.             SetCross(S2Reg);
  1563.             __erg = CodeS(Index, DReg, S1Reg, S2Reg);
  1564.           }
  1565.         }
  1566.       }
  1567.     }
  1568.   }
  1569. }
  1570.  
  1571. static void DecodeMV(Word Index)
  1572. {
  1573.   LongWord SReg, DReg;
  1574.   UNUSED(Index);
  1575.  
  1576.   /* MV src,dst == ADD 0,src,dst */
  1577.  
  1578.   if (ChkArgCnt(2, 2))
  1579.   {
  1580.     DecodeAdr(&ArgStr[2], MModReg + MModLReg, True, &DReg);
  1581.     UnitFlag = DReg >> 4;
  1582.     switch (AdrMode)
  1583.     {
  1584.       case ModLReg:      /* MV ?,long */
  1585.         AddLDest(DReg);
  1586.         if (DecodeAdr(&ArgStr[1], MModLReg, True, &SReg))
  1587.         {                 /* MV long,long */
  1588.           if (ChkUnit(DReg, L1, L2))
  1589.           {
  1590.             if (IsCross(SReg)) WrError(ErrNum_InvAddrMode);
  1591.             else if (ThisCross) WrError(ErrNum_InvAddrMode);
  1592.             else
  1593.             {
  1594.               AddLSrc(SReg);
  1595.               __erg = CodeL(0x20, DReg, 0, SReg);
  1596.             }
  1597.           }
  1598.         }
  1599.         break;
  1600.  
  1601.       case ModReg:       /* MV ?,int */
  1602.         AddDest(DReg);
  1603.         if (DecodeAdr(&ArgStr[1], MModReg, True, &SReg))
  1604.         {
  1605.           AddSrc(SReg);
  1606.           if ((ThisCross) && ((SReg ^ DReg) < 16)) WrError(ErrNum_InvAddrMode);
  1607.           else
  1608.           {
  1609.             SetCross(SReg);
  1610.             if (DecideUnit(DReg, "LSD"))
  1611.               switch (ThisUnit)
  1612.               {
  1613.                 case L1: case L2:
  1614.                   __erg = CodeL(0x02, DReg, 0, SReg);
  1615.                   break;
  1616.                 case S1: case S2:
  1617.                   __erg = CodeS(0x06, DReg, 0, SReg);
  1618.                   break;
  1619.                 case D1: case D2:
  1620.                   __erg = CodeD(0x12, DReg, 0, SReg);
  1621.                   break;
  1622.                 default:
  1623.                   WrError(ErrNum_CannotUseUnit);
  1624.               }
  1625.           }
  1626.         }
  1627.         break;
  1628.     }
  1629.   }
  1630. }
  1631.  
  1632. static void DecodeNEG(Word Index)
  1633. {
  1634.   LongWord DReg, SReg;
  1635.   UNUSED(Index);
  1636.  
  1637.   /* NEG src,dst == SUB 0,src,dst */
  1638.  
  1639.   if (ChkArgCnt(2, 2))
  1640.   {
  1641.     DecodeAdr(&ArgStr[2], MModReg + MModLReg, True, &DReg);
  1642.     switch (AdrMode)
  1643.     {
  1644.       case ModReg:
  1645.         AddDest(DReg);
  1646.         if (DecodeAdr(&ArgStr[1], MModReg, True, &SReg))
  1647.         {
  1648.           if ((ThisCross) && ((SReg ^ DReg) < 16)) WrError(ErrNum_InvAddrMode);
  1649.           else
  1650.           {
  1651.             AddSrc(SReg);
  1652.             if (DecideUnit(DReg, "LS"))
  1653.               switch (ThisUnit)
  1654.               {
  1655.                 case L1: case L2:
  1656.                   __erg = CodeL(0x06, DReg, 0, SReg);
  1657.                   break;
  1658.                 case S1: case S2:
  1659.                   __erg = CodeS(0x16, DReg, 0, SReg);
  1660.                   break;
  1661.                 default:
  1662.                   WrError(ErrNum_CannotUseUnit);
  1663.               }
  1664.           }
  1665.         }
  1666.         break;
  1667.       case ModLReg:
  1668.         AddLDest(DReg);
  1669.         if (ChkUnit(DReg, L1, L2))
  1670.         {
  1671.           if (DecodeAdr(&ArgStr[1], MModLReg, True, &SReg))
  1672.           {
  1673.             if ((ThisCross) || (IsCross(SReg))) WrError(ErrNum_InvAddrMode);
  1674.             else
  1675.             {
  1676.               AddLSrc(SReg);
  1677.               __erg = CodeL(0x24, DReg, 0, SReg);
  1678.             }
  1679.           }
  1680.         }
  1681.         break;
  1682.     }
  1683.   }
  1684. }
  1685.  
  1686. static void DecodeLogic(Word Index)
  1687. {
  1688.   LongWord S1Reg, S2Reg, DReg;
  1689.   LongWord Code1, Code2;
  1690.   Boolean OK, WithImm;
  1691.  
  1692.   Code1 = Lo(Index);
  1693.   Code2 = Hi(Index);
  1694.  
  1695.   if (ChkArgCnt(3, 3))
  1696.   {
  1697.     if (DecodeAdr(&ArgStr[3], MModReg, True, &DReg))
  1698.     {
  1699.       AddDest(DReg);
  1700.       DecodeAdr(&ArgStr[1], MModImm + MModReg, True, &S1Reg);
  1701.       WithImm = False;
  1702.       switch (AdrMode)
  1703.       {
  1704.         case ModImm:
  1705.           OK = DecodeAdr(&ArgStr[2], MModReg, True, &S2Reg);
  1706.           if (OK) AddSrc(S2Reg);
  1707.           WithImm = True;
  1708.           break;
  1709.         case ModReg:
  1710.           AddSrc(S1Reg);
  1711.           OK = DecodeAdr(&ArgStr[2], MModImm + MModReg, True, &S2Reg);
  1712.           switch (AdrMode)
  1713.           {
  1714.             case ModImm:
  1715.               SwapReg(&S1Reg, &S2Reg);
  1716.               WithImm = True;
  1717.               break;
  1718.             case ModReg:
  1719.               AddSrc(S2Reg);
  1720.               WithImm = False;
  1721.               break;
  1722.             default:
  1723.               OK = False;
  1724.           }
  1725.           break;
  1726.         default:
  1727.           OK = False;
  1728.       }
  1729.       if ((OK) && (DecideUnit(DReg, "LS")))
  1730.       {
  1731.         if ((!WithImm) && (IsCross(S1Reg)) && (IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
  1732.         else if ((ThisCross) && (!IsCross(S2Reg)) && ((WithImm) || (!IsCross(S1Reg)))) WrError(ErrNum_InvAddrMode);
  1733.         else
  1734.         {
  1735.           if ((!WithImm) && (IsCross(S1Reg)))
  1736.             SwapReg(&S1Reg, &S2Reg);
  1737.           SetCross(S2Reg);
  1738.           switch (ThisUnit)
  1739.           {
  1740.             case L1: case L2:
  1741.               __erg = CodeL(Code1 - Ord(WithImm), DReg, S1Reg, S2Reg);
  1742.               break;
  1743.             case S1: case S2:
  1744.               __erg = CodeS(Code2 - Ord(WithImm), DReg, S1Reg, S2Reg);
  1745.               break;
  1746.             default:
  1747.               WrError(ErrNum_CannotUseUnit);
  1748.           }
  1749.         }
  1750.       }
  1751.     }
  1752.   }
  1753. }
  1754.  
  1755. static void DecodeNOT(Word Index)
  1756. {
  1757.   LongWord SReg, DReg;
  1758.  
  1759.   UNUSED(Index);
  1760.  
  1761.   /* NOT src,dst == XOR -1,src,dst */
  1762.  
  1763.   if (ChkArgCnt(2, 2))
  1764.   {
  1765.     if (DecodeAdr(&ArgStr[2], MModReg, True, &DReg))
  1766.     {
  1767.       AddDest(DReg);
  1768.       if (DecodeAdr(&ArgStr[1], MModReg, True, &SReg))
  1769.       {
  1770.         AddSrc(SReg);
  1771.         if (DecideUnit(DReg, "LS"))
  1772.         {
  1773.           if ((ThisCross) && (!IsCross(SReg))) WrError(ErrNum_InvAddrMode);
  1774.           else
  1775.           {
  1776.             SetCross(SReg);
  1777.             switch (ThisUnit)
  1778.             {
  1779.               case L1: case L2:
  1780.                 __erg = CodeL(0x6e, DReg, 0x1f, SReg);
  1781.                 break;
  1782.               case S1: case S2:
  1783.                 __erg = CodeS(0x0a, DReg, 0x1f, SReg);
  1784.                 break;
  1785.               default:
  1786.                 WrError(ErrNum_CannotUseUnit);
  1787.             }
  1788.           }
  1789.         }
  1790.       }
  1791.     }
  1792.   }
  1793. }
  1794.  
  1795. static void DecodeZERO(Word Index)
  1796. {
  1797.   LongWord DReg;
  1798.   UNUSED(Index);
  1799.  
  1800.   /* ZERO dst == SUB dst,dst,dst */
  1801.  
  1802.   if (ChkArgCnt(1, 1))
  1803.   {
  1804.     DecodeAdr(&ArgStr[1], MModReg + MModLReg, True, &DReg);
  1805.     if ((ThisCross) || (IsCross(DReg))) WrError(ErrNum_InvAddrMode);
  1806.     else
  1807.       switch (AdrMode)
  1808.       {
  1809.         case ModReg:
  1810.           AddDest(DReg);
  1811.           AddSrc(DReg);
  1812.           if (DecideUnit(DReg, "LSD"))
  1813.             switch (ThisUnit)
  1814.             {
  1815.               case L1: case L2:
  1816.                 __erg = CodeL(0x17, DReg, DReg, DReg);
  1817.                 break;
  1818.               case S1: case S2:
  1819.                 __erg = CodeS(0x17, DReg, DReg, DReg);
  1820.                 break;
  1821.               case D1: case D2:
  1822.                 __erg = CodeD(0x11, DReg, DReg, DReg);
  1823.                 break;
  1824.               default:
  1825.                 WrError(ErrNum_CannotUseUnit);
  1826.             }
  1827.           break;
  1828.         case ModLReg:
  1829.           AddLDest(DReg);
  1830.           AddLSrc(DReg);
  1831.           if (ChkUnit(DReg, L1, L2))
  1832.             __erg = CodeL(0x37, DReg, DReg, DReg);
  1833.           break;
  1834.       }
  1835.   }
  1836. }
  1837.  
  1838. static void DecodeCLR_EXT_EXTU_SET(Word Code)
  1839. {
  1840.   LongWord DReg, S1Reg, S2Reg, HReg;
  1841.   Boolean OK, IsEXT = (Code == 0x2f48);
  1842.  
  1843.   if (ChkArgCnt(3, 4))
  1844.   {
  1845.     if ((DecodeAdr(&ArgStr[ArgCnt], MModReg, IsEXT, &DReg))
  1846.      && (ChkUnit(DReg, S1, S2)))
  1847.     {
  1848.       AddDest(DReg);
  1849.       if (DecodeAdr(&ArgStr[1], MModReg, IsEXT, &S2Reg))
  1850.       {
  1851.         AddSrc(S2Reg);
  1852.         if (ArgCnt == 3)
  1853.         {
  1854.           if (DecodeAdr(&ArgStr[2], MModReg, False, &S1Reg))
  1855.           {
  1856.             if (IsCross(S1Reg)) WrError(ErrNum_InvAddrMode);
  1857.             else if ((ThisCross) && (!IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
  1858.             else
  1859.             {
  1860.               SetCross(S2Reg);
  1861.               __erg = CodeS(Hi(Code), DReg, S1Reg, S2Reg);
  1862.             }
  1863.           }
  1864.         }
  1865.         else if ((ThisCross) || (IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
  1866.         else
  1867.         {
  1868.           S1Reg = EvalStrIntExpression(&ArgStr[2], UInt5, &OK);
  1869.           if (OK)
  1870.           {
  1871.             HReg = EvalStrIntExpression(&ArgStr[3], UInt5, &OK);
  1872.             if (OK)
  1873.             {
  1874.               ThisInst = (DReg << 23) + (S2Reg << 18) + (S1Reg << 13)
  1875.                        + (HReg << 8) + (UnitFlag << 1) + Lo(Code);
  1876.               __erg = True;
  1877.             }
  1878.           }
  1879.         }
  1880.       }
  1881.     }
  1882.   }
  1883. }
  1884.  
  1885. static void DecodeCmp(Word Index)
  1886. {
  1887.   const CmpOrder *pOrder = CmpOrders + Index;
  1888.   LongWord DReg, S1Reg, S2Reg;
  1889.  
  1890.   if (ChkArgCnt(3, 3)
  1891.    && DecodeAdr(&ArgStr[3], MModReg, False, &DReg)
  1892.    && ChkUnit(DReg, L1, L2))
  1893.   {
  1894.     AddDest(DReg);
  1895.     DecodeAdr(&ArgStr[1], MModReg + MModImm, pOrder->WithImm, &S1Reg);
  1896.     switch (AdrMode)
  1897.     {
  1898.       case ModReg:
  1899.         AddSrc(S1Reg);
  1900.         DecodeAdr(&ArgStr[2], MModReg + MModLReg, pOrder->WithImm, &S2Reg);
  1901.         switch (AdrMode)
  1902.         {
  1903.           case ModReg:
  1904.             if ((IsCross(S1Reg)) && (IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
  1905.             else if ((ThisCross) && (!IsCross(S1Reg)) && (!IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
  1906.             else
  1907.             {
  1908.               AddSrc(S2Reg);
  1909.               if (IsCross(S1Reg)) SwapReg(&S1Reg, &S2Reg);
  1910.               SetCross(S2Reg);
  1911.               __erg = CodeL(pOrder->Code + 3, DReg, S1Reg, S2Reg);
  1912.             }
  1913.             break;
  1914.           case ModLReg:
  1915.             if (IsCross(S2Reg)) WrError(ErrNum_InvAddrMode);
  1916.             else if ((ThisCross) && (!IsCross(S1Reg))) WrError(ErrNum_InvAddrMode);
  1917.             else
  1918.             {
  1919.               AddLSrc(S2Reg); SetCross(S1Reg);
  1920.               __erg = CodeL(pOrder->Code + 1, DReg, S1Reg, S2Reg);
  1921.             }
  1922.             break;
  1923.         }
  1924.         break;
  1925.       case ModImm:
  1926.         DecodeAdr(&ArgStr[2], MModReg + MModLReg, pOrder->WithImm, &S2Reg);
  1927.         switch (AdrMode)
  1928.         {
  1929.           case ModReg:
  1930.             if ((ThisCross) && (!IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
  1931.             else
  1932.             {
  1933.               AddSrc(S2Reg); SetCross(S2Reg);
  1934.               __erg = CodeL(pOrder->Code + 2, DReg, S1Reg, S2Reg);
  1935.             }
  1936.             break;
  1937.           case ModLReg:
  1938.             if ((ThisCross) || (IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
  1939.             else
  1940.             {
  1941.               AddLSrc(S2Reg);
  1942.               __erg = CodeL(pOrder->Code, DReg, S1Reg, S2Reg);
  1943.             }
  1944.             break;
  1945.         }
  1946.        break;
  1947.     }
  1948.   }
  1949. }
  1950.  
  1951. static void DecodeLMBD(Word Code)
  1952. {
  1953.   LongWord DReg, S1Reg, S2Reg;
  1954.   UNUSED(Code);
  1955.  
  1956.   if (ChkArgCnt(3, 3)
  1957.    && DecodeAdr(&ArgStr[3], MModReg, False, &DReg)
  1958.    && ChkUnit(DReg, L1, L2))
  1959.   {
  1960.     AddDest(DReg);
  1961.     if (DecodeAdr(&ArgStr[2], MModReg, False, &S2Reg))
  1962.     {
  1963.       if ((ThisCross) && (!IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
  1964.       else
  1965.       {
  1966.         SetCross(S2Reg);
  1967.         if (DecodeAdr(&ArgStr[1], MModImm + MModReg, False, &S1Reg))
  1968.         {
  1969.           if (AdrMode == ModReg)
  1970.             AddSrc(S1Reg);
  1971.           __erg = CodeL(0x6a + Ord(AdrMode == ModImm), DReg, S1Reg, S2Reg);
  1972.         }
  1973.       }
  1974.     }
  1975.   }
  1976. }
  1977.  
  1978. static void DecodeNORM(Word Code)
  1979. {
  1980.   LongWord DReg, S2Reg;
  1981.  
  1982.   UNUSED(Code);
  1983.  
  1984.   if (ChkArgCnt(2, 2)
  1985.    && DecodeAdr(&ArgStr[2], MModReg, False, &DReg)
  1986.    && ChkUnit(DReg, L1, L2))
  1987.   {
  1988.     AddDest(DReg);
  1989.     DecodeAdr(&ArgStr[1], MModReg + MModLReg, True, &S2Reg);
  1990.     switch (AdrMode)
  1991.     {
  1992.       case ModReg:
  1993.         if ((ThisCross) && (!IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
  1994.         else
  1995.         {
  1996.           SetCross(S2Reg); AddSrc(S2Reg);
  1997.           __erg = CodeL(0x63, DReg, 0, S2Reg);
  1998.         }
  1999.         break;
  2000.       case ModLReg:
  2001.         if ((ThisCross) || (IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
  2002.         else
  2003.         {
  2004.           AddLSrc(S2Reg);
  2005.           __erg = CodeL(0x60, DReg, 0, S2Reg);
  2006.         }
  2007.         break;
  2008.     }
  2009.   }
  2010. }
  2011.  
  2012. static void DecodeSADD(Word Code)
  2013. {
  2014.   LongWord DReg, S1Reg, S2Reg;
  2015.  
  2016.   UNUSED(Code);
  2017.  
  2018.   if (ChkArgCnt(3, 3)
  2019.    && DecodeAdr(&ArgStr[3], MModReg + MModLReg, True, &DReg)
  2020.    && ChkUnit(DReg, L1, L2))
  2021.   {
  2022.     switch (AdrMode)
  2023.     {
  2024.       case ModReg:
  2025.         AddDest(DReg);
  2026.         DecodeAdr(&ArgStr[1], MModReg + MModImm, True, &S1Reg);
  2027.         switch (AdrMode)
  2028.         {
  2029.           case ModReg:
  2030.             AddSrc(S1Reg);
  2031.             DecodeAdr(&ArgStr[2], MModReg + MModImm, True, &S2Reg);
  2032.             switch (AdrMode)
  2033.             {
  2034.               case ModReg:
  2035.                if ((ThisCross) && (!IsCross(S1Reg)) && (!IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
  2036.                else if ((IsCross(S1Reg)) && (IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
  2037.                else
  2038.                {
  2039.                  AddSrc(S2Reg);
  2040.                  if (IsCross(S1Reg)) SwapReg(&S1Reg, &S2Reg);
  2041.                  SetCross(S2Reg);
  2042.                  __erg = CodeL(0x13, DReg, S1Reg, S2Reg);
  2043.                }
  2044.                break;
  2045.               case ModImm:
  2046.                if ((ThisCross) && (!IsCross(S1Reg))) WrError(ErrNum_InvAddrMode);
  2047.                else
  2048.                {
  2049.                  SetCross(S1Reg);
  2050.                  __erg = CodeL(0x12, DReg, S2Reg, S1Reg);
  2051.                }
  2052.                break;
  2053.             }
  2054.             break;
  2055.           case ModImm:
  2056.             if (DecodeAdr(&ArgStr[2], MModReg, True, &S2Reg))
  2057.             {
  2058.               if ((ThisCross) && (!IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
  2059.               else
  2060.               {
  2061.                 SetCross(S2Reg);
  2062.                 __erg = CodeL(0x12, DReg, S1Reg, S2Reg);
  2063.               }
  2064.             }
  2065.             break;
  2066.         }
  2067.         break;
  2068.       case ModLReg:
  2069.         AddLDest(DReg);
  2070.         DecodeAdr(&ArgStr[1], MModReg + MModLReg + MModImm, True, &S1Reg);
  2071.         switch (AdrMode)
  2072.         {
  2073.           case ModReg:
  2074.             AddSrc(S1Reg);
  2075.             if (DecodeAdr(&ArgStr[2], MModLReg, True, &S2Reg))
  2076.             {
  2077.               if ((ThisCross) && (!IsCross(S1Reg))) WrError(ErrNum_InvAddrMode);
  2078.               else
  2079.               {
  2080.                 AddLSrc(S2Reg); SetCross(S1Reg);
  2081.                 __erg = CodeL(0x31, DReg, S1Reg, S2Reg);
  2082.               }
  2083.             }
  2084.             break;
  2085.           case ModLReg:
  2086.             if (IsCross(S1Reg)) WrError(ErrNum_InvAddrMode);
  2087.             else
  2088.             {
  2089.               AddLSrc(S1Reg);
  2090.               DecodeAdr(&ArgStr[2], MModReg + MModImm, True, &S2Reg);
  2091.               switch (AdrMode)
  2092.               {
  2093.                 case ModReg:
  2094.                   if ((ThisCross) && (!IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
  2095.                   else
  2096.                   {
  2097.                     AddSrc(S2Reg); SetCross(S2Reg);
  2098.                     __erg = CodeL(0x31, DReg, S2Reg, S1Reg);
  2099.                   }
  2100.                   break;
  2101.                 case ModImm:
  2102.                   __erg = CodeL(0x30, DReg, S2Reg, S1Reg);
  2103.                   break;
  2104.               }
  2105.             }
  2106.             break;
  2107.           case ModImm:
  2108.             if (DecodeAdr(&ArgStr[2], MModLReg, True, &S2Reg))
  2109.             {
  2110.               if (IsCross(S2Reg)) WrError(ErrNum_InvAddrMode);
  2111.               else
  2112.               {
  2113.                 AddLSrc(S2Reg);
  2114.                 __erg = CodeL(0x30, DReg, S1Reg, S2Reg);
  2115.               }
  2116.             }
  2117.             break;
  2118.         }
  2119.         break;
  2120.     }
  2121.   }
  2122. }
  2123.  
  2124. static void DecodeSAT(Word Code)
  2125. {
  2126.   LongWord DReg, S2Reg;
  2127.  
  2128.   UNUSED(Code);
  2129.  
  2130.   if (ChkArgCnt(2, 2)
  2131.    && DecodeAdr(&ArgStr[2], MModReg, True, &DReg)
  2132.    && ChkUnit(DReg, L1, L2))
  2133.   {
  2134.     AddDest(DReg);
  2135.     if (DecodeAdr(&ArgStr[1], MModLReg, True, &S2Reg))
  2136.     {
  2137.       if ((ThisCross) || (IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
  2138.       else
  2139.       {
  2140.         AddLSrc(S2Reg);
  2141.         __erg = CodeL(0x40, DReg, 0, S2Reg);
  2142.       }
  2143.     }
  2144.   }
  2145. }
  2146.  
  2147. static void DecodeMVC(Word Code)
  2148. {
  2149.   LongWord S1Reg, CReg;
  2150.  
  2151.   UNUSED(Code);
  2152.  
  2153.   if ((ThisUnit != NoUnit) && (ThisUnit != S2)) WrError(ErrNum_InvAddrMode);
  2154.   else if (ChkArgCnt(2, 2))
  2155.   {
  2156.     int z;
  2157.  
  2158.     z = 0;
  2159.     ThisUnit = S2;
  2160.     UnitFlag = 1;
  2161.     if (DecodeCtrlReg(ArgStr[1].str.p_str, &CReg, False))
  2162.       z = 2;
  2163.     else if (DecodeCtrlReg(ArgStr[2].str.p_str, &CReg, True))
  2164.       z = 1;
  2165.     else
  2166.       WrStrErrorPos(ErrNum_InvCtrlReg, &ArgStr[1]);
  2167.     if (z > 0)
  2168.     {
  2169.       if (DecodeAdr(&ArgStr[z], MModReg, False, &S1Reg))
  2170.       {
  2171.         if ((ThisCross) && ((z == 2) || (IsCross(S1Reg)))) WrError(ErrNum_InvAddrMode);
  2172.         else
  2173.         {
  2174.           if (z == 1)
  2175.           {
  2176.             AddSrc(S1Reg);
  2177.             SetCross(S1Reg);
  2178.             __erg = CodeS(0x0e, CReg, 0, S1Reg);
  2179.           }
  2180.           else
  2181.           {
  2182.             AddDest(S1Reg);
  2183.             __erg = CodeS(0x0f, S1Reg, 0, CReg);
  2184.           }
  2185.         }
  2186.       }
  2187.     }
  2188.   }
  2189. }
  2190.  
  2191. static void DecodeMVK(Word Code)
  2192. {
  2193.   LongWord DReg, S1Reg;
  2194.   Boolean OK;
  2195.  
  2196.   if (ChkArgCnt(2, 2))
  2197.   {
  2198.     if (DecodeAdr(&ArgStr[2], MModReg, True, &DReg))
  2199.      if (ChkUnit(DReg, S1, S2))
  2200.      {
  2201.        if (Memo("MVKLH"))
  2202.          S1Reg = EvalStrIntExpression(&ArgStr[1], Int16, &OK);
  2203.        else if (Memo("MVKL"))
  2204.          S1Reg = EvalStrIntExpression(&ArgStr[1], SInt16, &OK);
  2205.        else
  2206.          S1Reg = EvalStrIntExpression(&ArgStr[1], Int32, &OK);
  2207.        if (OK)
  2208.        {
  2209.          AddDest(DReg);
  2210.          ThisInst = (DReg << 23) + (((S1Reg >> Hi(Code)) & 0xffff) << 7) + (UnitFlag << 1) + Lo(Code);
  2211.          __erg = True;
  2212.        }
  2213.      }
  2214.   }
  2215. }
  2216.  
  2217. static void DecodeSHL(Word Code)
  2218. {
  2219.   LongWord DReg, S1Reg, S2Reg;
  2220.  
  2221.   UNUSED(Code);
  2222.  
  2223.   if (ChkArgCnt(3, 3))
  2224.   {
  2225.     DecodeAdr(&ArgStr[3], MModReg + MModLReg, True, &DReg);
  2226.     if ((AdrMode != ModNone) && (ChkUnit(DReg, S1, S2)))
  2227.      switch (AdrMode)
  2228.      {
  2229.        case ModReg:
  2230.          AddDest(DReg);
  2231.          if (DecodeAdr(&ArgStr[1], MModReg, True, &S2Reg))
  2232.          {
  2233.            if ((ThisCross) && (!IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
  2234.            else
  2235.            {
  2236.              AddSrc(S2Reg);
  2237.              SetCross(S2Reg);
  2238.              DecodeAdr(&ArgStr[2], MModReg + MModImm, False, &S1Reg);
  2239.              switch (AdrMode)
  2240.              {
  2241.                case ModReg:
  2242.                  if (IsCross(S1Reg)) WrError(ErrNum_InvAddrMode);
  2243.                  else
  2244.                  {
  2245.                    AddSrc(S1Reg);
  2246.                    __erg = CodeS(0x33, DReg, S1Reg, S2Reg);
  2247.                  }
  2248.                  break;
  2249.                case ModImm:
  2250.                  __erg = CodeS(0x32, DReg, S1Reg, S2Reg);
  2251.                  break;
  2252.              }
  2253.            }
  2254.          }
  2255.          break;
  2256.        case ModLReg:
  2257.          AddLDest(DReg);
  2258.          DecodeAdr(&ArgStr[1], MModReg + MModLReg, True, &S2Reg);
  2259.          switch (AdrMode)
  2260.          {
  2261.            case ModReg:
  2262.              if ((ThisCross) && (!IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
  2263.              else
  2264.              {
  2265.                AddSrc(S2Reg); SetCross(S2Reg);
  2266.                DecodeAdr(&ArgStr[2], MModImm + MModReg, False, &S1Reg);
  2267.                switch (AdrMode)
  2268.                {
  2269.                  case ModReg:
  2270.                    if (IsCross(S1Reg)) WrError(ErrNum_InvAddrMode);
  2271.                    else
  2272.                    {
  2273.                      AddSrc(S1Reg);
  2274.                      __erg = CodeS(0x13, DReg, S1Reg, S2Reg);
  2275.                    }
  2276.                    break;
  2277.                  case ModImm:
  2278.                    __erg = CodeS(0x12, DReg, S1Reg, S2Reg);
  2279.                    break;
  2280.                }
  2281.              }
  2282.              break;
  2283.            case ModLReg:
  2284.              if ((ThisCross) || (IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
  2285.              else
  2286.              {
  2287.                AddLSrc(S2Reg);
  2288.                DecodeAdr(&ArgStr[2], MModImm + MModReg, False, &S1Reg);
  2289.                switch (AdrMode)
  2290.                {
  2291.                  case ModReg:
  2292.                    if (IsCross(S1Reg)) WrError(ErrNum_InvAddrMode);
  2293.                    else
  2294.                    {
  2295.                      AddSrc(S1Reg);
  2296.                      __erg = CodeS(0x31, DReg, S1Reg, S2Reg);
  2297.                    }
  2298.                    break;
  2299.                  case ModImm:
  2300.                    __erg = CodeS(0x30, DReg, S1Reg, S2Reg);
  2301.                    break;
  2302.                }
  2303.              }
  2304.              break;
  2305.          }
  2306.          break;
  2307.       }
  2308.   }
  2309. }
  2310.  
  2311. static void DecodeSHR_SHRU(Word Code)
  2312. {
  2313.   LongWord DReg, S1Reg, S2Reg;
  2314.   Boolean HasSign = Code != 0;
  2315.  
  2316.   if (ChkArgCnt(3, 3))
  2317.   {
  2318.     DecodeAdr(&ArgStr[3], MModReg + MModLReg, HasSign, &DReg);
  2319.     if ((AdrMode != ModNone) && (ChkUnit(DReg, S1, S2)))
  2320.      switch (AdrMode)
  2321.      {
  2322.        case ModReg:
  2323.          AddDest(DReg);
  2324.          if (DecodeAdr(&ArgStr[1], MModReg, HasSign, &S2Reg))
  2325.          {
  2326.            if ((ThisCross) && (!IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
  2327.            else
  2328.            {
  2329.              AddSrc(S2Reg); SetCross(S2Reg);
  2330.              DecodeAdr(&ArgStr[2], MModReg + MModImm, False, &S1Reg);
  2331.              switch (AdrMode)
  2332.              {
  2333.                case ModReg:
  2334.                  if (IsCross(S1Reg)) WrError(ErrNum_InvAddrMode);
  2335.                  else
  2336.                  {
  2337.                    AddSrc(S1Reg);
  2338.                    __erg = CodeS(0x27 + Code, DReg, S1Reg, S2Reg);
  2339.                  }
  2340.                  break;
  2341.                case ModImm:
  2342.                  __erg = CodeS(0x26 + Code, DReg, S1Reg, S2Reg);
  2343.                  break;
  2344.              }
  2345.            }
  2346.          }
  2347.          break;
  2348.        case ModLReg:
  2349.          AddLDest(DReg);
  2350.          if (DecodeAdr(&ArgStr[1], MModLReg, HasSign, &S2Reg))
  2351.          {
  2352.            if ((ThisCross) || (IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
  2353.            else
  2354.            {
  2355.              AddLSrc(S2Reg);
  2356.              DecodeAdr(&ArgStr[2], MModReg + MModImm, False, &S1Reg);
  2357.              switch (AdrMode)
  2358.              {
  2359.                case ModReg:
  2360.                  if (IsCross(S1Reg)) WrError(ErrNum_InvAddrMode);
  2361.                  else
  2362.                  {
  2363.                    AddSrc(S1Reg);
  2364.                    __erg = CodeS(0x25 + Code, DReg, S1Reg, S2Reg);
  2365.                  }
  2366.                  break;
  2367.                case ModImm:
  2368.                  __erg = CodeS(0x24 + Code, DReg, S1Reg, S2Reg);
  2369.                  break;
  2370.              }
  2371.            }
  2372.          }
  2373.          break;
  2374.      }
  2375.   }
  2376. }
  2377.  
  2378. static void DecodeSSHL(Word Code)
  2379. {
  2380.   LongWord DReg, S1Reg, S2Reg;
  2381.  
  2382.   UNUSED(Code);
  2383.  
  2384.   if (ChkArgCnt(3, 3))
  2385.   {
  2386.     if (DecodeAdr(&ArgStr[3], MModReg, True, &DReg))
  2387.      if (ChkUnit(DReg, S1, S2))
  2388.      {
  2389.        AddDest(DReg);
  2390.        if (DecodeAdr(&ArgStr[1], MModReg, True, &S2Reg))
  2391.        {
  2392.          if ((ThisCross) && (!IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
  2393.          else
  2394.          {
  2395.            AddSrc(S2Reg); SetCross(S2Reg);
  2396.            DecodeAdr(&ArgStr[2], MModReg + MModImm, False, &S1Reg);
  2397.            switch (AdrMode)
  2398.            {
  2399.              case ModReg:
  2400.                if (IsCross(S1Reg)) WrError(ErrNum_InvAddrMode);
  2401.                else
  2402.                {
  2403.                  AddSrc(S1Reg);
  2404.                  __erg = CodeS(0x23, DReg, S1Reg, S2Reg);
  2405.                }
  2406.                break;
  2407.              case ModImm:
  2408.                __erg = CodeS(0x22, DReg, S1Reg, S2Reg);
  2409.                break;
  2410.            }
  2411.          }
  2412.        }
  2413.      }
  2414.   }
  2415. }
  2416.  
  2417. static void DecodeSSUB(Word Code)
  2418. {
  2419.   LongWord DReg, S1Reg, S2Reg;
  2420.  
  2421.   UNUSED(Code);
  2422.  
  2423.   if (ChkArgCnt(3, 3))
  2424.   {
  2425.     DecodeAdr(&ArgStr[3], MModReg + MModLReg, True, &DReg);
  2426.     if ((AdrMode != ModNone) && (ChkUnit(DReg, L1, L2)))
  2427.      switch (AdrMode)
  2428.      {
  2429.        case ModReg:
  2430.         AddDest(DReg);
  2431.         DecodeAdr(&ArgStr[1], MModReg + MModImm, True, &S1Reg);
  2432.         switch (AdrMode)
  2433.         {
  2434.           case ModReg:
  2435.             AddSrc(S1Reg);
  2436.             if (DecodeAdr(&ArgStr[2], MModReg, True, &S2Reg))
  2437.             {
  2438.               if ((ThisCross) && (!IsCross(S1Reg)) && (!IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
  2439.               else if ((IsCross(S1Reg)) && (IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
  2440.               else if (IsCross(S1Reg))
  2441.               {
  2442.                 ThisCross = True;
  2443.                 __erg = CodeL(0x1f, DReg, S1Reg, S2Reg);
  2444.               }
  2445.               else
  2446.               {
  2447.                 SetCross(S2Reg);
  2448.                 __erg = CodeL(0x0f, DReg, S1Reg, S2Reg);
  2449.               }
  2450.             }
  2451.             break;
  2452.           case ModImm:
  2453.             if (DecodeAdr(&ArgStr[2], MModReg, True, &S2Reg))
  2454.             {
  2455.               if ((ThisCross) && (!IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
  2456.               else
  2457.               {
  2458.                 AddSrc(S2Reg); SetCross(S2Reg);
  2459.                 __erg = CodeL(0x0e, DReg, S1Reg, S2Reg);
  2460.               }
  2461.             }
  2462.             break;
  2463.         }
  2464.         break;
  2465.        case ModLReg:
  2466.         AddLDest(DReg);
  2467.          if (DecodeAdr(&ArgStr[1], MModImm, True, &S1Reg))
  2468.          {
  2469.            if (DecodeAdr(&ArgStr[2], MModLReg, True, &S2Reg))
  2470.            {
  2471.              if ((ThisCross) || (IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
  2472.              else
  2473.              {
  2474.                AddLSrc(S2Reg);
  2475.                __erg = CodeL(0x2c, DReg, S1Reg, S2Reg);
  2476.              }
  2477.            }
  2478.          }
  2479.          break;
  2480.      }
  2481.   }
  2482. }
  2483.  
  2484. /* Spruenge */
  2485.  
  2486. static void DecodeB(Word Code)
  2487. {
  2488.   LongWord S2Reg, Code1;
  2489.   LongInt Dist;
  2490.   Boolean WithImm, OK;
  2491.  
  2492.   UNUSED(Code);
  2493.  
  2494.   if (ArgCnt != 1) WrError(ErrNum_InvAddrMode);
  2495.   else if (ThisCross) WrError(ErrNum_InvAddrMode);
  2496.   else if ((ThisUnit != NoUnit) && (ThisUnit != S1) && (ThisUnit != S2)) WrError(ErrNum_InvAddrMode);
  2497.   else
  2498.   {
  2499.     OK = True;
  2500.     S2Reg = 0;
  2501.     WithImm = False;
  2502.     Code1 = 0;
  2503.     if (!as_strcasecmp(ArgStr[1].str.p_str, "IRP"))
  2504.     {
  2505.       Code1 = 0x03;
  2506.       S2Reg = 0x06;
  2507.     }
  2508.     else if (!as_strcasecmp(ArgStr[1].str.p_str, "NRP"))
  2509.     {
  2510.       Code1 = 0x03;
  2511.       S2Reg = 0x07;
  2512.     }
  2513.     else if (DecodeReg(ArgStr[1].str.p_str, &S2Reg, &OK, False))
  2514.     {
  2515.       if (OK) WrError(ErrNum_InvAddrMode);
  2516.       OK = !OK;
  2517.       Code1 = 0x0d;
  2518.     }
  2519.     else
  2520.       WithImm = OK = True;
  2521.     if (OK)
  2522.     {
  2523.       if (WithImm)
  2524.       {
  2525.         tSymbolFlags Flags;
  2526.  
  2527.         if (ThisUnit == NoUnit)
  2528.           ThisUnit = (UnitUsed(S1)) ? S2 : S1;
  2529.         UnitFlag = Ord(ThisUnit == S2);
  2530.  
  2531.         /* branches relative to fetch packet */
  2532.  
  2533.         Dist = EvalStrIntExpressionWithFlags(&ArgStr[1], Int32, &OK, &Flags) - (PacketAddr & (~31));
  2534.         if (OK)
  2535.         {
  2536.           if ((Dist & 3) != 0) WrError(ErrNum_NotAligned);
  2537.           else if (!mSymbolQuestionable(Flags) && ((Dist > 0x3fffff) || (Dist < -0x400000))) WrError(ErrNum_JmpDistTooBig);
  2538.           else
  2539.           {
  2540.             ThisInst = 0x10 + ((Dist & 0x007ffffc) << 5) + (UnitFlag << 1);
  2541.             ThisAbsBranch = True;
  2542.             __erg = True;
  2543.           }
  2544.         }
  2545.       }
  2546.       else
  2547.       {
  2548.         if (ChkUnit(0x10, S1, S2))
  2549.         {
  2550.           SetCross(S2Reg);
  2551.           __erg = CodeS(Code1, 0, 0, S2Reg);
  2552.         }
  2553.       }
  2554.     }
  2555.   }
  2556. }
  2557.  
  2558. static Boolean DecodeInst(void)
  2559. {
  2560.   __erg = False;
  2561.  
  2562.   /* ueber Tabelle: */
  2563.  
  2564.   if (LookupInstTable(InstTable, OpPart.str.p_str))
  2565.     return __erg;
  2566.  
  2567.   WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
  2568.   return False;
  2569. }
  2570.  
  2571. static void ChkPacket(void)
  2572. {
  2573.   LongWord EndAddr, Mask;
  2574.   LongInt z, z1, z2;
  2575.   Integer RegReads[32];
  2576.   char TestUnit[4];
  2577.   int BranchCnt;
  2578.  
  2579.   /* nicht ueber 8er-Grenze */
  2580.  
  2581.   EndAddr = PacketAddr + ((ParCnt << 2) - 1);
  2582.   if ((PacketAddr >> 5) != (EndAddr >> 5))
  2583.     WrError(ErrNum_PackCrossBoundary);
  2584.  
  2585.   /* doppelte Units,Crosspaths,Adressierer,Zielregister */
  2586.  
  2587.   for (z1 = 0; z1 < ParCnt; z1++)
  2588.     for (z2 = z1 + 1; z2 < ParCnt; z2++)
  2589.       if ((ParRecs[z1].OpCode >> 28) == (ParRecs[z2].OpCode >> 28))
  2590.       {
  2591.         /* doppelte Units */
  2592.  
  2593.         if ((ParRecs[z1].U != NoUnit) && (ParRecs[z1].U == ParRecs[z2].U))
  2594.           WrXError(ErrNum_UnitMultipleUsed, UnitNames[ParRecs[z1].U]);
  2595.  
  2596.         /* Crosspaths */
  2597.  
  2598.         z = ParRecs[z1].CrossUsed & ParRecs[z2].CrossUsed;
  2599.         if (z != 0)
  2600.         {
  2601.           *TestUnit = z + '0';
  2602.           TestUnit[1] = 'X';
  2603.           TestUnit[2] = '\0';
  2604.           WrXError(ErrNum_UnitMultipleUsed, TestUnit);
  2605.         }
  2606.  
  2607.         z = ParRecs[z1].AddrUsed & ParRecs[z2].AddrUsed;
  2608.  
  2609.         /* Adressgeneratoren */
  2610.  
  2611.         if ((z & 1) == 1) WrXError(ErrNum_UnitMultipleUsed, "Addr. A");
  2612.         if ((z & 2) == 2) WrXError(ErrNum_UnitMultipleUsed, "Addr. B");
  2613.  
  2614.         /* Hauptspeicherpfade */
  2615.  
  2616.         if ((z & 4) == 4) WrXError(ErrNum_UnitMultipleUsed, "LdSt. A");
  2617.         if ((z & 8) == 8) WrXError(ErrNum_UnitMultipleUsed, "LdSt. B");
  2618.  
  2619.         /* ueberlappende Zielregister */
  2620.  
  2621.         z = ParRecs[z1].DestMask & ParRecs[z2].DestMask;
  2622.         if (z != 0)
  2623.           WrXError(ErrNum_OverlapDests, RegName(FindReg(z)));
  2624.  
  2625.         if ((ParRecs[z1].U & 1) == (ParRecs[z2].U & 1))
  2626.         {
  2627.           TestUnit[0] = ParRecs[z1].U - NoUnit - 1 + 'A';
  2628.           TestUnit[1] = '\0';
  2629.  
  2630.           /* mehrere Long-Reads */
  2631.  
  2632.           if ((ParRecs[z1].LongSrc) && (ParRecs[z2].LongSrc))
  2633.             WrXError(ErrNum_MultipleLongRead, TestUnit);
  2634.  
  2635.           /* mehrere Long-Writes */
  2636.  
  2637.           if ((ParRecs[z1].LongDest) && (ParRecs[z2].LongDest))
  2638.             WrXError(ErrNum_MultipleLongWrite, TestUnit);
  2639.  
  2640.           /* Long-Read mit Store */
  2641.  
  2642.           if ((ParRecs[z1].StoreUsed) && (ParRecs[z2].LongSrc))
  2643.             WrXError(ErrNum_LongReadWithStore, TestUnit);
  2644.           if ((ParRecs[z2].StoreUsed) && (ParRecs[z1].LongSrc))
  2645.             WrXError(ErrNum_LongReadWithStore, TestUnit);
  2646.         }
  2647.       }
  2648.  
  2649.   for (z2 = 0; z2 < 32; z2++)
  2650.     RegReads[z2] = 0;
  2651.   for (z1 = 0; z1 < ParCnt; z1++)
  2652.   {
  2653.     Mask = 1;
  2654.     for (z2 = 0; z2 < 32; z2++)
  2655.     {
  2656.       if ((ParRecs[z1].SrcMask & Mask) != 0)
  2657.         RegReads[z2]++;
  2658.       if ((ParRecs[z1].SrcMask2 & Mask) != 0)
  2659.         RegReads[z2]++;
  2660.       Mask = Mask << 1;
  2661.     }
  2662.   }
  2663.  
  2664.   /* Register mehr als 4mal gelesen */
  2665.  
  2666.   for (z1 = 0; z1 < 32; z1++)
  2667.     if (RegReads[z1] > 4)
  2668.       WrXError(ErrNum_TooManyRegisterReads, RegName(z1));
  2669.  
  2670.   /* more than one branch to an absolute address */
  2671.  
  2672.   BranchCnt = 0;
  2673.   for (z1 = 0; z1 < ParCnt; z1++)
  2674.     if (ParRecs[z1].AbsBranch)
  2675.       BranchCnt++;
  2676.   if (BranchCnt > 1)
  2677.     WrError(ErrNum_TooManyBranchesInExPacket);
  2678. }
  2679.  
  2680. static void MakeCode_3206X(void)
  2681. {
  2682.   /* zu ignorierendes */
  2683.  
  2684.   if ((*OpPart.str.p_str == '\0') && (*LabPart.str.p_str == '\0'))
  2685.     return;
  2686.  
  2687.   /* Pseudoanweisungen */
  2688.  
  2689.   if (DecodePseudo())
  2690.     return;
  2691.  
  2692.   /* Flags zuruecksetzen */
  2693.  
  2694.   ThisPar = False;
  2695.     Condition = 0;
  2696.  
  2697.   /* Optionen aus Label holen */
  2698.  
  2699.   if (*LabPart.str.p_str != '\0')
  2700.     if ((!strcmp(LabPart.str.p_str, "||")) || (*LabPart.str.p_str == '['))
  2701.      if (!CheckOpt(LabPart.str.p_str))
  2702.        return;
  2703.  
  2704.   /* eventuell falsche Mnemonics verwerten */
  2705.  
  2706.   if (!strcmp(OpPart.str.p_str, "||"))
  2707.     if (!ReiterateOpPart())
  2708.       return;
  2709.   if (*OpPart.str.p_str == '[')
  2710.     if (!ReiterateOpPart())
  2711.       return;
  2712.  
  2713.   if (Memo(""))
  2714.     return;
  2715.  
  2716.   /* Attribut auswerten */
  2717.  
  2718.   ThisUnit = NoUnit;
  2719.   ThisCross = False;
  2720.   if (*AttrPart.str.p_str)
  2721.   {
  2722.     if (as_toupper(AttrPart.str.p_str[strlen(AttrPart.str.p_str) - 1]) == 'X')
  2723.     {
  2724.       ThisCross = True;
  2725.       AttrPart.str.p_str[strlen(AttrPart.str.p_str) - 1] = '\0';
  2726.     }
  2727.     if (*AttrPart.str.p_str == '\0') ThisUnit = NoUnit;
  2728.     else
  2729.       for (; ThisUnit != LastUnit; ThisUnit++)
  2730.         if (!as_strcasecmp(AttrPart.str.p_str, UnitNames[ThisUnit]))
  2731.           break;
  2732.     if (ThisUnit == LastUnit)
  2733.     {
  2734.       WrError(ErrNum_UndefAttr);
  2735.       return;
  2736.     }
  2737.     if (((ThisUnit == D1) || (ThisUnit == D2)) && (ThisCross))
  2738.     {
  2739.       WrError(ErrNum_InvAddrMode);
  2740.       return;
  2741.     }
  2742.   }
  2743.  
  2744.   /* falls nicht parallel, vorherigen Stack durchpruefen und verwerfen */
  2745.  
  2746.   if ((!ThisPar) && (ParCnt > 0))
  2747.   {
  2748.     ChkPacket();
  2749.     ParCnt = 0;
  2750.     PacketAddr = EProgCounter();
  2751.   }
  2752.  
  2753.   /* dekodieren */
  2754.  
  2755.   ThisSrc = 0;
  2756.   ThisSrc2 = 0;
  2757.   ThisDest = 0;
  2758.   ThisAddr = 0;
  2759.   ThisStore = ThisAbsBranch = False;
  2760.   ThisLong = 0;
  2761.   if (!DecodeInst())
  2762.     return;
  2763.  
  2764.   /* einsortieren */
  2765.  
  2766.   ParRecs[ParCnt].OpCode = (Condition << 28) + ThisInst;
  2767.   ParRecs[ParCnt].U = ThisUnit;
  2768.   if (ThisCross)
  2769.     switch (ThisUnit)
  2770.     {
  2771.       case L1: case S1: case M1: case D1:
  2772.         ParRecs[ParCnt].CrossUsed = 1;
  2773.         break;
  2774.       default:
  2775.         ParRecs[ParCnt].CrossUsed = 2;
  2776.     }
  2777.   else
  2778.     ParRecs[ParCnt].CrossUsed = 0;
  2779.   ParRecs[ParCnt].AddrUsed = ThisAddr;
  2780.   ParRecs[ParCnt].SrcMask = ThisSrc;
  2781.   ParRecs[ParCnt].SrcMask2 = ThisSrc2;
  2782.   ParRecs[ParCnt].DestMask = ThisDest;
  2783.   ParRecs[ParCnt].LongSrc = ((ThisLong & 1) == 1);
  2784.   ParRecs[ParCnt].LongDest = ((ThisLong & 2) == 2);
  2785.   ParRecs[ParCnt].StoreUsed = ThisStore;
  2786.   ParRecs[ParCnt].AbsBranch = ThisAbsBranch;
  2787.   ParCnt++;
  2788.  
  2789.   /* wenn mehr als eine Instruktion, Ressourcenkonflikte abklopfen und
  2790.     vorherige Instruktion zuruecknehmen */
  2791.  
  2792.   if (ParCnt > 1)
  2793.   {
  2794.     RetractWords(4);
  2795.     DAsmCode[CodeLen >> 2] = ParRecs[ParCnt - 2].OpCode | 1;
  2796.     CodeLen += 4;
  2797.   }
  2798.  
  2799.   /* aktuelle Instruktion auswerfen: fuer letzte kein Parallelflag setzen */
  2800.  
  2801.   DAsmCode[CodeLen >> 2] = ParRecs[ParCnt - 1].OpCode;
  2802.   CodeLen += 4;
  2803. }
  2804.  
  2805. /*-------------------------------------------------------------------------*/
  2806.  
  2807. static void AddLinAdd(const char *NName, LongInt NCode)
  2808. {
  2809.   order_array_rsv_end(LinAddOrders, FixedOrder);
  2810.   LinAddOrders[InstrZ].Code = NCode;
  2811.   AddInstTable(InstTable, NName, InstrZ++, DecodeLinAdd);
  2812. }
  2813.  
  2814. static void AddCmp(const char *NName, LongInt NCode)
  2815. {
  2816.   order_array_rsv_end(CmpOrders, CmpOrder);
  2817.   CmpOrders[InstrZ].WithImm = NName[strlen(NName) - 1] != 'U';
  2818.   CmpOrders[InstrZ].Code = NCode;
  2819.   AddInstTable(InstTable, NName, InstrZ++, DecodeCmp);
  2820. }
  2821.  
  2822. static void AddMem(const char *NName, LongInt NCode, LongInt NScale)
  2823. {
  2824.   order_array_rsv_end(MemOrders, MemOrder);
  2825.   MemOrders[InstrZ].Code = NCode;
  2826.   MemOrders[InstrZ].Scale = NScale;
  2827.   AddInstTable(InstTable,NName, InstrZ++, DecodeMemO);
  2828. }
  2829.  
  2830. static void AddMul(const char *NName, LongInt NCode,
  2831.                    Boolean NDSign, Boolean NSSign1, Boolean NSSign2, Boolean NMay)
  2832. {
  2833.   order_array_rsv_end(MulOrders, MulOrder);
  2834.   MulOrders[InstrZ].Code = NCode;
  2835.   MulOrders[InstrZ].DSign = NDSign;
  2836.   MulOrders[InstrZ].SSign1 = NSSign1;
  2837.   MulOrders[InstrZ].SSign2 = NSSign2;
  2838.   MulOrders[InstrZ].MayImm = NMay;
  2839.   AddInstTable(InstTable, NName, InstrZ++, DecodeMul);
  2840. }
  2841.  
  2842. static void AddCtrl(const char *NName, LongInt NCode,
  2843.                     Boolean NWr, Boolean NRd)
  2844. {
  2845.   order_array_rsv_end(CtrlRegs, CtrlReg);
  2846.   CtrlRegs[InstrZ].Name = NName;
  2847.   CtrlRegs[InstrZ].Code = NCode;
  2848.   CtrlRegs[InstrZ].Wr = NWr;
  2849.   CtrlRegs[InstrZ++].Rd = NRd;
  2850. }
  2851.  
  2852. static void InitFields(void)
  2853. {
  2854.   InstTable = CreateInstTable(203);
  2855.  
  2856.   AddInstTable(InstTable, "IDLE", 0, DecodeIDLE);
  2857.   AddInstTable(InstTable, "NOP", 0, DecodeNOP);
  2858.   AddInstTable(InstTable, "STP", 0, DecodeSTP);
  2859.   AddInstTable(InstTable, "ABS", 0, DecodeABS);
  2860.   AddInstTable(InstTable, "ADD", 0, DecodeADD);
  2861.   AddInstTable(InstTable, "ADDU", 0, DecodeADDU);
  2862.   AddInstTable(InstTable, "SUB", 0, DecodeSUB);
  2863.   AddInstTable(InstTable, "SUBU", 0, DecodeSUBU);
  2864.   AddInstTable(InstTable, "SUBC", 0, DecodeSUBC);
  2865.   AddInstTable(InstTable, "ADDK", 0, DecodeADDK);
  2866.   AddInstTable(InstTable, "ADD2", 0, DecodeADD2_SUB2);
  2867.   AddInstTable(InstTable, "SUB2", 1, DecodeADD2_SUB2);
  2868.   AddInstTable(InstTable, "AND", 0x1f7b, DecodeLogic);
  2869.   AddInstTable(InstTable, "OR", 0x1b7f, DecodeLogic);
  2870.   AddInstTable(InstTable, "XOR", 0x0b6f, DecodeLogic);
  2871.   AddInstTable(InstTable, "MV", 0, DecodeMV);
  2872.   AddInstTable(InstTable, "NEG", 0, DecodeNEG);
  2873.   AddInstTable(InstTable, "NOT", 0, DecodeNOT);
  2874.   AddInstTable(InstTable, "ZERO", 0, DecodeZERO);
  2875.   AddInstTable(InstTable, "CLR",  0x3fc8, DecodeCLR_EXT_EXTU_SET);
  2876.   AddInstTable(InstTable, "EXT",  0x2f48, DecodeCLR_EXT_EXTU_SET);
  2877.   AddInstTable(InstTable, "EXTU", 0x2b08, DecodeCLR_EXT_EXTU_SET);
  2878.   AddInstTable(InstTable, "SET",  0x3b88, DecodeCLR_EXT_EXTU_SET);
  2879.   AddInstTable(InstTable, "LMBD", 0, DecodeLMBD);
  2880.   AddInstTable(InstTable, "NORM", 0, DecodeNORM);
  2881.   AddInstTable(InstTable, "SADD", 0, DecodeSADD);
  2882.   AddInstTable(InstTable, "SAT", 0, DecodeSAT);
  2883.   AddInstTable(InstTable, "MVC", 0, DecodeMVC);
  2884.   AddInstTable(InstTable, "MVKL", 0x0028, DecodeMVK);
  2885.   AddInstTable(InstTable, "MVK", 0x0028, DecodeMVK);
  2886.   AddInstTable(InstTable, "MVKH", 0x1068, DecodeMVK);
  2887.   AddInstTable(InstTable, "MVKLH", 0x0068, DecodeMVK);
  2888.   AddInstTable(InstTable, "SHL", 0, DecodeSHL);
  2889.   AddInstTable(InstTable, "SHR", 16, DecodeSHR_SHRU);
  2890.   AddInstTable(InstTable, "SHRU", 0, DecodeSHR_SHRU);
  2891.   AddInstTable(InstTable, "SSHL", 0, DecodeSSHL);
  2892.   AddInstTable(InstTable, "SSUB", 0, DecodeSSUB);
  2893.   AddInstTable(InstTable, "B", 0, DecodeB);
  2894.  
  2895.   InstrZ = 0;
  2896.   AddLinAdd("ADDAB", 0x30); AddLinAdd("ADDAH", 0x34); AddLinAdd("ADDAW", 0x38);
  2897.   AddLinAdd("SUBAB", 0x31); AddLinAdd("SUBAH", 0x35); AddLinAdd("SUBAW", 0x39);
  2898.  
  2899.   InstrZ = 0;
  2900.   AddCmp("CMPEQ", 0x50); AddCmp("CMPGT", 0x44); AddCmp("CMPGTU", 0x4c);
  2901.   AddCmp("CMPLT", 0x54); AddCmp("CMPLTU", 0x5c);
  2902.  
  2903.   InstrZ = 0;
  2904.   AddMem("LDB", 2, 1);  AddMem("LDH", 4, 2);  AddMem("LDW", 6, 4);
  2905.   AddMem("LDBU", 1, 1); AddMem("LDHU", 0, 2); AddMem("STB", 3, 1);
  2906.   AddMem("STH", 5, 2);  AddMem("STW", 7, 4);
  2907.  
  2908.   InstrZ = 0;
  2909.   AddMul("MPY"    , 0x19, True , True , True , True );
  2910.   AddMul("MPYU"   , 0x1f, False, False, False, False);
  2911.   AddMul("MPYUS"  , 0x1d, True , False, True , False);
  2912.   AddMul("MPYSU"  , 0x1b, True , True , False, True );
  2913.   AddMul("MPYH"   , 0x01, True , True , True , False);
  2914.   AddMul("MPYHU"  , 0x07, False, False, False, False);
  2915.   AddMul("MPYHUS" , 0x05, True , False, True , False);
  2916.   AddMul("MPYHSU" , 0x03, True , True , False, False);
  2917.   AddMul("MPYHL"  , 0x09, True , True , True , False);
  2918.   AddMul("MPYHLU" , 0x0f, False, False, False, False);
  2919.   AddMul("MPYHULS", 0x0d, True , False, True , False);
  2920.   AddMul("MPYHSLU", 0x0b, True , True , False, False);
  2921.   AddMul("MPYLH"  , 0x11, True , True , True , False);
  2922.   AddMul("MPYLHU" , 0x17, False, False, False, False);
  2923.   AddMul("MPYLUHS", 0x15, True , False, True , False);
  2924.   AddMul("MPYLSHU", 0x13, True , True , False, False);
  2925.   AddMul("SMPY"   , 0x1a, True , True , True , False);
  2926.   AddMul("SMPYHL" , 0x0a, True , True , True , False);
  2927.   AddMul("SMPYLH" , 0x12, True , True , True , False);
  2928.   AddMul("SMPYH"  , 0x02, True , True , True , False);
  2929.  
  2930.   InstrZ = 0;
  2931.   AddCtrl("AMR"    ,  0, True , True );
  2932.   AddCtrl("CSR"    ,  1, True , True );
  2933.   AddCtrl("IFR"    ,  2, False, True );
  2934.   AddCtrl("ISR"    ,  2, True , False);
  2935.   AddCtrl("ICR"    ,  3, True , False);
  2936.   AddCtrl("IER"    ,  4, True , True );
  2937.   AddCtrl("ISTP"   ,  5, True , True );
  2938.   AddCtrl("IRP"    ,  6, True , True );
  2939.   AddCtrl("NRP"    ,  7, True , True );
  2940.   AddCtrl("IN"     ,  8, False, True );
  2941.   AddCtrl("OUT"    ,  9, True , True );
  2942.   AddCtrl("PCE1"   , 16, False, True );
  2943.   AddCtrl("PDATA_O", 15, True , True );
  2944.   AddCtrl(NULL     ,  0, False, False);
  2945. }
  2946.  
  2947. static void DeinitFields(void)
  2948. {
  2949.   DestroyInstTable(InstTable);
  2950.   order_array_free(LinAddOrders);
  2951.   order_array_free(CmpOrders);
  2952.   order_array_free(MemOrders);
  2953.   order_array_free(MulOrders);
  2954.   order_array_free(CtrlRegs);
  2955. }
  2956.  
  2957. /*------------------------------------------------------------------------*/
  2958.  
  2959. static Boolean IsDef_3206X(void)
  2960. {
  2961.   return (!strcmp(LabPart.str.p_str, "||")) || (*LabPart.str.p_str == '[');
  2962. }
  2963.  
  2964. static void SwitchFrom_3206X(void)
  2965. {
  2966.   if (ParCnt > 1)
  2967.     ChkPacket();
  2968.   DeinitFields();
  2969.   if (ParRecs)
  2970.   {
  2971.     free(ParRecs);
  2972.     ParRecs = NULL;
  2973.   }
  2974. }
  2975.  
  2976. static Boolean Chk34Arg(void)
  2977. {
  2978.   return (ArgCnt >= 3);
  2979. }
  2980.  
  2981. static void SwitchTo_3206X(void)
  2982. {
  2983.   TurnWords = False;
  2984.   SetIntConstMode(eIntConstModeIntel);
  2985.   SetIsOccupiedFnc = Chk34Arg;
  2986.  
  2987.   PCSymbol = "$";
  2988.   HeaderID = 0x47;
  2989.   NOPCode = 0x00000000;
  2990.   DivideChars = ",";
  2991.   HasAttrs = True;
  2992.   AttrChars = ".";
  2993.  
  2994.   ValidSegs = 1 << SegCode;
  2995.   Grans[SegCode] = 1; ListGrans[SegCode] = 4; SegInits[SegCode] = 0;
  2996.   SegLimits[SegCode] = (LargeWord)IntTypeDefs[UInt32].Max;
  2997.  
  2998.   MakeCode = MakeCode_3206X;
  2999.   IsDef = IsDef_3206X;
  3000.   SwitchFrom = SwitchFrom_3206X;
  3001.   ParRecs = (InstrRec*)malloc(sizeof(InstrRec) * MaxParCnt);
  3002.   InitFields();
  3003.  
  3004.   onoff_packing_add(True);
  3005.  
  3006.   ParCnt = 0;
  3007.   PacketAddr = 0;
  3008. }
  3009.  
  3010. void code3206x_init(void)
  3011. {
  3012.   CPU32060 = AddCPU("32060", SwitchTo_3206X);
  3013. }
  3014.