Subversion Repositories pentevo

Rev

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

  1. /* code7000.c */
  2. /*****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
  4. /*                                                                           */
  5. /* AS-Portierung                                                             */
  6. /*                                                                           */
  7. /* Codegenerator SH7x00                                                      */
  8. /*                                                                           */
  9. /*****************************************************************************/
  10.  
  11. #include "stdinc.h"
  12.  
  13. #include <ctype.h>
  14. #include <string.h>
  15.  
  16. #include "bpemu.h"
  17. #include "strutil.h"
  18. #include "asmdef.h"
  19. #include "asmsub.h"
  20. #include "asmpars.h"
  21. #include "asmallg.h"
  22. #include "literals.h"
  23. #include "onoff_common.h"
  24. #include "asmitree.h"
  25. #include "codepseudo.h"
  26. #include "motpseudo.h"
  27. #include "codevars.h"
  28. #include "errmsg.h"
  29.  
  30. #include "code7000.h"
  31.  
  32. enum
  33. {
  34.   ModNone = -1,
  35.   ModReg = 0,
  36.   ModIReg = 1,
  37.   ModPreDec = 2,
  38.   ModPostInc = 3,
  39.   ModIndReg = 4,
  40.   ModR0Base = 5,
  41.   ModGBRBase = 6,
  42.   ModGBRR0 = 7,
  43.   ModPCRel = 8,
  44.   ModImm = 9
  45. };
  46.  
  47. #define MModReg (1 << ModReg)
  48. #define MModIReg (1 << ModIReg)
  49. #define MModPreDec (1 << ModPreDec)
  50. #define MModPostInc (1 << ModPostInc)
  51. #define MModIndReg (1 << ModIndReg)
  52. #define MModR0Base (1 << ModR0Base)
  53. #define MModGBRBase (1 << ModGBRBase)
  54. #define MModGBRR0 (1 << ModGBRR0)
  55. #define MModPCRel (1 << ModPCRel)
  56. #define MModImm (1 << ModImm)
  57.  
  58. #define REG_SP 15
  59. #define RegNone (-1)
  60. #define RegPC (-2)
  61. #define RegGBR (-3)
  62.  
  63. #define CompLiteralsName "COMPRESSEDLITERALS"
  64.  
  65. typedef struct
  66. {
  67.   CPUVar MinCPU;
  68.   Boolean Priv;
  69.   Word Code;
  70. } FixedOrder;
  71.  
  72. typedef struct
  73. {
  74.   CPUVar MinCPU;
  75.   Boolean Priv;
  76.   Word Code;
  77.   Boolean Delayed;
  78. } OneRegOrder;
  79.  
  80. typedef struct
  81. {
  82.   CPUVar MinCPU;
  83.   Boolean Priv;
  84.   Word Code;
  85.   ShortInt DefSize;
  86. } TwoRegOrder;
  87.  
  88. typedef struct
  89. {
  90.   CPUVar MinCPU;
  91.   Word Code;
  92. } FixedMinOrder;
  93.  
  94. typedef struct
  95. {
  96.    const char *Name;
  97.    Word Code;
  98.    CPUVar MinCPU;
  99.    Boolean NeedsDSP;
  100. } TRegDef;
  101.  
  102. static tSymbolSize OpSize;  /* Groesse=8*(2^OpSize) */
  103. static ShortInt AdrMode;    /* Ergebnisadressmodus */
  104. static Word AdrPart;        /* Adressierungsmodusbits im Opcode */
  105.  
  106. static CPUVar CPU7000, CPU7600, CPU7700;
  107.  
  108. static FixedOrder *FixedOrders;
  109. static OneRegOrder *OneRegOrders;
  110. static TwoRegOrder *TwoRegOrders;
  111. static FixedMinOrder *MulRegOrders;
  112. static FixedOrder *BWOrders;
  113. static TRegDef *RegDefs;
  114.  
  115. static Boolean CurrDelayed, PrevDelayed, CompLiterals, DSPAvail;
  116. static LongInt DelayedAdr;
  117.  
  118. /*-------------------------------------------------------------------------*/
  119. /* die PC-relative Adresse: direkt nach verzoegerten Spruengen = Sprungziel+2 */
  120.  
  121. static LongInt PCRelAdr(void)
  122. {
  123.   if (PrevDelayed) return DelayedAdr + 2;
  124.   else return EProgCounter() + 4;
  125. }
  126.  
  127. static void ChkDelayed(void)
  128. {
  129.   if (PrevDelayed) WrError(ErrNum_Pipeline);
  130. }
  131.  
  132. /*-------------------------------------------------------------------------*/
  133. /* Adressparsing */
  134.  
  135. static void SetOpSize(tSymbolSize Size)
  136. {
  137.   if (OpSize == eSymbolSizeUnknown) OpSize = Size;
  138.   else if (Size != OpSize)
  139.   {
  140.     WrError(ErrNum_ConfOpSizes); AdrMode = ModNone;
  141.   }
  142. }
  143.  
  144. /*!------------------------------------------------------------------------
  145.  * \fn     DecodeRegCore(const char *pArg, Word *pResult)
  146.  * \brief  check whether argument is a CPU register
  147.  * \param  pArg source argument
  148.  * \param  pResult register # if yes
  149.  * \return True if yes
  150.  * ------------------------------------------------------------------------ */
  151.  
  152. static Boolean DecodeRegCore(const char *pArg, Word *pResult)
  153. {
  154.   size_t l;
  155.   Boolean OK;
  156.  
  157.   if (!as_strcasecmp(pArg, "SP"))
  158.   {
  159.     *pResult = REG_SP | REGSYM_FLAG_ALIAS;
  160.     return True;
  161.   }
  162.  
  163.   l = strlen(pArg);
  164.   if ((l < 2) || (l > 3) || (as_toupper(*pArg) != 'R'))
  165.     return False;
  166.  
  167.   *pResult = ConstLongInt(pArg + 1, &OK, 10);
  168.   return OK && (*pResult <= 15);
  169. }
  170.  
  171. /*!------------------------------------------------------------------------
  172.  * \fn     DissectReg_7000(char *pDest, size_t DestSize, tRegInt Value, tSymbolSize InpSize)
  173.  * \brief  dissect register symbols - SH7x00 variant
  174.  * \param  pDest destination buffer
  175.  * \param  DestSize destination buffer size
  176.  * \param  Value numeric register value
  177.  * \param  InpSize register size
  178.  * ------------------------------------------------------------------------ */
  179.  
  180. static void DissectReg_7000(char *pDest, size_t DestSize, tRegInt Value, tSymbolSize InpSize)
  181. {
  182.   switch (InpSize)
  183.   {
  184.     case eSymbolSize32Bit:
  185.       if (Value == (REG_SP | REGSYM_FLAG_ALIAS))
  186.         as_snprintf(pDest, DestSize, "SP");
  187.       else
  188.         as_snprintf(pDest, DestSize, "R%u", (unsigned)Value);
  189.       break;
  190.     default:
  191.       as_snprintf(pDest, DestSize, "%d-%u", (int)InpSize, (unsigned)Value);
  192.   }
  193. }
  194.  
  195. /*!------------------------------------------------------------------------
  196.  * \fn     DecodeReg(const tStrComp *pArg, Word *pResult, Boolean MustBeReg)
  197.  * \brief  check whether argument is a CPU register or register alias
  198.  * \param  pArg source argument
  199.  * \param  pResult register # if yes
  200.  * \return eval result
  201.  * ------------------------------------------------------------------------ */
  202.  
  203. static tRegEvalResult DecodeReg(const tStrComp *pArg, Word *pResult, Boolean MustBeReg)
  204. {
  205.   tRegEvalResult RegEvalResult;
  206.   tEvalResult EvalResult;
  207.   tRegDescr RegDescr;
  208.  
  209.   if (DecodeRegCore(pArg->str.p_str, pResult))
  210.   {
  211.     *pResult &= ~REGSYM_FLAG_ALIAS;
  212.     return eIsReg;
  213.   }
  214.  
  215.   RegEvalResult = EvalStrRegExpressionAsOperand(pArg, &RegDescr, &EvalResult, eSymbolSize32Bit, MustBeReg);
  216.   *pResult = RegDescr.Reg & ~REGSYM_FLAG_ALIAS;
  217.   return RegEvalResult;
  218. }
  219.  
  220. static Boolean DecodeCtrlReg(char *Asc, Word *Erg)
  221. {
  222.   CPUVar MinCPU = CPU7000;
  223.  
  224.   *Erg = 0xff;
  225.   if (!as_strcasecmp(Asc, "SR")) *Erg = 0;
  226.   else if (!as_strcasecmp(Asc, "GBR")) *Erg = 1;
  227.   else if (!as_strcasecmp(Asc, "VBR")) *Erg = 2;
  228.   else if (!as_strcasecmp(Asc, "SSR"))
  229.   {
  230.     *Erg = 3; MinCPU = CPU7700;
  231.   }
  232.   else if (!as_strcasecmp(Asc, "SPC"))
  233.   {
  234.     *Erg = 4; MinCPU = CPU7700;
  235.   }
  236.   else if ((strlen(Asc) == 7) && (as_toupper(*Asc) == 'R')
  237.       && (!as_strcasecmp(Asc + 2, "_BANK"))
  238.       && (Asc[1] >= '0') && (Asc[1] <= '7'))
  239.   {
  240.     *Erg = Asc[1] - '0' + 8; MinCPU = CPU7700;
  241.   }
  242.   if ((*Erg == 0xff) || (MomCPU < MinCPU))
  243.   {
  244.     WrXError(ErrNum_InvCtrlReg, Asc); return False;
  245.   }
  246.   else return True;
  247. }
  248.  
  249. static Boolean DecodeSReg(char *Asc, Word *Erg)
  250. {
  251.   int z;
  252.   Boolean Result = FALSE;
  253.  
  254.   for (z = 0; RegDefs[z].Name; z++)
  255.     if (!as_strcasecmp(Asc, RegDefs[z].Name))
  256.       break;
  257.   if (RegDefs[z].Name)
  258.   {
  259.     if (MomCPU < RegDefs[z].MinCPU);
  260.     else if ((!DSPAvail) && RegDefs[z].NeedsDSP);
  261.     else
  262.     {
  263.       Result = TRUE;
  264.       *Erg = RegDefs[z].Code;
  265.     }
  266.   }
  267.   return Result;
  268. }
  269.  
  270. static LongInt ExtOp(LongInt Inp, Byte Src, Boolean Signed)
  271. {
  272.   switch (Src)
  273.   {
  274.     case 0:
  275.       Inp &= 0xff;
  276.       break;
  277.     case 1:
  278.       Inp &= 0xffff;
  279.       break;
  280.   }
  281.   if (Signed)
  282.   {
  283.     if (Src < 1)
  284.       if ((Inp & 0x80) == 0x80)
  285.         Inp += 0xff00;
  286.     if (Src < 2)
  287.       if ((Inp & 0x8000) == 0x8000)
  288.         Inp += 0xffff0000;
  289.   }
  290.   return Inp;
  291. }
  292.  
  293. static LongInt OpMask(ShortInt OpSize)
  294. {
  295.   switch (OpSize)
  296.   {
  297.     case eSymbolSize8Bit:
  298.       return 0xff;
  299.     case eSymbolSize16Bit:
  300.       return 0xffff;
  301.     case eSymbolSize32Bit:
  302.       return 0xffffffff;
  303.     default:
  304.       return 0;
  305.   }
  306. }
  307.  
  308. static void DecodeAdr(const tStrComp *pArg, Word Mask, Boolean Signed)
  309. {
  310.   Word HReg;
  311.   char *pos;
  312.   ShortInt BaseReg, IndReg;
  313.   tSymbolSize DOpSize;
  314.   LongInt DispAcc;
  315.   Boolean OK, FirstFlag;
  316.   tSymbolFlags Flags;
  317.  
  318.   AdrMode = ModNone;
  319.  
  320.   switch (DecodeReg(pArg, &HReg, False))
  321.   {
  322.     case eIsReg:
  323.       AdrPart = HReg;
  324.       AdrMode = ModReg;
  325.       goto chk;
  326.     case eIsNoReg:
  327.       break;
  328.     case eRegAbort:
  329.       return;
  330.   }
  331.  
  332.   if (*pArg->str.p_str == '@')
  333.   {
  334.     tStrComp Arg;
  335.  
  336.     StrCompRefRight(&Arg, pArg, 1);
  337.     if (IsIndirect(Arg.str.p_str))
  338.     {
  339.       tStrComp Remainder;
  340.  
  341.       StrCompIncRefLeft(&Arg, 1);
  342.       StrCompShorten(&Arg, 1);
  343.       BaseReg = RegNone;
  344.       IndReg = RegNone;
  345.       DispAcc = 0;
  346.       FirstFlag = False;
  347.       OK = True;
  348.       do
  349.       {
  350.         pos = QuotPos(Arg.str.p_str, ',');
  351.         if (pos)
  352.           StrCompSplitRef(&Arg, &Remainder, &Arg, pos);
  353.         if (!as_strcasecmp(Arg.str.p_str, "PC"))
  354.         {
  355.           if (BaseReg == RegNone)
  356.             BaseReg = RegPC;
  357.           else
  358.           {
  359.             WrError(ErrNum_InvAddrMode);
  360.             OK = False;
  361.           }
  362.         }
  363.         else if (!as_strcasecmp(Arg.str.p_str, "GBR"))
  364.         {
  365.           if (BaseReg == RegNone)
  366.             BaseReg = RegGBR;
  367.           else
  368.           {
  369.             WrError(ErrNum_InvAddrMode);
  370.             OK = False;
  371.           }
  372.         }
  373.         else switch (DecodeReg(&Arg, &HReg, False))
  374.         {
  375.           case eIsReg:
  376.             if (IndReg == RegNone)
  377.               IndReg = HReg;
  378.             else if ((BaseReg == RegNone) && (HReg == 0))
  379.               BaseReg = 0;
  380.             else if ((IndReg == 0) && (BaseReg == RegNone))
  381.             {
  382.               BaseReg = 0;
  383.               IndReg = HReg;
  384.             }
  385.             else
  386.             {
  387.               WrStrErrorPos(ErrNum_InvAddrMode, &Arg); OK = False;
  388.             }
  389.             break;
  390.           case eIsNoReg:
  391.             DispAcc += EvalStrIntExpressionWithFlags(&Arg, Int32, &OK, &Flags);
  392.             if (mFirstPassUnknown(Flags))
  393.               FirstFlag = True;
  394.             break;
  395.           case eRegAbort:
  396.             OK = False;
  397.         }
  398.         if (pos)
  399.           Arg = Remainder;
  400.       }
  401.       while (pos && OK);
  402.       if (FirstFlag) DispAcc = 0;
  403.       if ((OK) && ((DispAcc & ((1 << OpSize) - 1)) != 0))
  404.       {
  405.         WrError(ErrNum_NotAligned);
  406.         OK = False;
  407.       }
  408.       else if ((OK) && (DispAcc < 0))
  409.       {
  410.         WrXError(ErrNum_UnderRange, "Disp<0");
  411.         OK = False;
  412.       }
  413.       else DispAcc = DispAcc >> OpSize;
  414.       if (OK)
  415.       {
  416.         switch (BaseReg)
  417.         {
  418.           case 0:
  419.             if ((IndReg < 0) || (DispAcc != 0)) WrError(ErrNum_InvAddrMode);
  420.             else
  421.             {
  422.               AdrMode = ModR0Base;
  423.               AdrPart = IndReg;
  424.             }
  425.             break;
  426.           case RegGBR:
  427.             if ((IndReg == 0) && (DispAcc == 0)) AdrMode = ModGBRR0;
  428.             else if (IndReg != RegNone) WrError(ErrNum_InvAddrMode);
  429.             else if (DispAcc > 255) WrError(ErrNum_OverRange);
  430.             else
  431.             {
  432.               AdrMode = ModGBRBase;
  433.               AdrPart = DispAcc;
  434.             }
  435.             break;
  436.           case RegNone:
  437.             if (IndReg == RegNone) WrError(ErrNum_InvAddrMode);
  438.             else if (DispAcc > 15) WrError(ErrNum_OverRange);
  439.             else
  440.             {
  441.               AdrMode = ModIndReg;
  442.               AdrPart = (IndReg << 4) + DispAcc;
  443.             }
  444.             break;
  445.           case RegPC:
  446.             if (IndReg != RegNone) WrError(ErrNum_InvAddrMode);
  447.             else if (DispAcc > 255) WrError(ErrNum_OverRange);
  448.             else
  449.             {
  450.               AdrMode = ModPCRel;
  451.               AdrPart = DispAcc;
  452.             }
  453.             break;
  454.         }
  455.       }
  456.       goto chk;
  457.     }
  458.     else /* !IsIndirect */
  459.     {
  460.       int ArgLen = strlen(Arg.str.p_str);
  461.  
  462.       if ((ArgLen > 1) && (*Arg.str.p_str == '-'))
  463.       {
  464.         StrCompIncRefLeft(&Arg, 1);
  465.         if (DecodeReg(&Arg, &HReg, True) == eIsReg)
  466.         {
  467.           AdrPart = HReg;
  468.           AdrMode = ModPreDec;
  469.         }
  470.       }
  471.       else if ((ArgLen > 1) && (Arg.str.p_str[ArgLen - 1] == '+'))
  472.       {
  473.         StrCompShorten(&Arg, 1);
  474.         if (DecodeReg(&Arg, &HReg, True) == eIsReg)
  475.         {
  476.           AdrPart = HReg;
  477.           AdrMode = ModPostInc;
  478.         }
  479.       }
  480.       else if (DecodeReg(&Arg, &HReg, True))
  481.       {
  482.         AdrPart = HReg;
  483.         AdrMode = ModIReg;
  484.       }
  485.       goto chk;
  486.     }
  487.   }
  488.  
  489.   if (*pArg->str.p_str == '#')
  490.   {
  491.     switch (OpSize)
  492.     {
  493.       case eSymbolSize8Bit:
  494.         DispAcc = EvalStrIntExpressionOffsWithFlags(pArg, 1, Int8, &OK, &Flags);
  495.         break;
  496.       case eSymbolSize16Bit:
  497.         DispAcc = EvalStrIntExpressionOffsWithFlags(pArg, 1, Int16, &OK, &Flags);
  498.         break;
  499.       case eSymbolSize32Bit:
  500.         DispAcc = EvalStrIntExpressionOffsWithFlags(pArg, 1, Int32, &OK, &Flags);
  501.         break;
  502.       default:
  503.         DispAcc = 0;
  504.         OK = True;
  505.         Flags = eSymbolFlag_None;
  506.     }
  507.     if (OK)
  508.     {
  509.       Boolean Critical = mFirstPassUnknown(Flags) || mUsesForwards(Flags);
  510.  
  511.       /* minimale Groesse optimieren */
  512.  
  513.       DOpSize = (OpSize == eSymbolSize8Bit) ? eSymbolSize8Bit : (Critical ? eSymbolSize16Bit : eSymbolSize8Bit);
  514.       while (((ExtOp(DispAcc, DOpSize, Signed) ^ DispAcc) & OpMask(OpSize)) != 0)
  515.         DOpSize++;
  516.       if (DOpSize == 0)
  517.       {
  518.         AdrPart = DispAcc & 0xff;
  519.         AdrMode = ModImm;
  520.       }
  521.       else if (Mask & MModPCRel)
  522.       {
  523.         tStrComp LStrComp;
  524.         String LStr;
  525.         tSymbolSize lit_size;
  526.         Byte data_offset = 0;
  527.  
  528.         StrCompMkTemp(&LStrComp, LStr, sizeof(LStr));
  529.  
  530.         lit_size = (DOpSize == 2) ? eSymbolSize32Bit : eSymbolSize16Bit;
  531.  
  532.         literal_make(&LStrComp, &data_offset, DispAcc, lit_size, Critical);
  533.  
  534.         /* Distanz abfragen - im naechsten Pass... */
  535.  
  536.         DispAcc = EvalStrIntExpressionWithFlags(&LStrComp, Int32, &OK, &Flags) + data_offset;
  537.         if (OK)
  538.         {
  539.           if (mFirstPassUnknown(Flags))
  540.             DispAcc = 0;
  541.           else if (lit_size == eSymbolSize32Bit)
  542.             DispAcc = (DispAcc - (PCRelAdr() & 0xfffffffc)) >> 2;
  543.           else
  544.             DispAcc = (DispAcc - PCRelAdr()) >> 1;
  545.           if (DispAcc < 0)
  546.           {
  547.             WrXError(ErrNum_UnderRange, "Disp<0");
  548.             OK = False;
  549.           }
  550.           else if ((DispAcc > 255) && !mSymbolQuestionable(Flags)) WrError(ErrNum_DistTooBig);
  551.           else
  552.           {
  553.             AdrMode = ModPCRel;
  554.             AdrPart = DispAcc;
  555.             OpSize = lit_size;
  556.           }
  557.         }
  558.       }
  559.       else
  560.         WrError(ErrNum_InvAddrMode);
  561.     }
  562.     goto chk;
  563.   }
  564.  
  565.   /* absolut ueber PC-relativ abwickeln */
  566.  
  567.   if ((OpSize != eSymbolSize16Bit) && (OpSize != eSymbolSize32Bit)) WrError(ErrNum_InvOpSize);
  568.   else
  569.   {
  570.     DispAcc = EvalStrIntExpressionWithFlags(pArg, Int32, &OK, &Flags);
  571.     if (mFirstPassUnknown(Flags))
  572.       DispAcc = 0;
  573.     else if (OpSize == eSymbolSize32Bit)
  574.       DispAcc -= (PCRelAdr() & 0xfffffffc);
  575.     else
  576.       DispAcc -= PCRelAdr();
  577.     if (DispAcc < 0)
  578.       WrXError(ErrNum_UnderRange, "Disp<0");
  579.     else if ((DispAcc & ((1 << OpSize) - 1)) != 0)
  580.       WrError(ErrNum_NotAligned);
  581.     else
  582.     {
  583.       DispAcc = DispAcc >> OpSize;
  584.       if (DispAcc > 255) WrError(ErrNum_OverRange);
  585.       else
  586.       {
  587.         AdrMode = ModPCRel;
  588.         AdrPart = DispAcc;
  589.       }
  590.     }
  591.   }
  592.  
  593. chk:
  594.   if ((AdrMode != ModNone) && ((Mask & (1 << AdrMode)) == 0))
  595.   {
  596.     WrError(ErrNum_InvAddrMode);
  597.     AdrMode = ModNone;
  598.   }
  599. }
  600.  
  601. static void SetCode(Word Code)
  602. {
  603.   CodeLen = 2;
  604.   WAsmCode[0] = Code;
  605. }
  606.  
  607. /*-------------------------------------------------------------------------*/
  608. /* Instruction Decoders */
  609.  
  610. static void DecodeFixed(Word Index)
  611. {
  612.   const FixedOrder *pOrder = FixedOrders + Index;
  613.  
  614.   if (!ChkArgCnt(0, 0));
  615.   else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  616.   else if (ChkMinCPU(pOrder->MinCPU))
  617.   {
  618.     SetCode(pOrder->Code);
  619.     if ((!SupAllowed) && (pOrder->Priv)) WrError(ErrNum_PrivOrder);
  620.   }
  621. }
  622.  
  623. static void DecodeMOV(Word Code)
  624. {
  625.   Word HReg;
  626.  
  627.   UNUSED(Code);
  628.  
  629.   if (OpSize == eSymbolSizeUnknown)
  630.     SetOpSize(eSymbolSize32Bit);
  631.   if (!ChkArgCnt(2, 2));
  632.   else if (OpSize > eSymbolSize32Bit) WrError(ErrNum_InvOpSize);
  633.   else if (DecodeReg(&ArgStr[1], &HReg, False) == eIsReg)
  634.   {
  635.     DecodeAdr(&ArgStr[2], MModReg | MModIReg | MModPreDec | MModIndReg | MModR0Base | MModGBRBase, True);
  636.     switch (AdrMode)
  637.     {
  638.       case ModReg:
  639.         if (OpSize != eSymbolSize32Bit) WrError(ErrNum_InvOpSize);
  640.         else
  641.           SetCode(0x6003 + (HReg << 4) + (AdrPart << 8));
  642.         break;
  643.       case ModIReg:
  644.         SetCode(0x2000 + (HReg  << 4) + (AdrPart << 8) + OpSize);
  645.         break;
  646.       case ModPreDec:
  647.         SetCode(0x2004 + (HReg << 4) + (AdrPart << 8) + OpSize);
  648.         break;
  649.       case ModIndReg:
  650.         if (OpSize == eSymbolSize32Bit)
  651.           SetCode(0x1000 + (HReg << 4) + (AdrPart & 15) + ((AdrPart & 0xf0) << 4));
  652.         else if (HReg != 0)
  653.           WrError(ErrNum_InvAddrMode);
  654.         else
  655.           SetCode(0x8000 + AdrPart + (((Word)OpSize) << 8));
  656.         break;
  657.       case ModR0Base:
  658.         SetCode(0x0004 + (AdrPart << 8) + (HReg << 4) + OpSize);
  659.         break;
  660.       case ModGBRBase:
  661.         if (HReg != 0)
  662.           WrError(ErrNum_InvAddrMode);
  663.         else
  664.           SetCode(0xc000 + AdrPart + (((Word)OpSize) << 8));
  665.         break;
  666.     }
  667.   }
  668.   else if (DecodeReg(&ArgStr[2], &HReg, False) == eIsReg)
  669.   {
  670.     DecodeAdr(&ArgStr[1], MModImm | MModPCRel | MModIReg | MModPostInc | MModIndReg | MModR0Base | MModGBRBase, True);
  671.     switch (AdrMode)
  672.     {
  673.       case ModIReg:
  674.         SetCode(0x6000 + (AdrPart << 4) + (((Word)HReg) << 8) + OpSize);
  675.         break;
  676.       case ModPostInc:
  677.         SetCode(0x6004 + (AdrPart << 4) + (((Word)HReg) << 8) + OpSize);
  678.         break;
  679.       case ModIndReg:
  680.         if (OpSize == eSymbolSize32Bit)
  681.           SetCode(0x5000 + (((Word)HReg) << 8) + AdrPart);
  682.         else if (HReg != 0)
  683.           WrError(ErrNum_InvAddrMode);
  684.         else
  685.           SetCode(0x8400 + AdrPart + (((Word)OpSize) << 8));
  686.         break;
  687.       case ModR0Base:
  688.         SetCode(0x000c + (AdrPart << 4) + (((Word)HReg) << 8) + OpSize);
  689.         break;
  690.       case ModGBRBase:
  691.         if (HReg != 0)
  692.           WrError(ErrNum_InvAddrMode);
  693.         else
  694.           SetCode(0xc400 + AdrPart + (((Word)OpSize) << 8));
  695.         break;
  696.       case ModPCRel:
  697.         if (OpSize == eSymbolSize8Bit)
  698.           WrError(ErrNum_InvAddrMode);
  699.         else
  700.           SetCode(0x9000 + (((Word)OpSize - 1) << 14) + (((Word)HReg) << 8) + AdrPart);
  701.         break;
  702.       case ModImm:
  703.         SetCode(0xe000 + (((Word)HReg) << 8) + AdrPart);
  704.         break;
  705.     }
  706.   }
  707.   else
  708.     WrError(ErrNum_InvAddrMode);
  709. }
  710.  
  711. static void DecodeMOVA(Word Code)
  712. {
  713.   Word HReg;
  714.  
  715.   UNUSED(Code);
  716.  
  717.   if (!ChkArgCnt(2, 2));
  718.   else if (!DecodeReg(&ArgStr[2], &HReg, True));
  719.   else if (HReg != 0) WrStrErrorPos(ErrNum_InvReg, &ArgStr[2]);
  720.   else
  721.   {
  722.     SetOpSize(eSymbolSize32Bit);
  723.     DecodeAdr(&ArgStr[1], MModPCRel, False);
  724.     if (AdrMode != ModNone)
  725.       SetCode(0xc700 + AdrPart);
  726.   }
  727. }
  728.  
  729. static void DecodePREF(Word Code)
  730. {
  731.   UNUSED(Code);
  732.  
  733.   if (!ChkArgCnt(1, 1));
  734.   else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  735.   else
  736.   {
  737.     DecodeAdr(&ArgStr[1], MModIReg, False);
  738.     if (AdrMode != ModNone)
  739.       SetCode(WAsmCode[0] = 0x0083 + (AdrPart << 8));
  740.   }
  741. }
  742.  
  743. static void DecodeLDC_STC(Word IsLDC)
  744. {
  745.   if (OpSize == eSymbolSizeUnknown)
  746.     SetOpSize(eSymbolSize32Bit);
  747.  
  748.   if (ChkArgCnt(2, 2))
  749.   {
  750.     tStrComp *pArg1 = IsLDC ? &ArgStr[2] : &ArgStr[1],
  751.              *pArg2 = IsLDC ? &ArgStr[1] : &ArgStr[2];
  752.     Word HReg;
  753.  
  754.     if (DecodeCtrlReg(pArg1->str.p_str, &HReg))
  755.     {
  756.       DecodeAdr(pArg2, MModReg | (IsLDC ? MModPostInc : MModPreDec), False);
  757.       switch (AdrMode)
  758.       {
  759.         case ModReg:
  760.           SetCode((IsLDC ? 0x400e : 0x0002) + (AdrPart << 8) + (HReg << 4));
  761.           break;
  762.         case ModPostInc:
  763.           SetCode(0x4007 + (AdrPart << 8) + (HReg << 4));
  764.           break;
  765.         case ModPreDec:
  766.           SetCode(0x4003 + (AdrPart << 8) + (HReg << 4));
  767.           break;
  768.       }
  769.       if ((AdrMode != ModNone) && (!SupAllowed))
  770.         WrError(ErrNum_PrivOrder);
  771.     }
  772.   }
  773. }
  774.  
  775. static void DecodeLDS_STS(Word IsLDS)
  776. {
  777.   if (OpSize == eSymbolSizeUnknown)
  778.     SetOpSize(eSymbolSize32Bit);
  779.  
  780.   if (ChkArgCnt(2, 2))
  781.   {
  782.     tStrComp *pArg1 = IsLDS ? &ArgStr[2] : &ArgStr[1],
  783.              *pArg2 = IsLDS ? &ArgStr[1] : &ArgStr[2];
  784.     Word HReg;
  785.  
  786.     if (!DecodeSReg(pArg1->str.p_str, &HReg)) WrError(ErrNum_InvCtrlReg);
  787.     else
  788.     {
  789.       DecodeAdr(pArg2, MModReg | (IsLDS ? MModPostInc : MModPreDec), False);
  790.       switch (AdrMode)
  791.       {
  792.         case ModReg:
  793.           SetCode((IsLDS << 14) + 0x000a + (AdrPart << 8) + (HReg << 4));
  794.           break;
  795.         case ModPostInc:
  796.           SetCode(0x4006 + (AdrPart << 8) + (HReg << 4));
  797.           break;
  798.         case ModPreDec:
  799.           SetCode(0x4002 + (AdrPart << 8) + (HReg << 4));
  800.           break;
  801.       }
  802.     }
  803.   }
  804. }
  805.  
  806. static void DecodeOneReg(Word Index)
  807. {
  808.   const OneRegOrder *pOrder = OneRegOrders + Index;
  809.  
  810.   if (!ChkArgCnt(1, 1));
  811.   else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  812.   else if (ChkMinCPU(pOrder->MinCPU))
  813.   {
  814.     DecodeAdr(&ArgStr[1], MModReg, False);
  815.     if (AdrMode != ModNone)
  816.       SetCode(pOrder->Code + (AdrPart << 8));
  817.     if ((!SupAllowed) && (pOrder->Priv)) WrError(ErrNum_PrivOrder);
  818.     if (pOrder->Delayed)
  819.     {
  820.       CurrDelayed = True;
  821.       DelayedAdr = 0x7fffffff;
  822.       ChkDelayed();
  823.     }
  824.   }
  825. }
  826.  
  827. static void DecodeTAS(Word Code)
  828. {
  829.   UNUSED(Code);
  830.  
  831.   if (OpSize == eSymbolSizeUnknown)
  832.     SetOpSize(eSymbolSize8Bit);
  833.   if (!ChkArgCnt(1, 1));
  834.   else if (OpSize != eSymbolSize8Bit) WrError(ErrNum_InvOpSize);
  835.   else
  836.   {
  837.     DecodeAdr(&ArgStr[1], MModIReg, False);
  838.     if (AdrMode != ModNone)
  839.       SetCode(0x401b + (AdrPart << 8));
  840.   }
  841. }
  842.  
  843. static void DecodeTwoReg(Word Index)
  844. {
  845.   const TwoRegOrder *pOrder = TwoRegOrders + Index;
  846.  
  847.   if (!ChkArgCnt(2, 2));
  848.   else if (*AttrPart.str.p_str && (OpSize != pOrder->DefSize)) WrError(ErrNum_UseLessAttr);
  849.   else if (ChkMinCPU(pOrder->MinCPU))
  850.   {
  851.     DecodeAdr(&ArgStr[1], MModReg, False);
  852.     if (AdrMode != ModNone)
  853.     {
  854.       WAsmCode[0] = pOrder->Code + (AdrPart << 4);
  855.       DecodeAdr(&ArgStr[2], MModReg, False);
  856.       if (AdrMode != ModNone)
  857.         SetCode(WAsmCode[0] + (((Word)AdrPart) << 8));
  858.       if ((!SupAllowed) && (pOrder->Priv))
  859.         WrError(ErrNum_PrivOrder);
  860.     }
  861.   }
  862. }
  863.  
  864. static void DecodeMulReg(Word Index)
  865. {
  866.   const FixedMinOrder *pOrder = MulRegOrders + Index;
  867.  
  868.   if (ChkArgCnt(2, 2)
  869.    && ChkMinCPU(pOrder->MinCPU))
  870.   {
  871.     if (!*AttrPart.str.p_str)
  872.       OpSize = eSymbolSize32Bit;
  873.     if (OpSize != eSymbolSize32Bit) WrError(ErrNum_InvOpSize);
  874.     else
  875.     {
  876.       DecodeAdr(&ArgStr[1], MModReg, False);
  877.       if (AdrMode != ModNone)
  878.       {
  879.         WAsmCode[0] = pOrder->Code + (AdrPart << 4);
  880.         DecodeAdr(&ArgStr[2], MModReg, False);
  881.         if (AdrMode != ModNone)
  882.           SetCode(WAsmCode[0] + (((Word)AdrPart) << 8));
  883.       }
  884.     }
  885.   }
  886. }
  887.  
  888. static void DecodeBW(Word Index)
  889. {
  890.   const FixedOrder *pOrder = BWOrders + Index;
  891.  
  892.   if (OpSize == eSymbolSizeUnknown)
  893.     SetOpSize(eSymbolSize16Bit);
  894.   if (!ChkArgCnt(2, 2));
  895.   else if ((OpSize != eSymbolSize8Bit) && (OpSize != eSymbolSize16Bit)) WrError(ErrNum_InvOpSize);
  896.   else
  897.   {
  898.     DecodeAdr(&ArgStr[1], MModReg, False);
  899.     if (AdrMode != ModNone)
  900.     {
  901.       WAsmCode[0] = pOrder->Code + OpSize + (AdrPart << 4);
  902.       DecodeAdr(&ArgStr[2], MModReg, False);
  903.       if (AdrMode != ModNone)
  904.         SetCode(WAsmCode[0] + (((Word)AdrPart) << 8));
  905.     }
  906.   }
  907. }
  908.  
  909. static void DecodeMAC(Word Code)
  910. {
  911.   UNUSED(Code);
  912.  
  913.   if (OpSize == eSymbolSizeUnknown)
  914.     SetOpSize(eSymbolSize16Bit);
  915.   if (!ChkArgCnt(2, 2));
  916.   else if ((OpSize != eSymbolSize16Bit) && (OpSize != eSymbolSize32Bit)) WrError(ErrNum_InvOpSize);
  917.   else if ((OpSize == eSymbolSize32Bit) && !ChkMinCPU(CPU7600));
  918.   else
  919.   {
  920.     DecodeAdr(&ArgStr[1], MModPostInc, False);
  921.     if (AdrMode != ModNone)
  922.     {
  923.       WAsmCode[0] = 0x000f + (AdrPart << 4) + (((Word)2 - OpSize) << 14);
  924.       DecodeAdr(&ArgStr[2], MModPostInc, False);
  925.       if (AdrMode != ModNone)
  926.         SetCode(WAsmCode[0] + (((Word)AdrPart) << 8));
  927.     }
  928.   }
  929. }
  930.  
  931. static void DecodeADD(Word Code)
  932. {
  933.   UNUSED(Code);
  934.  
  935.   if (!ChkArgCnt(2, 2));
  936.   else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  937.   else
  938.   {
  939.     DecodeAdr(&ArgStr[2], MModReg, False);
  940.     if (AdrMode != ModNone)
  941.     {
  942.       Word HReg = AdrPart;
  943.  
  944.       OpSize = eSymbolSize32Bit;
  945.       DecodeAdr(&ArgStr[1], MModReg | MModImm, True);
  946.       switch (AdrMode)
  947.       {
  948.         case ModReg:
  949.           SetCode(0x300c + (((Word)HReg) << 8) + (AdrPart << 4));
  950.           break;
  951.         case ModImm:
  952.           SetCode(0x7000 + AdrPart + (((Word)HReg) << 8));
  953.           break;
  954.       }
  955.     }
  956.   }
  957. }
  958.  
  959. static void DecodeCMPEQ(Word Code)
  960. {
  961.   UNUSED(Code);
  962.  
  963.   if (!ChkArgCnt(2, 2));
  964.   else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  965.   else
  966.   {
  967.     DecodeAdr(&ArgStr[2], MModReg, False);
  968.     if (AdrMode != ModNone)
  969.     {
  970.       Word HReg = AdrPart;
  971.  
  972.       OpSize = eSymbolSize32Bit;
  973.       DecodeAdr(&ArgStr[1], MModReg | MModImm, True);
  974.       switch (AdrMode)
  975.       {
  976.         case ModReg:
  977.           SetCode(0x3000 + (((Word)HReg) << 8) + (AdrPart << 4));
  978.           break;
  979.         case ModImm:
  980.           if (HReg != 0) WrError(ErrNum_InvAddrMode);
  981.           else
  982.             SetCode(0x8800 + AdrPart);
  983.           break;
  984.       }
  985.     }
  986.   }
  987. }
  988.  
  989. static void DecodeLog(Word Code)
  990. {
  991.   Word HReg;
  992.  
  993.   if (ChkArgCnt(2, 2))
  994.   {
  995.     DecodeAdr(&ArgStr[2], MModReg | MModGBRR0, False);
  996.     switch (AdrMode)
  997.     {
  998.       case ModReg:
  999.         if (*AttrPart.str.p_str && (OpSize != eSymbolSize32Bit)) WrError(ErrNum_InvOpSize);
  1000.         else
  1001.         {
  1002.           OpSize = eSymbolSize32Bit;
  1003.           HReg = AdrPart;
  1004.           DecodeAdr(&ArgStr[1], MModReg | MModImm, False);
  1005.           switch (AdrMode)
  1006.           {
  1007.             case ModReg:
  1008.               SetCode(0x2008 + Code + (((Word)HReg) << 8) + (AdrPart << 4));
  1009.               break;
  1010.             case ModImm:
  1011.               if (HReg != 0) WrError(ErrNum_InvAddrMode);
  1012.               else
  1013.                 SetCode(0xc800 + (Code << 8) + AdrPart);
  1014.               break;
  1015.           }
  1016.         }
  1017.         break;
  1018.       case ModGBRR0:
  1019.         DecodeAdr(&ArgStr[1], MModImm, False);
  1020.         if (AdrMode != ModNone)
  1021.           SetCode(0xcc00 + (Code << 8) + AdrPart);
  1022.         break;
  1023.     }
  1024.   }
  1025. }
  1026.  
  1027. static void DecodeTRAPA(Word Code)
  1028. {
  1029.   UNUSED(Code);
  1030.  
  1031.   if (!ChkArgCnt(1, 1));
  1032.   else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  1033.   else
  1034.   {
  1035.     OpSize = eSymbolSize8Bit;
  1036.     DecodeAdr(&ArgStr[1], MModImm, False);
  1037.     if (AdrMode == ModImm)
  1038.       SetCode(0xc300 + AdrPart);
  1039.     ChkDelayed();
  1040.   }
  1041. }
  1042.  
  1043. static void DecodeBT_BF(Word Code)
  1044. {
  1045.   if (!ChkArgCnt(1, 1));
  1046.   else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  1047.   else if ((Code & 0x400) && !ChkMinCPU(CPU7600));
  1048.   else
  1049.   {
  1050.     Boolean OK;
  1051.     tSymbolFlags Flags;
  1052.     LongInt AdrLong;
  1053.  
  1054.     DelayedAdr = EvalStrIntExpressionWithFlags(&ArgStr[1], Int32, &OK, &Flags);
  1055.     AdrLong = DelayedAdr - (EProgCounter() + 4);
  1056.     if (OK)
  1057.     {
  1058.       if (Odd(AdrLong)) WrError(ErrNum_DistIsOdd);
  1059.       else if (((AdrLong < -256) || (AdrLong > 254)) && !mSymbolQuestionable(Flags)) WrError(ErrNum_JmpDistTooBig);
  1060.       else
  1061.       {
  1062.         SetCode(Code + ((AdrLong >> 1) & 0xff));
  1063.         if (Code & 0x400)
  1064.           CurrDelayed = True;
  1065.         ChkDelayed();
  1066.       }
  1067.     }
  1068.   }
  1069. }
  1070.  
  1071. static void DecodeBRA_BSR(Word Code)
  1072. {
  1073.   if (!ChkArgCnt(1, 1));
  1074.   else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  1075.   else
  1076.   {
  1077.     Boolean OK;
  1078.     tSymbolFlags Flags;
  1079.     LongInt AdrLong;
  1080.  
  1081.     DelayedAdr = EvalStrIntExpressionWithFlags(&ArgStr[1], Int32, &OK, &Flags);
  1082.     AdrLong = DelayedAdr - (EProgCounter() + 4);
  1083.     if (OK)
  1084.     {
  1085.       if (Odd(AdrLong)) WrError(ErrNum_DistIsOdd);
  1086.       else if (((AdrLong < -4096) || (AdrLong > 4094)) && !mSymbolQuestionable(Flags)) WrError(ErrNum_JmpDistTooBig);
  1087.       else
  1088.       {
  1089.         SetCode(Code + ((AdrLong >> 1) & 0xfff));
  1090.         CurrDelayed = True;
  1091.         ChkDelayed();
  1092.       }
  1093.     }
  1094.   }
  1095. }
  1096.  
  1097. static void DecodeJSR_JMP(Word Code)
  1098. {
  1099.   if (!ChkArgCnt(1, 1));
  1100.   else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  1101.   else
  1102.   {
  1103.     DecodeAdr(&ArgStr[1], MModIReg, False);
  1104.     if (AdrMode != ModNone)
  1105.     {
  1106.       SetCode(Code + (AdrPart << 8));
  1107.       CurrDelayed = True;
  1108.       DelayedAdr = 0x7fffffff;
  1109.       ChkDelayed();
  1110.     }
  1111.   }
  1112. }
  1113.  
  1114. static void DecodeDCT_DCF(Word Cond)
  1115. {
  1116.   char *pos;
  1117.   int z;
  1118.  
  1119.   if (!DSPAvail)
  1120.   {
  1121.     WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
  1122.     return;
  1123.   }
  1124.  
  1125.   /* strip off DSP condition */
  1126.  
  1127.   if (!ChkArgCnt(1, ArgCntMax))
  1128.     return;
  1129.  
  1130.   pos = FirstBlank(ArgStr[1].str.p_str);
  1131.   if (!pos)
  1132.   {
  1133.     StrCompCopy(&OpPart, &ArgStr[1]);
  1134.     for (z = 1; z < ArgCnt; z++)
  1135.       StrCompCopy(&ArgStr[z], &ArgStr[z + 1]);
  1136.     ArgCnt--;
  1137.   }
  1138.   else
  1139.     StrCompSplitLeft(&ArgStr[1], &OpPart, pos);
  1140.  
  1141.   UNUSED(Cond);
  1142. }
  1143.  
  1144. static LargeInt ltorg_16(const as_literal_t *p_lit, tStrComp *p_name)
  1145. {
  1146.   LargeInt ret;
  1147.  
  1148.   SetMaxCodeLen(CodeLen + 2);
  1149.   WAsmCode[CodeLen >> 1] = p_lit->value;
  1150.   ret = EProgCounter() + CodeLen;
  1151.   EnterIntSymbol(p_name, ret, ActPC, False);
  1152.   CodeLen += 2;
  1153.   return ret;
  1154. }
  1155.  
  1156. static LargeInt ltorg_32(const as_literal_t *p_lit, tStrComp *p_name)
  1157. {
  1158.   LargeInt ret;
  1159.  
  1160.   SetMaxCodeLen(CodeLen + 6);
  1161.   if (((EProgCounter() + CodeLen) & 2) != 0)
  1162.   {
  1163.     WAsmCode[CodeLen >> 1] = 0;
  1164.     CodeLen += 2;
  1165.   }
  1166.   WAsmCode[CodeLen >> 1] = (p_lit->value >> 16);
  1167.   WAsmCode[(CodeLen >> 1) + 1] = (p_lit->value & 0xffff);
  1168.   ret = EProgCounter() + CodeLen;
  1169.   EnterIntSymbol(p_name, ret, ActPC, False);
  1170.   CodeLen += 4;
  1171.   return ret;
  1172. }
  1173.  
  1174. static void DecodeLTORG(Word Code)
  1175. {
  1176.   UNUSED(Code);
  1177.  
  1178.   if (!ChkArgCnt(0, 0));
  1179.   else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  1180.   else
  1181.   {
  1182.     if ((EProgCounter() & 3) == 0)
  1183.     {
  1184.       literals_dump(ltorg_32, eSymbolSize32Bit, MomSectionHandle, True);
  1185.       literals_dump(ltorg_16, eSymbolSize16Bit, MomSectionHandle, False);
  1186.     }
  1187.     else
  1188.     {
  1189.       literals_dump(ltorg_16, eSymbolSize16Bit, MomSectionHandle, False);
  1190.       literals_dump(ltorg_32, eSymbolSize32Bit, MomSectionHandle, True);
  1191.     }
  1192.   }
  1193. }
  1194.  
  1195. /*-------------------------------------------------------------------------*/
  1196. /* dynamische Belegung/Freigabe Codetabellen */
  1197.  
  1198. static void AddFixed(const char *NName, Word NCode, Boolean NPriv, CPUVar NMin)
  1199. {
  1200.   order_array_rsv_end(FixedOrders, FixedOrder);
  1201.   FixedOrders[InstrZ].Priv = NPriv;
  1202.   FixedOrders[InstrZ].MinCPU = NMin;
  1203.   FixedOrders[InstrZ].Code = NCode;
  1204.   AddInstTable(InstTable, NName, InstrZ++, DecodeFixed);
  1205. }
  1206.  
  1207. static void AddOneReg(const char *NName, Word NCode, CPUVar NMin, Boolean NPriv, Boolean NDel)
  1208. {
  1209.   order_array_rsv_end(OneRegOrders, OneRegOrder);
  1210.   OneRegOrders[InstrZ].Code = NCode;
  1211.   OneRegOrders[InstrZ].MinCPU = NMin;
  1212.   OneRegOrders[InstrZ].Priv = NPriv;
  1213.   OneRegOrders[InstrZ].Delayed = NDel;
  1214.   AddInstTable(InstTable, NName, InstrZ++, DecodeOneReg);
  1215. }
  1216.  
  1217. static void AddTwoReg(const char *NName, Word NCode, Boolean NPriv, CPUVar NMin, ShortInt NDef)
  1218. {
  1219.   order_array_rsv_end(TwoRegOrders, TwoRegOrder);
  1220.   TwoRegOrders[InstrZ].Priv = NPriv;
  1221.   TwoRegOrders[InstrZ].DefSize = NDef;
  1222.   TwoRegOrders[InstrZ].MinCPU = NMin;
  1223.   TwoRegOrders[InstrZ].Code = NCode;
  1224.   AddInstTable(InstTable, NName, InstrZ++, DecodeTwoReg);
  1225. }
  1226.  
  1227. static void AddMulReg(const char *NName, Word NCode, CPUVar NMin)
  1228. {
  1229.   order_array_rsv_end(MulRegOrders, FixedMinOrder);
  1230.   MulRegOrders[InstrZ].Code = NCode;
  1231.   MulRegOrders[InstrZ].MinCPU = NMin;
  1232.   AddInstTable(InstTable, NName, InstrZ++, DecodeMulReg);
  1233. }
  1234.  
  1235. static void AddBW(const char *NName, Word NCode)
  1236. {
  1237.   order_array_rsv_end(BWOrders, FixedOrder);
  1238.   BWOrders[InstrZ].Code = NCode;
  1239.   AddInstTable(InstTable, NName, InstrZ++, DecodeBW);
  1240. }
  1241.  
  1242. static void AddSReg(const char *NName, Word NCode, CPUVar NMin, Boolean NDSP)
  1243. {
  1244.   order_array_rsv_end(RegDefs, TRegDef);
  1245.   RegDefs[InstrZ].Name = NName;
  1246.   RegDefs[InstrZ].Code = NCode;
  1247.   RegDefs[InstrZ].MinCPU = NMin;
  1248.   RegDefs[InstrZ++].NeedsDSP = NDSP;
  1249. }
  1250.  
  1251. static void InitFields(void)
  1252. {
  1253.   InstTable = CreateInstTable(201);
  1254.   AddInstTable(InstTable, "MOV", 0, DecodeMOV);
  1255.   AddInstTable(InstTable, "MOVA", 0, DecodeMOVA);
  1256.   AddInstTable(InstTable, "PREF", 0, DecodePREF);
  1257.   AddInstTable(InstTable, "LDC", 1, DecodeLDC_STC);
  1258.   AddInstTable(InstTable, "STC", 0, DecodeLDC_STC);
  1259.   AddInstTable(InstTable, "LDS", 1, DecodeLDS_STS);
  1260.   AddInstTable(InstTable, "STS", 0, DecodeLDS_STS);
  1261.   AddInstTable(InstTable, "TAS", 0, DecodeTAS);
  1262.   AddInstTable(InstTable, "MAC", 0, DecodeMAC);
  1263.   AddInstTable(InstTable, "ADD", 0, DecodeADD);
  1264.   AddInstTable(InstTable, "CMP/EQ", 0, DecodeCMPEQ);
  1265.   AddInstTable(InstTable, "TRAPA", 0, DecodeTRAPA);
  1266.   AddInstTable(InstTable, "BF", 0x8b00, DecodeBT_BF);
  1267.   AddInstTable(InstTable, "BT", 0x8900, DecodeBT_BF);
  1268.   AddInstTable(InstTable, "BF/S", 0x8f00, DecodeBT_BF);
  1269.   AddInstTable(InstTable, "BT/S", 0x8d00, DecodeBT_BF);
  1270.   AddInstTable(InstTable, "BRA", 0xa000, DecodeBRA_BSR);
  1271.   AddInstTable(InstTable, "BSR", 0xb000, DecodeBRA_BSR);
  1272.   AddInstTable(InstTable, "JSR", 0x400b, DecodeJSR_JMP);
  1273.   AddInstTable(InstTable, "JMP", 0x402b, DecodeJSR_JMP);
  1274.   AddInstTable(InstTable, "DCT", 1, DecodeDCT_DCF);
  1275.   AddInstTable(InstTable, "DCF", 2, DecodeDCT_DCF);
  1276.   AddInstTable(InstTable, "LTORG", 0, DecodeLTORG);
  1277.  
  1278.   InstrZ = 0;
  1279.   AddFixed("CLRT"  , 0x0008, False, CPU7000);
  1280.   AddFixed("CLRMAC", 0x0028, False, CPU7000);
  1281.   AddFixed("NOP"   , 0x0009, False, CPU7000);
  1282.   AddFixed("RTE"   , 0x002b, False, CPU7000);
  1283.   AddFixed("SETT"  , 0x0018, False, CPU7000);
  1284.   AddFixed("SLEEP" , 0x001b, False, CPU7000);
  1285.   AddFixed("RTS"   , 0x000b, False, CPU7000);
  1286.   AddFixed("DIV0U" , 0x0019, False, CPU7000);
  1287.   AddFixed("BRK"   , 0x0000, True , CPU7000);
  1288.   AddFixed("RTB"   , 0x0001, True , CPU7000);
  1289.   AddFixed("CLRS"  , 0x0048, False, CPU7700);
  1290.   AddFixed("SETS"  , 0x0058, False, CPU7700);
  1291.   AddFixed("LDTLB" , 0x0038, True , CPU7700);
  1292.  
  1293.   InstrZ = 0;
  1294.   AddOneReg("MOVT"  , 0x0029, CPU7000, False, False);
  1295.   AddOneReg("CMP/PZ", 0x4011, CPU7000, False, False);
  1296.   AddOneReg("CMP/PL", 0x4015, CPU7000, False, False);
  1297.   AddOneReg("ROTL"  , 0x4004, CPU7000, False, False);
  1298.   AddOneReg("ROTR"  , 0x4005, CPU7000, False, False);
  1299.   AddOneReg("ROTCL" , 0x4024, CPU7000, False, False);
  1300.   AddOneReg("ROTCR" , 0x4025, CPU7000, False, False);
  1301.   AddOneReg("SHAL"  , 0x4020, CPU7000, False, False);
  1302.   AddOneReg("SHAR"  , 0x4021, CPU7000, False, False);
  1303.   AddOneReg("SHLL"  , 0x4000, CPU7000, False, False);
  1304.   AddOneReg("SHLR"  , 0x4001, CPU7000, False, False);
  1305.   AddOneReg("SHLL2" , 0x4008, CPU7000, False, False);
  1306.   AddOneReg("SHLR2" , 0x4009, CPU7000, False, False);
  1307.   AddOneReg("SHLL8" , 0x4018, CPU7000, False, False);
  1308.   AddOneReg("SHLR8" , 0x4019, CPU7000, False, False);
  1309.   AddOneReg("SHLL16", 0x4028, CPU7000, False, False);
  1310.   AddOneReg("SHLR16", 0x4029, CPU7000, False, False);
  1311.   AddOneReg("LDBR"  , 0x0021, CPU7000, True , False);
  1312.   AddOneReg("STBR"  , 0x0020, CPU7000, True , False);
  1313.   AddOneReg("DT"    , 0x4010, CPU7600, False, False);
  1314.   AddOneReg("BRAF"  , 0x0023, CPU7600, False, True );
  1315.   AddOneReg("BSRF"  , 0x0003, CPU7600, False, True );
  1316.  
  1317.   InstrZ = 0;
  1318.   AddTwoReg("XTRCT" , 0x200d, False, CPU7000, 2);
  1319.   AddTwoReg("ADDC"  , 0x300e, False, CPU7000, 2);
  1320.   AddTwoReg("ADDV"  , 0x300f, False, CPU7000, 2);
  1321.   AddTwoReg("CMP/HS", 0x3002, False, CPU7000, 2);
  1322.   AddTwoReg("CMP/GE", 0x3003, False, CPU7000, 2);
  1323.   AddTwoReg("CMP/HI", 0x3006, False, CPU7000, 2);
  1324.   AddTwoReg("CMP/GT", 0x3007, False, CPU7000, 2);
  1325.   AddTwoReg("CMP/STR", 0x200c, False, CPU7000, 2);
  1326.   AddTwoReg("DIV1"  , 0x3004, False, CPU7000, 2);
  1327.   AddTwoReg("DIV0S" , 0x2007, False, CPU7000, -1);
  1328.   AddTwoReg("MULS"  , 0x200f, False, CPU7000, 1);
  1329.   AddTwoReg("MULU"  , 0x200e, False, CPU7000, 1);
  1330.   AddTwoReg("NEG"   , 0x600b, False, CPU7000, 2);
  1331.   AddTwoReg("NEGC"  , 0x600a, False, CPU7000, 2);
  1332.   AddTwoReg("SUB"   , 0x3008, False, CPU7000, 2);
  1333.   AddTwoReg("SUBC"  , 0x300a, False, CPU7000, 2);
  1334.   AddTwoReg("SUBV"  , 0x300b, False, CPU7000, 2);
  1335.   AddTwoReg("NOT"   , 0x6007, False, CPU7000, 2);
  1336.   AddTwoReg("SHAD"  , 0x400c, False, CPU7700, 2);
  1337.   AddTwoReg("SHLD"  , 0x400d, False, CPU7700, 2);
  1338.  
  1339.   InstrZ = 0;
  1340.   AddMulReg("MUL"   , 0x0007, CPU7600);
  1341.   AddMulReg("DMULU" , 0x3005, CPU7600);
  1342.   AddMulReg("DMULS" , 0x300d, CPU7600);
  1343.  
  1344.   InstrZ = 0;
  1345.   AddBW("SWAP", 0x6008); AddBW("EXTS", 0x600e); AddBW("EXTU", 0x600c);
  1346.  
  1347.   InstrZ = 0;
  1348.   AddInstTable(InstTable, "TST", InstrZ++, DecodeLog);
  1349.   AddInstTable(InstTable, "AND", InstrZ++, DecodeLog);
  1350.   AddInstTable(InstTable, "XOR", InstrZ++, DecodeLog);
  1351.   AddInstTable(InstTable, "OR" , InstrZ++, DecodeLog);
  1352.  
  1353.   AddInstTable(InstTable, "REG", 0, CodeREG);
  1354.  
  1355.   InstrZ = 0;
  1356.   AddSReg("MACH",  0, CPU7000, FALSE);
  1357.   AddSReg("MACL",  1, CPU7000, FALSE);
  1358.   AddSReg("PR"  ,  2, CPU7000, FALSE);
  1359.   AddSReg("DSR" ,  6, CPU7000, TRUE );
  1360.   AddSReg("A0"  ,  7, CPU7000, TRUE );
  1361.   AddSReg("X0"  ,  8, CPU7000, TRUE );
  1362.   AddSReg("X1"  ,  9, CPU7000, TRUE );
  1363.   AddSReg("Y0"  , 10, CPU7000, TRUE );
  1364.   AddSReg("Y1"  , 11, CPU7000, TRUE );
  1365.   AddSReg(NULL  ,  0, CPU7000, FALSE);
  1366. }
  1367.  
  1368. static void DeinitFields(void)
  1369. {
  1370.   DestroyInstTable(InstTable);
  1371.   order_array_free(FixedOrders);
  1372.   order_array_free(OneRegOrders);
  1373.   order_array_free(TwoRegOrders);
  1374.   order_array_free(MulRegOrders);
  1375.   order_array_free(BWOrders);
  1376.   order_array_free(RegDefs);
  1377. }
  1378.  
  1379. /*-------------------------------------------------------------------------*/
  1380.  
  1381. static Boolean DecodeAttrPart_7000(void)
  1382. {
  1383.   if (*AttrPart.str.p_str)
  1384.   {
  1385.     if (strlen(AttrPart.str.p_str) != 1)
  1386.     {
  1387.       WrError(ErrNum_TooLongAttr);
  1388.       return False;
  1389.     }
  1390.     if (!DecodeMoto16AttrSize(*AttrPart.str.p_str, &AttrPartOpSize[0], False))
  1391.       return False;
  1392.   }
  1393.   return True;
  1394. }
  1395.  
  1396. static void MakeCode_7000(void)
  1397. {
  1398.   CodeLen = 0;
  1399.   DontPrint = False;
  1400.   OpSize = eSymbolSizeUnknown;
  1401.  
  1402.   /* zu ignorierendes */
  1403.  
  1404.   if (Memo("")) return;
  1405.  
  1406.   /* ab hier (und weiter in der Hauptroutine) stehen die Befehle,
  1407.      die Code erzeugen, deshalb wird der Merker fuer verzoegerte
  1408.      Spruenge hier weiter geschaltet. */
  1409.  
  1410.   PrevDelayed = CurrDelayed;
  1411.   CurrDelayed = False;
  1412.  
  1413.   /* Attribut verwursten */
  1414.  
  1415.   if (*AttrPart.str.p_str)
  1416.     SetOpSize(AttrPartOpSize[0]);
  1417.  
  1418.   if (DecodeMoto16Pseudo(OpSize, True))
  1419.     return;
  1420.  
  1421.   if (!LookupInstTable(InstTable, OpPart.str.p_str))
  1422.     WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
  1423. }
  1424.  
  1425. /*!------------------------------------------------------------------------
  1426.  * \fn     InternSymbol_7000(char *pArg, TempResult *pResult)
  1427.  * \brief  handle built-in symbols in SH7x00
  1428.  * \param  pArg source argument
  1429.  * \param  pResult result buffer
  1430.  * ------------------------------------------------------------------------ */
  1431.  
  1432. static void InternSymbol_7000(char *pArg, TempResult *pResult)
  1433. {
  1434.   Word Reg;
  1435.  
  1436.   if (DecodeRegCore(pArg, &Reg))
  1437.   {
  1438.     pResult->Typ = TempReg;
  1439.     pResult->DataSize = eSymbolSize32Bit;
  1440.     pResult->Contents.RegDescr.Reg = Reg;
  1441.     pResult->Contents.RegDescr.Dissect = DissectReg_7000;
  1442.     pResult->Contents.RegDescr.compare = NULL;
  1443.   }
  1444. }
  1445.  
  1446. static Boolean IsDef_7000(void)
  1447. {
  1448.   return Memo("REG");
  1449. }
  1450.  
  1451. static void SwitchFrom_7000(void)
  1452. {
  1453.   DeinitFields();
  1454. }
  1455.  
  1456. static void SwitchTo_7000(void)
  1457. {
  1458.   TurnWords = True;
  1459.   SetIntConstMode(eIntConstModeMoto);
  1460.  
  1461.   PCSymbol = "*";
  1462.   HeaderID = 0x6c;
  1463.   NOPCode = 0x0009;
  1464.   DivideChars = ",";
  1465.   HasAttrs = True;
  1466.   AttrChars = ".";
  1467.  
  1468.   ValidSegs = 1 << SegCode;
  1469.   Grans[SegCode] = 1; ListGrans[SegCode] = 2; SegInits[SegCode] = 0;
  1470.   SegLimits[SegCode] = (LargeWord)IntTypeDefs[UInt32].Max;
  1471.  
  1472.   DecodeAttrPart = DecodeAttrPart_7000;
  1473.   MakeCode = MakeCode_7000;
  1474.   IsDef = IsDef_7000;
  1475.   InternSymbol = InternSymbol_7000;
  1476.   DissectReg = DissectReg_7000;
  1477.   SwitchFrom = SwitchFrom_7000;
  1478.   InitFields();
  1479.   onoff_supmode_add();
  1480.   AddONOFF("COMPLITERALS", &CompLiterals, CompLiteralsName, False);
  1481.   AddMoto16PseudoONOFF(False);
  1482.  
  1483.   if (!onoff_test_and_set(e_onoff_reg_dsp))
  1484.     SetFlag(&DSPAvail, DSPSymName, False);
  1485.   AddONOFF(DSPCmdName, &DSPAvail, DSPSymName, False);
  1486.  
  1487.   CurrDelayed = False; PrevDelayed = False;
  1488. }
  1489.  
  1490. void code7000_init(void)
  1491. {
  1492.   CPU7000 = AddCPU("SH7000", SwitchTo_7000);
  1493.   CPU7600 = AddCPU("SH7600", SwitchTo_7000);
  1494.   CPU7700 = AddCPU("SH7700", SwitchTo_7000);
  1495. }
  1496.