Subversion Repositories pentevo

Rev

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

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