Subversion Repositories pentevo

Rev

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

  1. /* codeh8_5.c */
  2. /*****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
  4. /*                                                                           */
  5. /* AS-Portierung                                                             */
  6. /*                                                                           */
  7. /* AS-Codegenerator H8/500                                                   */
  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 "asmallg.h"
  22. #include "onoff_common.h"
  23. #include "asmitree.h"
  24. #include "asmstructs.h"
  25. #include "codepseudo.h"
  26. #include "motpseudo.h"
  27. #include "codevars.h"
  28. #include "errmsg.h"
  29.  
  30. #include "codeh8_5.h"
  31.  
  32. #define REG_SP 7
  33. #define REG_FP 6
  34.  
  35. #define ModNone (-1)
  36. #define ModReg 0
  37. #define MModReg (1 << ModReg)
  38. #define ModIReg 1
  39. #define MModIReg (1 << ModIReg)
  40. #define ModDisp8 2
  41. #define MModDisp8 (1 << ModDisp8)
  42. #define ModDisp16 3
  43. #define MModDisp16 (1 << ModDisp16)
  44. #define ModPredec 4
  45. #define MModPredec (1 << ModPredec)
  46. #define ModPostInc 5
  47. #define MModPostInc (1 << ModPostInc)
  48. #define ModAbs8 6
  49. #define MModAbs8 (1 << ModAbs8)
  50. #define ModAbs16 7
  51. #define MModAbs16 (1 << ModAbs16)
  52. #define ModImm 8
  53. #define MModImm (1 << ModImm)
  54. #define MModImmVariable (1 << 9)
  55.  
  56. #define MModAll (MModReg|MModIReg|MModDisp8|MModDisp16|MModPredec|MModPostInc|MModAbs8|MModAbs16|MModImm)
  57. #define MModNoImm (MModAll & ~MModImm)
  58.  
  59.  
  60. typedef struct
  61. {
  62.   char *Name;
  63.   Word Code;
  64.   Byte SizeMask;
  65.   tSymbolSize DefSize;
  66. } OneOrder;
  67.  
  68.  
  69. static CPUVar CPU532,CPU534,CPU536,CPU538;
  70.  
  71. static tSymbolSize OpSize;
  72. static char *Format;
  73. static ShortInt AdrMode;
  74. static Byte AdrByte,FormatCode;
  75. static Byte AdrVals[3];
  76. static Byte AbsBank;
  77. static tSymbolSize ImmSize;
  78.  
  79. static ShortInt Adr2Mode;
  80. static Byte Adr2Byte, Adr2Cnt;
  81. static Byte Adr2Vals[3];
  82. static tSymbolSize Imm2Size;
  83.  
  84. static LongInt Reg_DP,Reg_EP,Reg_TP,Reg_BR;
  85.  
  86. static OneOrder *OneOrders;
  87. static OneOrder *OneRegOrders;
  88. static OneOrder *RegEAOrders;
  89. static OneOrder *TwoRegOrders;
  90.  
  91. #define ASSUMEH8_5Count 4
  92. static ASSUMERec ASSUMEH8_5s[ASSUMEH8_5Count] =
  93. {
  94.   {"DP", &Reg_DP, 0, 0xff, -1, NULL},
  95.   {"EP", &Reg_EP, 0, 0xff, -1, NULL},
  96.   {"TP", &Reg_TP, 0, 0xff, -1, NULL},
  97.   {"BR", &Reg_BR, 0, 0xff, -1, NULL}
  98. };
  99.  
  100. /*-------------------------------------------------------------------------*/
  101. /* Adressparsing */
  102.  
  103. static void SetOpSize(tSymbolSize NSize)
  104. {
  105.   if (OpSize == eSymbolSizeUnknown) OpSize = NSize;
  106.   else if (OpSize != NSize) WrError(ErrNum_ConfOpSizes);
  107. }
  108.  
  109. /*!------------------------------------------------------------------------
  110.  * \fn     DecodeRegCore(const char *pArg, Byte *pResult)
  111.  * \brief  check whether argument is a CPU register
  112.  * \param  pArg source argument
  113.  * \param  pResult register # if yes
  114.  * \return True if yes
  115.  * ------------------------------------------------------------------------ */
  116.  
  117. static Boolean DecodeRegCore(const char *pArg, Byte *pResult)
  118. {
  119.   if (!as_strcasecmp(pArg, "SP")) *pResult = REG_SP | REGSYM_FLAG_ALIAS;
  120.   else if (!as_strcasecmp(pArg, "FP")) *pResult = REG_FP | REGSYM_FLAG_ALIAS;
  121.   else if ((strlen(pArg) == 2) && (as_toupper(*pArg) == 'R') && (pArg[1] >= '0') && (pArg[1] <= '7'))
  122.     *pResult = pArg[1] - '0';
  123.   else
  124.     return False;
  125.   return True;
  126. }
  127.  
  128. /*!------------------------------------------------------------------------
  129.  * \fn     DissectReg_H8_5(char *pDest, size_t DestSize, tRegInt Value, tSymbolSize InpSize)
  130.  * \brief  dissect register symbols - H8/500 variant
  131.  * \param  pDest destination buffer
  132.  * \param  DestSize destination buffer size
  133.  * \param  Value numeric register value
  134.  * \param  InpSize register size
  135.  * ------------------------------------------------------------------------ */
  136.  
  137. static void DissectReg_H8_5(char *pDest, size_t DestSize, tRegInt Value, tSymbolSize InpSize)
  138. {
  139.   switch (InpSize)
  140.   {
  141.     case eSymbolSize16Bit:
  142.       if (Value == (REG_SP | REGSYM_FLAG_ALIAS))
  143.         as_snprintf(pDest, DestSize, "SP");
  144.       else if (Value == (REG_FP | REGSYM_FLAG_ALIAS))
  145.         as_snprintf(pDest, DestSize, "FP");
  146.       else
  147.         as_snprintf(pDest, DestSize, "R%u", (unsigned)Value);
  148.       break;
  149.     default:
  150.       as_snprintf(pDest, DestSize, "%d-%u", (int)InpSize, (unsigned)Value);
  151.   }
  152. }
  153.  
  154.  
  155. /*!------------------------------------------------------------------------
  156.  * \fn     DecodeReg(const tStrComp *pArg, Byte *pResult, Boolean MustBeReg)
  157.  * \brief  check whether argument is a CPU register or CPU alias
  158.  * \param  pArg source argument
  159.  * \param  pResult register # if yes
  160.  * \param  MustBeReg True if argument must be a register
  161.  * \return EvalResult
  162.  * ------------------------------------------------------------------------ */
  163.  
  164. static tRegEvalResult DecodeReg(const tStrComp *pArg, Byte *pResult, Boolean MustBeReg)
  165. {
  166.   tRegDescr RegDescr;
  167.   tEvalResult EvalResult;
  168.   tRegEvalResult RegEvalResult;
  169.  
  170.   if (DecodeRegCore(pArg->str.p_str, pResult))
  171.   {
  172.     *pResult &= ~REGSYM_FLAG_ALIAS;
  173.     return eIsReg;
  174.   }
  175.  
  176.   RegEvalResult = EvalStrRegExpressionAsOperand(pArg, &RegDescr, &EvalResult, eSymbolSize16Bit, MustBeReg);
  177.   *pResult = RegDescr.Reg;
  178.   return RegEvalResult;
  179. }
  180.  
  181. static Boolean DecodeRegList(tStrComp *pArg, Byte *pResult)
  182. {
  183.   tStrComp Arg, Remainder;
  184.   Byte Reg1, Reg2, z;
  185.   char *p, *p2;
  186.  
  187.   StrCompRefRight(&Arg, pArg, 0);
  188.   if (IsIndirect(Arg.str.p_str))
  189.   {
  190.     StrCompIncRefLeft(&Arg, 1);
  191.     StrCompShorten(&Arg, 1);
  192.     KillPrefBlanksStrCompRef(&Arg);
  193.     KillPostBlanksStrComp(&Arg);
  194.   }
  195.  
  196.   *pResult = 0;
  197.   do
  198.   {
  199.     p = QuotPos(Arg.str.p_str, ',');
  200.     if (p)
  201.       StrCompSplitRef(&Arg, &Remainder, &Arg, p);
  202.     p2 = strchr(Arg.str.p_str, '-');
  203.     if (p2)
  204.     {
  205.       tStrComp Left, Right;
  206.  
  207.       StrCompSplitRef(&Left, &Right, &Arg, p2);
  208.       if (DecodeReg(&Left, &Reg1, True) != eIsReg) return False;
  209.       if (DecodeReg(&Right, &Reg2, True) != eIsReg) return False;
  210.       if (Reg1 > Reg2) Reg2 += 8;
  211.       for (z = Reg1; z <= Reg2; z++) *pResult |= (1 << (z & 7));
  212.     }
  213.     else
  214.     {
  215.       if (DecodeReg(&Arg, &Reg1, True) != eIsReg) return False;
  216.       *pResult |= (1 << Reg1);
  217.     }
  218.     if (p)
  219.       Arg = Remainder;
  220.   }
  221.   while (p);
  222.  
  223.   return True;
  224. }
  225.  
  226. static Boolean DecodeCReg(char *Asc, Byte *pErg)
  227. {
  228.   if (!as_strcasecmp(Asc, "SR"))
  229.   {
  230.     *pErg = 0; SetOpSize(eSymbolSize16Bit);
  231.   }
  232.   else if (!as_strcasecmp(Asc, "CCR"))
  233.   {
  234.     *pErg = 1; SetOpSize(eSymbolSize8Bit);
  235.   }
  236.   else if (!as_strcasecmp(Asc, "BR"))
  237.   {
  238.     *pErg = 3; SetOpSize(eSymbolSize8Bit);
  239.   }
  240.   else if (!as_strcasecmp(Asc, "EP"))
  241.   {
  242.     *pErg = 4; SetOpSize(eSymbolSize8Bit);
  243.   }
  244.   else if (!as_strcasecmp(Asc, "DP"))
  245.   {
  246.     *pErg = 5; SetOpSize(eSymbolSize8Bit);
  247.   }
  248.   else if (!as_strcasecmp(Asc, "TP"))
  249.   {
  250.     *pErg = 7; SetOpSize(eSymbolSize8Bit);
  251.   }
  252.   else
  253.     return False;
  254.   return True;
  255. }
  256.  
  257. static void SplitDisp(tStrComp *pArg, tSymbolSize *pSize)
  258. {
  259.   int l = strlen(pArg->str.p_str);
  260.  
  261.   if ((l > 2) && !strcmp(pArg->str.p_str + l - 2, ":8"))
  262.   {
  263.     StrCompShorten(pArg, 2);
  264.     *pSize = eSymbolSize8Bit;
  265.   }
  266.   else if ((l > 3) && !strcmp(pArg->str.p_str + l - 3, ":16"))
  267.   {
  268.     StrCompShorten(pArg, 3);
  269.     *pSize = eSymbolSize16Bit;
  270.   }
  271. }
  272.  
  273. static void DecideAbsolute(LongInt Value, tSymbolSize Size, Boolean Unknown, Word Mask)
  274. {
  275.   LongInt Base;
  276.  
  277.   if (Size == eSymbolSizeUnknown)
  278.   {
  279.     if (((Value >> 8) == Reg_BR) && (Mask & MModAbs8)) Size = eSymbolSize8Bit;
  280.     else Size = eSymbolSize16Bit;
  281.   }
  282.  
  283.   AdrMode = ModNone;
  284.   AdrCnt = 0;
  285.  
  286.   switch (Size)
  287.   {
  288.     case eSymbolSize8Bit:
  289.       if (Unknown) Value = (Value & 0xff) | (Reg_BR << 8);
  290.       if ((Value >> 8) != Reg_BR) WrError(ErrNum_InAccPage);
  291.       AdrMode = ModAbs8; AdrByte = 0x05;
  292.       AdrVals[0] = Value & 0xff; AdrCnt = 1;
  293.       break;
  294.     case eSymbolSize16Bit:
  295.       if (MaxMode)
  296.       {
  297.         Base = AbsBank;
  298.         Base <<= 16;
  299.       }
  300.       else
  301.         Base = 0;
  302.       if (Unknown) Value = (Value & 0xffff) | Base;
  303.       if ((Value >> 16) != (Base >> 16)) WrError(ErrNum_InAccPage);
  304.       AdrMode = ModAbs16; AdrByte = 0x15;
  305.       AdrVals[0] = (Value >> 8) & 0xff;
  306.       AdrVals[1] = Value & 0xff;
  307.       AdrCnt = 2;
  308.       break;
  309.     default:
  310.       break;
  311.   }
  312. }
  313.  
  314. static void ChkAdr(Word Mask)
  315. {
  316.   if ((AdrMode != ModNone) && (!(Mask & (1 << AdrMode))))
  317.   {
  318.     WrError(ErrNum_InvAddrMode); AdrMode = ModNone; AdrCnt = 0;
  319.   }
  320. }
  321.  
  322. static void DecodeAdr(tStrComp *pArg, Word Mask)
  323. {
  324.   Word AdrWord;
  325.   Boolean OK, Unknown;
  326.   tSymbolFlags Flags;
  327.   LongInt DispAcc;
  328.   Byte HReg;
  329.   tSymbolSize DispSize;
  330.   ShortInt RegPart;
  331.   char *p;
  332.  
  333.   AdrMode = ModNone; AdrCnt = 0;
  334.   ImmSize = eSymbolSizeUnknown;
  335.  
  336.   /* einfaches Register ? */
  337.  
  338.   switch (DecodeReg(pArg, &AdrByte, False))
  339.   {
  340.     case eIsReg:
  341.       AdrMode = ModReg; AdrByte |= 0xa0;
  342.       ChkAdr(Mask); return;
  343.     case eRegAbort:
  344.       return;
  345.     case eIsNoReg:
  346.       break;
  347.   }
  348.  
  349.   /* immediate ? */
  350.  
  351.   if (*pArg->str.p_str == '#')
  352.   {
  353.     SplitDisp(pArg, &ImmSize);
  354.     if (ImmSize == eSymbolSizeUnknown)
  355.     {
  356.       if (!(Mask & MModImmVariable))
  357.         ImmSize = OpSize;
  358.     }
  359.     else if ((ImmSize != OpSize) && !(Mask & MModImmVariable))
  360.     {
  361.       WrStrErrorPos(ErrNum_ConfOpSizes, pArg);
  362.       return;
  363.     }
  364.     switch (OpSize)
  365.     {
  366.       case eSymbolSizeUnknown:
  367.         OK = False; WrError(ErrNum_UndefOpSizes);
  368.         break;
  369.       case eSymbolSize8Bit:
  370.         AdrVals[0] = EvalStrIntExpressionOffs(pArg, 1, Int8, &OK);
  371.         break;
  372.       case eSymbolSize16Bit:
  373.         AdrWord = EvalStrIntExpressionOffs(pArg, 1, Int16, &OK);
  374.         AdrVals[0] = Hi(AdrWord); AdrVals[1] = Lo(AdrWord);
  375.         break;
  376.       default:
  377.         OK = False;
  378.         break;
  379.     }
  380.     if (OK)
  381.     {
  382.       AdrMode = ModImm; AdrByte = 0x04; AdrCnt = OpSize + 1;
  383.     }
  384.     ChkAdr(Mask); return;
  385.   }
  386.  
  387.   /* indirekt ? */
  388.  
  389.   if (*pArg->str.p_str == '@')
  390.   {
  391.     tStrComp Arg, Remainder;
  392.  
  393.     StrCompRefRight(&Arg, pArg, 1);
  394.     if (IsIndirect(Arg.str.p_str))
  395.     {
  396.       StrCompIncRefLeft(&Arg, 1);
  397.       StrCompShorten(&Arg, 1);
  398.     }
  399.  
  400.     /* Predekrement ? */
  401.  
  402.     if (*Arg.str.p_str == '-')
  403.     {
  404.       tStrComp RegArg;
  405.  
  406.       StrCompRefRight(&RegArg, &Arg, 1);
  407.       if (DecodeReg(&RegArg, &AdrByte, True) == eIsReg)
  408.       {
  409.         AdrMode = ModPredec; AdrByte |= 0xb0;
  410.         ChkAdr(Mask); return;
  411.       }
  412.     }
  413.  
  414.     /* Postinkrement ? */
  415.  
  416.     if ((*Arg.str.p_str) && (Arg.str.p_str[strlen(Arg.str.p_str) - 1] == '+'))
  417.     {
  418.       StrCompShorten(&Arg, 1);
  419.       if (DecodeReg(&Arg, &AdrByte, True) == eIsReg)
  420.       {
  421.         AdrMode = ModPostInc; AdrByte |= 0xc0;
  422.         ChkAdr(Mask); return;
  423.       }
  424.     }
  425.  
  426.     /* zusammengesetzt */
  427.  
  428.     DispAcc = 0; DispSize = eSymbolSizeUnknown; RegPart = -1; OK = True; Unknown = False;
  429.     do
  430.     {
  431.       p = QuotPos(Arg.str.p_str, ',');
  432.       if (p)
  433.         StrCompSplitRef(&Arg, &Remainder, &Arg, p);
  434.       switch (DecodeReg(&Arg, &HReg, False))
  435.       {
  436.         case eIsReg:
  437.           if (RegPart != -1)
  438.           {
  439.             WrStrErrorPos(ErrNum_InvAddrMode, &Arg); OK = False;
  440.           }
  441.           else
  442.             RegPart = HReg;
  443.           break;
  444.         case eIsNoReg:
  445.           SplitDisp(&Arg, &DispSize);
  446.           DispAcc += EvalStrIntExpressionOffsWithFlags(&Arg, !!(*Arg.str.p_str == '#'), Int32, &OK, &Flags);
  447.           if (mFirstPassUnknown(Flags)) Unknown = True;
  448.           break;
  449.         default:
  450.           OK = False;
  451.       }
  452.       if (p)
  453.         Arg = Remainder;
  454.     }
  455.     while (p && OK);
  456.     if (OK)
  457.     {
  458.       if (RegPart == -1) DecideAbsolute(DispAcc, DispSize, Unknown, Mask);
  459.       else if (DispAcc == 0)
  460.       {
  461.         switch (DispSize)
  462.         {
  463.           case eSymbolSizeUnknown:
  464.             AdrMode = ModIReg; AdrByte = 0xd0 | RegPart;
  465.             break;
  466.           case eSymbolSize8Bit:
  467.             AdrMode = ModDisp8; AdrByte = 0xe0 | RegPart;
  468.             AdrVals[0] = 0; AdrCnt = 1;
  469.             break;
  470.           case eSymbolSize16Bit:
  471.             AdrMode = ModDisp16; AdrByte = 0xf0 | RegPart;
  472.             AdrVals[0] = 0; AdrVals[1] = 0; AdrCnt = 2;
  473.             break;
  474.           default:
  475.             break;
  476.         }
  477.       }
  478.       else
  479.       {
  480.         if (DispSize == eSymbolSizeUnknown)
  481.         {
  482.           if ((DispAcc >= -128) && (DispAcc < 127)) DispSize = eSymbolSize8Bit;
  483.           else DispSize = eSymbolSize16Bit;
  484.         }
  485.         switch (DispSize)
  486.         {
  487.           case eSymbolSize8Bit:
  488.             if (Unknown) DispAcc &= 0x7f;
  489.             if (ChkRange(DispAcc, -128, 127))
  490.             {
  491.               AdrMode = ModDisp8; AdrByte = 0xe0 | RegPart;
  492.               AdrVals[0] = DispAcc & 0xff; AdrCnt = 1;
  493.             }
  494.             break;
  495.           case eSymbolSize16Bit:
  496.             if (Unknown) DispAcc &= 0x7fff;
  497.             if (ChkRange(DispAcc, -0x8000l, 0xffffl))
  498.             {
  499.               AdrMode = ModDisp16; AdrByte = 0xf0 | RegPart;
  500.               AdrVals[1] = DispAcc & 0xff;
  501.               AdrVals[0] = (DispAcc >> 8) & 0xff;
  502.               AdrCnt = 2;
  503.             }
  504.             break;
  505.           default:
  506.             break;
  507.         }
  508.       }
  509.     }
  510.  
  511.     ChkAdr(Mask); return;
  512.   }
  513.  
  514.   /* absolut */
  515.  
  516.   DispSize = eSymbolSizeUnknown; SplitDisp(pArg, &DispSize);
  517.   DispAcc = EvalStrIntExpressionWithFlags(pArg, UInt24, &OK, &Flags);
  518.   DecideAbsolute(DispAcc, DispSize, mFirstPassUnknown(Flags), Mask);
  519.  
  520.   ChkAdr(Mask);
  521. }
  522.  
  523. static LongInt ImmVal(void)
  524. {
  525.   LongInt t;
  526.  
  527.   switch (OpSize)
  528.   {
  529.     case eSymbolSize8Bit:
  530.       t = AdrVals[0]; if (t > 127) t -= 256;
  531.       break;
  532.     case eSymbolSize16Bit:
  533.       t = (((Word)AdrVals[0]) << 8) + AdrVals[1];
  534.       if (t > 0x7fff) t -= 0x10000;
  535.       break;
  536.     default:
  537.       t = 0; WrError(ErrNum_InternalError);
  538.   }
  539.   return t;
  540. }
  541.  
  542. /*!------------------------------------------------------------------------
  543.  * \fn     AdaptImmSize(const tStrComp *pArg)
  544.  * \brief  necessary post-processing if immediate operand size may differ from insn size
  545.  * \param  pArg immediate argument
  546.  * \return True if adaption succeeded
  547.  * ------------------------------------------------------------------------ */
  548.  
  549. static Boolean AdaptImmSize(const tStrComp *pArg)
  550. {
  551.   LongInt ImmV = ImmVal();
  552.   Boolean ImmValShort = CompMode ? ((ImmV >= 0) && (ImmV <= 255)) : ((ImmV >= -128) && (ImmV <= 127));
  553.  
  554.   switch (OpSize)
  555.   {
  556.     /* no AdrVals adaptions needed for pure 8 bit: */
  557.  
  558.     case eSymbolSize8Bit:
  559.       if (ImmSize == eSymbolSize16Bit)
  560.       {
  561.         WrStrErrorPos(ErrNum_ConfOpSizes, pArg);
  562.         return False;
  563.       }
  564.       else
  565.       {
  566.         ImmSize = eSymbolSize8Bit;
  567.         return True;
  568.       }
  569.  
  570.     case eSymbolSize16Bit:
  571.       switch (ImmSize)
  572.       {
  573.         case eSymbolSize16Bit:
  574.           return True;
  575.         case eSymbolSize8Bit:
  576.           if (!ImmValShort)
  577.           {
  578.             WrStrErrorPos(ErrNum_OverRange, pArg);
  579.             return False;
  580.           }
  581.           else
  582.             goto Make8;
  583.         case eSymbolSizeUnknown:
  584.           if (ImmValShort)
  585.           {
  586.             ImmSize = eSymbolSize8Bit;
  587.             goto Make8;
  588.           }
  589.           else
  590.           {
  591.             ImmSize = eSymbolSize16Bit;
  592.             return True;
  593.           }
  594.         default:
  595.           WrStrErrorPos(ErrNum_InternalError, pArg);
  596.           return False;
  597.         Make8:
  598.           AdrVals[0] = AdrVals[1];
  599.           AdrCnt--;
  600.           return True;
  601.       }
  602.  
  603.     default:
  604.       WrStrErrorPos(ErrNum_InternalError, pArg);
  605.       return False;
  606.   }
  607. }
  608.  
  609. /*--------------------------------------------------------------------------*/
  610. /* Bit Symbol Handling */
  611.  
  612. /*
  613.  * Compact representation of bits in symbol table:
  614.  * Bit 31/30: Operand size (00 = unknown, 10=8, 11=16 bits)
  615.  * Bit 29/28: address field size (00 = unknown, 10=8, 11=16 bits)
  616.  * Bits 27...4 or 26..3: Absolute address
  617.  * Bits 0..2 or 0..3: Bit position
  618.  */
  619.  
  620. static LongWord CodeOpSize(tSymbolSize Size)
  621. {
  622.   return (Size == eSymbolSizeUnknown)
  623.        ? 0
  624.        : ((Size == eSymbolSize16Bit) ? 3 : 2);
  625. }
  626.  
  627. static tSymbolSize DecodeOpSize(Byte SizeCode)
  628. {
  629.   return (SizeCode & 2)
  630.        ? ((SizeCode & 1) ? eSymbolSize16Bit : eSymbolSize8Bit)
  631.        : eSymbolSizeUnknown;
  632. }
  633.  
  634. /*!------------------------------------------------------------------------
  635.  * \fn     EvalBitPosition(const tStrComp *pArg, tSymbolSize Size, Boolean *pOK)
  636.  * \brief  evaluate bit position
  637.  * \param  bit position argument (with or without #)
  638.  * \param  Size operand size (8/16/unknown)
  639.  * \param  pOK parsing OK?
  640.  * \return numeric bit position
  641.  * ------------------------------------------------------------------------ */
  642.  
  643. static LongWord EvalBitPosition(const tStrComp *pArg, tSymbolSize Size, Boolean *pOK)
  644. {
  645.   return EvalStrIntExpressionOffs(pArg, !!(*pArg->str.p_str == '#'), (Size == eSymbolSize16Bit) ? UInt4 : UInt3, pOK);
  646. }
  647.  
  648. /*!------------------------------------------------------------------------
  649.  * \fn     AssembleBitSymbol(Byte BitPos, LongWord Address, tSymbolSize OpSize, tSymbolSize AddrSize)
  650.  * \brief  build the compact internal representation of a bit symbol
  651.  * \param  BitPos bit position in word
  652.  * \param  Address register address
  653.  * \param  OpSize memory operand size
  654.  * \param  AddrSize address length
  655.  * \return compact representation
  656.  * ------------------------------------------------------------------------ */
  657.  
  658. static LongWord AssembleBitSymbol(Byte BitPos, Word Address, tSymbolSize OpSize, tSymbolSize AddrSize)
  659. {
  660.   return
  661.     (CodeOpSize(OpSize) << 30)
  662.   | (CodeOpSize(AddrSize) << 28)
  663.   | (Address << ((OpSize == eSymbolSize8Bit) ? 3 : 4))
  664.   | (BitPos << 0);
  665. }
  666.  
  667. /*!------------------------------------------------------------------------
  668.  * \fn     DecodeBitArg2(LongWord *pResult, const tStrComp *pBitArg, tStrComp *pRegArg)
  669.  * \brief  encode a bit symbol, address & bit position separated
  670.  * \param  pResult resulting encoded bit
  671.  * \param  pRegArg register argument
  672.  * \param  pBitArg bit argument
  673.  * \return True if success
  674.  * ------------------------------------------------------------------------ */
  675.  
  676. static Boolean DecodeBitArg2(LongWord *pResult, const tStrComp *pBitArg, tStrComp *pRegArg)
  677. {
  678.   Boolean OK;
  679.   LongWord Addr, BitPos;
  680.   tSymbolSize AddrSize = eSymbolSizeUnknown;
  681.  
  682.   BitPos = EvalBitPosition(pBitArg, (OpSize == eSymbolSizeUnknown) ? eSymbolSize16Bit : OpSize, &OK);
  683.   if (!OK)
  684.     return False;
  685.  
  686.   SplitDisp(pRegArg, &AddrSize);
  687.   Addr = EvalStrIntExpression(pRegArg, UInt24, &OK);
  688.   if (!OK)
  689.     return False;
  690.  
  691.   *pResult = AssembleBitSymbol(BitPos, Addr, OpSize, AddrSize);
  692.  
  693.   return True;
  694. }
  695.  
  696. /*!------------------------------------------------------------------------
  697.  * \fn     DecodeBitArg(LongWord *pResult, int Start, int Stop)
  698.  * \brief  encode a bit symbol from instruction argument(s)
  699.  * \param  pResult resulting encoded bit
  700.  * \param  Start first argument
  701.  * \param  Stop last argument
  702.  * \return True if success
  703.  * ------------------------------------------------------------------------ */
  704.  
  705. static Boolean DecodeBitArg(LongWord *pResult, int Start, int Stop)
  706. {
  707.   *pResult = 0;
  708.  
  709.   /* Just one argument -> parse as bit argument */
  710.  
  711.   if (Start == Stop)
  712.   {
  713.     tEvalResult EvalResult;
  714.  
  715.     *pResult = EvalStrIntExpressionWithResult(&ArgStr[Start], UInt32, &EvalResult);
  716.     if (EvalResult.OK)
  717.       ChkSpace(SegBData, EvalResult.AddrSpaceMask);
  718.     return EvalResult.OK;
  719.   }
  720.  
  721.   /* register & bit position are given as separate arguments */
  722.  
  723.   else if (Stop == Start + 1)
  724.     return DecodeBitArg2(pResult, &ArgStr[Start], &ArgStr[Stop]);
  725.  
  726.   /* other # of arguments not allowed */
  727.  
  728.   else
  729.   {
  730.     WrError(ErrNum_WrongArgCnt);
  731.     return False;
  732.   }
  733. }
  734.  
  735. /*!------------------------------------------------------------------------
  736.  * \fn     DissectBitSymbol(LongWord BitSymbol, Word *pAddress, Byte *pBitPos, tSymbolSize *pOpSize, tSymbolSize *pAddrSize)
  737.  * \brief  transform compact representation of bit (field) symbol into components
  738.  * \param  BitSymbol compact storage
  739.  * \param  pAddress register address
  740.  * \param  pBitPos bit position
  741.  * \param  pOpSize operand size
  742.  * \param  pAddrSize address length
  743.  * \return constant True
  744.  * ------------------------------------------------------------------------ */
  745.  
  746. static Boolean DissectBitSymbol(LongWord BitSymbol, LongWord *pAddress, Byte *pBitPos, tSymbolSize *pOpSize, tSymbolSize *pAddrSize)
  747. {
  748.   *pOpSize = DecodeOpSize(BitSymbol >> 30);
  749.   *pAddrSize = DecodeOpSize(BitSymbol >> 28);
  750.   *pAddress = (BitSymbol >> ((*pOpSize == eSymbolSize8Bit) ? 3 : 4)) & 0xfffffful;
  751.   *pBitPos = BitSymbol & (*pOpSize ? 15 : 7);
  752.   return True;
  753. }
  754.  
  755. /*!------------------------------------------------------------------------
  756.  * \fn     DissectBit_H8_5(char *pDest, size_t DestSize, LargeWord Inp)
  757.  * \brief  dissect compact storage of bit (field) into readable form for listing
  758.  * \param  pDest destination for ASCII representation
  759.  * \param  DestSize destination buffer size
  760.  * \param  Inp compact storage
  761.  * ------------------------------------------------------------------------ */
  762.  
  763. static void DissectBit_H8_5(char *pDest, size_t DestSize, LargeWord Inp)
  764. {
  765.   Byte BitPos;
  766.   LongWord Address;
  767.   tSymbolSize OpSize, AddrSize;
  768.  
  769.   DissectBitSymbol(Inp, &Address, &BitPos, &OpSize, &AddrSize);
  770.  
  771.   as_snprintf(pDest, DestSize, "#%u,$%llx", BitPos, (LargeWord)Address);
  772.   if (AddrSize != eSymbolSizeUnknown)
  773.     as_snprcatf(pDest, DestSize, ":%u", AddrSize ? 16 : 8);
  774.   if (OpSize != eSymbolSizeUnknown)
  775.     as_snprcatf(pDest, DestSize, ".%c", "BW"[OpSize]);
  776. }
  777.  
  778. /*!------------------------------------------------------------------------
  779.  * \fn     ExpandBit_H8_5(const tStrComp *pVarName, const struct sStructElem *pStructElem, LargeWord Base)
  780.  * \brief  expands bit definition when a structure is instantiated
  781.  * \param  pVarName desired symbol name
  782.  * \param  pStructElem element definition
  783.  * \param  Base base address of instantiated structure
  784.  * ------------------------------------------------------------------------ */
  785.  
  786. static void ExpandBit_H8_5(const tStrComp *pVarName, const struct sStructElem *pStructElem, LargeWord Base)
  787. {
  788.   LongWord Address = Base + pStructElem->Offset;
  789.  
  790.   if (pInnermostNamedStruct)
  791.   {
  792.     PStructElem pElem = CloneStructElem(pVarName, pStructElem);
  793.  
  794.     if (!pElem)
  795.       return;
  796.     pElem->Offset = Address;
  797.     AddStructElem(pInnermostNamedStruct->StructRec, pElem);
  798.   }
  799.   else
  800.   {
  801.     tSymbolSize OpSize = (pStructElem->OpSize < 0) ? eSymbolSize8Bit : pStructElem->OpSize;
  802.  
  803.     if (!ChkRange(Address, 0, 0xffffff)
  804.      || !ChkRange(pStructElem->BitPos, 0, (8 << OpSize) - 1))
  805.       return;
  806.  
  807.     PushLocHandle(-1);
  808.     EnterIntSymbol(pVarName, AssembleBitSymbol(pStructElem->BitPos, Address, OpSize, eSymbolSizeUnknown), SegBData, False);
  809.     PopLocHandle();
  810.     /* TODO: MakeUseList? */
  811.   }
  812. }
  813.  
  814. /*-------------------------------------------------------------------------*/
  815.  
  816. static Boolean CheckFormat(const char *FSet)
  817. {
  818.   const char *p;
  819.  
  820.   if (!strcmp(Format, " "))
  821.     FormatCode = 0;
  822.   else
  823.   {
  824.     p = strchr(FSet, *Format);
  825.     if (!p)
  826.     {
  827.       WrError(ErrNum_InvFormat);
  828.       return False;
  829.     }
  830.     else
  831.       FormatCode = p - FSet + 1;
  832.   }
  833.   return True;
  834. }
  835.  
  836. static Boolean FormatToBranchSize(const char *pFormat, tSymbolSize *pOpSize)
  837. {
  838.   if (!strcmp(pFormat, " "));
  839.  
  840.   else if (!strcmp(pFormat, "16")) /* treat like .L */
  841.   {
  842.     if (*pOpSize == eSymbolSizeUnknown) *pOpSize = eSymbolSize32Bit;
  843.     else if (*pOpSize != eSymbolSize32Bit)
  844.     {
  845.       WrXError(ErrNum_ConfOpSizes, Format);
  846.       return False;
  847.     }
  848.   }
  849.   else if (!strcmp(pFormat, "8")) /* treat like .S */
  850.   {
  851.     if (*pOpSize == eSymbolSizeUnknown) *pOpSize = eSymbolSizeFloat32Bit;
  852.     else if (*pOpSize != eSymbolSizeFloat32Bit)
  853.     {
  854.       WrXError(ErrNum_ConfOpSizes, Format);
  855.       return False;
  856.     }
  857.   }
  858.   else
  859.   {
  860.     WrXError(ErrNum_InvFormat, Format);
  861.     return False;
  862.   }
  863.   return True;
  864. }
  865.  
  866. static void CopyAdr(void)
  867. {
  868.   Adr2Mode = AdrMode;
  869.   Adr2Byte = AdrByte;
  870.   Adr2Cnt = AdrCnt;
  871.   Imm2Size = ImmSize;
  872.   memcpy(Adr2Vals, AdrVals, AdrCnt);
  873. }
  874.  
  875. /*-------------------------------------------------------------------------*/
  876. /* Instruction Decoders */
  877.  
  878. static void DecodeFixed(Word Code)
  879. {
  880.   if (!ChkArgCnt(0, 0));
  881.   else if (OpSize != eSymbolSizeUnknown) WrError(ErrNum_UseLessAttr);
  882.   else if (strcmp(Format, " ")) WrError(ErrNum_InvFormat);
  883.   else
  884.   {
  885.     CodeLen = 0;
  886.     if (Hi(Code) != 0)
  887.       BAsmCode[CodeLen++] = Hi(Code);
  888.     BAsmCode[CodeLen++] = Lo(Code);
  889.   }
  890. }
  891.  
  892. static void DecodeMOV(Word Dummy)
  893. {
  894.   UNUSED(Dummy);
  895.  
  896.   if (!ChkArgCnt(2, 2));
  897.   else if (CheckFormat("GEIFLS"))
  898.   {
  899.     if (OpSize == eSymbolSizeUnknown)
  900.       SetOpSize((FormatCode == 2) ? eSymbolSize8Bit : eSymbolSize16Bit);
  901.     if ((OpSize != eSymbolSize8Bit) && (OpSize != eSymbolSize16Bit)) WrError(ErrNum_InvOpSize);
  902.     else
  903.     {
  904.       DecodeAdr(&ArgStr[2], MModNoImm);
  905.       if (AdrMode != ModNone)
  906.       {
  907.         CopyAdr();
  908.         DecodeAdr(&ArgStr[1], MModAll | MModImmVariable);
  909.         if (AdrMode != ModNone)
  910.         {
  911.           if (FormatCode == 0)
  912.           {
  913.             if ((AdrMode == ModImm) && ((ImmSize == OpSize) || (ImmSize == eSymbolSizeUnknown)) && (Adr2Mode == ModReg)) FormatCode = 2 + OpSize;
  914.             else if ((AdrMode == ModReg) && (Adr2Byte == 0xe6)) FormatCode = 4;
  915.             else if ((Adr2Mode == ModReg) && (AdrByte == 0xe6)) FormatCode = 4;
  916.             else if ((AdrMode == ModReg) && (Adr2Mode == ModAbs8)) FormatCode = 6;
  917.             else if ((AdrMode == ModAbs8) && (Adr2Mode == ModReg)) FormatCode = 5;
  918.             else FormatCode = 1;
  919.           }
  920.           switch (FormatCode)
  921.           {
  922.             case 1:
  923.               if ((AdrMode == ModReg) && (Adr2Mode == ModReg))
  924.               {
  925.                 BAsmCode[0] = AdrByte | (OpSize << 3);
  926.                 BAsmCode[1] = 0x80 | (Adr2Byte & 7);
  927.                 CodeLen = 2;
  928.               }
  929.               else if (AdrMode == ModReg)
  930.               {
  931.                 BAsmCode[0] = Adr2Byte | (OpSize << 3);
  932.                 memcpy(BAsmCode + 1, Adr2Vals, Adr2Cnt);
  933.                 BAsmCode[1 + Adr2Cnt] = 0x90 | (AdrByte & 7);
  934.                 CodeLen = 2 + Adr2Cnt;
  935.               }
  936.               else if (Adr2Mode == ModReg)
  937.               {
  938.                 BAsmCode[0] = AdrByte | (OpSize << 3);
  939.                 memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  940.                 BAsmCode[1 + AdrCnt] = 0x80 | (Adr2Byte & 7);
  941.                 CodeLen = 2 + AdrCnt;
  942.               }
  943.               else if (AdrMode == ModImm)
  944.               {
  945.                 BAsmCode[0] = Adr2Byte | (OpSize << 3);
  946.                 memcpy(BAsmCode + 1, Adr2Vals, Adr2Cnt);
  947.                 if (AdaptImmSize(&ArgStr[1]))
  948.                 {
  949.                   BAsmCode[1 + Adr2Cnt] = 0x06 + ImmSize;
  950.                   memcpy(BAsmCode + 1 + Adr2Cnt + 1, AdrVals, AdrCnt);
  951.                   CodeLen = 1 + Adr2Cnt + 1 + AdrCnt;
  952.                 }
  953.               }
  954.               else WrError(ErrNum_InvAddrMode);
  955.               break;
  956.             case 2:
  957.               if ((AdrMode != ModImm) || (Adr2Mode != ModReg)) WrError(ErrNum_InvAddrMode);
  958.               else if (OpSize != eSymbolSize8Bit) WrError(ErrNum_InvOpSize);
  959.               else
  960.               {
  961.                 BAsmCode[0] = 0x50 | (Adr2Byte & 7);
  962.                 memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  963.                 CodeLen = 1 + AdrCnt;
  964.               }
  965.               break;
  966.             case 3:
  967.               if ((AdrMode != ModImm) || (Adr2Mode != ModReg)) WrError(ErrNum_InvAddrMode);
  968.               else if (OpSize != eSymbolSize16Bit) WrError(ErrNum_InvOpSize);
  969.               else
  970.               {
  971.                 BAsmCode[0] = 0x58 | (Adr2Byte & 7);
  972.                 memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  973.                 CodeLen = 1 + AdrCnt;
  974.               }
  975.               break;
  976.             case 4:
  977.               if ((AdrMode == ModReg) && (Adr2Byte == 0xe6))
  978.               {
  979.                 BAsmCode[0] = 0x90 | (OpSize << 3) | (AdrByte & 7);
  980.                 memcpy(BAsmCode + 1, Adr2Vals, Adr2Cnt);
  981.                 CodeLen =1 + Adr2Cnt;
  982.               }
  983.               else if ((Adr2Mode == ModReg) && (AdrByte == 0xe6))
  984.               {
  985.                 BAsmCode[0] = 0x80 | (OpSize << 3) | (Adr2Byte & 7);
  986.                 memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  987.                 CodeLen = 1 + AdrCnt;
  988.               }
  989.               else WrError(ErrNum_InvAddrMode);
  990.               break;
  991.             case 5:
  992.               if ((AdrMode != ModAbs8) || (Adr2Mode != ModReg)) WrError(ErrNum_InvAddrMode);
  993.               else
  994.               {
  995.                 BAsmCode[0] = 0x60 | (OpSize << 3) | (Adr2Byte & 7);
  996.                 memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  997.                 CodeLen = 1 + AdrCnt;
  998.               }
  999.               break;
  1000.             case 6:
  1001.               if ((Adr2Mode != ModAbs8) || (AdrMode != ModReg)) WrError(ErrNum_InvAddrMode);
  1002.               else
  1003.               {
  1004.                 BAsmCode[0] = 0x70 | (OpSize << 3) | (AdrByte & 7);
  1005.                 memcpy(BAsmCode + 1, Adr2Vals, Adr2Cnt);
  1006.                 CodeLen = 1 + Adr2Cnt;
  1007.               }
  1008.               break;
  1009.           }
  1010.         }
  1011.       }
  1012.     }
  1013.   }
  1014. }
  1015.  
  1016. static void DecodeLDC_STC(Word IsSTC_16)
  1017. {
  1018.   Byte HReg;
  1019.   int CRegIdx = 2, AdrIdx = 1;
  1020.  
  1021.   if (!ChkArgCnt(2, 2));
  1022.   else if (strcmp(Format, " ")) WrError(ErrNum_InvFormat);
  1023.   else
  1024.   {
  1025.     if (IsSTC_16)
  1026.     {
  1027.       CRegIdx = 1;
  1028.       AdrIdx = 2;
  1029.     }
  1030.     if (!DecodeCReg(ArgStr[CRegIdx].str.p_str, &HReg)) WrStrErrorPos(ErrNum_InvCtrlReg, &ArgStr[2]);
  1031.     else
  1032.     {
  1033.       DecodeAdr(&ArgStr[AdrIdx], IsSTC_16 ? MModNoImm : MModAll);
  1034.       if (AdrMode != ModNone)
  1035.       {
  1036.         BAsmCode[0] = AdrByte | (OpSize << 3);
  1037.         memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  1038.         BAsmCode[1 + AdrCnt] = 0x88 | IsSTC_16 | HReg;
  1039.         CodeLen = 2 + AdrCnt;
  1040.       }
  1041.     }
  1042.   }
  1043. }
  1044.  
  1045. static void DecodeLDM(Word Dummy)
  1046. {
  1047.   UNUSED(Dummy);
  1048.  
  1049.   if (OpSize == eSymbolSizeUnknown) OpSize = eSymbolSize16Bit;
  1050.   if (!ChkArgCnt(2, 2));
  1051.   else if (OpSize != eSymbolSize16Bit) WrError(ErrNum_InvOpSize);
  1052.   else if (strcmp(Format, " ")) WrError(ErrNum_InvFormat);
  1053.   else if (!DecodeRegList(&ArgStr[2], BAsmCode + 1)) WrError(ErrNum_InvRegList);
  1054.   else
  1055.   {
  1056.     DecodeAdr(&ArgStr[1], MModPostInc);
  1057.     if (AdrMode != ModNone)
  1058.     {
  1059.       if ((AdrByte & 7) != 7) WrError(ErrNum_InvAddrMode);
  1060.       else
  1061.       {
  1062.         BAsmCode[0] = 0x02; CodeLen = 2;
  1063.       }
  1064.     }
  1065.   }
  1066. }
  1067.  
  1068. static void DecodeSTM(Word Dummy)
  1069. {
  1070.   UNUSED(Dummy);
  1071.  
  1072.   if (OpSize == eSymbolSizeUnknown) OpSize = eSymbolSize16Bit;
  1073.   if (!ChkArgCnt(2, 2));
  1074.   else if (OpSize != eSymbolSize16Bit) WrError(ErrNum_InvOpSize);
  1075.   else if (strcmp(Format, " ")) WrError(ErrNum_InvFormat);
  1076.   else if (!DecodeRegList(&ArgStr[1], BAsmCode + 1)) WrError(ErrNum_InvRegList);
  1077.   else
  1078.   {
  1079.     DecodeAdr(&ArgStr[2], MModPredec);
  1080.     if (AdrMode != ModNone)
  1081.     {
  1082.       if ((AdrByte & 7) != 7) WrError(ErrNum_InvAddrMode);
  1083.       else
  1084.       {
  1085.         BAsmCode[0] = 0x12; CodeLen = 2;
  1086.       }
  1087.     }
  1088.   }
  1089. }
  1090.  
  1091. static void DecodeMOVTPE_MOVFPE(Word IsMOVTPE_16)
  1092. {
  1093.   Byte HReg;
  1094.   int RegIdx = 2, AdrIdx = 1;
  1095.  
  1096.   if (ChkArgCnt(2, 2)
  1097.    && CheckFormat("G"))
  1098.   {
  1099.     if (IsMOVTPE_16)
  1100.     {
  1101.       RegIdx = 1;
  1102.       AdrIdx = 2;
  1103.     }
  1104.     if (OpSize == eSymbolSizeUnknown) SetOpSize(eSymbolSize8Bit);
  1105.     if (OpSize != eSymbolSize8Bit) WrError(ErrNum_InvOpSize);
  1106.     else if (DecodeReg(&ArgStr[RegIdx], &HReg, True))
  1107.     {
  1108.       DecodeAdr(&ArgStr[AdrIdx], MModNoImm & (~MModReg));
  1109.       if (AdrMode != ModNone)
  1110.       {
  1111.         BAsmCode[0] = AdrByte | (OpSize << 3);
  1112.         memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  1113.         BAsmCode[1 + AdrCnt] = 0;
  1114.         BAsmCode[2 + AdrCnt] = 0x80 | HReg | IsMOVTPE_16;
  1115.         CodeLen =3 + AdrCnt;
  1116.       }
  1117.     }
  1118.   }
  1119. }
  1120.  
  1121. static void DecodeADD_SUB(Word IsSUB_16)
  1122. {
  1123.   LongInt AdrLong;
  1124.  
  1125.   if (ChkArgCnt(2, 2)
  1126.    && CheckFormat("GQ"))
  1127.   {
  1128.     if (OpSize == eSymbolSizeUnknown) SetOpSize(eSymbolSize16Bit);
  1129.     if ((OpSize != eSymbolSize8Bit) && (OpSize != eSymbolSize16Bit)) WrError(ErrNum_InvOpSize);
  1130.     else
  1131.     {
  1132.       DecodeAdr(&ArgStr[2], MModNoImm);
  1133.       if (AdrMode != ModNone)
  1134.       {
  1135.         CopyAdr();
  1136.         DecodeAdr(&ArgStr[1], MModAll);
  1137.         if (AdrMode != ModNone)
  1138.         {
  1139.           AdrLong = ImmVal();
  1140.           if (FormatCode == 0)
  1141.           {
  1142.             if ((AdrMode == ModImm) && (abs(AdrLong) >= 1) && (abs(AdrLong) <= 2) && !IsSUB_16) FormatCode = 2;
  1143.             else FormatCode = 1;
  1144.           }
  1145.           switch (FormatCode)
  1146.           {
  1147.             case 1:
  1148.               if (Adr2Mode != ModReg) WrError(ErrNum_InvAddrMode);
  1149.               else
  1150.               {
  1151.                 BAsmCode[0] = AdrByte | (OpSize << 3);
  1152.                 memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  1153.                 BAsmCode[1 + AdrCnt] = 0x20 | IsSUB_16 | (Adr2Byte & 7);
  1154.                 CodeLen = 2 + AdrCnt;
  1155.               }
  1156.               break;
  1157.             case 2:
  1158.               if (ChkRange(AdrLong, -2, 2))
  1159.               {
  1160.                 if (AdrLong == 0) WrError(ErrNum_UnderRange);
  1161.                 else
  1162.                 {
  1163.                   if (IsSUB_16) AdrLong = (-AdrLong);
  1164.                   BAsmCode[0] = Adr2Byte | (OpSize << 3);
  1165.                   memcpy(BAsmCode + 1, Adr2Vals, Adr2Cnt);
  1166.                   BAsmCode[1 + Adr2Cnt] = 0x08 | (abs(AdrLong) - 1);
  1167.                   if (AdrLong < 0) BAsmCode[1 + Adr2Cnt] |= 4;
  1168.                   CodeLen = 2 + Adr2Cnt;
  1169.                 }
  1170.               }
  1171.               break;
  1172.           }
  1173.         }
  1174.       }
  1175.     }
  1176.   }
  1177. }
  1178.  
  1179. /* NOTE: though the length of immediate data im G format is explicitly
  1180.    coded and independent of the operand size, the manual seems to suggest
  1181.    that it is not allowed for CMP to use an 8-bit immediate value with a
  1182.    16-bit operand, assuming the immediate value will be sign-extended.
  1183.    This mechanism is described e.g. for MOV:G, but not for CMP:G.  So
  1184.    we omit this optimization here: */
  1185.  
  1186. #define CMP_IMMVARIABLE 0
  1187.  
  1188. static void DecodeCMP(Word Dummy)
  1189. {
  1190.   UNUSED(Dummy);
  1191.  
  1192.   if (ChkArgCnt(2, 2)
  1193.    && CheckFormat("GEI"))
  1194.   {
  1195.     if (OpSize == eSymbolSizeUnknown)
  1196.       SetOpSize((FormatCode == 2) ? eSymbolSize8Bit : eSymbolSize16Bit);
  1197.     if ((OpSize != 0) && (OpSize != 1)) WrError(ErrNum_InvOpSize);
  1198.     else
  1199.     {
  1200.       DecodeAdr(&ArgStr[2], MModNoImm);
  1201.       if (AdrMode != ModNone)
  1202.       {
  1203.         CopyAdr();
  1204.  
  1205.  
  1206.         DecodeAdr(&ArgStr[1], MModAll
  1207. #if CMP_IMMVARIABLE
  1208.                             | MModImmVariable
  1209. #endif
  1210.                  );
  1211.         if (AdrMode != ModNone)
  1212.         {
  1213.           if (FormatCode == 0)
  1214.           {
  1215.             if ((AdrMode == ModImm) && ((ImmSize == OpSize) || (ImmSize == eSymbolSizeUnknown)) && (Adr2Mode == ModReg)) FormatCode = 2 + OpSize;
  1216.             else FormatCode = 1;
  1217.           }
  1218.           switch (FormatCode)
  1219.           {
  1220.             case 1:
  1221.               if (Adr2Mode == ModReg)
  1222.               {
  1223.                 BAsmCode[0] = AdrByte | (OpSize << 3);
  1224.                 memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  1225.                 BAsmCode[1 + AdrCnt] = 0x70 | (Adr2Byte & 7);
  1226.                 CodeLen = 2 + AdrCnt;
  1227.               }
  1228.               else if (AdrMode == ModImm)
  1229.               {
  1230. #if CMP_IMMVARIABLE
  1231.                 if (AdaptImmSize(&ArgStr[1]))
  1232. #endif
  1233.                 {
  1234.                   BAsmCode[0] = Adr2Byte | (OpSize << 3);
  1235.                   memcpy(BAsmCode + 1, Adr2Vals, Adr2Cnt);
  1236.                   BAsmCode[1 + Adr2Cnt] = 0x04 | ImmSize;
  1237.                   memcpy(BAsmCode + 2 + Adr2Cnt, AdrVals, AdrCnt);
  1238.                   CodeLen = 2 + AdrCnt + Adr2Cnt;
  1239.                 }
  1240.               }
  1241.               else WrError(ErrNum_InvAddrMode);
  1242.               break;
  1243.             case 2:
  1244.               if ((AdrMode != ModImm) || (Adr2Mode != ModReg)) WrError(ErrNum_InvAddrMode);
  1245.               else if (OpSize != eSymbolSize8Bit) WrError(ErrNum_InvOpSize);
  1246.               else
  1247.               {
  1248.                 BAsmCode[0] = 0x40 | (Adr2Byte & 7);
  1249.                 memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  1250.                 CodeLen = 1 + AdrCnt;
  1251.               }
  1252.               break;
  1253.              case 3:
  1254.                if ((AdrMode != ModImm) || (Adr2Mode != ModReg)) WrError(ErrNum_InvAddrMode);
  1255.                else if (OpSize != eSymbolSize16Bit) WrError(ErrNum_InvOpSize);
  1256.                else
  1257.                {
  1258.                  BAsmCode[0] = 0x48 + (Adr2Byte & 7);
  1259.                  memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  1260.                  CodeLen = 1 + AdrCnt;
  1261.                }
  1262.                break;
  1263.           }
  1264.         }
  1265.       }
  1266.     }
  1267.   }
  1268. }
  1269.  
  1270. static void DecodeRegEA(Word Index)
  1271. {
  1272.   Byte HReg;
  1273.   OneOrder *pOrder = RegEAOrders + Index;
  1274.  
  1275.   if (ChkArgCnt(2, 2)
  1276.    && CheckFormat("G"))
  1277.   {
  1278.     if (OpSize == eSymbolSizeUnknown) SetOpSize(pOrder->DefSize);
  1279.     if (!((1 << OpSize) & pOrder->SizeMask)) WrError(ErrNum_InvOpSize);
  1280.     else if (DecodeReg(&ArgStr[2], &HReg, True))
  1281.     {
  1282.       DecodeAdr(&ArgStr[1], MModAll);
  1283.       if (AdrMode != ModNone)
  1284.       {
  1285.         BAsmCode[0] = AdrByte | (OpSize << 3);
  1286.         memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  1287.         BAsmCode[1 + AdrCnt] = pOrder->Code | HReg;
  1288.         CodeLen = 2 + AdrCnt;
  1289.       }
  1290.     }
  1291.   }
  1292. }
  1293.  
  1294. static void DecodeTwoReg(Word Index)
  1295. {
  1296.   Byte HReg;
  1297.   OneOrder *pOrder = TwoRegOrders + Index;
  1298.  
  1299.   if (!ChkArgCnt(2, 2));
  1300.   else if (strcmp(Format, " ")) WrError(ErrNum_InvFormat);
  1301.   else if (DecodeReg(&ArgStr[1], &HReg, True)
  1302.        &&  DecodeReg(&ArgStr[2], &AdrByte, True))
  1303.   {
  1304.     if (OpSize == eSymbolSizeUnknown) SetOpSize(pOrder->DefSize);
  1305.     if (!((1 << OpSize) & pOrder->SizeMask)) WrError(ErrNum_InvOpSize);
  1306.     else
  1307.     {
  1308.       BAsmCode[0] = 0xa0 | HReg | (OpSize << 3);
  1309.       if (Hi(pOrder->Code))
  1310.       {
  1311.         BAsmCode[1] = Lo(pOrder->Code);
  1312.         BAsmCode[2] = Hi(pOrder->Code) | AdrByte;
  1313.         CodeLen = 3;
  1314.       }
  1315.       else
  1316.       {
  1317.         BAsmCode[1] = pOrder->Code | AdrByte;
  1318.         CodeLen = 2;
  1319.       }
  1320.     }
  1321.   }
  1322. }
  1323.  
  1324. static void DecodeLog(Word Code)
  1325. {
  1326.   Byte HReg;
  1327.  
  1328.   if (!ChkArgCnt(2, 2));
  1329.   else if (!DecodeCReg(ArgStr[2].str.p_str, &HReg)) WrStrErrorPos(ErrNum_InvCtrlReg, &ArgStr[2]);
  1330.   else
  1331.   {
  1332.     DecodeAdr(&ArgStr[1], MModImm);
  1333.     if (AdrMode != ModNone)
  1334.     {
  1335.       BAsmCode[0] = AdrByte | (OpSize << 3);
  1336.       memcpy(BAsmCode + 1,AdrVals, AdrCnt);
  1337.       BAsmCode[1 + AdrCnt] = Code | HReg;
  1338.       CodeLen = 2 + AdrCnt;
  1339.     }
  1340.   }
  1341. }
  1342.  
  1343. static void DecodeOne(Word Index)
  1344. {
  1345.   OneOrder *pOrder = OneOrders + Index;
  1346.  
  1347.   if (!ChkArgCnt(1, 1));
  1348.   else if (CheckFormat("G"))
  1349.   {
  1350.     if (OpSize == eSymbolSizeUnknown) SetOpSize(pOrder->DefSize);
  1351.     if (!((1 << OpSize) & pOrder->SizeMask)) WrError(ErrNum_InvOpSize);
  1352.     else
  1353.     {
  1354.       DecodeAdr(&ArgStr[1], MModNoImm);
  1355.       if (AdrMode != ModNone)
  1356.       {
  1357.         BAsmCode[0] = AdrByte | (OpSize << 3);
  1358.         memcpy(BAsmCode+1, AdrVals, AdrCnt);
  1359.         BAsmCode[1 + AdrCnt] = pOrder->Code;
  1360.         CodeLen = 2 + AdrCnt;
  1361.       }
  1362.     }
  1363.   }
  1364. }
  1365.  
  1366. static void DecodeOneReg(Word Index)
  1367. {
  1368.   Byte HReg;
  1369.   OneOrder *pOrder = OneRegOrders + Index;
  1370.  
  1371.   if (!ChkArgCnt(1, 1));
  1372.   else if (strcmp(Format, " ")) WrError(ErrNum_InvFormat);
  1373.   else if (DecodeReg(&ArgStr[1], &HReg, True))
  1374.   {
  1375.     if (OpSize == -1) SetOpSize(pOrder->DefSize);
  1376.     if (!((1 << OpSize) & pOrder->SizeMask)) WrError(ErrNum_InvOpSize);
  1377.     else
  1378.     {
  1379.       BAsmCode[0] = 0xa0 | HReg | (OpSize << 3);
  1380.       BAsmCode[1] = pOrder->Code;
  1381.       CodeLen = 2;
  1382.     }
  1383.   }
  1384. }
  1385.  
  1386. static void DecodeBit(Word Code)
  1387. {
  1388.   Boolean OK;
  1389.   Byte BitPos;
  1390.  
  1391.   switch (ArgCnt)
  1392.   {
  1393.     case 1:
  1394.     {
  1395.       LongWord BitSpec;
  1396.  
  1397.       if (DecodeBitArg(&BitSpec, 1, 1))
  1398.       {
  1399.         LongWord Addr;
  1400.         tSymbolSize ThisOpSize, ThisAddrSize;
  1401.  
  1402.         DissectBitSymbol(BitSpec, &Addr, &BitPos, &ThisOpSize, &ThisAddrSize);
  1403.         if (OpSize == eSymbolSizeUnknown)
  1404.           OpSize = ThisOpSize;
  1405.         else if (OpSize != ThisOpSize)
  1406.         {
  1407.           WrStrErrorPos(ErrNum_ConfOpSizes, &ArgStr[1]);
  1408.           return;
  1409.         }
  1410.         if (OpSize == eSymbolSizeUnknown)
  1411.           OpSize = eSymbolSize8Bit;
  1412.         BitPos |= 0x80;
  1413.         DecideAbsolute(Addr, ThisAddrSize, False, MModAbs8 | MModAbs16);
  1414.         if (AdrMode != ModNone)
  1415.           goto common;
  1416.       }
  1417.       break;
  1418.     }
  1419.     case 2:
  1420.     {
  1421.       DecodeAdr(&ArgStr[2], MModNoImm);
  1422.       if (AdrMode != ModNone)
  1423.       {
  1424.         if (OpSize == eSymbolSizeUnknown)
  1425.           OpSize = (AdrMode == ModReg) ? eSymbolSize16Bit : eSymbolSize8Bit;
  1426.         if ((OpSize != 0) && (OpSize != 1)) WrError(ErrNum_InvOpSize);
  1427.         else
  1428.         {
  1429.           switch (DecodeReg(&ArgStr[1], &BitPos, False))
  1430.           {
  1431.             case eIsReg:
  1432.               OK = True; BitPos += 8;
  1433.               break;
  1434.             case eIsNoReg:
  1435.               BitPos = EvalStrIntExpressionOffs(&ArgStr[1], !!(*ArgStr[1].str.p_str == '#'), (OpSize == eSymbolSize8Bit) ? UInt3 : UInt4, &OK);
  1436.               if (OK) BitPos |= 0x80;
  1437.               break;
  1438.             default:
  1439.               OK = False;
  1440.           }
  1441.           if (OK)
  1442.             goto common;
  1443.         }
  1444.       }
  1445.       break;
  1446.     }
  1447.     common:
  1448.       BAsmCode[0] = AdrByte | (OpSize << 3);
  1449.       memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  1450.       BAsmCode[1 + AdrCnt] = Code | BitPos;
  1451.       CodeLen = 2 + AdrCnt;
  1452.       break;
  1453.     default:
  1454.       (void)ChkArgCnt(1, 2);
  1455.   }
  1456. }
  1457.  
  1458. static void DecodeRel(Word Code)
  1459. {
  1460.   Boolean OK;
  1461.   tSymbolFlags Flags;
  1462.   LongInt AdrLong;
  1463.  
  1464.   if (ChkArgCnt(1, 1)
  1465.    && FormatToBranchSize(Format, &OpSize))
  1466.   {
  1467.     AdrLong = EvalStrIntExpressionWithFlags(&ArgStr[1], UInt24, &OK, &Flags);
  1468.     if (OK)
  1469.     {
  1470.       if (!ChkSamePage(AdrLong, EProgCounter(), 16, Flags));
  1471.       else if ((EProgCounter() & 0xffff) >= 0xfffc) WrError(ErrNum_NotFromThisAddress);
  1472.       else
  1473.       {
  1474.         AdrLong -= EProgCounter() + 2;
  1475.         if (AdrLong > 0x7fff) AdrLong -= 0x10000;
  1476.         else if (AdrLong < -0x8000l) AdrLong += 0x10000;
  1477.         if (OpSize == eSymbolSizeUnknown)
  1478.         {
  1479.           if ((AdrLong <= 127) && (AdrLong >= -128)) OpSize = eSymbolSizeFloat32Bit;
  1480.           else OpSize = eSymbolSize32Bit;
  1481.         }
  1482.         switch (OpSize)
  1483.         {
  1484.           case eSymbolSize32Bit:
  1485.             AdrLong--;
  1486.             BAsmCode[0] = Code | 0x10;
  1487.             BAsmCode[1] = (AdrLong >> 8) & 0xff;
  1488.             BAsmCode[2] = AdrLong & 0xff;
  1489.             CodeLen = 3;
  1490.             break;
  1491.           case eSymbolSizeFloat32Bit:
  1492.             if (((AdrLong < -128) || (AdrLong > 127)) && !mSymbolQuestionable(Flags)) WrError(ErrNum_JmpDistTooBig);
  1493.             else
  1494.             {
  1495.               BAsmCode[0] = Code;
  1496.               BAsmCode[1] = AdrLong & 0xff;
  1497.               CodeLen = 2;
  1498.             }
  1499.             break;
  1500.           default:
  1501.            WrError(ErrNum_InvOpSize);
  1502.         }
  1503.       }
  1504.     }
  1505.   }
  1506. }
  1507.  
  1508. static void DecodeJMP_JSR(Word IsJSR_8)
  1509. {
  1510.   if (ChkArgCnt(1, 1)
  1511.    && CheckFormat("G"))
  1512.   {
  1513.     AbsBank = EProgCounter() >> 16;
  1514.     DecodeAdr(&ArgStr[1], MModIReg | MModReg | MModDisp8 | MModDisp16 | MModAbs16);
  1515.     switch (AdrMode)
  1516.     {
  1517.       case ModReg:
  1518.       case ModIReg:
  1519.         BAsmCode[0] = 0x11; BAsmCode[1] = 0xd0 | IsJSR_8 | (AdrByte & 7);
  1520.         CodeLen = 2;
  1521.         break;
  1522.       case ModDisp8:
  1523.       case ModDisp16:
  1524.         BAsmCode[0] = 0x11; BAsmCode[1] = AdrByte | IsJSR_8;
  1525.         memcpy(BAsmCode + 2, AdrVals, AdrCnt);
  1526.         CodeLen = 2 + AdrCnt;
  1527.         break;
  1528.       case ModAbs16:
  1529.         BAsmCode[0] = 0x10 | IsJSR_8; memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  1530.         CodeLen = 1 + AdrCnt;
  1531.         break;
  1532.     }
  1533.   }
  1534. }
  1535.  
  1536. static void DecodePJMP_PJSR(Word IsPJMP)
  1537. {
  1538.   if (!ChkArgCnt(1, 1));
  1539.   else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  1540.   else if (strcmp(Format, " ")) WrError(ErrNum_InvFormat);
  1541.   else if (!MaxMode) WrError(ErrNum_OnlyInMaxmode);
  1542.   else
  1543.   {
  1544.     tStrComp *pArg = &ArgStr[1], Arg;
  1545.     unsigned ArgOffs = !!(*pArg->str.p_str == '@');
  1546.     Byte HReg;
  1547.  
  1548.     StrCompRefRight(&Arg, pArg, ArgOffs);
  1549.     switch (DecodeReg(&Arg, &HReg, False))
  1550.     {
  1551.       case eIsReg:
  1552.         BAsmCode[0] = 0x11; BAsmCode[1] = 0xc0 | ((1 - IsPJMP) << 3) | HReg;
  1553.         CodeLen = 2;
  1554.         break;
  1555.       case eIsNoReg:
  1556.       {
  1557.         Boolean OK;
  1558.         LongInt AdrLong = EvalStrIntExpressionOffs(pArg, ArgOffs, UInt24, &OK);
  1559.  
  1560.         if (OK)
  1561.         {
  1562.           BAsmCode[0] = 0x03 | (IsPJMP << 4);
  1563.           BAsmCode[1] = (AdrLong >> 16) & 0xff;
  1564.           BAsmCode[2] = (AdrLong >> 8) & 0xff;
  1565.           BAsmCode[3] = AdrLong & 0xff;
  1566.           CodeLen = 4;
  1567.         }
  1568.         break;
  1569.       }
  1570.       default:
  1571.         break;
  1572.     }
  1573.   }
  1574. }
  1575.  
  1576. static void DecodeSCB(Word Code)
  1577. {
  1578.   Byte HReg;
  1579.   LongInt AdrLong;
  1580.   Boolean OK;
  1581.   tSymbolFlags Flags;
  1582.  
  1583.   if (!ChkArgCnt(2, 2));
  1584.   else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  1585.   else if (strcmp(Format, " ")) WrError(ErrNum_InvFormat);
  1586.   else if (DecodeReg(&ArgStr[1], &HReg, True))
  1587.   {
  1588.     AdrLong = EvalStrIntExpressionWithFlags(&ArgStr[2], UInt24, &OK, &Flags);
  1589.     if (OK)
  1590.     {
  1591.       if (!ChkSamePage(AdrLong, EProgCounter(), 16, Flags));
  1592.       else if ((EProgCounter() & 0xffff) >= 0xfffc) WrError(ErrNum_NotFromThisAddress);
  1593.       else
  1594.       {
  1595.         AdrLong -= EProgCounter() + 3;
  1596.         if (!mSymbolQuestionable(Flags) && ((AdrLong > 127) || (AdrLong < -128))) WrError(ErrNum_JmpDistTooBig);
  1597.         else
  1598.         {
  1599.           BAsmCode[0] = Code;
  1600.           BAsmCode[1] = 0xb8 | HReg;
  1601.           BAsmCode[2] = AdrLong & 0xff;
  1602.           CodeLen = 3;
  1603.         }
  1604.       }
  1605.     }
  1606.   }
  1607. }
  1608.  
  1609. static void DecodePRTD_RTD(Word IsPRTD)
  1610. {
  1611.   tSymbolSize HSize;
  1612.   Integer AdrInt;
  1613.  
  1614.   if (!ChkArgCnt(1, 1));
  1615.   else if (strcmp(Format, " ")) WrError(ErrNum_InvFormat);
  1616.   else if (*ArgStr[1].str.p_str != '#') WrError(ErrNum_OnlyImmAddr);
  1617.   else
  1618.   {
  1619.     tStrComp Arg;
  1620.     Boolean OK;
  1621.     tSymbolFlags Flags;
  1622.  
  1623.     StrCompRefRight(&Arg, &ArgStr[1], 1);
  1624.     HSize = eSymbolSizeUnknown; SplitDisp(&Arg, &HSize);
  1625.     if (HSize != eSymbolSizeUnknown) SetOpSize(HSize);
  1626.     AdrInt = EvalStrIntExpressionWithFlags(&Arg, SInt16, &OK, &Flags);
  1627.     if (mFirstPassUnknown(Flags)) AdrInt &= 127;
  1628.     if (OK)
  1629.     {
  1630.       if (OpSize == eSymbolSizeUnknown)
  1631.       {
  1632.         if ((AdrInt < 127) && (AdrInt > -128)) OpSize = eSymbolSize8Bit;
  1633.         else OpSize = eSymbolSize16Bit;
  1634.       }
  1635.       if (IsPRTD) BAsmCode[0] = 0x11;
  1636.       switch (OpSize)
  1637.       {
  1638.         case eSymbolSize8Bit:
  1639.           if (ChkRange(AdrInt, -128, 127))
  1640.           {
  1641.             BAsmCode[IsPRTD] = 0x14;
  1642.             BAsmCode[1 + IsPRTD] = AdrInt & 0xff;
  1643.             CodeLen = 2 + IsPRTD;
  1644.           }
  1645.           break;
  1646.         case eSymbolSize16Bit:
  1647.           BAsmCode[IsPRTD] = 0x1c;
  1648.           BAsmCode[1 + IsPRTD] = (AdrInt >> 8) & 0xff;
  1649.           BAsmCode[2 + IsPRTD] = AdrInt & 0xff;
  1650.           CodeLen = 3 + IsPRTD;
  1651.           break;
  1652.         default:
  1653.           WrError(ErrNum_InvOpSize);
  1654.       }
  1655.     }
  1656.   }
  1657. }
  1658.  
  1659. static void DecodeLINK(Word Dummy)
  1660. {
  1661.   UNUSED(Dummy);
  1662.  
  1663.   if (!ChkArgCnt(2, 2));
  1664.   else if (strcmp(Format, " ")) WrError(ErrNum_InvFormat);
  1665.   else
  1666.   {
  1667.     DecodeAdr(&ArgStr[1], MModReg);
  1668.     if (AdrMode != ModNone)
  1669.     {
  1670.       if ((AdrByte & 7) != 6) WrError(ErrNum_InvAddrMode);
  1671.       else if (*ArgStr[2].str.p_str != '#') WrError(ErrNum_OnlyImmAddr);
  1672.       else
  1673.       {
  1674.         tStrComp Arg;
  1675.         tSymbolSize HSize;
  1676.         Integer AdrInt;
  1677.         Boolean OK;
  1678.         tSymbolFlags Flags;
  1679.  
  1680.         StrCompRefRight(&Arg, &ArgStr[2], 1);
  1681.         HSize = eSymbolSizeUnknown; SplitDisp(&Arg, &HSize);
  1682.         if (HSize != eSymbolSizeUnknown) SetOpSize(HSize);
  1683.         AdrInt = EvalStrIntExpressionWithFlags(&Arg, SInt16, &OK, &Flags);
  1684.         if (mFirstPassUnknown(Flags)) AdrInt &= 127;
  1685.         if (OK)
  1686.         {
  1687.           if (OpSize == eSymbolSizeUnknown)
  1688.           {
  1689.             if ((AdrInt < 127) && (AdrInt > -128)) OpSize = eSymbolSize8Bit;
  1690.             else OpSize = eSymbolSize16Bit;
  1691.           }
  1692.           switch (OpSize)
  1693.           {
  1694.             case eSymbolSize8Bit:
  1695.               if (ChkRange(AdrInt, -128, 127))
  1696.               {
  1697.                 BAsmCode[0] = 0x17;
  1698.                 BAsmCode[1] = AdrInt & 0xff;
  1699.                 CodeLen = 2;
  1700.               }
  1701.               break;
  1702.             case eSymbolSize16Bit:
  1703.               BAsmCode[0] = 0x1f;
  1704.               BAsmCode[1] = (AdrInt >> 8) & 0xff;
  1705.               BAsmCode[2] = AdrInt & 0xff;
  1706.               CodeLen = 3;
  1707.               break;
  1708.             default:
  1709.               WrError(ErrNum_InvOpSize);
  1710.           }
  1711.         }
  1712.       }
  1713.     }
  1714.   }
  1715. }
  1716.  
  1717. static void DecodeUNLK(Word Dummy)
  1718. {
  1719.   UNUSED(Dummy);
  1720.  
  1721.   if (!ChkArgCnt(1, 1));
  1722.   else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  1723.   else if (strcmp(Format, " ")) WrError(ErrNum_InvFormat);
  1724.   else
  1725.   {
  1726.     DecodeAdr(&ArgStr[1], MModReg);
  1727.     if (AdrMode != ModNone)
  1728.     {
  1729.       if ((AdrByte & 7) != 6) WrError(ErrNum_InvAddrMode);
  1730.       else
  1731.       {
  1732.         BAsmCode[0] = 0x0f; CodeLen = 1;
  1733.       }
  1734.     }
  1735.   }
  1736. }
  1737.  
  1738. static void DecodeTRAPA(Word Dummy)
  1739. {
  1740.   UNUSED(Dummy);
  1741.  
  1742.   if (!ChkArgCnt(1, 1));
  1743.   else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  1744.   else if (strcmp(Format, " ")) WrError(ErrNum_InvFormat);
  1745.   else if (*ArgStr[1].str.p_str != '#') WrError(ErrNum_OnlyImmAddr);
  1746.   else
  1747.   {
  1748.     Boolean OK;
  1749.  
  1750.     BAsmCode[1] = 0x10 | EvalStrIntExpressionOffs(&ArgStr[1], 1, UInt4, &OK);
  1751.     if (OK)
  1752.     {
  1753.       BAsmCode[0] = 0x08; CodeLen = 2;
  1754.     }
  1755.   }
  1756. }
  1757.  
  1758. static void DecodeDATA(Word Dummy)
  1759. {
  1760.   UNUSED(Dummy);
  1761.  
  1762.   DecodeMotoDC(OpSize, True);
  1763. }
  1764.  
  1765. static void DecodeBIT(Word Code)
  1766. {
  1767.   UNUSED(Code);
  1768.  
  1769.   /* if in structure definition, add special element to structure */
  1770.  
  1771.   if (OpSize > eSymbolSize16Bit)
  1772.   {
  1773.     WrError(ErrNum_InvOpSize);
  1774.     return;
  1775.   }
  1776.   if (ActPC == StructSeg)
  1777.   {
  1778.     Boolean OK;
  1779.     Byte BitPos;
  1780.     PStructElem pElement;
  1781.  
  1782.     if (!ChkArgCnt(2, 2))
  1783.       return;
  1784.     BitPos = EvalBitPosition(&ArgStr[1], OpSize, &OK);
  1785.     if (!OK)
  1786.       return;
  1787.     pElement = CreateStructElem(&LabPart);
  1788.     if (!pElement)
  1789.       return;
  1790.     pElement->pRefElemName = as_strdup(ArgStr[2].str.p_str);
  1791.     pElement->OpSize = OpSize;
  1792.     pElement->BitPos = BitPos;
  1793.     pElement->ExpandFnc = ExpandBit_H8_5;
  1794.     AddStructElem(pInnermostNamedStruct->StructRec, pElement);
  1795.   }
  1796.   else
  1797.   {
  1798.     LongWord BitSpec;
  1799.  
  1800.     if (DecodeBitArg(&BitSpec, 1, ArgCnt))
  1801.     {
  1802.       *ListLine = '=';
  1803.       DissectBit_H8_5(ListLine + 1, STRINGSIZE - 3, BitSpec);
  1804.       PushLocHandle(-1);
  1805.       EnterIntSymbol(&LabPart, BitSpec, SegBData, False);
  1806.       PopLocHandle();
  1807.       /* TODO: MakeUseList? */
  1808.     }
  1809.   }
  1810. }
  1811.  
  1812. /*-------------------------------------------------------------------------*/
  1813. /* dynamische Belegung/Freigabe Codetabellen */
  1814.  
  1815. static void AddFixed(const char *NName, Word NCode)
  1816. {
  1817.   AddInstTable(InstTable, NName, NCode, DecodeFixed);
  1818. }
  1819.  
  1820. static void AddRel(const char *NName, Word NCode)
  1821. {
  1822.   AddInstTable(InstTable, NName, NCode, DecodeRel);
  1823. }
  1824.  
  1825. static void AddOne(const char *NName, Word NCode, Byte NMask, tSymbolSize NDef)
  1826. {
  1827.   order_array_rsv_end(OneOrders, OneOrder);
  1828.   OneOrders[InstrZ].Code = NCode;
  1829.   OneOrders[InstrZ].SizeMask = NMask;
  1830.   OneOrders[InstrZ].DefSize = NDef;
  1831.   AddInstTable(InstTable, NName, InstrZ++, DecodeOne);
  1832. }
  1833.  
  1834. static void AddOneReg(const char *NName, Word NCode, Byte NMask, tSymbolSize NDef)
  1835. {
  1836.   order_array_rsv_end(OneRegOrders, OneOrder);
  1837.   OneRegOrders[InstrZ].Code=NCode;
  1838.   OneRegOrders[InstrZ].SizeMask = NMask;
  1839.   OneRegOrders[InstrZ].DefSize = NDef;
  1840.   AddInstTable(InstTable, NName, InstrZ++, DecodeOneReg);
  1841. }
  1842.  
  1843. static void AddRegEA(const char *NName, Word NCode, Byte NMask, tSymbolSize NDef)
  1844. {
  1845.   order_array_rsv_end(RegEAOrders, OneOrder);
  1846.   RegEAOrders[InstrZ].Code = NCode;
  1847.   RegEAOrders[InstrZ].SizeMask = NMask;
  1848.   RegEAOrders[InstrZ].DefSize = NDef;
  1849.   AddInstTable(InstTable, NName, InstrZ++, DecodeRegEA);
  1850. }
  1851.  
  1852. static void AddTwoReg(const char *NName, Word NCode, Byte NMask, tSymbolSize NDef)
  1853. {
  1854.   order_array_rsv_end(TwoRegOrders, OneOrder);
  1855.   TwoRegOrders[InstrZ].Code = NCode;
  1856.   TwoRegOrders[InstrZ].SizeMask = NMask;
  1857.   TwoRegOrders[InstrZ].DefSize = NDef;
  1858.   AddInstTable(InstTable, NName, InstrZ++, DecodeTwoReg);
  1859. }
  1860.  
  1861. static void AddLog(const char *NName, Word NCode)
  1862. {
  1863.   AddInstTable(InstTable, NName, NCode, DecodeLog);
  1864. }
  1865.  
  1866. static void AddBit(const char *NName, Word NCode)
  1867. {
  1868.   AddInstTable(InstTable, NName, NCode, DecodeBit);
  1869. }
  1870.  
  1871. static void InitFields(void)
  1872. {
  1873.   Format = (char*)malloc(sizeof(char) * STRINGSIZE);
  1874.  
  1875.   InstTable = CreateInstTable(302);
  1876.  
  1877.   AddFixed("NOP"  , 0x0000); AddFixed("PRTS"   , 0x1119);
  1878.   AddFixed("RTE"  , 0x000a); AddFixed("RTS"    , 0x0019);
  1879.   AddFixed("SLEEP", 0x001a); AddFixed("TRAP/VS", 0x0009);
  1880.  
  1881.   AddInstTable(InstTable, "MOV"   , 0   , DecodeMOV);
  1882.   AddInstTable(InstTable, "LDC"   , 0   , DecodeLDC_STC);
  1883.   AddInstTable(InstTable, "STC"   , 16  , DecodeLDC_STC);
  1884.   AddInstTable(InstTable, "LDM"   , 0   , DecodeLDM);
  1885.   AddInstTable(InstTable, "STM"   , 0   , DecodeSTM);
  1886.   AddInstTable(InstTable, "MOVTPE", 16  , DecodeMOVTPE_MOVFPE);
  1887.   AddInstTable(InstTable, "MOVFPE", 0   , DecodeMOVTPE_MOVFPE);
  1888.   AddInstTable(InstTable, "ADD"   , 0   , DecodeADD_SUB);
  1889.   AddInstTable(InstTable, "SUB"   , 16  , DecodeADD_SUB);
  1890.   AddInstTable(InstTable, "CMP"   , 0   , DecodeCMP);
  1891.   AddInstTable(InstTable, "JMP"   , 0   , DecodeJMP_JSR);
  1892.   AddInstTable(InstTable, "JSR"   , 8   , DecodeJMP_JSR);
  1893.   AddInstTable(InstTable, "PJMP"  , 1   , DecodePJMP_PJSR);
  1894.   AddInstTable(InstTable, "PJSR"  , 0   , DecodePJMP_PJSR);
  1895.   AddInstTable(InstTable, "SCB/F" , 0x01, DecodeSCB);
  1896.   AddInstTable(InstTable, "SCB/NE", 0x06, DecodeSCB);
  1897.   AddInstTable(InstTable, "SCB/EQ", 0x07, DecodeSCB);
  1898.   AddInstTable(InstTable, "RTD"   , 0   , DecodePRTD_RTD);
  1899.   AddInstTable(InstTable, "PRTD"  , 1   , DecodePRTD_RTD);
  1900.   AddInstTable(InstTable, "LINK"  , 0   , DecodeLINK);
  1901.   AddInstTable(InstTable, "UNLK"  , 0   , DecodeUNLK);
  1902.   AddInstTable(InstTable, "TRAPA" , 0   , DecodeTRAPA);
  1903.  
  1904.   AddRel("BRA", 0x20); AddRel("BT" , 0x20); AddRel("BRN", 0x21);
  1905.   AddRel("BF" , 0x21); AddRel("BHI", 0x22); AddRel("BLS", 0x23);
  1906.   AddRel("BCC", 0x24); AddRel("BHS", 0x24); AddRel("BCS", 0x25);
  1907.   AddRel("BLO", 0x25); AddRel("BNE", 0x26); AddRel("BEQ", 0x27);
  1908.   AddRel("BVC", 0x28); AddRel("BVS", 0x29); AddRel("BPL", 0x2a);
  1909.   AddRel("BMI", 0x2b); AddRel("BGE", 0x2c); AddRel("BLT", 0x2d);
  1910.   AddRel("BGT", 0x2e); AddRel("BLE", 0x2f); AddRel("BSR", 0x0e);
  1911.  
  1912.   InstrZ = 0;
  1913.   AddOne("CLR"  , 0x13, 3, eSymbolSize16Bit); AddOne("NEG"  , 0x14, 3, eSymbolSize16Bit);
  1914.   AddOne("NOT"  , 0x15, 3, eSymbolSize16Bit); AddOne("ROTL" , 0x1c, 3, eSymbolSize16Bit);
  1915.   AddOne("ROTR" , 0x1d, 3, eSymbolSize16Bit); AddOne("ROTXL", 0x1e, 3, eSymbolSize16Bit);
  1916.   AddOne("ROTXR", 0x1f, 3, eSymbolSize16Bit); AddOne("SHAL" , 0x18, 3, eSymbolSize16Bit);
  1917.   AddOne("SHAR" , 0x19, 3, eSymbolSize16Bit); AddOne("SHLL" , 0x1a, 3, eSymbolSize16Bit);
  1918.   AddOne("SHLR" , 0x1b, 3, eSymbolSize16Bit); AddOne("TAS"  , 0x17, 1, eSymbolSize8Bit);
  1919.   AddOne("TST"  , 0x16, 3, eSymbolSize16Bit);
  1920.  
  1921.   InstrZ = 0;
  1922.   AddOneReg("EXTS", 0x11, 1, eSymbolSize8Bit);
  1923.   AddOneReg("EXTU", 0x12, 1, eSymbolSize8Bit);
  1924.   AddOneReg("SWAP", 0x10, 1, eSymbolSize8Bit);
  1925.  
  1926.   InstrZ = 0;
  1927.   AddRegEA("ADDS" , 0x28, 3, eSymbolSize16Bit); AddRegEA("ADDX" , 0xa0, 3, eSymbolSize16Bit);
  1928.   AddRegEA("AND"  , 0x50, 3, eSymbolSize16Bit); AddRegEA("DIVXU", 0xb8, 3, eSymbolSize16Bit);
  1929.   AddRegEA("MULXU", 0xa8, 3, eSymbolSize16Bit); AddRegEA("OR"   , 0x40, 3, eSymbolSize16Bit);
  1930.   AddRegEA("SUBS" , 0x38, 3, eSymbolSize16Bit); AddRegEA("SUBX" , 0xb0, 3, eSymbolSize16Bit);
  1931.   AddRegEA("XOR"  , 0x60, 3, eSymbolSize16Bit);
  1932.  
  1933.   InstrZ = 0;
  1934.   AddTwoReg("DADD", 0xa000, 1, eSymbolSize8Bit);
  1935.   AddTwoReg("DSUB", 0xb000, 1, eSymbolSize8Bit);
  1936.   AddTwoReg("XCH" ,   0x90, 2, eSymbolSize16Bit);
  1937.  
  1938.   AddLog("ANDC", 0x58); AddLog("ORC", 0x48); AddLog("XORC", 0x68);
  1939.  
  1940.   AddBit("BCLR", 0x50); AddBit("BNOT", 0x60);
  1941.   AddBit("BSET", 0x40); AddBit("BTST", 0x70);
  1942.  
  1943.   AddInstTable(InstTable, "REG", 0, CodeREG);
  1944.   AddInstTable(InstTable, "DATA", 0, DecodeDATA);
  1945.   AddInstTable(InstTable, "BIT", 0, DecodeBIT);
  1946. }
  1947.  
  1948. static void DeinitFields(void)
  1949. {
  1950.   free(Format);
  1951.   order_array_free(OneOrders);
  1952.   order_array_free(OneRegOrders);
  1953.   order_array_free(RegEAOrders);
  1954.   order_array_free(TwoRegOrders);
  1955.   DestroyInstTable(InstTable);
  1956. }
  1957.  
  1958. /*!------------------------------------------------------------------------
  1959.  * \fn     InternSymbol_H8_5(char *pArg, TempResult *pResult)
  1960.  * \brief  handle built-in symbols on H8/500
  1961.  * \param  pArg source argument
  1962.  * \param  pResult result buffer
  1963.  * ------------------------------------------------------------------------ */
  1964.  
  1965. static void InternSymbol_H8_5(char *pArg, TempResult *pResult)
  1966. {
  1967.   Byte Erg;
  1968.  
  1969.   if (DecodeRegCore(pArg, &Erg))
  1970.   {
  1971.     pResult->Typ = TempReg;
  1972.     pResult->DataSize = eSymbolSize16Bit;
  1973.     pResult->Contents.RegDescr.Reg = Erg;
  1974.     pResult->Contents.RegDescr.Dissect = DissectReg_H8_5;
  1975.     pResult->Contents.RegDescr.compare = NULL;
  1976.   }
  1977. }
  1978.  
  1979. static Boolean DecodeAttrPart_H8_5(void)
  1980. {
  1981.   char *p;
  1982.  
  1983.   /* Formatangabe abspalten */
  1984.  
  1985.   switch (AttrSplit)
  1986.   {
  1987.     case '.':
  1988.       p = strchr(AttrPart.str.p_str, ':');
  1989.       if (p)
  1990.       {
  1991.         if (p < AttrPart.str.p_str + strlen(AttrPart.str.p_str) - 1)
  1992.           strmaxcpy(Format, p + 1, STRINGSIZE - 1);
  1993.         else
  1994.           strcpy(Format, " ");
  1995.         *p = '\0';
  1996.       }
  1997.       else
  1998.         strcpy(Format, " ");
  1999.       break;
  2000.     case ':':
  2001.       p = strchr(AttrPart.str.p_str, '.');
  2002.       if (!p)
  2003.       {
  2004.         strmaxcpy(Format, AttrPart.str.p_str, STRINGSIZE - 1);
  2005.         *AttrPart.str.p_str = '\0';
  2006.       }
  2007.       else
  2008.       {
  2009.         *p = '\0';
  2010.         if (p == AttrPart.str.p_str)
  2011.           strcpy(Format, " ");
  2012.         else
  2013.           strmaxcpy(Format, AttrPart.str.p_str, STRINGSIZE - 1);
  2014.         strcpy(AttrPart.str.p_str, p + 1);
  2015.       }
  2016.       break;
  2017.     default:
  2018.       strcpy(Format, " ");
  2019.   }
  2020.  
  2021.   NLS_UpString(Format);
  2022.  
  2023.   if (*AttrPart.str.p_str)
  2024.   {
  2025.     if (!DecodeMoto16AttrSize(*AttrPart.str.p_str, &AttrPartOpSize[0], False))
  2026.       return False;
  2027.   }
  2028.   return True;
  2029. }
  2030.  
  2031. static void MakeCode_H8_5(void)
  2032. {
  2033.   CodeLen = 0; DontPrint = False; AbsBank = Reg_DP;
  2034.  
  2035.   /* to be ignored */
  2036.  
  2037.   if (Memo("")) return;
  2038.  
  2039.   OpSize = eSymbolSizeUnknown;
  2040.   if (*AttrPart.str.p_str)
  2041.     SetOpSize(AttrPartOpSize[0]);
  2042.  
  2043.   if (DecodeMoto16Pseudo(OpSize, True)) return;
  2044.  
  2045.   /* Sonderfaelle */
  2046.  
  2047.   if (!LookupInstTable(InstTable, OpPart.str.p_str))
  2048.     WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
  2049. }
  2050.  
  2051. static Boolean ChkPC_H8_5(LargeWord Addr)
  2052. {
  2053.   if (ActPC == SegCode)
  2054.     return (Addr < (MaxMode ? 0x1000000u : 0x10000u));
  2055.   else
  2056.     return False;
  2057. }
  2058.  
  2059. static Boolean IsDef_H8_5(void)
  2060. {
  2061.   return Memo("REG")
  2062.       || Memo("BIT");
  2063. }
  2064.  
  2065. static void InitCode_H8_5(void)
  2066. {
  2067.   Reg_DP = -1;
  2068.   Reg_EP = -1;
  2069.   Reg_TP = -1;
  2070.   Reg_BR = -1;
  2071. }
  2072.  
  2073. static void SwitchTo_H8_5(void)
  2074. {
  2075.   TurnWords = True;
  2076.   SetIntConstMode(eIntConstModeMoto);
  2077.  
  2078.   PCSymbol = "*"; HeaderID = 0x69; NOPCode = 0x00;
  2079.   DivideChars = ","; HasAttrs = True; AttrChars = ".:";
  2080.  
  2081.   ValidSegs = 1 << SegCode;
  2082.   Grans[SegCode] = 1; ListGrans[SegCode] = 1; SegInits[SegCode] = 0;
  2083.  
  2084.   DecodeAttrPart = DecodeAttrPart_H8_5;
  2085.   MakeCode = MakeCode_H8_5;
  2086.   ChkPC = ChkPC_H8_5;
  2087.   IsDef = IsDef_H8_5;
  2088.   SwitchFrom = DeinitFields;
  2089.   InternSymbol = InternSymbol_H8_5;
  2090.   DissectReg = DissectReg_H8_5;
  2091.   DissectBit = DissectBit_H8_5;
  2092.   QualifyQuote = QualifyQuote_SingleQuoteConstant;
  2093.   IntConstModeIBMNoTerm = True;
  2094.   InitFields();
  2095.   onoff_maxmode_add();
  2096.   onoff_compmode_add();
  2097.   AddMoto16PseudoONOFF(False);
  2098.  
  2099.   pASSUMERecs = ASSUMEH8_5s;
  2100.   ASSUMERecCnt = ASSUMEH8_5Count;
  2101. }
  2102.  
  2103. void codeh8_5_init(void)
  2104. {
  2105.   CPU532 = AddCPU("HD6475328", SwitchTo_H8_5);
  2106.   CPU534 = AddCPU("HD6475348", SwitchTo_H8_5);
  2107.   CPU536 = AddCPU("HD6475368", SwitchTo_H8_5);
  2108.   CPU538 = AddCPU("HD6475388", SwitchTo_H8_5);
  2109.  
  2110.   AddInitPassProc(InitCode_H8_5);
  2111. }
  2112.