Subversion Repositories pentevo

Rev

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

  1. /* codem16c.c */
  2. /*****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
  4. /*                                                                           */
  5. /* AS-Portierung                                                             */
  6. /*                                                                           */
  7. /* Codegenerator M16C                                                        */
  8. /*                                                                           */
  9. /*****************************************************************************/
  10.  
  11. #include "stdinc.h"
  12. #include <string.h>
  13. #include <ctype.h>
  14.  
  15. #include "nls.h"
  16. #include "bpemu.h"
  17. #include "strutil.h"
  18. #include "asmdef.h"
  19. #include "asmsub.h"
  20. #include "asmpars.h"
  21. #include "asmitree.h"
  22. #include "asmallg.h"
  23. #include "codepseudo.h"
  24. #include "intpseudo.h"
  25. #include "codevars.h"
  26. #include "errmsg.h"
  27.  
  28. #include "codem16c.h"
  29.  
  30. #define REG_SB 6
  31. #define REG_FB 7
  32.  
  33. #define ModNone (-1)
  34. #define ModGen 0
  35. #define MModGen (1 << ModGen)
  36. #define ModAbs20 1
  37. #define MModAbs20 (1 << ModAbs20)
  38. #define ModAReg32 2
  39. #define MModAReg32 (1 << ModAReg32)
  40. #define ModDisp20 3
  41. #define MModDisp20 (1 << ModDisp20)
  42. #define ModReg32 4
  43. #define MModReg32 (1 << ModReg32)
  44. #define ModIReg32 5
  45. #define MModIReg32 (1 << ModIReg32)
  46. #define ModImm 6
  47. #define MModImm (1 << ModImm)
  48. #define ModSPRel 7
  49. #define MModSPRel (1 << ModSPRel)
  50.  
  51. typedef struct
  52. {
  53.   Byte Code1,Code2,Code3;
  54. } Gen2Order;
  55.  
  56. typedef struct
  57. {
  58.   Byte Mode;
  59.   ShortInt Type;
  60.   Byte Cnt;
  61.   Byte Vals[3];
  62.   tSymbolFlags ImmSymFlags;
  63. } tAdrResult;
  64.  
  65. static const char Flags[] = "CDZSBOIU";
  66.  
  67. static CPUVar CPUM16C, CPUM30600M8, CPUM30610, CPUM30620;
  68.  
  69. static char *Format;
  70. static Byte FormatCode;
  71. static ShortInt OpSize;
  72.  
  73. static Gen2Order *Gen2Orders;
  74. static Gen2Order *DivOrders;
  75.  
  76. /*------------------------------------------------------------------------*/
  77. /* Adressparser */
  78.  
  79. static void SetOpSize(ShortInt NSize, tAdrResult *pResult)
  80. {
  81.   if (OpSize == eSymbolSizeUnknown)
  82.     OpSize = NSize;
  83.   else if (NSize != OpSize)
  84.   {
  85.     WrError(ErrNum_ConfOpSizes);
  86.     if (pResult)
  87.     {
  88.       pResult->Cnt = 0;
  89.       pResult->Type = ModNone;
  90.     }
  91.   }
  92. }
  93.  
  94. /*!------------------------------------------------------------------------
  95.  * \fn     DecodeRegCore(const char *pArg, Byte *pResult, tSymbolSize *pSize)
  96.  * \brief  is argument a COU register?
  97.  * \param  pArg source argument
  98.  * \param  pResult result buffer
  99.  * \param  pSize resulting register size
  100.  * \return True if it's a register
  101.  * ------------------------------------------------------------------------ */
  102.  
  103. static Boolean DecodeRegCore(const char *pArg, Byte *pResult, tSymbolSize *pSize)
  104. {
  105.   if (!as_strcasecmp(pArg, "FB"))
  106.   {
  107.     *pResult = REG_FB;
  108.     *pSize = eSymbolSize16Bit;
  109.     return True;
  110.   }
  111.   if (!as_strcasecmp(pArg, "SB"))
  112.   {
  113.     *pResult = REG_SB;
  114.     *pSize = eSymbolSize16Bit;
  115.     return True;
  116.   }
  117.   if (!as_strcasecmp(pArg, "R2R0"))
  118.   {
  119.     *pResult = 0;
  120.     *pSize = eSymbolSize32Bit;
  121.     return True;
  122.   }
  123.   if (!as_strcasecmp(pArg, "R3R1"))
  124.   {
  125.     *pResult = 1;
  126.     *pSize = eSymbolSize32Bit;
  127.     return True;
  128.   }
  129.   if (!as_strcasecmp(pArg, "A1A0"))
  130.   {
  131.     *pResult = 2;
  132.     *pSize = eSymbolSize32Bit;
  133.     return True;
  134.   }
  135.  
  136.   switch (strlen(pArg))
  137.   {
  138.     case 3:
  139.       if ((as_toupper(*pArg) == 'R')
  140.        && (pArg[1] >= '0') && (pArg[1] <= '1')
  141.        && ((as_toupper(pArg[2]) == 'L') || (as_toupper(pArg[2]) == 'H')))
  142.       {
  143.         *pResult = ((pArg[1] - '0') << 1) + Ord(as_toupper(pArg[2]) == 'H');
  144.         *pSize = eSymbolSize8Bit;
  145.         return True;
  146.       }
  147.       break;
  148.     case 2:
  149.       if ((as_toupper(*pArg) == 'R')
  150.        && (pArg[1] >= '0') && (pArg[1] <= '3'))
  151.       {
  152.         *pResult = pArg[1] - '0';
  153.         *pSize = eSymbolSize16Bit;
  154.         return True;
  155.       }
  156.       if ((as_toupper(*pArg) == 'A')
  157.        && (pArg[1] >= '0') && (pArg[1] <= '1'))
  158.       {
  159.         *pResult = pArg[1] - '0' + 4;
  160.         *pSize = eSymbolSize16Bit;
  161.         return True;
  162.       }
  163.       break;
  164.   }
  165.  
  166.   return False;
  167. }
  168.  
  169. /*!------------------------------------------------------------------------
  170.  * \fn     DissectReg_M16C(char *pDest, size_t DestSize, tRegInt Value, tSymbolSize InpSize)
  171.  * \brief  dissect register symbols - M16C variant
  172.  * \param  pDest destination buffer
  173.  * \param  DestSize destination buffer size
  174.  * \param  Value numeric register value
  175.  * \param  InpSize register size
  176.  * ------------------------------------------------------------------------ */
  177.  
  178. static void DissectReg_M16C(char *pDest, size_t DestSize, tRegInt Value, tSymbolSize InpSize)
  179. {
  180.   switch (InpSize)
  181.   {
  182.     case eSymbolSize32Bit:
  183.       if (Value >= 2)
  184.         as_snprintf(pDest, DestSize, "A%uA%u", Value - 1, Value - 2);
  185.       else
  186.         as_snprintf(pDest, DestSize, "R%uR%u", Value + 2, Value);
  187.       break;
  188.     case eSymbolSize16Bit:
  189.       switch (Value)
  190.       {
  191.         case REG_FB:
  192.           as_snprintf(pDest, DestSize, "FB");
  193.           break;
  194.         case REG_SB:
  195.           as_snprintf(pDest, DestSize, "SB");
  196.           break;
  197.         default:
  198.           as_snprintf(pDest, DestSize, "%c%u", (Value & 4) ? 'A' : 'R', (unsigned)(Value & 3));
  199.       }
  200.       break;
  201.     case eSymbolSize8Bit:
  202.       as_snprintf(pDest, DestSize, "R%u%c", (unsigned)(Value >> 1), "HL"[Value & 1]);
  203.       break;
  204.     default:
  205.       as_snprintf(pDest, DestSize, "%d-%u", (int)InpSize, (unsigned)Value);
  206.   }
  207. }
  208.  
  209. /*!------------------------------------------------------------------------
  210.  * \fn     DecodeReg(const tStrComp *pArg, Byte *pResult, Boolean MustBeReg, tSymbolSize *pSize)
  211.  * \brief  check whether argument is a CPU register or register alias
  212.  * \param  pArg argument to check
  213.  * \param  pResult numeric register value if yes
  214.  * \param  MustBeReg argument is expected to be a register
  215.  * \param  pSize register size (in/out)
  216.  * \return RegEvalResult
  217.  * ------------------------------------------------------------------------ */
  218.  
  219. static tRegEvalResult DecodeReg(const tStrComp *pArg, Byte *pResult, Boolean MustBeReg, tSymbolSize *pSize)
  220. {
  221.   tRegDescr RegDescr;
  222.   tEvalResult EvalResult;
  223.   tRegEvalResult RegEvalResult;
  224.  
  225.   if (DecodeRegCore(pArg->str.p_str, pResult, &EvalResult.DataSize))
  226.   {
  227.     if ((*pSize != eSymbolSizeUnknown) && (EvalResult.DataSize != *pSize))
  228.     {
  229.       WrStrErrorPos(ErrNum_InvOpSize, pArg);
  230.       return MustBeReg ? eIsNoReg : eRegAbort;
  231.     }
  232.     *pSize = EvalResult.DataSize;
  233.     return eIsReg;
  234.   }
  235.  
  236.   RegEvalResult = EvalStrRegExpressionAsOperand(pArg, &RegDescr, &EvalResult, *pSize, MustBeReg);
  237.   *pResult = RegDescr.Reg;
  238.   *pSize = EvalResult.DataSize;
  239.   return RegEvalResult;
  240. }
  241.  
  242. static LargeInt eval_outer_disp(const tStrComp *p_arg, IntType type, Boolean *p_ok)
  243. {
  244.   if (p_arg->str.p_str[0])
  245.     return EvalStrIntExpression(p_arg, type, p_ok);
  246.   else
  247.   {
  248.     *p_ok = True;
  249.     return 0;
  250.   }
  251. }
  252.  
  253. static ShortInt DecodeAdr(const tStrComp *pArg, Word Mask, tAdrResult *pResult)
  254. {
  255.   LongInt DispAcc;
  256.   String RegPartStr, DispPartStr;
  257.   tStrComp RegPart, DispPart;
  258.   char *p;
  259.   Boolean OK;
  260.   tSymbolSize RegSize = eSymbolSizeUnknown;
  261.   int ArgLen = strlen(pArg->str.p_str);
  262.  
  263.   pResult->Cnt = 0;
  264.   pResult->Type = ModNone;
  265.   StrCompMkTemp(&RegPart, RegPartStr, sizeof(RegPartStr));
  266.   StrCompMkTemp(&DispPart, DispPartStr, sizeof(DispPartStr));
  267.  
  268.   switch (DecodeReg(pArg, &pResult->Mode, False, &RegSize))
  269.   {
  270.     case eIsReg:
  271.       switch (RegSize)
  272.       {
  273.         /* Data Register R(0|1)(L|H) */
  274.         case eSymbolSize8Bit:
  275.           pResult->Type = ModGen;
  276.           SetOpSize(RegSize, pResult);
  277.           goto chk;
  278.         case eSymbolSize16Bit:
  279.           /* Data Register R0..R3, Address Register A0...A1 */
  280.           if (pResult->Type < 6)
  281.           {
  282.             pResult->Type = ModGen;
  283.             /* opsize may be overridden by attribute */
  284.             goto chk;
  285.           }
  286.           break;
  287.         case eSymbolSize32Bit:
  288.           /* Data Register R2R0/R3R1, Address Register A1A0 */
  289.           pResult->Type = (pResult->Mode < 2) ? ModReg32 : ModAReg32;
  290.           pResult->Mode &= 1;
  291.           SetOpSize(RegSize, pResult);
  292.           goto chk;
  293.         default:
  294.           break;
  295.       }
  296.       break;
  297.     case eIsNoReg:
  298.       break;
  299.     case eRegAbort:
  300.       return pResult->Type;
  301.   }
  302.  
  303.   /* indirekt */
  304.  
  305.   p = strchr(pArg->str.p_str, '[');
  306.   if ((p) && (pArg->str.p_str[ArgLen - 1] == ']'))
  307.   {
  308.     RegSize = eSymbolSizeUnknown;
  309.     StrCompSplitCopy(&DispPart, &RegPart, pArg, p);
  310.     StrCompShorten(&RegPart, 1);
  311.     if (!as_strcasecmp(RegPart.str.p_str, "SP"))
  312.     {
  313.       DispAcc = eval_outer_disp(&DispPart, SInt8, &OK);
  314.       if (OK)
  315.       {
  316.         pResult->Type = ModSPRel;
  317.         pResult->Vals[0] = DispAcc & 0xff;
  318.         pResult->Cnt = 1;
  319.       }
  320.     }
  321.     else if (eIsReg == DecodeReg(&RegPart, &pResult->Mode, True, &RegSize))
  322.     {
  323.       switch (RegSize)
  324.       {
  325.         case eSymbolSize8Bit:
  326.           WrStrErrorPos(ErrNum_InvReg, &RegPart);
  327.           break;
  328.         case eSymbolSize16Bit:
  329.           switch (pResult->Mode)
  330.           {
  331.             case REG_SB:
  332.               DispAcc = eval_outer_disp(&DispPart, Int16, &OK);
  333.               if (OK)
  334.               {
  335.                 if ((DispAcc >= 0) && (DispAcc <= 255))
  336.                 {
  337.                   pResult->Type = ModGen;
  338.                   pResult->Vals[0] = DispAcc & 0xff;
  339.                   pResult->Cnt = 1;
  340.                   pResult->Mode = 10;
  341.                 }
  342.                 else
  343.                 {
  344.                   pResult->Type = ModGen;
  345.                   pResult->Vals[0] = DispAcc & 0xff;
  346.                   pResult->Vals[1] = (DispAcc >> 8) & 0xff;
  347.                   pResult->Cnt = 2;
  348.                   pResult->Mode = 14;
  349.                 }
  350.               }
  351.               break;
  352.             case REG_FB:
  353.               DispAcc = eval_outer_disp(&DispPart, SInt8, &OK);
  354.               if (OK)
  355.               {
  356.                 pResult->Type = ModGen;
  357.                 pResult->Vals[0] = DispAcc & 0xff;
  358.                 pResult->Cnt = 1;
  359.                 pResult->Mode = 11;
  360.               }
  361.               break;
  362.             case 4: case 5:
  363.             {
  364.               DispAcc = eval_outer_disp(&DispPart, (Mask & MModDisp20)  ? Int20 : Int16, &OK);
  365.               if (OK)
  366.               {
  367.                 if ((DispAcc == 0) && (Mask & MModGen))
  368.                 {
  369.                   pResult->Type = ModGen;
  370.                   pResult->Mode = (pResult->Mode & 1) + 6;
  371.                 }
  372.                 else if ((DispAcc >= 0) && (DispAcc <= 255) && (Mask & MModGen))
  373.                 {
  374.                   pResult->Type = ModGen;
  375.                   pResult->Vals[0] = DispAcc & 0xff;
  376.                   pResult->Cnt = 1;
  377.                   pResult->Mode = (pResult->Mode & 1) + 8;
  378.                 }
  379.                 else if ((DispAcc >= -32768) && (DispAcc <= 65535) && (Mask & MModGen))
  380.                 {
  381.                   pResult->Type = ModGen;
  382.                   pResult->Vals[0] = DispAcc & 0xff;
  383.                   pResult->Vals[1] = (DispAcc >> 8) & 0xff;
  384.                   pResult->Cnt = 2;
  385.                   pResult->Mode = (pResult->Mode & 1) + 12;
  386.                 }
  387.                 else if (pResult->Mode != 4) WrError(ErrNum_InvAddrMode);
  388.                 else
  389.                 {
  390.                   pResult->Type = ModDisp20;
  391.                   pResult->Vals[0] = DispAcc & 0xff;
  392.                   pResult->Vals[1] = (DispAcc >> 8) & 0xff;
  393.                   pResult->Vals[2] = (DispAcc >> 16) & 0x0f;
  394.                   pResult->Cnt = 3;
  395.                   pResult->Mode = 0;
  396.                 }
  397.               }
  398.               break;
  399.             }
  400.             default:
  401.               WrStrErrorPos(ErrNum_InvReg, &RegPart);
  402.           }
  403.           break;
  404.         case eSymbolSize32Bit:
  405.           if (pResult->Mode != 2) WrStrErrorPos(ErrNum_InvReg, &RegPart);
  406.           else
  407.           {
  408.             DispAcc = eval_outer_disp(&DispPart, SInt8, &OK);
  409.             if (OK)
  410.             {
  411.               if (DispAcc != 0) WrError(ErrNum_OverRange);
  412.               else pResult->Type = ModIReg32;
  413.             }
  414.           }
  415.           break;
  416.         default:
  417.           break;
  418.       }
  419.     }
  420.     goto chk;
  421.   }
  422.  
  423.   /* immediate */
  424.  
  425.   if (*pArg->str.p_str == '#')
  426.   {
  427.     switch (OpSize)
  428.     {
  429.       case eSymbolSizeUnknown:
  430.         WrError(ErrNum_UndefOpSizes);
  431.         break;
  432.       case eSymbolSize8Bit:
  433.         pResult->Vals[0] = EvalStrIntExpressionOffsWithFlags(pArg, 1, Int8, &OK, &pResult->ImmSymFlags);
  434.         if (OK)
  435.         {
  436.           pResult->Type = ModImm;
  437.           pResult->Cnt = 1;
  438.         }
  439.         break;
  440.       case eSymbolSize16Bit:
  441.         DispAcc = EvalStrIntExpressionOffsWithFlags(pArg, 1, Int16, &OK, &pResult->ImmSymFlags);
  442.         if (OK)
  443.         {
  444.           pResult->Type = ModImm;
  445.           pResult->Vals[0] = DispAcc & 0xff;
  446.           pResult->Vals[1] = (DispAcc >> 8) & 0xff;
  447.           pResult->Cnt = 2;
  448.         }
  449.         break;
  450.     }
  451.     goto chk;
  452.   }
  453.  
  454.   /* then it's absolute: */
  455.  
  456.   DispAcc = EvalStrIntExpression(pArg, (Mask & MModAbs20) ? UInt20 : UInt16, &OK);
  457.   if ((DispAcc <= 0xffff) && ((Mask & MModGen) != 0))
  458.   {
  459.     pResult->Type = ModGen;
  460.     pResult->Mode = 15;
  461.     pResult->Vals[0] = DispAcc & 0xff;
  462.     pResult->Vals[1] = (DispAcc >> 8) & 0xff;
  463.     pResult->Cnt = 2;
  464.   }
  465.   else
  466.   {
  467.     pResult->Type = ModAbs20;
  468.     pResult->Vals[0] = DispAcc & 0xff;
  469.     pResult->Vals[1] = (DispAcc >> 8) & 0xff;
  470.     pResult->Vals[2] = (DispAcc >> 16) & 0x0f;
  471.     pResult->Cnt = 3;
  472.   }
  473.  
  474. chk:
  475.   if ((pResult->Type != ModNone) && ((Mask & (1 << pResult->Type)) == 0))
  476.   {
  477.      pResult->Cnt = 0;
  478.      pResult->Type = ModNone;
  479.      WrError(ErrNum_InvAddrMode);
  480.   }
  481.   return pResult->Type;
  482. }
  483.  
  484. static Boolean DecodeCReg(char *Asc, Byte *Erg)
  485. {
  486.   if (!as_strcasecmp(Asc, "INTBL")) *Erg = 1;
  487.   else if (!as_strcasecmp(Asc, "INTBH")) *Erg = 2;
  488.   else if (!as_strcasecmp(Asc, "FLG")) *Erg = 3;
  489.   else if (!as_strcasecmp(Asc, "ISP")) *Erg = 4;
  490.   else if (!as_strcasecmp(Asc, "SP")) *Erg = 5;
  491.   else if (!as_strcasecmp(Asc, "SB")) *Erg = 6;
  492.   else if (!as_strcasecmp(Asc, "FB")) *Erg = 7;
  493.   else
  494.   {
  495.     WrXError(ErrNum_InvCtrlReg, Asc);
  496.     return False;
  497.   }
  498.   return True;
  499. }
  500.  
  501. static void DecodeDisp(tStrComp *pArg, IntType Type1, IntType Type2, LongInt *DispAcc, Boolean *OK)
  502. {
  503.   if (ArgCnt == 2)
  504.     *DispAcc += eval_outer_disp(pArg, Type2, OK) * 8;
  505.   else
  506.     *DispAcc = eval_outer_disp(pArg, Type1, OK);
  507. }
  508.  
  509. static Boolean DecodeBitAdr(Boolean MayShort, tAdrResult *pResult)
  510. {
  511.   LongInt DispAcc;
  512.   Boolean OK;
  513.   char *Pos1;
  514.   String RegPartStr, DispPartStr;
  515.   tStrComp RegPart, DispPart;
  516.   int ArgLen;
  517.   tSymbolSize RegSize = eSymbolSize16Bit;
  518.  
  519.   pResult->Cnt = 0;
  520.   StrCompMkTemp(&RegPart, RegPartStr, sizeof(RegPartStr));
  521.   StrCompMkTemp(&DispPart, DispPartStr, sizeof(DispPartStr));
  522.  
  523.   /* Nur 1 oder 2 Argumente zugelassen */
  524.  
  525.   if (!ChkArgCnt(1, 2))
  526.     return False;
  527.  
  528.   /* Ist Teil 1 ein Register ? */
  529.  
  530.   switch (DecodeReg(&ArgStr[ArgCnt], &pResult->Mode, False, &RegSize))
  531.   {
  532.     case eIsReg:
  533.       if (pResult->Mode < 6)
  534.       {
  535.         if (ChkArgCnt(2, 2))
  536.         {
  537.           pResult->Vals[0] = EvalStrIntExpression(&ArgStr[1], UInt4, &OK);
  538.           if (OK)
  539.           {
  540.             pResult->Cnt = 1;
  541.             return True;
  542.           }
  543.         }
  544.         return False;
  545.       }
  546.       break;
  547.     case eRegAbort:
  548.       return False;
  549.     case eIsNoReg:
  550.       break;
  551.   }
  552.  
  553.   /* Bitnummer ? */
  554.  
  555.   if (ArgCnt == 2)
  556.   {
  557.     DispAcc = EvalStrIntExpression(&ArgStr[1], UInt16, &OK); /* RMS 02: The displacement can be 16 bits */
  558.     if (!OK)
  559.       return False;
  560.   }
  561.   else
  562.     DispAcc = 0;
  563.  
  564.   /* Registerangabe ? */
  565.  
  566.   Pos1 = QuotPos(ArgStr[ArgCnt].str.p_str, '[');
  567.  
  568.   /* nein->absolut */
  569.  
  570.   if (!Pos1)
  571.   {
  572.     DecodeDisp(&ArgStr[ArgCnt], UInt16, UInt13, &DispAcc, &OK);
  573.     if (OK && (DispAcc < 0x10000))     /* RMS 09: This is optional, it detects rollover of the bit address. */
  574.     {
  575.       pResult->Mode = 15;
  576.       pResult->Vals[0] = DispAcc & 0xff;
  577.       pResult->Vals[1] = (DispAcc >> 8) & 0xff;
  578.       pResult->Cnt = 2;
  579.       return True;
  580.     }
  581.     WrStrErrorPos(ErrNum_InvBitPos, &ArgStr[ArgCnt]);   /* RMS 08: Notify user there's a problem with address */
  582.     return False;
  583.   }
  584.  
  585.   /* Register abspalten */
  586.  
  587.   ArgLen = strlen(ArgStr[ArgCnt].str.p_str);
  588.   if ((*ArgStr[ArgCnt].str.p_str) && (ArgStr[ArgCnt].str.p_str[ArgLen - 1] != ']'))
  589.   {
  590.     WrError(ErrNum_InvAddrMode);
  591.     return False;
  592.   }
  593.   StrCompSplitCopy(&DispPart, &RegPart, &ArgStr[ArgCnt], Pos1);
  594.   StrCompShorten(&RegPart, 1);
  595.  
  596.   if (DecodeReg(&RegPart, &pResult->Mode, True, &RegSize) == eIsReg)
  597.   {
  598.     switch (pResult->Mode)
  599.     {
  600.       case REG_SB:
  601.         DecodeDisp(&DispPart, UInt13, UInt16, &DispAcc, &OK);
  602.         if (OK)
  603.         {
  604.           if ((MayShort) && (DispAcc <= 0x7ff))
  605.           {
  606.             pResult->Mode = 16 + (DispAcc & 7);
  607.             pResult->Vals[0] = DispAcc >> 3;
  608.             pResult->Cnt = 1;
  609.           }
  610.           else if ((DispAcc > 0) && (DispAcc < 256))
  611.           {
  612.             pResult->Mode = 10;
  613.             pResult->Vals[0] = DispAcc & 0xff;
  614.             pResult->Cnt = 1;
  615.           }
  616.           else
  617.           {
  618.             pResult->Mode = 14;
  619.             pResult->Vals[0] = DispAcc & 0xff;
  620.             pResult->Vals[1] = (DispAcc >> 8) & 0xff;
  621.             pResult->Cnt = 2;
  622.           }
  623.           return True;
  624.         }
  625.         WrError(ErrNum_InvBitPos);             /* RMS 08: Notify user there's a problem with the offset */
  626.         return False;
  627.       case REG_FB:
  628.         DecodeDisp(&DispPart, SInt5, SInt8, &DispAcc, &OK);
  629.         if (OK)
  630.         {
  631.           pResult->Mode = 11;
  632.           pResult->Vals[0] = DispAcc & 0xff;
  633.           pResult->Cnt = 1;
  634.           return True;
  635.         }
  636.         WrError(ErrNum_InvBitPos);             /* RMS 08: Notify user there's a problem with the offset */
  637.         return False;
  638.       case 4: case 5:
  639.         pResult->Mode &= 1;
  640.         DecodeDisp(&DispPart, UInt16, UInt16, &DispAcc, &OK); /* RMS 03: The offset is a full 16 bits */
  641.         if (OK)
  642.         {
  643.           if (DispAcc == 0) pResult->Mode += 6;
  644.           else if ((DispAcc > 0) && (DispAcc < 256))
  645.           {
  646.             pResult->Mode += 8;
  647.             pResult->Vals[0] = DispAcc & 0xff;
  648.             pResult->Cnt = 1;
  649.           }
  650.           else
  651.           {
  652.             pResult->Mode += 12;
  653.             pResult->Vals[0] = DispAcc & 0xff;
  654.             pResult->Vals[1] = (DispAcc >> 8) & 0xff;
  655.             pResult->Cnt = 2;
  656.           }
  657.           return True;
  658.         }
  659.         WrError(ErrNum_InvBitPos);             /* RMS 08: Notify user there's a problem with the offset */
  660.         return False;
  661.       default:
  662.         WrStrErrorPos(ErrNum_InvReg, &RegPart);
  663.         return False;
  664.     }
  665.   }
  666.   else
  667.     return False;
  668. }
  669.  
  670. static Boolean CheckFormat(const char *FSet)
  671. {
  672.   const char *p;
  673.  
  674.   if (!strcmp(Format, " "))
  675.   {
  676.     FormatCode = 0;
  677.     return True;
  678.   }
  679.   else
  680.   {
  681.     p = strchr(FSet, *Format);
  682.     if (!p) WrError(ErrNum_InvFormat);
  683.     else FormatCode = p - FSet + 1;
  684.     return (p != 0);
  685.   }
  686. }
  687.  
  688. static Integer ImmVal(const tAdrResult *pResult)
  689. {
  690.   if (OpSize == eSymbolSize8Bit)
  691.     return (ShortInt)pResult->Vals[0];
  692.   else
  693.     return (((Integer)pResult->Vals[1]) << 8) + pResult->Vals[0];
  694. }
  695.  
  696. static Boolean IsShort(Byte GenMode, Byte *SMode)
  697. {
  698.   switch (GenMode)
  699.   {
  700.     case 0:  *SMode = 4; break;
  701.     case 1:  *SMode = 3; break;
  702.     case 10: *SMode = 5; break;
  703.     case 11: *SMode = 6; break;
  704.     case 15: *SMode = 7; break;
  705.     default: return False;
  706.   }
  707.   return True;
  708. }
  709.  
  710. static void CodeGen(Byte GenCode, Byte Imm1Code, Byte Imm2Code, const tAdrResult *pSrcAdrResult, const tAdrResult *pDestAdrResult)
  711. {
  712.   if (pSrcAdrResult->Type == ModImm)
  713.   {
  714.     BAsmCode[0] = Imm1Code + OpSize;
  715.     BAsmCode[1] = Imm2Code + pDestAdrResult->Mode;
  716.     memcpy(BAsmCode + 2, pDestAdrResult->Vals, pDestAdrResult->Cnt);
  717.     memcpy(BAsmCode + 2 + pDestAdrResult->Cnt, pSrcAdrResult->Vals, pSrcAdrResult->Cnt);
  718.   }
  719.   else
  720.   {
  721.     BAsmCode[0] = GenCode + OpSize;
  722.     BAsmCode[1] = (pSrcAdrResult->Mode << 4) + pDestAdrResult->Mode;
  723.     memcpy(BAsmCode + 2, pSrcAdrResult->Vals, pSrcAdrResult->Cnt);
  724.     memcpy(BAsmCode + 2 + pSrcAdrResult->Cnt, pDestAdrResult->Vals, pDestAdrResult->Cnt);
  725.   }
  726.   CodeLen = 2 + pSrcAdrResult->Cnt + pDestAdrResult->Cnt;
  727. }
  728.  
  729. /*------------------------------------------------------------------------*/
  730. /* instruction decoders */
  731.  
  732. static void DecodeFixed(Word Code)
  733. {
  734.   if (!ChkArgCnt(0, 0));
  735.   else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  736.   else if (strcmp(Format, " ")) WrError(ErrNum_InvFormat);
  737.   else if (!Hi(Code))
  738.   {
  739.     BAsmCode[0] = Lo(Code);
  740.     CodeLen = 1;
  741.   }
  742.   else
  743.   {
  744.     BAsmCode[0] = Hi(Code);
  745.     BAsmCode[1] = Lo(Code);
  746.     CodeLen = 2;
  747.   }
  748. }
  749.  
  750. static void DecodeString(Word Code)
  751. {
  752.   if (OpSize == eSymbolSizeUnknown) OpSize = 1;
  753.   if (!ChkArgCnt(0, 0));
  754.   else if ((OpSize != 0) && (OpSize != 1)) WrError(ErrNum_InvOpSize);
  755.   else if (strcmp(Format," ")) WrError(ErrNum_InvFormat);
  756.   else if (!Hi(Code))
  757.   {
  758.     BAsmCode[0] = Lo(Code) + OpSize;
  759.     CodeLen = 1;
  760.   }
  761.   else
  762.   {
  763.     BAsmCode[0] = Hi(Code) + OpSize;
  764.     BAsmCode[1] = Lo(Code);
  765.     CodeLen = 2;
  766.   }
  767. }
  768.  
  769. static void DecodeMOV(Word Code)
  770. {
  771.   Integer Num1;
  772.   Byte SMode;
  773.  
  774.   UNUSED(Code);
  775.  
  776.   if (ChkArgCnt(2, 2)
  777.    && CheckFormat("GSQZ"))
  778.   {
  779.     tAdrResult DestAdrResult, SrcAdrResult;
  780.  
  781.     if ((DecodeAdr(&ArgStr[2], MModGen | MModSPRel, &DestAdrResult) != ModNone)
  782.      && (DecodeAdr(&ArgStr[1], MModGen | MModSPRel | MModImm, &SrcAdrResult) != ModNone))
  783.     {
  784.       if (OpSize == eSymbolSizeUnknown) WrError(ErrNum_UndefOpSizes);
  785.       else if ((OpSize != 0) && (OpSize != 1)) WrError(ErrNum_InvOpSize);
  786.       else
  787.       {
  788.         if (FormatCode == 0)
  789.         {
  790.           if ((DestAdrResult.Type == ModSPRel) || (SrcAdrResult.Type == ModSPRel))
  791.             FormatCode = 1;
  792.           else if ((OpSize == 0) && (SrcAdrResult.Type == ModImm) && (IsShort(DestAdrResult.Mode, &SMode)))
  793.             FormatCode = (ImmVal(&SrcAdrResult) == 0) ? 4 : 2;
  794.           else if ((SrcAdrResult.Type == ModImm) && (ImmVal(&SrcAdrResult) >= -8) && (ImmVal(&SrcAdrResult) <= 7))
  795.             FormatCode = 3;
  796.           else if ((SrcAdrResult.Type == ModImm) && ((DestAdrResult.Mode & 14) == 4))
  797.             FormatCode = 2;
  798.           else if ((OpSize == 0) && (SrcAdrResult.Type == ModGen) && (IsShort(SrcAdrResult.Mode, &SMode)) && ((DestAdrResult.Mode & 14) == 4)
  799.                 && ((SrcAdrResult.Mode >= 2) || (Odd(SrcAdrResult.Mode ^ DestAdrResult.Mode))))
  800.             FormatCode = 2;
  801.           else if ((OpSize == 0) && (SrcAdrResult.Type == ModGen) && (SrcAdrResult.Mode <= 1) && (IsShort(DestAdrResult.Mode, &SMode))
  802.                 && ((DestAdrResult.Mode >= 2) || (Odd(SrcAdrResult.Mode ^ DestAdrResult.Mode))))
  803.             FormatCode = 2;
  804.           else if ((OpSize == 0) && (DestAdrResult.Mode <= 1) && (SrcAdrResult.Type == ModGen) && (IsShort(SrcAdrResult.Mode, &SMode))
  805.                 && ((SrcAdrResult.Mode >= 2) || (Odd(SrcAdrResult.Mode ^ DestAdrResult.Mode))))
  806.             FormatCode = 2;
  807.           else
  808.             FormatCode = 1;
  809.         }
  810.         switch (FormatCode)
  811.         {
  812.           case 1:
  813.             if (SrcAdrResult.Type == ModSPRel)
  814.             {
  815.               BAsmCode[0] = 0x74 + OpSize;
  816.               BAsmCode[1] = 0xb0 + DestAdrResult.Mode;
  817.               memcpy(BAsmCode + 2, DestAdrResult.Vals, DestAdrResult.Cnt);
  818.               memcpy(BAsmCode + 2 + DestAdrResult.Cnt, SrcAdrResult.Vals, SrcAdrResult.Cnt);
  819.               CodeLen = 2 + SrcAdrResult.Cnt + DestAdrResult.Cnt;
  820.             }
  821.             else if (DestAdrResult.Type == ModSPRel)
  822.             {
  823.               BAsmCode[0] = 0x74 + OpSize;
  824.               BAsmCode[1] = 0x30 + SrcAdrResult.Mode;
  825.               memcpy(BAsmCode + 2, SrcAdrResult.Vals, SrcAdrResult.Cnt);
  826.               memcpy(BAsmCode + 2 + SrcAdrResult.Cnt, DestAdrResult.Vals, DestAdrResult.Cnt);
  827.               CodeLen = 2 + DestAdrResult.Cnt + SrcAdrResult.Cnt;
  828.             }
  829.             else
  830.               CodeGen(0x72, 0x74, 0xc0, &SrcAdrResult, &DestAdrResult);
  831.             break;
  832.           case 2:
  833.             if (SrcAdrResult.Type == ModImm)
  834.             {
  835.               if (DestAdrResult.Type != ModGen) WrError(ErrNum_InvAddrMode);
  836.               else if ((DestAdrResult.Mode & 14) == 4)
  837.               {
  838.                 BAsmCode[0] = 0xe2 - (OpSize << 6) + ((DestAdrResult.Mode & 1) << 3);
  839.                 memcpy(BAsmCode + 1, SrcAdrResult.Vals, SrcAdrResult.Cnt);
  840.                 CodeLen = 1 + SrcAdrResult.Cnt;
  841.               }
  842.               else if (IsShort(DestAdrResult.Mode, &SMode))
  843.               {
  844.                 if (OpSize != 0) WrError(ErrNum_InvOpSize);
  845.                 else
  846.                 {
  847.                   BAsmCode[0] = 0xc0 + SMode;
  848.                   memcpy(BAsmCode + 1, SrcAdrResult.Vals, SrcAdrResult.Cnt);
  849.                   memcpy(BAsmCode + 1 + SrcAdrResult.Cnt, DestAdrResult.Vals, DestAdrResult.Cnt);
  850.                   CodeLen = 1 + SrcAdrResult.Cnt + DestAdrResult.Cnt;
  851.                 }
  852.               }
  853.               else
  854.                 WrError(ErrNum_InvAddrMode);
  855.             }
  856.             else if ((SrcAdrResult.Type == ModGen) && (IsShort(SrcAdrResult.Mode, &SMode)))
  857.             {
  858.               if (DestAdrResult.Type != ModGen) WrError(ErrNum_InvAddrMode);
  859.               else if ((DestAdrResult.Mode & 14) == 4)
  860.               {
  861.                 if ((SrcAdrResult.Mode <= 1) && (!Odd(SrcAdrResult.Mode ^ DestAdrResult.Mode))) WrError(ErrNum_InvAddrMode);
  862.                 else
  863.                 {
  864.                   if (SMode == 3) SMode++;
  865.                   BAsmCode[0] = 0x30 + ((DestAdrResult.Mode & 1) << 2) + (SMode & 3);
  866.                   memcpy(BAsmCode + 1, SrcAdrResult.Vals, SrcAdrResult.Cnt);
  867.                   CodeLen = 1 + SrcAdrResult.Cnt;
  868.                 }
  869.               }
  870.               else if ((DestAdrResult.Mode & 14) == 0)
  871.               {
  872.                 if ((SrcAdrResult.Mode <= 1) && (!Odd(SrcAdrResult.Mode ^ DestAdrResult.Mode))) WrError(ErrNum_InvAddrMode);
  873.                 else
  874.                 {
  875.                   if (SMode == 3) SMode++;
  876.                   BAsmCode[0] = 0x08 + ((DestAdrResult.Mode & 1) << 2) + (SMode & 3);
  877.                   memcpy(BAsmCode + 1, SrcAdrResult.Vals, SrcAdrResult.Cnt);
  878.                   CodeLen = 1 + SrcAdrResult.Cnt;
  879.                 }
  880.               }
  881.               else if (((SrcAdrResult.Mode & 14) != 0) || (!IsShort(DestAdrResult.Mode, &SMode))) WrError(ErrNum_InvAddrMode);
  882.               else if ((DestAdrResult.Mode <= 1) && (!Odd(SrcAdrResult.Mode ^ DestAdrResult.Mode))) WrError(ErrNum_InvAddrMode);
  883.               else
  884.               {
  885.                 if (SMode == 3) SMode++;
  886.                 BAsmCode[0] = 0x00 + ((SrcAdrResult.Mode & 1) << 2) + (SMode & 3);
  887.                 memcpy(BAsmCode + 1, DestAdrResult.Vals, DestAdrResult.Cnt);
  888.                 CodeLen = 1 + DestAdrResult.Cnt;
  889.               }
  890.             }
  891.             else
  892.               WrError(ErrNum_InvAddrMode);
  893.             break;
  894.           case 3:
  895.             if (SrcAdrResult.Type != ModImm) WrError(ErrNum_InvAddrMode);
  896.             else
  897.             {
  898.               Num1 = ImmVal(&SrcAdrResult);
  899.               if (ChkRange(Num1, -8, 7))
  900.               {
  901.                 BAsmCode[0] = 0xd8 + OpSize;
  902.                 BAsmCode[1] = (Num1 << 4) + DestAdrResult.Mode;
  903.                 memcpy(BAsmCode + 2, DestAdrResult.Vals, DestAdrResult.Cnt);
  904.                 CodeLen = 2 + DestAdrResult.Cnt;
  905.               }
  906.             }
  907.             break;
  908.           case 4:
  909.             if (OpSize != 0) WrError(ErrNum_InvOpSize);
  910.             else if (SrcAdrResult.Type != ModImm) WrError(ErrNum_InvAddrMode);
  911.             else if (!IsShort(DestAdrResult.Mode, &SMode)) WrError(ErrNum_InvAddrMode);
  912.             else
  913.             {
  914.               Num1 = ImmVal(&SrcAdrResult);
  915.               if (ChkRange(Num1, 0, 0))
  916.               {
  917.                 BAsmCode[0] = 0xb0 + SMode;
  918.                 memcpy(BAsmCode + 1, DestAdrResult.Vals, DestAdrResult.Cnt);
  919.                 CodeLen = 1 + DestAdrResult.Cnt;
  920.               }
  921.             }
  922.             break;
  923.         }
  924.       }
  925.     }
  926.   }
  927. }
  928.  
  929. static void DecodeLDC_STC(Word IsSTC)
  930. {
  931.   Byte CReg;
  932.  
  933.   if (ChkArgCnt(2, 2)
  934.    && CheckFormat("G"))
  935.   {
  936.     const tStrComp *pRegArg = IsSTC ? &ArgStr[1] : &ArgStr[2],
  937.                    *pMemArg = IsSTC ? &ArgStr[2] : &ArgStr[1];
  938.  
  939.     if (!as_strcasecmp(pRegArg->str.p_str, "PC"))
  940.     {
  941.       if (!IsSTC) WrError(ErrNum_InvAddrMode);
  942.       else
  943.       {
  944.         tAdrResult AdrResult;
  945.  
  946.         DecodeAdr(pMemArg, MModGen | MModReg32 | MModAReg32, &AdrResult);
  947.         if (AdrResult.Type == ModAReg32)
  948.           AdrResult.Mode = 4;
  949.         if ((AdrResult.Type == ModGen) && (AdrResult.Mode < 6)) WrError(ErrNum_InvAddrMode);
  950.         else
  951.         {
  952.           BAsmCode[0] = 0x7c;
  953.           BAsmCode[1] = 0xc0 + AdrResult.Mode;
  954.           memcpy(BAsmCode + 2, AdrResult.Vals, AdrResult.Cnt);
  955.           CodeLen = 2 + AdrResult.Cnt;
  956.         }
  957.       }
  958.     }
  959.     else if (DecodeCReg(pRegArg->str.p_str, &CReg))
  960.     {
  961.       tAdrResult AdrResult;
  962.  
  963.       SetOpSize(1, NULL);
  964.       if (DecodeAdr(pMemArg, MModGen | (IsSTC ? 0 : MModImm), &AdrResult) == ModImm)
  965.       {
  966.         BAsmCode[0] = 0xeb;
  967.         BAsmCode[1] = CReg << 4;
  968.         memcpy(BAsmCode + 2, AdrResult.Vals, AdrResult.Cnt);
  969.         CodeLen = 2 + AdrResult.Cnt;
  970.       }
  971.       else if (AdrResult.Type == ModGen)
  972.       {
  973.         BAsmCode[0] = 0x7a + IsSTC;
  974.         BAsmCode[1] = 0x80 + (CReg << 4) + AdrResult.Mode;
  975.         memcpy(BAsmCode + 2, AdrResult.Vals, AdrResult.Cnt);
  976.         CodeLen = 2 + AdrResult.Cnt;
  977.       }
  978.     }
  979.   }
  980. }
  981.  
  982. static void DecodeLDCTX_STCTX(Word Code)
  983. {
  984.   if (!ChkArgCnt(2, 2));
  985.   else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  986.   else
  987.   {
  988.     tAdrResult SrcAdrResult;
  989.  
  990.     if (DecodeAdr(&ArgStr[1], MModGen, &SrcAdrResult) == ModGen)
  991.     {
  992.       if (SrcAdrResult.Mode != 15) WrError(ErrNum_InvAddrMode);
  993.       else
  994.       {
  995.         tAdrResult DestAdrResult;
  996.  
  997.         memcpy(BAsmCode + 2, SrcAdrResult.Vals, SrcAdrResult.Cnt);
  998.         if (DecodeAdr(&ArgStr[2], MModAbs20, &DestAdrResult) == ModAbs20)
  999.         {
  1000.           memcpy(BAsmCode + 4, DestAdrResult.Vals, DestAdrResult.Cnt);
  1001.           BAsmCode[0] = Code;
  1002.           BAsmCode[1] = 0xf0;
  1003.           CodeLen = 7;
  1004.         }
  1005.       }
  1006.     }
  1007.   }
  1008. }
  1009.  
  1010. static void DecodeLDE_STE(Word IsLDE)
  1011. {
  1012.   if (ChkArgCnt(2, 2)
  1013.    && CheckFormat("G"))
  1014.   {
  1015.     tStrComp *pArg1 = IsLDE ? &ArgStr[2] : &ArgStr[1],
  1016.              *pArg2 = IsLDE ? &ArgStr[1] : &ArgStr[2];
  1017.     tAdrResult AdrResult1;
  1018.  
  1019.     if (DecodeAdr(pArg1, MModGen, &AdrResult1) != ModNone)
  1020.     {
  1021.       if (OpSize == eSymbolSizeUnknown) WrError(ErrNum_UndefOpSizes);
  1022.       else if (OpSize > 1) WrError(ErrNum_InvOpSize);
  1023.       else
  1024.       {
  1025.         tAdrResult AdrResult2;
  1026.  
  1027.         if (DecodeAdr(pArg2, MModAbs20 | MModDisp20 | MModIReg32, &AdrResult2) != ModNone)
  1028.         {
  1029.           BAsmCode[0] = 0x74 + OpSize;
  1030.           BAsmCode[1] = (IsLDE << 7) + AdrResult1.Mode;
  1031.           switch (AdrResult2.Type)
  1032.           {
  1033.             case ModDisp20: BAsmCode[1] += 0x10; break;
  1034.             case ModIReg32: BAsmCode[1] += 0x20; break;
  1035.           }
  1036.           memcpy(BAsmCode + 2, AdrResult1.Vals, AdrResult1.Cnt);
  1037.           memcpy(BAsmCode + 2 + AdrResult1.Cnt, AdrResult2.Vals, AdrResult2.Cnt);
  1038.           CodeLen = 2 + AdrResult1.Cnt + AdrResult2.Cnt;
  1039.         }
  1040.       }
  1041.     }
  1042.   }
  1043. }
  1044.  
  1045. static void DecodeMOVA(Word Code)
  1046. {
  1047.   UNUSED(Code);
  1048.  
  1049.   if (ChkArgCnt(2, 2)
  1050.    && CheckFormat("G"))
  1051.   {
  1052.     tAdrResult SrcAdrResult;
  1053.  
  1054.     if (DecodeAdr(&ArgStr[1], MModGen, &SrcAdrResult) != ModNone)
  1055.     {
  1056.       if (SrcAdrResult.Mode < 8) WrError(ErrNum_InvAddrMode);
  1057.       else
  1058.       {
  1059.         tAdrResult DestAdrResult;
  1060.  
  1061.         if (DecodeAdr(&ArgStr[2], MModGen, &DestAdrResult) != ModNone)
  1062.         {
  1063.           if (DestAdrResult.Mode > 5) WrError(ErrNum_InvAddrMode);
  1064.           else
  1065.           {
  1066.             BAsmCode[0] = 0xeb;
  1067.             BAsmCode[1] = (DestAdrResult.Mode << 4) + SrcAdrResult.Mode;
  1068.             memcpy(BAsmCode + 2, SrcAdrResult.Vals, SrcAdrResult.Cnt);
  1069.             CodeLen = 2 + SrcAdrResult.Cnt;
  1070.           }
  1071.         }
  1072.       }
  1073.     }
  1074.   }
  1075. }
  1076.  
  1077. static void DecodeDir(Word Code)
  1078. {
  1079.   Boolean OK;
  1080.   Integer Num1;
  1081.  
  1082.   if (OpSize > 0) WrError(ErrNum_InvOpSize);
  1083.   else if (ChkArgCnt(2, 2)
  1084.         && CheckFormat("G"))
  1085.   {
  1086.     OK = True; Num1 = 0;
  1087.     if (!as_strcasecmp(ArgStr[2].str.p_str, "R0L"));
  1088.     else if (!as_strcasecmp(ArgStr[1].str.p_str, "R0L")) Num1 = 1;
  1089.     else OK = False;
  1090.     if (!OK) WrError(ErrNum_InvAddrMode);
  1091.     else
  1092.     {
  1093.       tAdrResult AdrResult;
  1094.  
  1095.       if (DecodeAdr(&ArgStr[Num1 + 1], MModGen, &AdrResult) != ModNone)
  1096.       {
  1097.         if (((AdrResult.Mode & 14) == 4) || ((AdrResult.Mode == 0) && (Num1 == 1))) WrError(ErrNum_InvAddrMode);
  1098.         else
  1099.         {
  1100.           BAsmCode[0] = 0x7c;
  1101.           BAsmCode[1] = (Num1 << 7) + (Code << 4) + AdrResult.Mode;
  1102.           memcpy(BAsmCode + 2, AdrResult.Vals, AdrResult.Cnt);
  1103.           CodeLen = 2 + AdrResult.Cnt;
  1104.         }
  1105.       }
  1106.     }
  1107.   }
  1108. }
  1109.  
  1110. static void DecodePUSH_POP(Word IsPOP)
  1111. {
  1112.   if (ChkArgCnt(1, 1)
  1113.    && CheckFormat("GS"))
  1114.   {
  1115.     tAdrResult AdrResult;
  1116.  
  1117.     if (DecodeAdr(&ArgStr[1], MModGen | (IsPOP ? 0 : MModImm), &AdrResult) != ModNone)
  1118.     {
  1119.       if (OpSize == eSymbolSizeUnknown) WrError(ErrNum_UndefOpSizes);
  1120.       else if (OpSize > 1) WrError(ErrNum_InvOpSize);
  1121.       else
  1122.       {
  1123.         if (FormatCode == 0)
  1124.         {
  1125.           if ((AdrResult.Type != ModGen))
  1126.             FormatCode = 1;
  1127.           else if ((OpSize == 0) && (AdrResult.Mode < 2))
  1128.             FormatCode = 2;
  1129.           else if ((OpSize == 1) && ((AdrResult.Mode & 14) == 4))
  1130.             FormatCode = 2;
  1131.           else
  1132.             FormatCode = 1;
  1133.         }
  1134.         switch (FormatCode)
  1135.         {
  1136.           case 1:
  1137.             if (AdrResult.Type == ModImm)
  1138.             {
  1139.               BAsmCode[0] = 0x7c + OpSize;
  1140.               BAsmCode[1] = 0xe2;
  1141.             }
  1142.             else
  1143.             {
  1144.               BAsmCode[0] = 0x74 + OpSize;
  1145.               BAsmCode[1] = 0x40 + (IsPOP * 0x90) + AdrResult.Mode;
  1146.             }
  1147.             memcpy(BAsmCode + 2, AdrResult.Vals, AdrResult.Cnt);
  1148.             CodeLen = 2 + AdrResult.Cnt;
  1149.             break;
  1150.           case 2:
  1151.             if (AdrResult.Type != ModGen) WrError(ErrNum_InvAddrMode);
  1152.             else if ((OpSize == 0) && (AdrResult.Mode < 2))
  1153.             {
  1154.               BAsmCode[0] = 0x82 + (AdrResult.Mode << 3) + (IsPOP << 4);
  1155.               CodeLen = 1;
  1156.             }
  1157.             else if ((OpSize == 1) && ((AdrResult.Mode & 14) == 4))
  1158.             {
  1159.               BAsmCode[0] = 0xc2 + ((AdrResult.Mode & 1) << 3) + (IsPOP << 4);
  1160.               CodeLen = 1;
  1161.             }
  1162.             else
  1163.               WrError(ErrNum_InvAddrMode);
  1164.             break;
  1165.         }
  1166.       }
  1167.     }
  1168.   }
  1169. }
  1170.  
  1171. static void DecodePUSHC_POPC(Word Code)
  1172. {
  1173.   Byte CReg;
  1174.  
  1175.   if (ChkArgCnt(1, 1)
  1176.    && CheckFormat("G"))
  1177.    if (DecodeCReg(ArgStr[1].str.p_str, &CReg))
  1178.    {
  1179.      BAsmCode[0] = 0xeb;
  1180.      BAsmCode[1] = Code + (CReg << 4);
  1181.      CodeLen = 2;
  1182.    }
  1183. }
  1184.  
  1185. static void DecodePUSHM_POPM(Word IsPOPM)
  1186. {
  1187.   if (ChkArgCnt(1, ArgCntMax))
  1188.   {
  1189.     int z;
  1190.     Byte Reg;
  1191.     tSymbolSize DataSize = eSymbolSize16Bit;
  1192.  
  1193.     BAsmCode[1] = 0; z = 1;
  1194.     for (z = 1; z <= ArgCnt; z++)
  1195.     {
  1196.       if (!DecodeReg(&ArgStr[z], &Reg, True, &DataSize))
  1197.         return;
  1198.       BAsmCode[1] |= 1 << (IsPOPM ? Reg : 7 - Reg);
  1199.     }
  1200.     BAsmCode[0] = 0xec + IsPOPM;
  1201.     CodeLen = 2;
  1202.   }
  1203. }
  1204.  
  1205. static void DecodePUSHA(Word Code)
  1206. {
  1207.   UNUSED(Code);
  1208.  
  1209.   if (ChkArgCnt(1, 1)
  1210.    && CheckFormat("G"))
  1211.   {
  1212.     tAdrResult AdrResult;
  1213.  
  1214.     if (DecodeAdr(&ArgStr[1], MModGen, &AdrResult) != ModNone)
  1215.     {
  1216.       if (AdrResult.Mode < 8) WrError(ErrNum_InvAddrMode);
  1217.       else
  1218.       {
  1219.         BAsmCode[0] = 0x7d;
  1220.         BAsmCode[1] = 0x90 + AdrResult.Mode;
  1221.         memcpy(BAsmCode + 2, AdrResult.Vals, AdrResult.Cnt);
  1222.         CodeLen = 2 + AdrResult.Cnt;
  1223.       }
  1224.     }
  1225.   }
  1226. }
  1227.  
  1228. static void DecodeXCHG(Word Code)
  1229. {
  1230.   UNUSED(Code);
  1231.  
  1232.   if (ChkArgCnt(2, 2)
  1233.    && CheckFormat("G"))
  1234.   {
  1235.     tAdrResult SrcAdrResult, DestAdrResult;
  1236.  
  1237.     if ((DecodeAdr(&ArgStr[1], MModGen, &SrcAdrResult) != ModNone)
  1238.      && (DecodeAdr(&ArgStr[2], MModGen, &DestAdrResult) != ModNone))
  1239.     {
  1240.       if (OpSize == eSymbolSizeUnknown) WrError(ErrNum_UndefOpSizes);
  1241.       else if (OpSize > 1) WrError(ErrNum_InvOpSize);
  1242.       else if (SrcAdrResult.Mode < 4)
  1243.       {
  1244.         BAsmCode[0] = 0x7a + OpSize;
  1245.         BAsmCode[1] = (SrcAdrResult.Mode << 4) + DestAdrResult.Mode;
  1246.         memcpy(BAsmCode + 2, DestAdrResult.Vals, DestAdrResult.Cnt);
  1247.         CodeLen = 2 + DestAdrResult.Cnt;
  1248.       }
  1249.       else if (DestAdrResult.Mode < 4)
  1250.       {
  1251.         BAsmCode[0] = 0x7a + OpSize;
  1252.         BAsmCode[1] = (DestAdrResult.Mode << 4) + SrcAdrResult.Mode;
  1253.         memcpy(BAsmCode + 2, SrcAdrResult.Vals, SrcAdrResult.Cnt);
  1254.         CodeLen = 2 + SrcAdrResult.Cnt;
  1255.       }
  1256.       else
  1257.         WrError(ErrNum_InvAddrMode);
  1258.     }
  1259.   }
  1260. }
  1261.  
  1262. static void DecodeSTZ_STNZ(Word Code)
  1263. {
  1264.   Byte SMode;
  1265.  
  1266.   if (ChkArgCnt(2, 2)
  1267.    && CheckFormat("G"))
  1268.   {
  1269.     tAdrResult DestAdrResult;
  1270.  
  1271.     if (OpSize == eSymbolSizeUnknown) OpSize++;
  1272.     if (DecodeAdr(&ArgStr[2], MModGen, &DestAdrResult) != ModNone)
  1273.     {
  1274.       if (!IsShort(DestAdrResult.Mode, &SMode)) WrError(ErrNum_InvAddrMode);
  1275.       else
  1276.       {
  1277.         tAdrResult SrcAdrResult;
  1278.  
  1279.         if (DecodeAdr(&ArgStr[1], MModImm, &SrcAdrResult) != ModNone)
  1280.         {
  1281.           BAsmCode[0] = Code + SMode;
  1282.           BAsmCode[1] = SrcAdrResult.Vals[0];
  1283.           memcpy(BAsmCode + 2, DestAdrResult.Vals, DestAdrResult.Cnt);
  1284.           CodeLen =2 + DestAdrResult.Cnt;
  1285.         }
  1286.       }
  1287.     }
  1288.   }
  1289. }
  1290.  
  1291. static void DecodeSTZX(Word Code)
  1292. {
  1293.   Byte SMode;
  1294.  
  1295.   UNUSED(Code);
  1296.  
  1297.   if (ChkArgCnt(3, 3)
  1298.    && CheckFormat("G"))
  1299.   {
  1300.     tAdrResult AdrResult3;
  1301.  
  1302.     if (OpSize == eSymbolSizeUnknown) OpSize++;
  1303.     if (DecodeAdr(&ArgStr[3], MModGen, &AdrResult3) != ModNone)
  1304.     {
  1305.       if (!IsShort(AdrResult3.Mode, &SMode)) WrError(ErrNum_InvAddrMode);
  1306.       else
  1307.       {
  1308.         tAdrResult AdrResult1;
  1309.  
  1310.         if (DecodeAdr(&ArgStr[1], MModImm, &AdrResult1) != ModNone)
  1311.         {
  1312.           tAdrResult AdrResult2;
  1313.  
  1314.           if (DecodeAdr(&ArgStr[2], MModImm, &AdrResult2) != ModNone)
  1315.           {
  1316.             BAsmCode[0] = 0xd8 + SMode;
  1317.             BAsmCode[1] = AdrResult1.Vals[0];
  1318.             memcpy(BAsmCode + 2, AdrResult3.Vals, AdrResult3.Cnt);
  1319.             BAsmCode[2 + AdrResult3.Cnt] = AdrResult2.Vals[0];
  1320.             CodeLen = 3 + AdrResult3.Cnt;
  1321.           }
  1322.         }
  1323.       }
  1324.     }
  1325.   }
  1326. }
  1327.  
  1328. static void DecodeADD(Word Code)
  1329. {
  1330.   Integer Num1;
  1331.   Byte SMode;
  1332.   LongInt AdrLong;
  1333.  
  1334.   UNUSED(Code);
  1335.  
  1336.   if (!ChkArgCnt(2, 2));
  1337.   else if (!as_strcasecmp(ArgStr[2].str.p_str, "SP"))
  1338.   {
  1339.     if (OpSize == eSymbolSizeUnknown) OpSize = 1;
  1340.     if (CheckFormat("GQ"))
  1341.     {
  1342.       tAdrResult SrcAdrResult;
  1343.  
  1344.       if (DecodeAdr(&ArgStr[1], MModImm, &SrcAdrResult) != ModNone)
  1345.       {
  1346.         if (OpSize == eSymbolSizeUnknown) WrError(ErrNum_UndefOpSizes);
  1347.         else if (OpSize > 1) WrError(ErrNum_InvOpSize);
  1348.         else
  1349.         {
  1350.           AdrLong = ImmVal(&SrcAdrResult);
  1351.           if (FormatCode == 0)
  1352.           {
  1353.             if ((AdrLong >= -8) && (AdrLong <= 7)) FormatCode = 2;
  1354.             else FormatCode = 1;
  1355.           }
  1356.           switch (FormatCode)
  1357.           {
  1358.             case 1:
  1359.               BAsmCode[0] = 0x7c + OpSize;
  1360.               BAsmCode[1] = 0xeb;
  1361.               memcpy(BAsmCode + 2, SrcAdrResult.Vals, SrcAdrResult.Cnt);
  1362.               CodeLen = 2 + SrcAdrResult.Cnt;
  1363.               break;
  1364.             case 2:
  1365.               if (ChkRange(AdrLong, -8, 7))
  1366.               {
  1367.                 BAsmCode[0] = 0x7d;
  1368.                 BAsmCode[1] = 0xb0 + (AdrLong & 15);
  1369.                 CodeLen = 2;
  1370.               }
  1371.               break;
  1372.           }
  1373.         }
  1374.       }
  1375.     }
  1376.   }
  1377.   else if (CheckFormat("GQS"))
  1378.   {
  1379.     tAdrResult DestAdrResult, SrcAdrResult;
  1380.  
  1381.     if ((DecodeAdr(&ArgStr[2], MModGen, &DestAdrResult) != ModNone)
  1382.      && (DecodeAdr(&ArgStr[1], MModImm | MModGen, &SrcAdrResult) != ModNone))
  1383.     {
  1384.       if (OpSize == eSymbolSizeUnknown) WrError(ErrNum_UndefOpSizes);
  1385.       else if ((OpSize != 0) && (OpSize != 1)) WrError(ErrNum_InvOpSize);
  1386.       else
  1387.       {
  1388.         if (FormatCode == 0)
  1389.         {
  1390.           if (SrcAdrResult.Type == ModImm)
  1391.           {
  1392.             if ((ImmVal(&SrcAdrResult) >= -8) && (ImmVal(&SrcAdrResult) <= 7))
  1393.               FormatCode = 2;
  1394.             else if ((IsShort(DestAdrResult.Mode, &SMode)) && (OpSize == 0))
  1395.               FormatCode = 3;
  1396.             else
  1397.               FormatCode = 1;
  1398.           }
  1399.           else
  1400.           {
  1401.             if ((OpSize == 0) && (IsShort(SrcAdrResult.Mode, &SMode)) && (DestAdrResult.Mode <= 1) &&
  1402.                 ((SrcAdrResult.Mode > 1) || (Odd(SrcAdrResult.Mode ^ DestAdrResult.Mode))))
  1403.               FormatCode = 3;
  1404.             else
  1405.               FormatCode = 1;
  1406.           }
  1407.         }
  1408.         switch (FormatCode)
  1409.         {
  1410.           case 1:
  1411.             CodeGen(0xa0, 0x76, 0x40, &SrcAdrResult, &DestAdrResult);
  1412.             break;
  1413.           case 2:
  1414.             if (SrcAdrResult.Type != ModImm) WrError(ErrNum_InvAddrMode);
  1415.             else
  1416.             {
  1417.               Num1 = ImmVal(&SrcAdrResult);
  1418.               if (ChkRange(Num1, -8, 7))
  1419.               {
  1420.                 BAsmCode[0] = 0xc8 + OpSize;
  1421.                 BAsmCode[1] = (Num1 << 4) + DestAdrResult.Mode;
  1422.                 memcpy(BAsmCode + 2, DestAdrResult.Vals, DestAdrResult.Cnt);
  1423.                 CodeLen = 2 + DestAdrResult.Cnt;
  1424.               }
  1425.             }
  1426.             break;
  1427.           case 3:
  1428.             if (OpSize != 0) WrError(ErrNum_InvOpSize);
  1429.             else if (!IsShort(DestAdrResult.Mode, &SMode)) WrError(ErrNum_InvAddrMode);
  1430.             else if (SrcAdrResult.Type == ModImm)
  1431.             {
  1432.               BAsmCode[0] = 0x80 + SMode;
  1433.               BAsmCode[1] = SrcAdrResult.Vals[0];
  1434.               memcpy(BAsmCode + 2, DestAdrResult.Vals, DestAdrResult.Cnt);
  1435.               CodeLen = 2 + DestAdrResult.Cnt;
  1436.             }
  1437.             else if ((DestAdrResult.Mode >= 2) || (!IsShort(SrcAdrResult.Mode, &SMode))) WrError(ErrNum_InvAddrMode);
  1438.             else if ((SrcAdrResult.Mode < 2) && (!Odd(SrcAdrResult.Mode ^ DestAdrResult.Mode))) WrError(ErrNum_InvAddrMode);
  1439.             else
  1440.             {
  1441.               if (SMode == 3) SMode++;
  1442.               BAsmCode[0] = 0x20 + ((DestAdrResult.Mode & 1) << 2) + (SMode & 3);    /* RMS 05: Just like #04 */
  1443.               memcpy(BAsmCode + 1, SrcAdrResult.Vals, SrcAdrResult.Cnt);
  1444.               CodeLen = 1 + SrcAdrResult.Cnt;
  1445.             }
  1446.             break;
  1447.         }
  1448.       }
  1449.     }
  1450.   }
  1451. }
  1452.  
  1453. static void DecodeCMP(Word Code)
  1454. {
  1455.   Byte SMode;
  1456.   Integer Num1;
  1457.  
  1458.   UNUSED(Code);
  1459.  
  1460.   if (ChkArgCnt(2, 2)
  1461.    && CheckFormat("GQS"))
  1462.   {
  1463.     tAdrResult DestAdrResult, SrcAdrResult;
  1464.  
  1465.     if ((DecodeAdr(&ArgStr[2], MModGen, &DestAdrResult) != ModNone)
  1466.      && (DecodeAdr(&ArgStr[1], MModImm | MModGen, &SrcAdrResult) != ModNone))
  1467.     {
  1468.       if (OpSize == eSymbolSizeUnknown) WrError(ErrNum_UndefOpSizes);
  1469.       else if ((OpSize != 0) && (OpSize != 1)) WrError(ErrNum_InvOpSize);
  1470.       else
  1471.       {
  1472.         if (FormatCode == 0)
  1473.         {
  1474.           if (SrcAdrResult.Type == ModImm)
  1475.           {
  1476.             if ((ImmVal(&SrcAdrResult) >= -8) && (ImmVal(&SrcAdrResult) <= 7))
  1477.               FormatCode = 2;
  1478.             else if ((IsShort(DestAdrResult.Mode, &SMode)) && (OpSize == 0))
  1479.               FormatCode = 3;
  1480.             else
  1481.               FormatCode = 1;
  1482.           }
  1483.           else
  1484.           {
  1485.             if ((OpSize == 0) && (IsShort(SrcAdrResult.Mode, &SMode)) && (DestAdrResult.Mode <= 1) &&
  1486.                 ((SrcAdrResult.Mode > 1) || (Odd(SrcAdrResult.Mode ^ DestAdrResult.Mode))))
  1487.               FormatCode = 3;
  1488.             else
  1489.               FormatCode = 1;
  1490.           }
  1491.         }
  1492.         switch (FormatCode)
  1493.         {
  1494.           case 1:
  1495.             CodeGen(0xc0, 0x76, 0x80, &SrcAdrResult, &DestAdrResult);
  1496.             break;
  1497.           case 2:
  1498.             if (SrcAdrResult.Type != ModImm) WrError(ErrNum_InvAddrMode);
  1499.             else
  1500.             {
  1501.               Num1 = ImmVal(&SrcAdrResult);
  1502.               if (ChkRange(Num1, -8, 7))
  1503.               {
  1504.                 BAsmCode[0] = 0xd0 + OpSize;
  1505.                 BAsmCode[1] = (Num1 << 4) + DestAdrResult.Mode;
  1506.                 memcpy(BAsmCode + 2, DestAdrResult.Vals, DestAdrResult.Cnt);
  1507.                 CodeLen = 2 + DestAdrResult.Cnt;
  1508.               }
  1509.               /* else? */
  1510.             }
  1511.             break;
  1512.           case 3:
  1513.             if (OpSize != 0) WrError(ErrNum_InvOpSize);
  1514.             else if (!IsShort(DestAdrResult.Mode, &SMode)) WrError(ErrNum_InvAddrMode);
  1515.             else if (SrcAdrResult.Type == ModImm)
  1516.             {
  1517.               BAsmCode[0] = 0xe0 + SMode;
  1518.               BAsmCode[1] = SrcAdrResult.Vals[0];
  1519.               memcpy(BAsmCode + 2, DestAdrResult.Vals, DestAdrResult.Cnt);
  1520.               CodeLen = 2 + DestAdrResult.Cnt;
  1521.             }
  1522.             else if ((DestAdrResult.Mode >= 2) || (!IsShort(SrcAdrResult.Mode, &SMode))) WrError(ErrNum_InvAddrMode);
  1523.             else if ((SrcAdrResult.Mode < 2) && (!Odd(SrcAdrResult.Mode ^ DestAdrResult.Mode))) WrError(ErrNum_InvAddrMode);
  1524.             else
  1525.             {
  1526.               if (SMode == 3) SMode++;
  1527.               BAsmCode[0] = 0x38 + ((DestAdrResult.Mode & 1) << 2) + (SMode & 3); /* RMS 04: destination reg is bit 2! */
  1528.               memcpy(BAsmCode + 1, SrcAdrResult.Vals, SrcAdrResult.Cnt);
  1529.               CodeLen = 1 + SrcAdrResult.Cnt;
  1530.             }
  1531.             break;
  1532.         }
  1533.       }
  1534.     }
  1535.   }
  1536. }
  1537.  
  1538. static void DecodeSUB(Word Code)
  1539. {
  1540.   Byte SMode;
  1541.   Integer Num1;
  1542.  
  1543.   UNUSED(Code);
  1544.  
  1545.   if (ChkArgCnt(2, 2)
  1546.    && CheckFormat("GQS"))
  1547.   {
  1548.     tAdrResult DestAdrResult, SrcAdrResult;
  1549.  
  1550.     if ((DecodeAdr(&ArgStr[2], MModGen, &DestAdrResult) != ModNone)
  1551.      && (DecodeAdr(&ArgStr[1], MModImm | MModGen, &SrcAdrResult) != ModNone))
  1552.     {
  1553.       if (OpSize == eSymbolSizeUnknown) WrError(ErrNum_UndefOpSizes);
  1554.       else if ((OpSize != 0) && (OpSize != 1)) WrError(ErrNum_InvOpSize);
  1555.       else
  1556.       {
  1557.         if (FormatCode == 0)
  1558.         {
  1559.           if (SrcAdrResult.Type == ModImm)
  1560.           {
  1561.             if ((ImmVal(&SrcAdrResult) >= -7) && (ImmVal(&SrcAdrResult) <= 8))
  1562.               FormatCode = 2;
  1563.             else if ((IsShort(DestAdrResult.Mode, &SMode)) && (OpSize == 0))
  1564.               FormatCode = 3;
  1565.             else
  1566.               FormatCode = 1;
  1567.           }
  1568.           else
  1569.           {
  1570.             if ((OpSize == 0) && (IsShort(SrcAdrResult.Mode, &SMode)) & (DestAdrResult.Mode <= 1) &&
  1571.                 ((SrcAdrResult.Mode > 1) || (Odd(SrcAdrResult.Mode ^ DestAdrResult.Mode))))
  1572.               FormatCode = 3;
  1573.             else
  1574.               FormatCode = 1;
  1575.           }
  1576.         }
  1577.         switch (FormatCode)
  1578.         {
  1579.           case 1:
  1580.             CodeGen(0xa8, 0x76, 0x50, &SrcAdrResult, &DestAdrResult);
  1581.             break;
  1582.           case 2:
  1583.             if (SrcAdrResult.Type != ModImm) WrError(ErrNum_InvAddrMode);
  1584.             else
  1585.             {
  1586.               Num1 = ImmVal(&SrcAdrResult);
  1587.               if (ChkRange(Num1, -7, 8))
  1588.               {
  1589.                 BAsmCode[0] = 0xc8 + OpSize;
  1590.                 BAsmCode[1] = ((-Num1) << 4) + DestAdrResult.Mode;
  1591.                 memcpy(BAsmCode + 2, DestAdrResult.Vals, DestAdrResult.Cnt);
  1592.                 CodeLen = 2 + DestAdrResult.Cnt;
  1593.               }
  1594.             }
  1595.             break;
  1596.           case 3:
  1597.             if (OpSize != 0) WrError(ErrNum_InvOpSize);
  1598.             else if (!IsShort(DestAdrResult.Mode, &SMode)) WrError(ErrNum_InvAddrMode);
  1599.             else if (SrcAdrResult.Type == ModImm)
  1600.             {
  1601.               BAsmCode[0] = 0x88 + SMode;
  1602.               BAsmCode[1] = SrcAdrResult.Vals[0];
  1603.               memcpy(BAsmCode + 2, DestAdrResult.Vals, DestAdrResult.Cnt);
  1604.               CodeLen = 2 + DestAdrResult.Cnt;
  1605.             }
  1606.             else if ((DestAdrResult.Mode >= 2) || (!IsShort(SrcAdrResult.Mode, &SMode))) WrError(ErrNum_InvAddrMode);
  1607.             else if ((SrcAdrResult.Mode < 2) && (!Odd(SrcAdrResult.Mode ^ DestAdrResult.Mode))) WrError(ErrNum_InvAddrMode);
  1608.             else
  1609.             {
  1610.               if (SMode == 3) SMode++;
  1611.               BAsmCode[0] = 0x28 + ((DestAdrResult.Mode & 1) << 2) + (SMode & 3);    /* RMS 06: just like RMS 04 */
  1612.               memcpy(BAsmCode + 1, SrcAdrResult.Vals, SrcAdrResult.Cnt);
  1613.               CodeLen = 1 + SrcAdrResult.Cnt;
  1614.             }
  1615.             break;
  1616.         }
  1617.       }
  1618.     }
  1619.   }
  1620. }
  1621.  
  1622. static void DecodeGen1(Word Code)
  1623. {
  1624.   if (ChkArgCnt(1, 1)
  1625.    && CheckFormat("G"))
  1626.   {
  1627.     tAdrResult AdrResult;
  1628.  
  1629.     if (DecodeAdr(&ArgStr[1], MModGen, &AdrResult) != ModNone)
  1630.     {
  1631.       if (OpSize == eSymbolSizeUnknown) WrError(ErrNum_UndefOpSizes);
  1632.       else if ((OpSize != 0) && (OpSize != 1)) WrError(ErrNum_InvOpSize);
  1633.       else
  1634.       {
  1635.         BAsmCode[0] = Hi(Code) + OpSize;
  1636.         BAsmCode[1] = Lo(Code) + AdrResult.Mode;
  1637.         memcpy(BAsmCode + 2, AdrResult.Vals, AdrResult.Cnt);
  1638.         CodeLen = 2 + AdrResult.Cnt;
  1639.       }
  1640.     }
  1641.   }
  1642. }
  1643.  
  1644. static void DecodeGen2(Word Index)
  1645. {
  1646.   Gen2Order *pOrder = Gen2Orders + Index;
  1647.  
  1648.   if (ChkArgCnt(2, 2)
  1649.    && CheckFormat("G"))
  1650.   {
  1651.     tAdrResult DestAdrResult, SrcAdrResult;
  1652.  
  1653.     if ((DecodeAdr(&ArgStr[2], MModGen, &DestAdrResult) != ModNone)
  1654.      && (DecodeAdr(&ArgStr[1], MModGen | MModImm, &SrcAdrResult) != ModNone))
  1655.     {
  1656.       if (OpSize == eSymbolSizeUnknown) WrError(ErrNum_UndefOpSizes);
  1657.       else if ((OpSize != 0) && (OpSize != 1)) WrError(ErrNum_InvOpSize);
  1658.       else if ((*OpPart.str.p_str == 'M') && ((DestAdrResult.Mode == 3) || (DestAdrResult.Mode == 5) || (DestAdrResult.Mode - OpSize == 1))) WrError(ErrNum_InvAddrMode);
  1659.       else
  1660.         CodeGen(pOrder->Code1, pOrder->Code2, pOrder->Code3, &SrcAdrResult, &DestAdrResult);
  1661.     }
  1662.   }
  1663. }
  1664.  
  1665. static void DecodeINC_DEC(Word IsDEC)
  1666. {
  1667.   Byte SMode;
  1668.  
  1669.   if (ChkArgCnt(1, 1)
  1670.    && CheckFormat("G"))
  1671.   {
  1672.     tAdrResult AdrResult;
  1673.  
  1674.     if (DecodeAdr(&ArgStr[1], MModGen, &AdrResult) != ModNone)
  1675.     {
  1676.       if (OpSize == eSymbolSizeUnknown) WrError(ErrNum_UndefOpSizes);
  1677.       else if ((OpSize == 1) && ((AdrResult.Mode & 14) == 4))
  1678.       {
  1679.         BAsmCode[0] = 0xb2 + (IsDEC << 6) + ((AdrResult.Mode & 1) << 3);
  1680.         CodeLen = 1;
  1681.       }
  1682.       else if (!IsShort(AdrResult.Mode, &SMode)) WrError(ErrNum_InvAddrMode);
  1683.       else if (OpSize != 0) WrError(ErrNum_InvOpSize);
  1684.       else
  1685.       {
  1686.         BAsmCode[0] = 0xa0 + (IsDEC << 3) + SMode;
  1687.         memcpy(BAsmCode + 1, AdrResult.Vals, AdrResult.Cnt);
  1688.         CodeLen = 1 + AdrResult.Cnt;
  1689.       }
  1690.     }
  1691.   }
  1692. }
  1693.  
  1694. static void DecodeDiv(Word Index)
  1695. {
  1696.   Gen2Order *pOrder = DivOrders + Index;
  1697.  
  1698.   if (ChkArgCnt(1, 1)
  1699.    && CheckFormat("G"))
  1700.   {
  1701.     tAdrResult AdrResult;
  1702.  
  1703.     if (DecodeAdr(&ArgStr[1], MModImm | MModGen, &AdrResult) != ModNone)
  1704.     {
  1705.       if (OpSize == eSymbolSizeUnknown) WrError(ErrNum_UndefOpSizes);
  1706.       else if ((OpSize != 0) && (OpSize != 1)) WrError(ErrNum_InvOpSize);
  1707.       else if (AdrResult.Type == ModImm)
  1708.       {
  1709.         BAsmCode[0] = 0x7c + OpSize;
  1710.         BAsmCode[1] = pOrder->Code1;
  1711.         memcpy(BAsmCode + 2, AdrResult.Vals, AdrResult.Cnt);
  1712.         CodeLen = 2 + AdrResult.Cnt;
  1713.       }
  1714.       else
  1715.       {
  1716.         BAsmCode[0] = pOrder->Code2 + OpSize;
  1717.         BAsmCode[1] = pOrder->Code3 + AdrResult.Mode;
  1718.         memcpy(BAsmCode + 2, AdrResult.Vals, AdrResult.Cnt);
  1719.         CodeLen = 2 + AdrResult.Cnt;
  1720.       }
  1721.     }
  1722.   }
  1723. }
  1724.  
  1725. static void DecodeBCD(Word Code)
  1726. {
  1727.   if (ChkArgCnt(2, 2))
  1728.   {
  1729.     tAdrResult DestAdrResult;
  1730.  
  1731.     if (DecodeAdr(&ArgStr[2], MModGen, &DestAdrResult) != ModNone)
  1732.     {
  1733.       if (DestAdrResult.Mode != 0) WrError(ErrNum_InvAddrMode);
  1734.       else
  1735.       {
  1736.         tAdrResult SrcAdrResult;
  1737.  
  1738.         if (DecodeAdr(&ArgStr[1], MModGen | MModImm, &SrcAdrResult) != ModNone)
  1739.         {
  1740.           if (SrcAdrResult.Type == ModImm)
  1741.           {
  1742.             BAsmCode[0] = 0x7c + OpSize;
  1743.             BAsmCode[1] = 0xec + Code;
  1744.             memcpy(BAsmCode + 2, SrcAdrResult.Vals, SrcAdrResult.Cnt);
  1745.             CodeLen = 2 + SrcAdrResult.Cnt;
  1746.           }
  1747.           else if (SrcAdrResult.Mode != 1) WrError(ErrNum_InvAddrMode);
  1748.           else
  1749.           {
  1750.             BAsmCode[0] = 0x7c + OpSize;
  1751.             BAsmCode[1] = 0xe4 + Code;
  1752.             CodeLen = 2;
  1753.           }
  1754.         }
  1755.       }
  1756.     }
  1757.   }
  1758. }
  1759.  
  1760. static void DecodeEXTS(Word Code)
  1761. {
  1762.   UNUSED(Code);
  1763.  
  1764.   if (ChkArgCnt(1, 1)
  1765.    && CheckFormat("G"))
  1766.   {
  1767.     tAdrResult AdrResult;
  1768.  
  1769.     if (DecodeAdr(&ArgStr[1], MModGen, &AdrResult) != ModNone)
  1770.     {
  1771.       if (OpSize == eSymbolSizeUnknown) OpSize = 0;
  1772.       if (OpSize == 0)
  1773.       {
  1774.         if ((AdrResult.Mode == 1) || ((AdrResult.Mode >= 3) && (AdrResult.Mode <= 5))) WrError(ErrNum_InvAddrMode);
  1775.         else
  1776.         {
  1777.           BAsmCode[0] = 0x7c;
  1778.           BAsmCode[1] = 0x60 + AdrResult.Mode;
  1779.           memcpy(BAsmCode + 2, AdrResult.Vals, AdrResult.Cnt);
  1780.           CodeLen = 2 + AdrResult.Cnt;
  1781.         }
  1782.       }
  1783.       else if (OpSize == 1)
  1784.       {
  1785.         if (AdrResult.Mode != 0) WrError(ErrNum_InvAddrMode);
  1786.         else
  1787.         {
  1788.           BAsmCode[0] = 0x7c;
  1789.           BAsmCode[1] = 0xf3;
  1790.           CodeLen = 2;
  1791.         }
  1792.       }
  1793.       else WrError(ErrNum_InvOpSize);
  1794.     }
  1795.   }
  1796. }
  1797.  
  1798. static void DecodeNOT(Word Code)
  1799. {
  1800.   Byte SMode;
  1801.  
  1802.   UNUSED(Code);
  1803.  
  1804.   if (ChkArgCnt(1, 1)
  1805.    && CheckFormat("GS"))
  1806.   {
  1807.     tAdrResult AdrResult;
  1808.  
  1809.     if (DecodeAdr(&ArgStr[1], MModGen, &AdrResult) != ModNone)
  1810.     {
  1811.       if (OpSize == eSymbolSizeUnknown) WrError(ErrNum_UndefOpSizes);
  1812.       else if (OpSize > 1) WrError(ErrNum_InvOpSize);
  1813.       else
  1814.       {
  1815.         if (FormatCode == 0)
  1816.         {
  1817.           if ((OpSize == 0) && (IsShort(AdrResult.Mode, &SMode)))
  1818.             FormatCode = 2;
  1819.           else
  1820.             FormatCode = 1;
  1821.         }
  1822.         switch (FormatCode)
  1823.         {
  1824.           case 1:
  1825.             BAsmCode[0] = 0x74 + OpSize;
  1826.             BAsmCode[1] = 0x70 + AdrResult.Mode;
  1827.             memcpy(BAsmCode + 2, AdrResult.Vals, AdrResult.Cnt);
  1828.             CodeLen = 2 + AdrResult.Cnt;
  1829.             break;
  1830.           case 2:
  1831.             if (OpSize != 0) WrError(ErrNum_InvOpSize);
  1832.             else if (!IsShort(AdrResult.Mode, &SMode)) WrError(ErrNum_InvAddrMode);
  1833.             else
  1834.             {
  1835.               BAsmCode[0] = 0xb8 + SMode;
  1836.               memcpy(BAsmCode + 1, AdrResult.Vals, AdrResult.Cnt);
  1837.               CodeLen = 1 + AdrResult.Cnt;
  1838.             }
  1839.             break;
  1840.         }
  1841.       }
  1842.     }
  1843.   }
  1844. }
  1845.  
  1846. static void DecodeAND_OR(Word IsOR)
  1847. {
  1848.   Byte SMode;
  1849.  
  1850.   if (ChkArgCnt(2, 2)
  1851.    && CheckFormat("GS"))        /* RMS 01: The format codes are G and S, not G and Q */
  1852.   {
  1853.     tAdrResult DestAdrResult, SrcAdrResult;
  1854.  
  1855.     if ((DecodeAdr(&ArgStr[2], MModGen, &DestAdrResult) != ModNone)
  1856.      && (DecodeAdr(&ArgStr[1], MModGen | MModImm, &SrcAdrResult) != ModNone))
  1857.     {
  1858.       if (OpSize == eSymbolSizeUnknown) WrError(ErrNum_UndefOpSizes);
  1859.       else if (OpSize > 1) WrError(ErrNum_InvOpSize);
  1860.       else
  1861.       {
  1862.         if (FormatCode == 0)
  1863.         {
  1864.           if (SrcAdrResult.Type == ModImm)
  1865.           {
  1866.             if ((OpSize == 0) && (IsShort(DestAdrResult.Mode, &SMode)))
  1867.               FormatCode = 2;
  1868.             else
  1869.               FormatCode = 1;
  1870.           }
  1871.           else
  1872.           {
  1873.             if ((DestAdrResult.Mode <= 1) && (IsShort(SrcAdrResult.Mode, &SMode)) && ((SrcAdrResult.Mode > 1) || Odd(SrcAdrResult.Mode ^ DestAdrResult.Mode)))
  1874.               FormatCode = 2;
  1875.             else
  1876.               FormatCode = 1;
  1877.           }
  1878.         }
  1879.         switch (FormatCode)
  1880.         {
  1881.           case 1:
  1882.             CodeGen(0x90 + (IsOR << 3), 0x76, 0x20 + (IsOR << 4), &SrcAdrResult, &DestAdrResult);
  1883.             break;
  1884.           case 2:
  1885.             if (OpSize != 0) WrError(ErrNum_InvOpSize);
  1886.             else if (SrcAdrResult.Type == ModImm)
  1887.             if (!IsShort(DestAdrResult.Mode, &SMode)) WrError(ErrNum_InvAddrMode);
  1888.             else
  1889.             {
  1890.               BAsmCode[0] = 0x90 + (IsOR << 3) + SMode;
  1891.               BAsmCode[1] = ImmVal(&SrcAdrResult);
  1892.               memcpy(BAsmCode + 2, DestAdrResult.Vals, DestAdrResult.Cnt);
  1893.               CodeLen = 2 + DestAdrResult.Cnt;
  1894.             }
  1895.             else if ((!IsShort(SrcAdrResult.Mode, &SMode)) || (DestAdrResult.Mode > 1)) WrError(ErrNum_InvAddrMode);
  1896.             else if ((SrcAdrResult.Mode <= 1) && (!Odd(SrcAdrResult.Mode ^ DestAdrResult.Mode))) WrError(ErrNum_InvAddrMode);
  1897.             else
  1898.             {
  1899.               if (SMode == 3) SMode++;
  1900.               BAsmCode[0] = 0x10 + (IsOR << 3) + ((DestAdrResult.Mode & 1) << 2) + (SMode & 3);
  1901.               memcpy(BAsmCode + 1, SrcAdrResult.Vals, SrcAdrResult.Cnt);
  1902.               CodeLen = 1 + SrcAdrResult.Cnt;
  1903.             }
  1904.             break;
  1905.         }
  1906.       }
  1907.     }
  1908.   }
  1909. }
  1910.  
  1911. static void DecodeROT(Word Code)
  1912. {
  1913.   ShortInt OpSize2;
  1914.  
  1915.   UNUSED(Code);
  1916.  
  1917.   if (ChkArgCnt(2, 2)
  1918.    && CheckFormat("G"))
  1919.   {
  1920.     tAdrResult DestAdrResult;
  1921.  
  1922.     if (DecodeAdr(&ArgStr[2], MModGen, &DestAdrResult) != ModNone)
  1923.     {
  1924.       if (OpSize == eSymbolSizeUnknown) WrError(ErrNum_UndefOpSizes);
  1925.       else if (OpSize > 1) WrError(ErrNum_InvOpSize);
  1926.       else
  1927.       {
  1928.         tAdrResult SrcAdrResult;
  1929.  
  1930.         OpSize2 = OpSize;
  1931.         OpSize = 0;
  1932.         if (DecodeAdr(&ArgStr[1], MModGen | MModImm, &SrcAdrResult) == ModGen)
  1933.         {
  1934.           if (SrcAdrResult.Mode != 3) WrError(ErrNum_InvAddrMode);
  1935.           else if (DestAdrResult.Mode + 2 * OpSize2 == 3) WrError(ErrNum_InvAddrMode);
  1936.           else
  1937.           {
  1938.             BAsmCode[0] = 0x74 + OpSize2;
  1939.             BAsmCode[1] = 0x60 + DestAdrResult.Mode;
  1940.             memcpy(BAsmCode + 2, DestAdrResult.Vals, DestAdrResult.Cnt);
  1941.             CodeLen = 2 + DestAdrResult.Cnt;
  1942.           }
  1943.         }
  1944.         else if (SrcAdrResult.Type == ModImm)
  1945.         {
  1946.           Integer Num1 = ImmVal(&SrcAdrResult);
  1947.           if (Num1 == 0) WrError(ErrNum_UnderRange);
  1948.           else if (ChkRange(Num1, -8, 8))
  1949.           {
  1950.             Num1 = (Num1 > 0) ? (Num1 - 1) : -9 -Num1;
  1951.             BAsmCode[0] = 0xe0 + OpSize2;
  1952.             BAsmCode[1] = (Num1 << 4) + DestAdrResult.Mode;
  1953.             memcpy(BAsmCode + 2, DestAdrResult.Vals, DestAdrResult.Cnt);
  1954.             CodeLen = 2 + DestAdrResult.Cnt;
  1955.           }
  1956.         }
  1957.       }
  1958.     }
  1959.   }
  1960. }
  1961.  
  1962. static void DecodeSHA_SHL(Word IsSHA)
  1963. {
  1964.   ShortInt OpSize2;
  1965.  
  1966.   if (ChkArgCnt(2, 2)
  1967.    && CheckFormat("G"))
  1968.   {
  1969.     tAdrResult DestAdrResult;
  1970.  
  1971.     if (DecodeAdr(&ArgStr[2], MModGen | MModReg32, &DestAdrResult) != ModNone)
  1972.     {
  1973.       if (OpSize == eSymbolSizeUnknown) WrError(ErrNum_UndefOpSizes);
  1974.       else if ((OpSize > 2) || ((OpSize == 2) && (DestAdrResult.Type == ModGen))) WrError(ErrNum_InvOpSize);
  1975.       else
  1976.       {
  1977.         tAdrResult SrcAdrResult;
  1978.  
  1979.         OpSize2 = OpSize; OpSize = 0;
  1980.         if (DecodeAdr(&ArgStr[1], MModImm | MModGen, &SrcAdrResult) == ModGen)
  1981.         {
  1982.           if (SrcAdrResult.Mode != 3) WrError(ErrNum_InvAddrMode);
  1983.           else if (DestAdrResult.Mode + 2 * OpSize2 == 3) WrError(ErrNum_InvAddrMode);
  1984.           else
  1985.           {
  1986.             if (OpSize2 == 2)
  1987.             {
  1988.               BAsmCode[0] = 0xeb;
  1989.               BAsmCode[1] = 0x01 | (DestAdrResult.Mode << 4) | (IsSHA << 5);
  1990.             }
  1991.             else
  1992.             {
  1993.               BAsmCode[0] = 0x74 | OpSize2;
  1994.               BAsmCode[1] = 0xe0 | (IsSHA << 4) | DestAdrResult.Mode;
  1995.             }
  1996.             memcpy(BAsmCode + 2, DestAdrResult.Vals, DestAdrResult.Cnt);
  1997.             CodeLen = 2 + DestAdrResult.Cnt;
  1998.           }
  1999.         }
  2000.         else if (SrcAdrResult.Type == ModImm)
  2001.         {
  2002.           Integer Num1 = ImmVal(&SrcAdrResult);
  2003.           if (Num1 == 0) WrError(ErrNum_UnderRange);
  2004.           else if (ChkRange(Num1, -8, 8))
  2005.           {
  2006.             if (Num1 > 0) Num1--; else Num1 = (-9) - Num1;
  2007.             if (OpSize2 == 2)
  2008.             {
  2009.               BAsmCode[0] = 0xeb;
  2010.               BAsmCode[1] = 0x80 | (DestAdrResult.Mode << 4) | (IsSHA << 5) | (Num1 & 15);
  2011.             }
  2012.             else
  2013.             {
  2014.               BAsmCode[0] = (0xe8 + (IsSHA << 3)) | OpSize2;
  2015.               BAsmCode[1] = (Num1 << 4) | DestAdrResult.Mode;
  2016.             }
  2017.             memcpy(BAsmCode + 2, DestAdrResult.Vals, DestAdrResult.Cnt);
  2018.             CodeLen = 2 + DestAdrResult.Cnt;
  2019.           }
  2020.         }
  2021.       }
  2022.     }
  2023.   }
  2024. }
  2025.  
  2026. static void DecodeBit(Word Code)
  2027. {
  2028.   Boolean MayShort = (Code & 12) == 8;
  2029.  
  2030.   if (CheckFormat(MayShort ? "GS" : "G"))
  2031.   {
  2032.     tAdrResult AdrResult;
  2033.  
  2034.     if (DecodeBitAdr((FormatCode != 1) && MayShort, &AdrResult))
  2035.     {
  2036.       if (AdrResult.Mode >= 16)
  2037.       {
  2038.         BAsmCode[0] = 0x40 + ((Code - 8) << 3) + (AdrResult.Mode & 7);
  2039.         BAsmCode[1] = AdrResult.Vals[0];
  2040.         CodeLen = 2;
  2041.       }
  2042.       else
  2043.       {
  2044.         BAsmCode[0] = 0x7e;
  2045.         BAsmCode[1] = (Code << 4) + AdrResult.Mode;
  2046.         memcpy(BAsmCode + 2, AdrResult.Vals, AdrResult.Cnt);
  2047.         CodeLen = 2 + AdrResult.Cnt;
  2048.       }
  2049.     }
  2050.   }
  2051. }
  2052.  
  2053. static void DecodeFCLR_FSET(Word Code)
  2054. {
  2055.   if (!ChkArgCnt(1, 1));
  2056.   else if (strlen(ArgStr[1].str.p_str) != 1) WrError(ErrNum_InvAddrMode);
  2057.   else
  2058.   {
  2059.     const char *p = strchr(Flags, as_toupper(*ArgStr[1].str.p_str));
  2060.     if (!p) WrStrErrorPos(ErrNum_InvCtrlReg, &ArgStr[1]);
  2061.     else
  2062.     {
  2063.       BAsmCode[0] = 0xeb;
  2064.       BAsmCode[1] = Code + ((p - Flags) << 4);
  2065.       CodeLen = 2;
  2066.     }
  2067.   }
  2068. }
  2069.  
  2070. static void DecodeJMP(Word Code)
  2071. {
  2072.   LongInt AdrLong, Diff;
  2073.   Boolean OK;
  2074.   tSymbolFlags Flags;
  2075.  
  2076.   UNUSED(Code);
  2077.  
  2078.   if (ChkArgCnt(1, 1))
  2079.   {
  2080.     AdrLong = EvalStrIntExpressionWithFlags(&ArgStr[1], UInt20, &OK, &Flags);
  2081.     Diff = AdrLong - EProgCounter();
  2082.  
  2083.     /* RMS 12: Repaired JMP.S forward-label as follows:
  2084.  
  2085.                If it's an unknown symbol, make PC+1 the "safe" value, otherwise
  2086.                the user will get OUT OF RANGE errors on every attempt to use JMP.S
  2087.                Since the instruction can only branch forward, and AS stuffs the PC
  2088.                back for a "temp" forward reference value, the range-checking will
  2089.                always fail.
  2090.  
  2091.                One side-effect also is that for auto-determination purposes, one
  2092.                fewer pass is needed.  Before, the first pass would signal JMP.B,
  2093.                then once the forward reference is known, it'd signal JMP.S, which
  2094.                would cause a "phase error" forcing another pass.
  2095.     */
  2096.  
  2097.     if (mFirstPassUnknown(Flags) && (Diff == 0))
  2098.       Diff = 1;
  2099.  
  2100.     if (OpSize == eSymbolSizeUnknown)
  2101.     {                                                        /* RMS 13: The other part of the */
  2102.       if ((Diff >= 1) && (Diff <= 9))                        /* "looping phase error" fix  */
  2103.         OpSize = 4;
  2104.       else if ((Diff >= -127) && (Diff <= 128))
  2105.         OpSize = 0;
  2106.       else if ((Diff >= -32767) && (Diff <= 32768))
  2107.         OpSize = 1;
  2108.       else
  2109.         OpSize = 7;
  2110.     }
  2111.     /*
  2112.        The following code is to deal with a silicon bug in the first generation of
  2113.        M16C CPUs (the so-called M16C/60 group).  It has been observed that this
  2114.        silicon bug has been fixed as of the M16C/61, so we disable JMP.S promotion
  2115.        to JMP.B when the target crosses a 64k boundary for those CPUs.
  2116.  
  2117.        Since M16C is a "generic" specification, we do JMP.S promotion for that
  2118.        CPU specification, as follows:
  2119.  
  2120.          RMS 11: According to Mitsubishi App Note M16C-06-9612
  2121.          JMP.S cannot cross a 64k boundary.. so trim up to JMP.B
  2122.  
  2123.        It is admittedly a very low likelihood of occurrence [JMP.S has only 8
  2124.        possible targets, being a 3 bit "jump addressing mode"], but since the
  2125.        occurrence of this bug could cause such evil debugging issues, I have
  2126.        taken the liberty of addressing it in the assembler.  Heck, it's JUST one
  2127.        extra byte.  One byte's worth the peace of mind, isn't it? :)
  2128.     */
  2129.     if ((MomCPU == CPUM16C) || (MomCPU == CPUM30600M8))
  2130.     {
  2131.       if (OpSize == 4)
  2132.       {
  2133.         if ( (AdrLong & 0x0f0000) != (((int)EProgCounter()) & 0x0f0000) )
  2134.           OpSize = 0;
  2135.       }            /* NOTE! This not an ASX bug, but rather in the CPU!! */
  2136.     }
  2137.     switch (OpSize)
  2138.     {
  2139.       case 4:
  2140.         if (((Diff < 1) || (Diff > 9)) && !mSymbolQuestionable(Flags) ) WrError(ErrNum_JmpDistTooBig);
  2141.         else
  2142.         {
  2143.           if (Diff == 1)
  2144.           {                                   /* RMS 13: To avoid infinite loop phase errors... Turn a */
  2145.             BAsmCode[0] = 0x04;               /* JMP (or JMP.S) to following instruction into a NOP */
  2146.           }
  2147.           else
  2148.           {
  2149.             BAsmCode[0] = 0x60 + ((Diff - 2) & 7);
  2150.           }
  2151.           CodeLen = 1;
  2152.         }
  2153.         break;
  2154.       case 0:
  2155.         if (((Diff < -127) || (Diff > 128)) && !mSymbolQuestionable(Flags)) WrError(ErrNum_JmpDistTooBig);
  2156.         else
  2157.         {
  2158.           BAsmCode[0] = 0xfe;
  2159.           BAsmCode[1] = (Diff - 1) & 0xff;
  2160.           CodeLen = 2;
  2161.         }
  2162.         break;
  2163.       case 1:
  2164.         if (((Diff< -32767) || (Diff > 32768)) && !mSymbolQuestionable(Flags)) WrError(ErrNum_JmpDistTooBig);
  2165.         else
  2166.         {
  2167.           BAsmCode[0] = 0xf4;
  2168.           Diff--;
  2169.           BAsmCode[1] = Diff & 0xff;
  2170.           BAsmCode[2] = (Diff >> 8) & 0xff;
  2171.           CodeLen = 3;
  2172.         }
  2173.         break;
  2174.       case 7:
  2175.         BAsmCode[0] = 0xfc;
  2176.         BAsmCode[1] = AdrLong & 0xff;
  2177.         BAsmCode[2] = (AdrLong >> 8) & 0xff;
  2178.         BAsmCode[3] = (AdrLong >> 16) & 0xff;
  2179.         CodeLen = 4;
  2180.         break;
  2181.       default:
  2182.         WrError(ErrNum_InvOpSize);
  2183.     }
  2184.   }
  2185. }
  2186.  
  2187. static void DecodeJSR(Word Code)
  2188. {
  2189.   LongInt AdrLong, Diff;
  2190.   Boolean OK;
  2191.   tSymbolFlags Flags;
  2192.  
  2193.   UNUSED(Code);
  2194.  
  2195.   if (ChkArgCnt(1, 1))
  2196.   {
  2197.     AdrLong = EvalStrIntExpressionWithFlags(&ArgStr[1], UInt20, &OK, &Flags);
  2198.     Diff = AdrLong-EProgCounter();
  2199.     if (OpSize == eSymbolSizeUnknown)
  2200.       OpSize = ((Diff >= -32767) && (Diff <= 32768)) ? 1 : 7;
  2201.     switch (OpSize)
  2202.     {
  2203.       case 1:
  2204.         if (((Diff <- 32767) || (Diff > 32768)) && !mSymbolQuestionable(Flags)) WrError(ErrNum_JmpDistTooBig);
  2205.         else
  2206.         {
  2207.           BAsmCode[0] = 0xf5;
  2208.           Diff--;
  2209.           BAsmCode[1] = Diff & 0xff;
  2210.           BAsmCode[2] = (Diff >> 8) & 0xff;
  2211.           CodeLen = 3;
  2212.         }
  2213.         break;
  2214.       case 7:
  2215.         BAsmCode[0] = 0xfd;
  2216.         BAsmCode[1] = AdrLong & 0xff;
  2217.         BAsmCode[2] = (AdrLong >> 8) & 0xff;
  2218.         BAsmCode[3] = (AdrLong >> 16) & 0xff;
  2219.         CodeLen = 4;
  2220.         break;
  2221.       default:
  2222.         WrError(ErrNum_InvOpSize);
  2223.     }
  2224.   }
  2225. }
  2226.  
  2227. static void DecodeJMPI_JSRI(Word Code)
  2228. {
  2229.   if (ChkArgCnt(1, 1)
  2230.    && CheckFormat("G"))
  2231.   {
  2232.     tAdrResult AdrResult;
  2233.  
  2234.     if (OpSize == 7)
  2235.       OpSize = 2;
  2236.     DecodeAdr(&ArgStr[1], MModGen | MModDisp20 | MModReg32| MModAReg32, &AdrResult);
  2237.     if ((AdrResult.Type == ModGen) && ((AdrResult.Mode & 14) == 12))
  2238.       AdrResult.Vals[AdrResult.Cnt++] = 0;
  2239.     if ((AdrResult.Type == ModGen) && ((AdrResult.Mode & 14) == 4))
  2240.     {
  2241.       if (OpSize == eSymbolSizeUnknown) OpSize = 1;
  2242.       else if (OpSize != 1)
  2243.       {
  2244.         AdrResult.Type = ModNone; WrError(ErrNum_ConfOpSizes);
  2245.       }
  2246.     }
  2247.     if (AdrResult.Type == ModAReg32) AdrResult.Mode = 4;
  2248.     if (AdrResult.Type != ModNone)
  2249.     {
  2250.       if (OpSize == eSymbolSizeUnknown) WrError(ErrNum_UndefOpSizes);
  2251.       else if ((OpSize != 1) && (OpSize != 2)) WrError(ErrNum_InvOpSize);
  2252.       else
  2253.       {
  2254.         BAsmCode[0] = 0x7d;
  2255.         BAsmCode[1] = Code + (Ord(OpSize == 1) << 5) + AdrResult.Mode;
  2256.         memcpy(BAsmCode + 2, AdrResult.Vals, AdrResult.Cnt);
  2257.         CodeLen = 2 + AdrResult.Cnt;
  2258.       }
  2259.     }
  2260.   }
  2261. }
  2262.  
  2263. static void DecodeJMPS_JSRS(Word Code)
  2264. {
  2265.   if (ChkArgCnt(1, 1))
  2266.   {
  2267.     tAdrResult AdrResult;
  2268.  
  2269.     OpSize = 0;
  2270.     if (DecodeAdr(&ArgStr[1], MModImm, &AdrResult) != ModNone)
  2271.     {
  2272.       if (mFirstPassUnknown(AdrResult.ImmSymFlags) && (AdrResult.Vals[0] < 18))
  2273.         AdrResult.Vals[0] = 18;
  2274.       if (AdrResult.Vals[0] < 18) WrError(ErrNum_UnderRange);
  2275.       else
  2276.       {
  2277.         BAsmCode[0] = Code;
  2278.         BAsmCode[1] = AdrResult.Vals[0];
  2279.         CodeLen = 2;
  2280.       }
  2281.     }
  2282.   }
  2283. }
  2284.  
  2285. static void DecodeADJNZ_SBJNZ(Word IsSBJNZ)
  2286. {
  2287.   if (ChkArgCnt(3, 3)
  2288.    && CheckFormat("G"))
  2289.   {
  2290.     tAdrResult DestAdrResult;
  2291.  
  2292.     if (DecodeAdr(&ArgStr[2], MModGen, &DestAdrResult) != ModNone)
  2293.     {
  2294.       ShortInt OpSize2;
  2295.  
  2296.       if (OpSize == eSymbolSizeUnknown) WrError(ErrNum_UndefOpSizes);
  2297.       else if (OpSize > 1) WrError(ErrNum_InvOpSize);
  2298.       else
  2299.       {
  2300.         Integer Num1;
  2301.         tAdrResult SrcAdrResult;
  2302.  
  2303.         OpSize2 = OpSize;
  2304.         OpSize = 0;
  2305.         DecodeAdr(&ArgStr[1], MModImm, &SrcAdrResult);
  2306.         /* TODO: ChkRes */
  2307.         Num1 = ImmVal(&DestAdrResult);
  2308.         if (mFirstPassUnknown(SrcAdrResult.ImmSymFlags))
  2309.           Num1 = 0;
  2310.         if (IsSBJNZ)
  2311.           Num1 = -Num1;
  2312.         if (ChkRange(Num1, -8, 7))
  2313.         {
  2314.           LongInt AdrLong;
  2315.           Boolean OK;
  2316.           tSymbolFlags Flags;
  2317.  
  2318.           AdrLong = EvalStrIntExpressionWithFlags(&ArgStr[3], UInt20, &OK, &Flags) - (EProgCounter() + 2);
  2319.           if (OK)
  2320.           {
  2321.             if (((AdrLong < -128) || (AdrLong > 127)) && !mSymbolQuestionable(Flags)) WrError(ErrNum_JmpDistTooBig);
  2322.             else
  2323.             {
  2324.               BAsmCode[0] = 0xf8 + OpSize2;
  2325.               BAsmCode[1] = (Num1 << 4) + DestAdrResult.Mode;
  2326.               memcpy(BAsmCode + 2, DestAdrResult.Vals, DestAdrResult.Cnt);
  2327.               BAsmCode[2 + DestAdrResult.Cnt] = AdrLong & 0xff;
  2328.               CodeLen = 3 + DestAdrResult.Cnt;
  2329.             }
  2330.           }
  2331.         }
  2332.       }
  2333.     }
  2334.   }
  2335. }
  2336.  
  2337. static void DecodeINT(Word Code)
  2338. {
  2339.   UNUSED(Code);
  2340.  
  2341.   if (!ChkArgCnt(1, 1));
  2342.   else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  2343.   else if (*ArgStr[1].str.p_str != '#') WrError(ErrNum_InvAddrMode);
  2344.   else
  2345.   {
  2346.     Boolean OK;
  2347.  
  2348.     BAsmCode[1] = 0xc0 + EvalStrIntExpressionOffs(&ArgStr[1], 1, UInt6, &OK);
  2349.     if (OK)
  2350.     {
  2351.       BAsmCode[0] = 0xeb;
  2352.       CodeLen = 2;
  2353.     }
  2354.   }
  2355. }
  2356.  
  2357. static void DecodeBM(Word Code)
  2358. {
  2359.   tAdrResult AdrResult;
  2360.  
  2361.   if ((ArgCnt == 1) && (!as_strcasecmp(ArgStr[1].str.p_str, "C")))
  2362.   {
  2363.     BAsmCode[0] = 0x7d;
  2364.     BAsmCode[1] = 0xd0 + Code;
  2365.     CodeLen = 2;
  2366.   }
  2367.   else if (DecodeBitAdr(False, &AdrResult))
  2368.   {
  2369.     BAsmCode[0] = 0x7e;
  2370.     BAsmCode[1] = 0x20 + AdrResult.Mode;
  2371.     memcpy(BAsmCode + 2, AdrResult.Vals, AdrResult.Cnt);
  2372.     if ((Code >= 4) && (Code < 12))
  2373.       Code ^= 12;
  2374.     if (Code >= 8)
  2375.        Code += 0xf0;
  2376.     BAsmCode[2 + AdrResult.Cnt] = Code;
  2377.     CodeLen = 3 + AdrResult.Cnt;
  2378.   }
  2379. }
  2380.  
  2381. static void DecodeJ(Word Code)
  2382. {
  2383.   Integer Num1 = 1 + Ord(Code >= 8);
  2384.   if (!ChkArgCnt(1, 1));
  2385.   else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  2386.   else if (strcmp(Format, " ")) WrError(ErrNum_InvFormat);
  2387.   else
  2388.   {
  2389.     Boolean OK;
  2390.     tSymbolFlags Flags;
  2391.     LongInt AdrLong = EvalStrIntExpressionWithFlags(&ArgStr[1], UInt20, &OK, &Flags) - (EProgCounter() + Num1);
  2392.  
  2393.     if (OK)
  2394.     {
  2395.       if (!mSymbolQuestionable(Flags) && ((AdrLong >127) || (AdrLong < -128))) WrError(ErrNum_JmpDistTooBig);
  2396.       else if (Code >= 8)
  2397.       {
  2398.         BAsmCode[0] = 0x7d;
  2399.         BAsmCode[1] = 0xc0 + Code;
  2400.         BAsmCode[2] = AdrLong & 0xff;
  2401.         CodeLen = 3;
  2402.       }
  2403.       else
  2404.       {
  2405.         BAsmCode[0] = 0x68 + Code;
  2406.         BAsmCode[1] = AdrLong & 0xff;
  2407.         CodeLen = 2;
  2408.       }
  2409.     }
  2410.   }
  2411. }
  2412.  
  2413. static void DecodeENTER(Word Code)
  2414. {
  2415.   UNUSED(Code);
  2416.  
  2417.   if (!ChkArgCnt(1, 1));
  2418.   else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  2419.   else if (*ArgStr[1].str.p_str != '#') WrError(ErrNum_InvAddrMode);
  2420.   else
  2421.   {
  2422.     Boolean OK;
  2423.  
  2424.     BAsmCode[2] = EvalStrIntExpressionOffs(&ArgStr[1], 1, UInt8, &OK);
  2425.     if (OK)
  2426.     {
  2427.       BAsmCode[0] = 0x7c;
  2428.       BAsmCode[1] = 0xf2;
  2429.       CodeLen = 3;
  2430.     }
  2431.   }
  2432. }
  2433.  
  2434. static void DecodeLDINTB(Word Code)
  2435. {
  2436.   UNUSED(Code);
  2437.  
  2438.   if (!ChkArgCnt(1, 1));
  2439.   else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  2440.   else if (*ArgStr[1].str.p_str != '#') WrError(ErrNum_InvAddrMode);
  2441.   else
  2442.   {
  2443.     Boolean OK;
  2444.     LongInt AdrLong = EvalStrIntExpressionOffs(&ArgStr[1], 1, UInt20, &OK);
  2445.     if (OK)
  2446.     {
  2447.       BAsmCode[0] = 0xeb;
  2448.       BAsmCode[1] = 0x20;
  2449.       BAsmCode[2] = (AdrLong >> 16) & 0xff;
  2450.       BAsmCode[3] = 0;
  2451.       BAsmCode[4] = 0xeb;
  2452.       BAsmCode[5] = 0x10;
  2453.       BAsmCode[7] = (AdrLong >> 8) & 0xff;
  2454.       BAsmCode[6] = AdrLong & 0xff; /* RMS 07: needs to be LSB, MSB order */
  2455.       CodeLen = 8;
  2456.     }
  2457.   }
  2458. }
  2459.  
  2460. static void DecodeLDIPL(Word Code)
  2461. {
  2462.   UNUSED(Code);
  2463.  
  2464.   if (!ChkArgCnt(1, 1));
  2465.   else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  2466.   else if (*ArgStr[1].str.p_str != '#') WrError(ErrNum_InvAddrMode);
  2467.   else
  2468.   {
  2469.     Boolean OK;
  2470.  
  2471.     BAsmCode[1] = 0xa0 + EvalStrIntExpressionOffs(&ArgStr[1], 1, UInt3, &OK);
  2472.     if (OK)
  2473.     {
  2474.       BAsmCode[0] = 0x7d;
  2475.       CodeLen = 2;
  2476.     }
  2477.   }
  2478. }
  2479.  
  2480. /*------------------------------------------------------------------------*/
  2481. /* code table handling */
  2482.  
  2483. static void AddFixed(const char *NName, Word NCode)
  2484. {
  2485.   AddInstTable(InstTable, NName, NCode, DecodeFixed);
  2486. }
  2487.  
  2488. static void AddString(const char *NName, Word NCode)
  2489. {
  2490.   AddInstTable(InstTable, NName, NCode, DecodeString);
  2491. }
  2492.  
  2493. static void AddGen1(const char *NName, Word NCode)
  2494. {
  2495.   AddInstTable(InstTable, NName, NCode, DecodeGen1);
  2496. }
  2497.  
  2498. static void AddGen2(const char *NName, Byte NCode1, Byte NCode2, Byte NCode3)
  2499. {
  2500.   order_array_rsv_end(Gen2Orders, Gen2Order);
  2501.   Gen2Orders[InstrZ].Code1 = NCode1;
  2502.   Gen2Orders[InstrZ].Code2 = NCode2;
  2503.   Gen2Orders[InstrZ].Code3 = NCode3;
  2504.   AddInstTable(InstTable, NName, InstrZ++, DecodeGen2);
  2505. }
  2506.  
  2507. static void AddDiv(const char *NName, Byte NCode1, Byte NCode2, Byte NCode3)
  2508. {
  2509.   order_array_rsv_end(DivOrders, Gen2Order);
  2510.   DivOrders[InstrZ].Code1 = NCode1;
  2511.   DivOrders[InstrZ].Code2 = NCode2;
  2512.   DivOrders[InstrZ].Code3 = NCode3;
  2513.   AddInstTable(InstTable, NName, InstrZ++, DecodeDiv);
  2514. }
  2515.  
  2516. static void AddCondition(const char *BMName, const char *JName, Word NCode)
  2517. {
  2518.   AddInstTable(InstTable, BMName, NCode, DecodeBM);
  2519.   AddInstTable(InstTable, JName, NCode, DecodeJ);
  2520. }
  2521.  
  2522. static void AddBCD(const char *NName)
  2523. {
  2524.   AddInstTable(InstTable, NName, InstrZ++, DecodeBCD);
  2525. }
  2526.  
  2527. static void AddDir(const char *NName, Word NCode)
  2528. {
  2529.   AddInstTable(InstTable, NName, NCode, DecodeDir);
  2530. }
  2531.  
  2532. static void AddBit(const char *NName, Word NCode)
  2533. {
  2534.   AddInstTable(InstTable, NName, NCode, DecodeBit);
  2535. }
  2536.  
  2537. static void InitFields(void)
  2538. {
  2539.   InstTable = CreateInstTable(403);
  2540.  
  2541.   add_null_pseudo(InstTable);
  2542.  
  2543.   AddInstTable(InstTable, "MOV", 0, DecodeMOV);
  2544.   AddInstTable(InstTable, "LDC", 0, DecodeLDC_STC);
  2545.   AddInstTable(InstTable, "STC", 1, DecodeLDC_STC);
  2546.   AddInstTable(InstTable, "LDCTX", 0x7c, DecodeLDCTX_STCTX);
  2547.   AddInstTable(InstTable, "STCTX", 0x7d, DecodeLDCTX_STCTX);
  2548.   AddInstTable(InstTable, "LDE", 1, DecodeLDE_STE);
  2549.   AddInstTable(InstTable, "STE", 0, DecodeLDE_STE);
  2550.   AddInstTable(InstTable, "MOVA", 0, DecodeMOVA);
  2551.   AddInstTable(InstTable, "POP", 1, DecodePUSH_POP);
  2552.   AddInstTable(InstTable, "PUSH", 0, DecodePUSH_POP);
  2553.   AddInstTable(InstTable, "POPC", 0x03, DecodePUSHC_POPC);
  2554.   AddInstTable(InstTable, "PUSHC", 0x02, DecodePUSHC_POPC);
  2555.   AddInstTable(InstTable, "POPM", 1, DecodePUSHM_POPM);
  2556.   AddInstTable(InstTable, "PUSHM", 0, DecodePUSHM_POPM);
  2557.   AddInstTable(InstTable, "PUSHA", 0, DecodePUSHA);
  2558.   AddInstTable(InstTable, "XCHG", 0, DecodeXCHG);
  2559.   AddInstTable(InstTable, "STZ", 0xc8, DecodeSTZ_STNZ);
  2560.   AddInstTable(InstTable, "STNZ", 0xd0, DecodeSTZ_STNZ);
  2561.   AddInstTable(InstTable, "STZX", 0, DecodeSTZX);
  2562.   AddInstTable(InstTable, "ADD", 0, DecodeADD);
  2563.   AddInstTable(InstTable, "CMP", 0, DecodeCMP);
  2564.   AddInstTable(InstTable, "SUB", 0, DecodeSUB);
  2565.   AddInstTable(InstTable, "INC", 0, DecodeINC_DEC);
  2566.   AddInstTable(InstTable, "DEC", 1, DecodeINC_DEC);
  2567.   AddInstTable(InstTable, "EXTS", 0, DecodeEXTS);
  2568.   AddInstTable(InstTable, "NOT", 0, DecodeNOT);
  2569.   AddInstTable(InstTable, "AND", 0, DecodeAND_OR);
  2570.   AddInstTable(InstTable, "OR", 1, DecodeAND_OR);
  2571.   AddInstTable(InstTable, "ROT", 0, DecodeROT);
  2572.   AddInstTable(InstTable, "SHA", 1, DecodeSHA_SHL);
  2573.   AddInstTable(InstTable, "SHL", 0, DecodeSHA_SHL);
  2574.   AddInstTable(InstTable, "FCLR", 0x05, DecodeFCLR_FSET);
  2575.   AddInstTable(InstTable, "FSET", 0x04, DecodeFCLR_FSET);
  2576.   AddInstTable(InstTable, "JMP", 0, DecodeJMP);
  2577.   AddInstTable(InstTable, "JSR", 0, DecodeJSR);
  2578.   AddInstTable(InstTable, "JMPI", 0x00, DecodeJMPI_JSRI);
  2579.   AddInstTable(InstTable, "JSRI", 0x10, DecodeJMPI_JSRI);
  2580.   AddInstTable(InstTable, "JMPS", 0xee, DecodeJMPS_JSRS);
  2581.   AddInstTable(InstTable, "JSRS", 0xef, DecodeJMPS_JSRS);
  2582.   AddInstTable(InstTable, "ADJNZ", 0, DecodeADJNZ_SBJNZ);
  2583.   AddInstTable(InstTable, "SBJNZ", 1, DecodeADJNZ_SBJNZ);
  2584.   AddInstTable(InstTable, "INT", 0, DecodeINT);
  2585.   AddInstTable(InstTable, "ENTER", 0, DecodeENTER);
  2586.   AddInstTable(InstTable, "LDINTB", 0, DecodeLDINTB);
  2587.   AddInstTable(InstTable, "LDIPL", 0, DecodeLDIPL);
  2588.  
  2589.   Format = (char*)malloc(sizeof(char) * STRINGSIZE);
  2590.  
  2591.   AddFixed("BRK"   , 0x0000);
  2592.   AddFixed("EXITD" , 0x7df2);
  2593.   AddFixed("INTO"  , 0x00f6);
  2594.   AddFixed("NOP"   , 0x0004);
  2595.   AddFixed("REIT"  , 0x00fb);
  2596.   AddFixed("RTS"   , 0x00f3);
  2597.   AddFixed("UND"   , 0x00ff);
  2598.   AddFixed("WAIT"  , 0x7df3);
  2599.  
  2600.   AddString("RMPA" , 0x7cf1);
  2601.   AddString("SMOVB", 0x7ce9);
  2602.   AddString("SMOVF", 0x7ce8);
  2603.   AddString("SSTR" , 0x7cea);
  2604.  
  2605.   AddGen1("ABS" , 0x76f0);
  2606.   AddGen1("ADCF", 0x76e0);
  2607.   AddGen1("NEG" , 0x7450);
  2608.   AddGen1("ROLC", 0x76a0);
  2609.   AddGen1("RORC", 0x76b0);
  2610.  
  2611.   InstrZ = 0;
  2612.   AddGen2("ADC" , 0xb0, 0x76, 0x60);
  2613.   AddGen2("SBB" , 0xb8, 0x76, 0x70);
  2614.   AddGen2("TST" , 0x80, 0x76, 0x00);
  2615.   AddGen2("XOR" , 0x88, 0x76, 0x10);
  2616.   AddGen2("MUL" , 0x78, 0x7c, 0x50);
  2617.   AddGen2("MULU", 0x70, 0x7c, 0x40);
  2618.  
  2619.   InstrZ = 0;
  2620.   AddDiv("DIV" ,0xe1,0x76,0xd0);
  2621.   AddDiv("DIVU",0xe0,0x76,0xc0);
  2622.   AddDiv("DIVX",0xe3,0x76,0x90);
  2623.  
  2624.   AddCondition("BMGEU", "JGEU",  0); AddCondition("BMC"  , "JC"  ,  0);
  2625.   AddCondition("BMGTU", "JGTU",  1); AddCondition("BMEQ" , "JEQ" ,  2);
  2626.   AddCondition("BMZ"  , "JZ"  ,  2); AddCondition("BMN"  , "JN"  ,  3);
  2627.   AddCondition("BMLTU", "JLTU",  4); AddCondition("BMNC" , "JNC" ,  4);
  2628.   AddCondition("BMLEU", "JLEU",  5); AddCondition("BMNE" , "JNE" ,  6);
  2629.   AddCondition("BMNZ" , "JNZ" ,  6); AddCondition("BMPZ" , "JPZ" ,  7);
  2630.   AddCondition("BMLE" , "JLE" ,  8); AddCondition("BMO"  , "JO"  ,  9);
  2631.   AddCondition("BMGE" , "JGE" , 10); AddCondition("BMGT" , "JGT" , 12);
  2632.   AddCondition("BMNO" , "JNO" , 13); AddCondition("BMLT" , "JLT" , 14);
  2633.  
  2634.   InstrZ = 0;
  2635.   AddBCD("DADD"); AddBCD("DSUB"); AddBCD("DADC"); AddBCD("DSBB");
  2636.  
  2637.   InstrZ = 0;
  2638.   AddDir("MOVLL", InstrZ++);
  2639.   AddDir("MOVHL", InstrZ++);
  2640.   AddDir("MOVLH", InstrZ++);
  2641.   AddDir("MOVHH", InstrZ++);
  2642.  
  2643.   AddBit("BAND"  , 4); AddBit("BNAND" , 5);
  2644.   AddBit("BNOR"  , 7); AddBit("BNTST" , 3);
  2645.   AddBit("BNXOR" ,13); AddBit("BOR"   , 6);
  2646.   AddBit("BTSTC" , 0); AddBit("BTSTS" , 1);
  2647.   AddBit("BXOR"  ,12); AddBit("BCLR"  , 8);
  2648.   AddBit("BNOT"  ,10); AddBit("BSET"  , 9);
  2649.   AddBit("BTST"  ,11);
  2650.  
  2651.   AddInstTable(InstTable, "REG", 0, CodeREG);
  2652.   AddIntelPseudo(InstTable, eIntPseudoFlag_LittleEndian);
  2653. }
  2654.  
  2655. static void DeinitFields(void)
  2656. {
  2657.   free(Format);
  2658.   order_array_free(Gen2Orders);
  2659.   order_array_free(DivOrders);
  2660.  
  2661.   DestroyInstTable(InstTable);
  2662. }
  2663.  
  2664. /*------------------------------------------------------------------------*/
  2665.  
  2666. static Boolean DecodeAttrPart_M16C(void)
  2667. {
  2668.   char *p;
  2669.  
  2670.   switch (AttrSplit)
  2671.   {
  2672.     case '.':
  2673.       p = strchr(AttrPart.str.p_str, ':');
  2674.       if (p)
  2675.       {
  2676.         if (p < AttrPart.str.p_str + strlen(AttrPart.str.p_str) - 1)
  2677.           strmaxcpy(Format, p + 1, STRINGSIZE - 1);
  2678.         *p = '\0';
  2679.       }
  2680.       else
  2681.         strcpy(Format,  " ");
  2682.       break;
  2683.     case ':':
  2684.       p = strchr(AttrPart.str.p_str, '.');
  2685.       if (!p)
  2686.       {
  2687.         strmaxcpy(Format, AttrPart.str.p_str, STRINGSIZE - 1);
  2688.         *AttrPart.str.p_str = '\0';
  2689.       }
  2690.       else
  2691.       {
  2692.         *p = '\0';
  2693.         strmaxcpy(Format, (p == AttrPart.str.p_str) ? " " : AttrPart.str.p_str, STRINGSIZE - 1);
  2694.       }
  2695.       break;
  2696.     default:
  2697.       strcpy(Format, " ");
  2698.   }
  2699.   NLS_UpString(Format);
  2700.  
  2701.   /* Attribut abarbeiten */
  2702.  
  2703.   switch (as_toupper(*AttrPart.str.p_str))
  2704.   {
  2705.     case '\0': AttrPartOpSize[0] = eSymbolSizeUnknown; break;
  2706.     case 'B': AttrPartOpSize[0] = eSymbolSize8Bit; break;
  2707.     case 'W': AttrPartOpSize[0] = eSymbolSize16Bit; break;
  2708.     case 'L': AttrPartOpSize[0] = eSymbolSize32Bit; break;
  2709.     case 'Q': AttrPartOpSize[0] = eSymbolSize64Bit; break;
  2710.     case 'S': AttrPartOpSize[0] = eSymbolSize80Bit; break;
  2711.     case 'D': AttrPartOpSize[0] = eSymbolSizeFloat32Bit; break;
  2712.     case 'X': AttrPartOpSize[0] = eSymbolSizeFloat64Bit; break;
  2713.     case 'A': AttrPartOpSize[0] = eSymbolSizeFloat96Bit; break;
  2714.     default:
  2715.       WrStrErrorPos(ErrNum_UndefAttr, &AttrPart); return False;
  2716.   }
  2717.   return True;
  2718. }
  2719.  
  2720. /*!------------------------------------------------------------------------
  2721.  * \fn     InternSymbol_M16C(char *pArg, TempResult *pResult)
  2722.  * \brief  handle built-in symbols on M16C
  2723.  * \param  pArg source argument
  2724.  * \param  pResult result buffer
  2725.  * ------------------------------------------------------------------------ */
  2726.  
  2727. static void InternSymbol_M16C(char *pArg, TempResult *pResult)
  2728. {
  2729.   Byte Erg;
  2730.   tSymbolSize Size;
  2731.  
  2732.   if (DecodeRegCore(pArg, &Erg, &Size))
  2733.   {
  2734.     pResult->Typ = TempReg;
  2735.     pResult->DataSize = Size;
  2736.     pResult->Contents.RegDescr.Reg = Erg;
  2737.     pResult->Contents.RegDescr.Dissect = DissectReg_M16C;
  2738.     pResult->Contents.RegDescr.compare = NULL;
  2739.   }
  2740. }
  2741.  
  2742. static void MakeCode_M16C(void)
  2743. {
  2744.   OpSize = AttrPartOpSize[0];
  2745.  
  2746.   if (!LookupInstTable(InstTable, OpPart.str.p_str))
  2747.     WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
  2748. }
  2749.  
  2750. static Boolean IsDef_M16C(void)
  2751. {
  2752.   return Memo("REG");
  2753. }
  2754.  
  2755. static void SwitchFrom_M16C(void)
  2756. {
  2757.   DeinitFields();
  2758. }
  2759.  
  2760. static void SwitchTo_M16C(void)
  2761. {
  2762.   TurnWords = True;
  2763.   SetIntConstMode(eIntConstModeIntel);
  2764.  
  2765.   PCSymbol = "$";
  2766.   HeaderID = 0x14;
  2767.   NOPCode = 0x04;
  2768.   DivideChars = ",";
  2769.   HasAttrs = True;
  2770.   AttrChars = ".:";
  2771.  
  2772.   ValidSegs = 1 << SegCode;
  2773.   Grans[SegCode] = 1;
  2774.   ListGrans[SegCode] = 1;
  2775.   SegInits[SegCode] = 0;
  2776.   SegLimits[SegCode] = 0xfffff;        /* RMS 10: Probably a typo (was 0xffff) */
  2777.  
  2778.   DecodeAttrPart = DecodeAttrPart_M16C;
  2779.   MakeCode = MakeCode_M16C;
  2780.   IsDef = IsDef_M16C;
  2781.   InternSymbol = InternSymbol_M16C;
  2782.   DissectReg = DissectReg_M16C;
  2783.   SwitchFrom = SwitchFrom_M16C;
  2784.   InitFields();
  2785. }
  2786.  
  2787. void codem16c_init(void)
  2788. {
  2789.   CPUM16C = AddCPU("M16C", SwitchTo_M16C);
  2790.   CPUM30600M8 = AddCPU("M30600M8", SwitchTo_M16C);
  2791.   CPUM30610 = AddCPU("M30610", SwitchTo_M16C);
  2792.   CPUM30620 = AddCPU("M30620", SwitchTo_M16C);
  2793.  
  2794.   AddCopyright("Mitsubishi M16C-Generator also (C) 1999 RMS");
  2795. }
  2796.