Subversion Repositories pentevo

Rev

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

  1. /* intpseudo.c */
  2. /*****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
  4. /*                                                                           */
  5. /* AS                                                                        */
  6. /*                                                                           */
  7. /* Commonly Used Intel-Style Pseudo Instructions                             */
  8. /*                                                                           */
  9. /*****************************************************************************/
  10.  
  11. /*****************************************************************************
  12.  * Includes
  13.  *****************************************************************************/
  14.  
  15. #include "stdinc.h"
  16. #include <ctype.h>
  17. #include <string.h>
  18. #include <assert.h>
  19. #include <math.h>
  20.  
  21. #include "bpemu.h"
  22. #include "be_le.h"
  23. #include "strutil.h"
  24. #include "nls.h"
  25. #include "asmdef.h"
  26. #include "asmsub.h"
  27. #include "asmpars.h"
  28. #include "asmitree.h"
  29. #include "onoff_common.h"
  30. #include "chartrans.h"
  31. #include "errmsg.h"
  32. #include "ieeefloat.h"
  33. #include "decfloat.h"
  34.  
  35. #include "intpseudo.h"
  36.  
  37. #define LEAVE goto func_exit
  38.  
  39. /*****************************************************************************
  40.  * Local Types
  41.  *****************************************************************************/
  42.  
  43. struct sLayoutCtx;
  44.  
  45. typedef Boolean (*TLayoutFunc)(
  46. #ifdef __PROTOS__
  47.                                const tStrComp *pArg, struct sLayoutCtx *pCtx
  48. #endif
  49.                                );
  50.  
  51. typedef enum
  52. {
  53.   DSNone, DSConstant, DSSpace
  54. } tDSFlag;
  55.  
  56. struct sCurrCodeFill
  57. {
  58.   LongInt FullWordCnt;
  59.   int LastWordFill;
  60. };
  61. typedef struct sCurrCodeFill tCurrCodeFill;
  62.  
  63. struct sLayoutCtx
  64. {
  65.   tDSFlag DSFlag;
  66.   Word flags;
  67.   TLayoutFunc LayoutFunc;
  68.   int BaseElemLenBits, FullWordSize, ElemsPerFullWord, ListGran;
  69.   Boolean (*Put4I)(Byte b, struct sLayoutCtx *pCtx);
  70.   Boolean (*Put8I)(Byte b, struct sLayoutCtx *pCtx);
  71.   Boolean (*Put16I)(Word w, struct sLayoutCtx *pCtx);
  72.   Boolean (*Put16F)(Double f, struct sLayoutCtx *pCtx);
  73.   Boolean (*Put32I)(LongWord l, struct sLayoutCtx *pCtx);
  74.   Boolean (*Put32F)(Double f, struct sLayoutCtx *pCtx);
  75.   Boolean (*Put48I)(LargeWord q, struct sLayoutCtx *pCtx);
  76.   Boolean (*Put48F)(Double f, struct sLayoutCtx *pCtx);
  77.   Boolean (*Put64I)(LargeWord q, struct sLayoutCtx *pCtx);
  78.   Boolean (*Put64F)(Double f, struct sLayoutCtx *pCtx);
  79.   Boolean (*Put80F)(Double t, struct sLayoutCtx *pCtx);
  80.   Boolean (*Replicate)(const tCurrCodeFill *pStartPos, const tCurrCodeFill *pEndPos, struct sLayoutCtx *pCtx);
  81.   tCurrCodeFill CurrCodeFill, FillIncPerElem;
  82.   const tStrComp *pCurrComp;
  83.   int LoHiMap;
  84. };
  85. typedef struct sLayoutCtx tLayoutCtx;
  86.  
  87. /*****************************************************************************
  88.  * Global Variables
  89.  *****************************************************************************/
  90.  
  91. static char Z80SyntaxName[] = "Z80SYNTAX";
  92. tZ80Syntax CurrZ80Syntax;
  93.  
  94. /*****************************************************************************
  95.  * Local Functions
  96.  *****************************************************************************/
  97.  
  98. void _DumpCodeFill(const char *pTitle, const tCurrCodeFill *pFill)
  99. {
  100.   fprintf(stderr, "%s %u %d\n", pTitle, (unsigned)pFill->FullWordCnt, pFill->LastWordFill);
  101. }
  102.  
  103. /*!------------------------------------------------------------------------
  104.  * \fn     Boolean SetDSFlag(struct sLayoutCtx *pCtx, tDSFlag Flag)
  105.  * \brief  check set data disposition/reservation flag in context
  106.  * \param  pCtx context
  107.  * \param  Flag operation to be set
  108.  * \return True if operation could be set or was alreday set
  109.  * ------------------------------------------------------------------------ */
  110.  
  111. static Boolean SetDSFlag(struct sLayoutCtx *pCtx, tDSFlag Flag)
  112. {
  113.   if ((pCtx->DSFlag != DSNone) && (pCtx->DSFlag != Flag))
  114.   {
  115.     WrStrErrorPos(ErrNum_MixDBDS, pCtx->pCurrComp);
  116.     return False;
  117.   }
  118.   pCtx->DSFlag = Flag;
  119.   return True;
  120. }
  121.  
  122. /*!------------------------------------------------------------------------
  123.  * \fn     IncMaxCodeLen(struct sLayoutCtx *pCtx, LongWord NumFullWords)
  124.  * \brief  assure xAsmCode has space for at moleast n more full words
  125.  * \param  pCtxcontext
  126.  * \param  NumFullWords # of additional words intended to write
  127.  * \return True if success
  128.  * ------------------------------------------------------------------------ */
  129.  
  130. static Boolean IncMaxCodeLen(struct sLayoutCtx *pCtx, LongWord NumFullWords)
  131. {
  132.   if (SetMaxCodeLen((pCtx->CurrCodeFill.FullWordCnt + NumFullWords) * pCtx->FullWordSize))
  133.   {
  134.     WrStrErrorPos(ErrNum_CodeOverflow, pCtx->pCurrComp);
  135.     return False;
  136.   }
  137.   else
  138.     return True;
  139. }
  140.  
  141. static LargeWord ByteInWord(Byte b, int Pos)
  142. {
  143.   return ((LargeWord)b) << (Pos << 3);
  144. }
  145.  
  146. static Byte NibbleInByte(Byte n, int Pos)
  147. {
  148.   return (n & 15) << (Pos << 2);
  149. }
  150.  
  151. static Word NibbleInWord(Byte n, int Pos)
  152. {
  153.   return ((Word)(n & 15)) << (Pos << 2);
  154. }
  155.  
  156. static Byte ByteFromWord(LargeWord w, int Pos)
  157. {
  158.   return (w >> (Pos << 3)) & 0xff;
  159. }
  160.  
  161. static Byte NibbleFromByte(Byte b, int Pos)
  162. {
  163.   return (b >> (Pos << 2)) & 0x0f;
  164. }
  165.  
  166. static Byte NibbleFromWord(Word w, int Pos)
  167. {
  168.   return (w >> (Pos << 2)) & 0x0f;
  169. }
  170.  
  171. /*!------------------------------------------------------------------------
  172.  * \fn     SubCodeFill
  173.  * \brief  perform 'c = a - b' on tCurrCodeFill structures
  174.  * \param  c result
  175.  * \param  b, c arguments
  176.  * ------------------------------------------------------------------------ */
  177.  
  178. static void SubCodeFill(tCurrCodeFill *c, const tCurrCodeFill *a, const tCurrCodeFill *b, struct sLayoutCtx *pCtx)
  179. {
  180.   c->FullWordCnt = a->FullWordCnt - b->FullWordCnt;
  181.   if ((c->LastWordFill = a->LastWordFill - b->LastWordFill) < 0)
  182.   {
  183.     c->LastWordFill += pCtx->ElemsPerFullWord;
  184.     c->FullWordCnt--;
  185.   }
  186. }
  187.  
  188. /*!------------------------------------------------------------------------
  189.  * \fn     MultCodeFill(tCurrCodeFill *b, LongWord a, struct sLayoutCtx *pCtx)
  190.  * \brief  perform 'b *= a' on tCurrCodeFill structures
  191.  * \param  b what to multiply
  192.  * \param  a scaling factor
  193.  * ------------------------------------------------------------------------ */
  194.  
  195. static void MultCodeFill(tCurrCodeFill *b, LongWord a, struct sLayoutCtx *pCtx)
  196. {
  197.   b->FullWordCnt *= a;
  198.   b->LastWordFill *= a;
  199.   if (pCtx->ElemsPerFullWord > 1)
  200.   {
  201.     LongWord div = b->LastWordFill / pCtx->ElemsPerFullWord,
  202.              mod = b->LastWordFill % pCtx->ElemsPerFullWord;
  203.     b->FullWordCnt += div;
  204.     b->LastWordFill = mod;
  205.   }
  206. }
  207.  
  208. /*!------------------------------------------------------------------------
  209.  * \fn     IncCodeFill(tCurrCodeFill *a, struct sLayoutCtx *pCtx)
  210.  * \brief  advance tCurrCodeFill pointer by one base element
  211.  * \param  a pointer to increment
  212.  * \param  pCtx context
  213.  * ------------------------------------------------------------------------ */
  214.  
  215. static void IncCodeFill(tCurrCodeFill *a, struct sLayoutCtx *pCtx)
  216. {
  217.   if (++a->LastWordFill >= pCtx->ElemsPerFullWord)
  218.   {
  219.     a->LastWordFill -= pCtx->ElemsPerFullWord;
  220.     a->FullWordCnt++;
  221.   }
  222. }
  223.  
  224. /*!------------------------------------------------------------------------
  225.  * \fn     IncCurrCodeFill(struct sLayoutCtx *pCtx)
  226.  * \brief  advance CodeFill pointer in context and reserve memory
  227.  * \param  pCtx context
  228.  * \return True if success
  229.  * ------------------------------------------------------------------------ */
  230.  
  231. static Boolean IncCurrCodeFill(struct sLayoutCtx *pCtx)
  232. {
  233.   LongInt OldFullWordCnt = pCtx->CurrCodeFill.FullWordCnt;
  234.  
  235.   IncCodeFill(&pCtx->CurrCodeFill, pCtx);
  236.   if (OldFullWordCnt == pCtx->CurrCodeFill.FullWordCnt)
  237.     return True;
  238.   else if (!IncMaxCodeLen(pCtx, 1))
  239.     return False;
  240.   else
  241.   {
  242.     WAsmCode[pCtx->CurrCodeFill.FullWordCnt] = 0;
  243.     return True;
  244.   }
  245. }
  246.  
  247. /*!------------------------------------------------------------------------
  248.  * \fn     IncCodeFillBy(tCurrCodeFill *a, const tCurrCodeFill *inc, struct sLayoutCtx *pCtx)
  249.  * \brief  perform 'a += inc' on tCurrCodeFill structures
  250.  * \param  a what to advance
  251.  * \param  inc by what to advance
  252.  * \param  pCtx context
  253.  * ------------------------------------------------------------------------ */
  254.  
  255. static void IncCodeFillBy(tCurrCodeFill *a, const tCurrCodeFill *inc, struct sLayoutCtx *pCtx)
  256. {
  257.   a->LastWordFill += inc->LastWordFill;
  258.   if ((pCtx->ElemsPerFullWord > 1) && (a->LastWordFill >= pCtx->ElemsPerFullWord))
  259.   {
  260.     a->LastWordFill -= pCtx->ElemsPerFullWord;
  261.     a->FullWordCnt++;
  262.   }
  263.   a->FullWordCnt += inc->FullWordCnt;
  264. }
  265.  
  266. /*****************************************************************************
  267.  * Function:    LayoutNibble
  268.  * Purpose:     parse argument, interprete as nibble,
  269.  *              and put into result buffer
  270.  * Result:      TRUE if no errors occured
  271.  *****************************************************************************/
  272.  
  273. static Boolean Put4I_To_8(Byte b, struct sLayoutCtx *pCtx)
  274. {
  275.   tCurrCodeFill Pos = pCtx->CurrCodeFill;
  276.   if (!IncCurrCodeFill(pCtx))
  277.     return False;
  278.   if (!Pos.LastWordFill)
  279.     BAsmCode[Pos.FullWordCnt] = NibbleInByte(b, Pos.LastWordFill ^ pCtx->LoHiMap);
  280.   else
  281.     BAsmCode[Pos.FullWordCnt] |= NibbleInByte(b, Pos.LastWordFill ^ pCtx->LoHiMap);
  282.   return True;
  283. }
  284.  
  285. static Boolean Replicate4_To_8(const tCurrCodeFill *pStartPos, const tCurrCodeFill *pEndPos, struct sLayoutCtx *pCtx)
  286. {
  287.   Byte b;
  288.   tCurrCodeFill CurrPos;
  289.  
  290.   CurrPos = *pStartPos;
  291.   while ((CurrPos.FullWordCnt != pEndPos->FullWordCnt) || (CurrPos.LastWordFill != pEndPos->LastWordFill))
  292.   {
  293.     b = NibbleFromByte(BAsmCode[CurrPos.FullWordCnt], CurrPos.LastWordFill ^ pCtx->LoHiMap);
  294.     if (!Put4I_To_8(b, pCtx))
  295.       return False;
  296.     IncCodeFill(&CurrPos, pCtx);
  297.   }
  298.  
  299.   return True;
  300. }
  301.  
  302. static Boolean Put4I_To_16(Byte b, struct sLayoutCtx *pCtx)
  303. {
  304.   tCurrCodeFill Pos = pCtx->CurrCodeFill;
  305.   if (!IncCurrCodeFill(pCtx))
  306.     return False;
  307.   if (!Pos.LastWordFill)
  308.     WAsmCode[Pos.FullWordCnt] = NibbleInWord(b, Pos.LastWordFill ^ pCtx->LoHiMap);
  309.   else
  310.     WAsmCode[Pos.FullWordCnt] |= NibbleInWord(b, Pos.LastWordFill ^ pCtx->LoHiMap);
  311.   return True;
  312. }
  313.  
  314. static Boolean Replicate4_To_16(const tCurrCodeFill *pStartPos, const tCurrCodeFill *pEndPos, struct sLayoutCtx *pCtx)
  315. {
  316.   Byte b;
  317.   tCurrCodeFill CurrPos;
  318.  
  319.   CurrPos = *pStartPos;
  320.   while ((CurrPos.FullWordCnt != pEndPos->FullWordCnt) || (CurrPos.LastWordFill != pEndPos->LastWordFill))
  321.   {
  322.     b = NibbleFromWord(WAsmCode[CurrPos.FullWordCnt], CurrPos.LastWordFill ^ pCtx->LoHiMap);
  323.     if (!Put4I_To_16(b, pCtx))
  324.       return False;
  325.     IncCodeFill(&CurrPos, pCtx);
  326.   }
  327.  
  328.   return True;
  329. }
  330.  
  331. static Boolean LayoutNibble(const tStrComp *pExpr, struct sLayoutCtx *pCtx)
  332. {
  333.   Boolean Result = False;
  334.   TempResult t;
  335.  
  336.   as_tempres_ini(&t);
  337.   EvalStrExpression(pExpr, &t);
  338.   switch (t.Typ)
  339.   {
  340.     case TempInt:
  341.       if (mFirstPassUnknown(t.Flags)) t.Contents.Int &= 0xf;
  342.       if (!mSymbolQuestionable(t.Flags) && !RangeCheck(t.Contents.Int, Int4)) WrStrErrorPos(ErrNum_OverRange, pExpr);
  343.       else
  344.       {
  345.         if (!pCtx->Put4I(t.Contents.Int, pCtx))
  346.           LEAVE;
  347.         Result = True;
  348.       }
  349.       break;
  350.     case TempFloat:
  351.       WrStrErrorPos(ErrNum_IntButFloat, pExpr);
  352.       break;
  353.     case TempString:
  354.       WrStrErrorPos(ErrNum_IntButString, pExpr);
  355.       break;
  356.     default:
  357.       break;
  358.   }
  359.  
  360. func_exit:
  361.   as_tempres_free(&t);
  362.   return Result;
  363. }
  364.  
  365. /*****************************************************************************
  366.  * Function:    LayoutByte
  367.  * Purpose:     parse argument, interprete as byte,
  368.  *              and put into result buffer
  369.  * Result:      TRUE if no errors occured
  370.  *****************************************************************************/
  371.  
  372. static Boolean Put8I_To_8(Byte b, struct sLayoutCtx *pCtx)
  373. {
  374.   if (!IncMaxCodeLen(pCtx, 1))
  375.     return False;
  376.   if ((pCtx->ListGran == 1) || !(pCtx->CurrCodeFill.FullWordCnt & 1))
  377.     BAsmCode[pCtx->CurrCodeFill.FullWordCnt] = b;
  378.   else if (pCtx->flags & eIntPseudoFlag_Turn)
  379.     WAsmCode[pCtx->CurrCodeFill.FullWordCnt >> 1] = (((Word)BAsmCode[pCtx->CurrCodeFill.FullWordCnt - 1]) << 8) | b;
  380.   else
  381.     WAsmCode[pCtx->CurrCodeFill.FullWordCnt >> 1] = (((Word)b) << 8) | BAsmCode[pCtx->CurrCodeFill.FullWordCnt - 1];
  382.   pCtx->CurrCodeFill.FullWordCnt++;
  383.   return True;
  384. }
  385.  
  386. static Boolean Put8I_To_16(Byte b, struct sLayoutCtx *pCtx)
  387. {
  388.   tCurrCodeFill Pos = pCtx->CurrCodeFill;
  389.   if (!IncCurrCodeFill(pCtx))
  390.     return False;
  391.   if (!Pos.LastWordFill)
  392.     WAsmCode[Pos.FullWordCnt] = ByteInWord(b, Pos.LastWordFill ^ pCtx->LoHiMap);
  393.   else
  394.     WAsmCode[Pos.FullWordCnt] |= ByteInWord(b, Pos.LastWordFill ^ pCtx->LoHiMap);
  395.   return True;
  396. }
  397.  
  398. static Boolean Replicate8ToN_To_8(const tCurrCodeFill *pStartPos, const tCurrCodeFill *pEndPos, struct sLayoutCtx *pCtx)
  399. {
  400.   tCurrCodeFill Pos;
  401.  
  402.   if (!IncMaxCodeLen(pCtx, pEndPos->FullWordCnt - pStartPos->FullWordCnt))
  403.     return False;
  404.  
  405.   for (Pos = *pStartPos; Pos.FullWordCnt < pEndPos->FullWordCnt; Pos.FullWordCnt += pCtx->BaseElemLenBits / 8)
  406.   {
  407.     memcpy(&BAsmCode[pCtx->CurrCodeFill.FullWordCnt], &BAsmCode[Pos.FullWordCnt], pCtx->BaseElemLenBits / 8);
  408.     pCtx->CurrCodeFill.FullWordCnt += pCtx->BaseElemLenBits / 8;
  409.   }
  410.   if (Pos.FullWordCnt != pEndPos->FullWordCnt)
  411.   {
  412.     WrXError(ErrNum_InternalError, "DUP replication inconsistency");
  413.     return False;
  414.   }
  415.  
  416.   return True;
  417. }
  418.  
  419. static Boolean Replicate8_To_16(const tCurrCodeFill *pStartPos, const tCurrCodeFill *pEndPos, struct sLayoutCtx *pCtx)
  420. {
  421.   Byte b;
  422.   tCurrCodeFill CurrPos;
  423.  
  424.   CurrPos = *pStartPos;
  425.   while ((CurrPos.FullWordCnt != pEndPos->FullWordCnt) || (CurrPos.LastWordFill != pEndPos->LastWordFill))
  426.   {
  427.     b = ByteFromWord(WAsmCode[CurrPos.FullWordCnt], CurrPos.LastWordFill ^ pCtx->LoHiMap);
  428.     if (!Put8I_To_16(b, pCtx))
  429.       return False;
  430.     IncCodeFill(&CurrPos, pCtx);
  431.   }
  432.  
  433.   return True;
  434. }
  435.  
  436. static Boolean LayoutByte(const tStrComp *pExpr, struct sLayoutCtx *pCtx)
  437. {
  438.   Boolean Result = False;
  439.   TempResult t;
  440.  
  441.   as_tempres_ini(&t);
  442.   EvalStrExpression(pExpr, &t);
  443.   switch (t.Typ)
  444.   {
  445.     case TempInt:
  446.     ToInt:
  447.       if (mFirstPassUnknown(t.Flags)) t.Contents.Int &= 0xff;
  448.       if (!mSymbolQuestionable(t.Flags) && !RangeCheck(t.Contents.Int, Int8)) WrStrErrorPos(ErrNum_OverRange, pExpr);
  449.       else
  450.       {
  451.         if (!pCtx->Put8I(t.Contents.Int, pCtx))
  452.           LEAVE;
  453.         Result = True;
  454.       }
  455.       break;
  456.     case TempFloat:
  457.       WrStrErrorPos(ErrNum_StringOrIntButFloat, pExpr);
  458.       break;
  459.     case TempString:
  460.     {
  461.       unsigned ch;
  462.       const char *p_run;
  463.       size_t run_len;
  464.       int ret;
  465.  
  466.       if (MultiCharToInt(&t, 1))
  467.         goto ToInt;
  468.  
  469.       p_run = t.Contents.str.p_str;
  470.       run_len = t.Contents.str.len;
  471.       while (!(ret = as_chartrans_xlate_next(CurrTransTable->p_table, &ch, &p_run, &run_len)))
  472.       {
  473.         if (!pCtx->Put8I(ch, pCtx))
  474.           LEAVE;
  475.       }
  476.       if (ENOENT == ret)
  477.       {
  478.         WrStrErrorPos(ErrNum_UnmappedChar, pExpr);
  479.         LEAVE;
  480.       }
  481.  
  482.       Result = True;
  483.       break;
  484.     }
  485.     default:
  486.       break;
  487.   }
  488.  
  489. func_exit:
  490.   as_tempres_free(&t);
  491.   return Result;
  492. }
  493.  
  494. /*****************************************************************************
  495.  * Function:    LayoutWord
  496.  * Purpose:     parse argument, interprete as 16-bit word,
  497.  *              and put into result buffer
  498.  * Result:      TRUE if no errors occured
  499.  *****************************************************************************/
  500.  
  501. static Boolean Put16I_To_8(Word w, struct sLayoutCtx *pCtx)
  502. {
  503.   if (!IncMaxCodeLen(pCtx, 2))
  504.     return False;
  505.   if (pCtx->ListGran == 2)
  506.     WAsmCode[pCtx->CurrCodeFill.FullWordCnt >> 1] = w;
  507.   else
  508.   {
  509.     BAsmCode[pCtx->CurrCodeFill.FullWordCnt + (0 ^ pCtx->LoHiMap)] = Lo(w);
  510.     BAsmCode[pCtx->CurrCodeFill.FullWordCnt + (1 ^ pCtx->LoHiMap)] = Hi(w);
  511.   }
  512.   pCtx->CurrCodeFill.FullWordCnt += 2;
  513.   return True;
  514. }
  515.  
  516. static Boolean Put16F_To_8(Double t, struct sLayoutCtx *pCtx)
  517. {
  518.   if (!IncMaxCodeLen(pCtx, 2))
  519.     return False;
  520.   if (!Double_2_ieee2(t, BAsmCode + pCtx->CurrCodeFill.FullWordCnt, !!pCtx->LoHiMap))
  521.   {
  522.     WrError(ErrNum_OverRange);
  523.     return False;
  524.   }
  525.   pCtx->CurrCodeFill.FullWordCnt += 2;
  526.   return True;
  527. }
  528.  
  529. static Boolean Put16I_To_16(Word w, struct sLayoutCtx *pCtx)
  530. {
  531.   if (!IncMaxCodeLen(pCtx, 1))
  532.     return False;
  533.   WAsmCode[pCtx->CurrCodeFill.FullWordCnt++] = w;
  534.   return True;
  535. }
  536.  
  537. static Boolean Put16F_To_16(Double t, struct sLayoutCtx *pCtx)
  538. {
  539.   Byte Tmp[2];
  540.  
  541.   if (!IncMaxCodeLen(pCtx, 1))
  542.     return False;
  543.  
  544.   Double_2_ieee2(t, Tmp, !!pCtx->LoHiMap);
  545.   WAsmCode[pCtx->CurrCodeFill.FullWordCnt + 0] = ByteInWord(Tmp[0], 0 ^ pCtx->LoHiMap) | ByteInWord(Tmp[1], 1 ^ pCtx->LoHiMap);
  546.   pCtx->CurrCodeFill.FullWordCnt += 1;
  547.   return True;
  548. }
  549.  
  550. static Boolean Replicate16ToN_To_16(const tCurrCodeFill *pStartPos, const tCurrCodeFill *pEndPos, struct sLayoutCtx *pCtx)
  551. {
  552.   tCurrCodeFill Pos;
  553.  
  554.   if (!IncMaxCodeLen(pCtx, pEndPos->FullWordCnt - pStartPos->FullWordCnt))
  555.     return False;
  556.  
  557.   for (Pos = *pStartPos; Pos.FullWordCnt < pEndPos->FullWordCnt; Pos.FullWordCnt += pCtx->BaseElemLenBits / 16)
  558.   {
  559.     memcpy(&WAsmCode[pCtx->CurrCodeFill.FullWordCnt], &WAsmCode[Pos.FullWordCnt], pCtx->BaseElemLenBits / 8);
  560.     pCtx->CurrCodeFill.FullWordCnt += pCtx->BaseElemLenBits / 16;
  561.   }
  562.   if (Pos.FullWordCnt != pEndPos->FullWordCnt)
  563.   {
  564.     WrXError(ErrNum_InternalError, "DUP replication inconsistency");
  565.     return False;
  566.   }
  567.  
  568.   return True;
  569. }
  570.  
  571. static Boolean LayoutWord(const tStrComp *pExpr, struct sLayoutCtx *pCtx)
  572. {
  573.   Boolean Result = False;
  574.   const Boolean allow_string = !!(pCtx->flags & eIntPseudoFlag_AllowString),
  575.                 allow_float = !!pCtx->Put16F;
  576.   TempResult t;
  577.  
  578.   as_tempres_ini(&t);
  579.   EvalStrExpression(pExpr, &t);
  580.   Result = True;
  581.   switch (t.Typ)
  582.   {
  583.     case TempInt:
  584.     ToInt:
  585.       if (pCtx->Put16I)
  586.       {
  587.         if (mFirstPassUnknown(t.Flags)) t.Contents.Int &= 0xffff;
  588.         if (!mSymbolQuestionable(t.Flags) && !RangeCheck(t.Contents.Int, Int16)) WrStrErrorPos(ErrNum_OverRange, pExpr);
  589.         else
  590.         {
  591.           if (!pCtx->Put16I(t.Contents.Int, pCtx))
  592.             LEAVE;
  593.           Result = True;
  594.         }
  595.         break;
  596.       }
  597.       else
  598.         TempResultToFloat(&t);
  599.       /* fall-through */
  600.     case TempFloat:
  601.       if (!allow_float) WrStrErrorPos(allow_string ? ErrNum_StringOrIntButFloat : ErrNum_IntButFloat, pExpr);
  602.       else if (!FloatRangeCheck(t.Contents.Float, Float16)) WrStrErrorPos(ErrNum_OverRange, pExpr);
  603.       else
  604.       {
  605.         if (!pCtx->Put16F(t.Contents.Float, pCtx))
  606.           LEAVE;
  607.         Result = True;
  608.       }
  609.       break;
  610.     case TempString:
  611.       if (!allow_string) WrStrErrorPos(allow_float ? ErrNum_IntOrFloatButString : ErrNum_IntButString, pExpr);
  612.       else
  613.       {
  614.         unsigned z;
  615.  
  616.         if (MultiCharToInt(&t, 2))
  617.           goto ToInt;
  618.  
  619.         if (as_chartrans_xlate_nonz_dynstr(CurrTransTable->p_table, &t.Contents.str, pExpr))
  620.           LEAVE;
  621.  
  622.         for (z = 0; z < t.Contents.str.len; z++)
  623.           if (!pCtx->Put16I(t.Contents.str.p_str[z], pCtx))
  624.             LEAVE;
  625.  
  626.         Result = True;
  627.       }
  628.       break;
  629.     case TempReg:
  630.       if (allow_float && allow_string)
  631.         WrStrErrorPos(ErrNum_StringOrIntOrFloatButReg, pExpr);
  632.       else if (allow_float)
  633.         WrStrErrorPos(ErrNum_IntOrFloatButReg, pExpr);
  634.       else if (allow_string)
  635.         WrStrErrorPos(ErrNum_IntOrStringButReg, pExpr);
  636.       else
  637.         WrStrErrorPos(ErrNum_IntButReg, pExpr);
  638.       break;
  639.     default:
  640.       break;
  641.   }
  642.  
  643. func_exit:
  644.   as_tempres_free(&t);
  645.   return Result;
  646. }
  647.  
  648. /*****************************************************************************
  649.  * Function:    LayoutDoubleWord
  650.  * Purpose:     parse argument, interprete as 32-bit word or
  651.                 single precision float, and put into result buffer
  652.  * Result:      TRUE if no errors occured
  653.  *****************************************************************************/
  654.  
  655. static Boolean Put32I_To_8(LongWord l, struct sLayoutCtx *pCtx)
  656. {
  657.   if (!IncMaxCodeLen(pCtx, 4))
  658.     return False;
  659.   BAsmCode[pCtx->CurrCodeFill.FullWordCnt + (0 ^ pCtx->LoHiMap)] = (l      ) & 0xff;
  660.   BAsmCode[pCtx->CurrCodeFill.FullWordCnt + (1 ^ pCtx->LoHiMap)] = (l >>  8) & 0xff;
  661.   BAsmCode[pCtx->CurrCodeFill.FullWordCnt + (2 ^ pCtx->LoHiMap)] = (l >> 16) & 0xff;
  662.   BAsmCode[pCtx->CurrCodeFill.FullWordCnt + (3 ^ pCtx->LoHiMap)] = (l >> 24) & 0xff;
  663.   pCtx->CurrCodeFill.FullWordCnt += 4;
  664.   return True;
  665. }
  666.  
  667. static Boolean Put32F_To_8(Double t, struct sLayoutCtx *pCtx)
  668. {
  669.   if (!IncMaxCodeLen(pCtx, 4))
  670.     return False;
  671.   if (pCtx->flags & eIntPseudoFlag_DECFormat)
  672.   {
  673.     int ret = Double_2_dec4(t, WAsmCode + (pCtx->CurrCodeFill.FullWordCnt / 2));
  674.     if (ret)
  675.     {
  676.       check_dec_fp_dispose_result(ret, pCtx->pCurrComp);
  677.       return False;
  678.     }
  679.   }
  680.   else
  681.     Double_2_ieee4(t, BAsmCode + pCtx->CurrCodeFill.FullWordCnt, !!pCtx->LoHiMap);
  682.   pCtx->CurrCodeFill.FullWordCnt += 4;
  683.   return True;
  684. }
  685.  
  686. static Boolean Put32I_To_16(LongWord l, struct sLayoutCtx *pCtx)
  687. {
  688.   if (!IncMaxCodeLen(pCtx, 2))
  689.     return False;
  690.   WAsmCode[pCtx->CurrCodeFill.FullWordCnt + (0 ^ pCtx->LoHiMap)] = LoWord(l);
  691.   WAsmCode[pCtx->CurrCodeFill.FullWordCnt + (1 ^ pCtx->LoHiMap)] = HiWord(l);
  692.   pCtx->CurrCodeFill.FullWordCnt += 2;
  693.   return True;
  694. }
  695.  
  696. static Boolean Put32F_To_16(Double t, struct sLayoutCtx *pCtx)
  697. {
  698.   Byte Tmp[4];
  699.  
  700.   if (!IncMaxCodeLen(pCtx, 2))
  701.     return False;
  702.   Double_2_ieee4(t, Tmp, !!pCtx->LoHiMap);
  703.   WAsmCode[pCtx->CurrCodeFill.FullWordCnt + 0] = ByteInWord(Tmp[0], 0 ^ pCtx->LoHiMap) | ByteInWord(Tmp[1], 1 ^ pCtx->LoHiMap);
  704.   WAsmCode[pCtx->CurrCodeFill.FullWordCnt + 1] = ByteInWord(Tmp[2], 0 ^ pCtx->LoHiMap) | ByteInWord(Tmp[3], 1 ^ pCtx->LoHiMap);
  705.   pCtx->CurrCodeFill.FullWordCnt += 2;
  706.   return True;
  707. }
  708.  
  709. static Boolean LayoutDoubleWord(const tStrComp *pExpr, struct sLayoutCtx *pCtx)
  710. {
  711.   TempResult erg;
  712.   Boolean Result = False;
  713.   const Boolean allow_string = !!(pCtx->flags & eIntPseudoFlag_AllowString),
  714.                 allow_float = !!pCtx->Put32F;
  715.   Word Cnt = 0;
  716.  
  717.   as_tempres_ini(&erg);
  718.   EvalStrExpression(pExpr, &erg);
  719.   Result = False;
  720.   switch (erg.Typ)
  721.   {
  722.     case TempNone:
  723.       break;
  724.     case TempInt:
  725.     ToInt:
  726.       if (pCtx->Put32I)
  727.       {
  728.         if (mFirstPassUnknown(erg.Flags)) erg.Contents.Int &= 0xfffffffful;
  729.         if (!mSymbolQuestionable(erg.Flags) && !RangeCheck(erg.Contents.Int, Int32)) WrStrErrorPos(ErrNum_OverRange, pExpr);
  730.         else
  731.         {
  732.           if (!pCtx->Put32I(erg.Contents.Int, pCtx))
  733.             LEAVE;
  734.           Cnt = 4;
  735.           Result = True;
  736.         }
  737.         break;
  738.       }
  739.       else
  740.         TempResultToFloat(&erg);
  741.       /* fall-through */
  742.     case TempFloat:
  743.       if (!allow_float) WrStrErrorPos(allow_string ? ErrNum_StringOrIntButFloat : ErrNum_IntButFloat, pExpr);
  744.       else if (!FloatRangeCheck(erg.Contents.Float, Float32)) WrStrErrorPos(ErrNum_OverRange, pExpr);
  745.       else
  746.       {
  747.         if (!pCtx->Put32F(erg.Contents.Float, pCtx))
  748.           LEAVE;
  749.         Cnt = 4;
  750.         Result = True;
  751.       }
  752.       break;
  753.     case TempString:
  754.       if (!allow_string) WrStrErrorPos(allow_float ? ErrNum_IntOrFloatButString : ErrNum_IntButString, pExpr);
  755.       else
  756.       {
  757.         unsigned z;
  758.  
  759.         if (MultiCharToInt(&erg, 4))
  760.           goto ToInt;
  761.  
  762.         if (as_chartrans_xlate_nonz_dynstr(CurrTransTable->p_table, &erg.Contents.str, pExpr))
  763.           WrStrErrorPos(ErrNum_UnmappedChar, pExpr);
  764.  
  765.         for (z = 0; z < erg.Contents.str.len; z++)
  766.           if (!pCtx->Put32I(erg.Contents.str.p_str[z], pCtx))
  767.             LEAVE;
  768.  
  769.         Cnt = erg.Contents.str.len * 4;
  770.         Result = True;
  771.       }
  772.       break;
  773.     case TempReg:
  774.       if (allow_float && allow_string)
  775.         WrStrErrorPos(ErrNum_StringOrIntOrFloatButReg, pExpr);
  776.       else if (allow_float)
  777.         WrStrErrorPos(ErrNum_IntOrFloatButReg, pExpr);
  778.       else if (allow_string)
  779.         WrStrErrorPos(ErrNum_IntOrStringButReg, pExpr);
  780.       else
  781.         WrStrErrorPos(ErrNum_IntButReg, pExpr);
  782.       break;
  783.     case TempAll:
  784.       assert(0);
  785.   }
  786.   (void)Cnt;
  787.  
  788. func_exit:
  789.   as_tempres_free(&erg);
  790.   return Result;
  791. }
  792.  
  793.  
  794. /*****************************************************************************
  795.  * Function:    LayoutMacAddr
  796.  * Purpose:     parse argument, interprete as 48-bit word or
  797.                 float, and put into result buffer
  798.  * Result:      TRUE if no errors occured
  799.  *****************************************************************************/
  800.  
  801. static Boolean Put48I_To_8(LargeWord l, struct sLayoutCtx *pCtx)
  802. {
  803.   if (!IncMaxCodeLen(pCtx, 8))
  804.     return False;
  805.   BAsmCode[pCtx->CurrCodeFill.FullWordCnt + (0 ^ pCtx->LoHiMap)      ] = (l      ) & 0xff;
  806.   BAsmCode[pCtx->CurrCodeFill.FullWordCnt + (1 ^ pCtx->LoHiMap)      ] = (l >>  8) & 0xff;
  807.   BAsmCode[pCtx->CurrCodeFill.FullWordCnt + (2 ^ (pCtx->LoHiMap & 1))] = (l >> 16) & 0xff;
  808.   BAsmCode[pCtx->CurrCodeFill.FullWordCnt + (3 ^ (pCtx->LoHiMap & 1))] = (l >> 24) & 0xff;
  809. #ifdef HAS64
  810.   BAsmCode[pCtx->CurrCodeFill.FullWordCnt + (4 ^ pCtx->LoHiMap)      ] = (l >> 32) & 0xff;
  811.   BAsmCode[pCtx->CurrCodeFill.FullWordCnt + (5 ^ pCtx->LoHiMap)      ] = (l >> 40) & 0xff;
  812. #else
  813.   /* TempResult is TempInt, so sign-extend */
  814.   BAsmCode[pCtx->CurrCodeFill.FullWordCnt + (4 ^ pCtx->LoHiMap)      ] =
  815.   BAsmCode[pCtx->CurrCodeFill.FullWordCnt + (5 ^ pCtx->LoHiMap)      ] = (l & 0x80000000ul) ? 0xff : 0x00;
  816. #endif
  817.   pCtx->CurrCodeFill.FullWordCnt += 6;
  818.   return True;
  819. }
  820.  
  821. static Boolean Put48F_To_8(Double t, struct sLayoutCtx *pCtx)
  822. {
  823.   /* make space for 8 bytes - last word of D format float is truncated */
  824.   if (!IncMaxCodeLen(pCtx, 8))
  825.     return False;
  826.   if (pCtx->flags & eIntPseudoFlag_DECFormat)
  827.   {
  828.     /* LoHiMap (endianess) is ignored */
  829.     int ret = Double_2_dec8(t, WAsmCode + (pCtx->CurrCodeFill.FullWordCnt / 2));
  830.     if (ret)
  831.     {
  832.       check_dec_fp_dispose_result(ret, pCtx->pCurrComp);
  833.       return False;
  834.     }
  835.   }
  836.   else
  837.     assert(0);  /* no 6 byte IEEE float format */
  838.   pCtx->CurrCodeFill.FullWordCnt += 6;
  839.   return True;
  840. }
  841.  
  842. static Boolean Put48I_To_16(LargeWord l, struct sLayoutCtx *pCtx)
  843. {
  844.   int LoHiMap = pCtx->LoHiMap ? 2 : 0; /* 5 or 0 -> 2 or 0 */
  845.  
  846.   if (!IncMaxCodeLen(pCtx, 3))
  847.     return False;
  848.   WAsmCode[pCtx->CurrCodeFill.FullWordCnt + (0 ^ LoHiMap)      ] = (l      ) & 0xffff;
  849.   WAsmCode[pCtx->CurrCodeFill.FullWordCnt + (1 ^ (LoHiMap & 1))] = (l >> 16) & 0xffff;
  850. #ifdef HAS64
  851.   WAsmCode[pCtx->CurrCodeFill.FullWordCnt + (2 ^ LoHiMap)      ] = (l >> 32) & 0xffff;
  852. #else
  853.   /* TempResult is TempInt, so sign-extend */
  854.   WAsmCode[pCtx->CurrCodeFill.FullWordCnt + (2 ^ LoHiMap)      ] = (l & 0x80000000ul) ? 0xffff : 0x0000;
  855. #endif
  856.   pCtx->CurrCodeFill.FullWordCnt += 3;
  857.   return True;
  858. }
  859.  
  860. static Boolean Put48F_To_16(Double t, struct sLayoutCtx *pCtx)
  861. {
  862.   if (!IncMaxCodeLen(pCtx, 3))
  863.     return False;
  864.   if (pCtx->flags & eIntPseudoFlag_DECFormat)
  865.   {
  866.     Word Tmp[4];
  867.     int ret = Double_2_dec8(t, Tmp);
  868.     if (ret)
  869.     {
  870.       check_dec_fp_dispose_result(ret, pCtx->pCurrComp);
  871.       return False;
  872.     }
  873.     /* LoHiMap (endianess) is ignored */
  874.     memcpy(&WAsmCode[pCtx->CurrCodeFill.FullWordCnt], Tmp, 6);
  875.   }
  876.   else
  877.     assert(0);  /* no 6 byte IEEE float format */
  878.   pCtx->CurrCodeFill.FullWordCnt += 3;
  879.   return True;
  880. }
  881.  
  882. static Boolean LayoutMacAddr(const tStrComp *pExpr, struct sLayoutCtx *pCtx)
  883. {
  884.   Boolean Result = False;
  885.   TempResult erg;
  886.   Word Cnt  = 0;
  887.  
  888.   as_tempres_ini(&erg);
  889.   EvalStrExpression(pExpr, &erg);
  890.   Result = False;
  891.   switch(erg.Typ)
  892.   {
  893.     case TempNone:
  894.       break;
  895.     case TempInt:
  896.     ToInt:
  897.       if (pCtx->Put48I)
  898.       {
  899.         if (!pCtx->Put64I(erg.Contents.Int, pCtx))
  900.           LEAVE;
  901.         Cnt = 6;
  902.         Result = True;
  903.         break;
  904.       }
  905.       else
  906.         TempResultToFloat(&erg);
  907.       /* fall-through */
  908.     case TempFloat:
  909.       if (!pCtx->Put48F) WrStrErrorPos(ErrNum_StringOrIntButFloat, pExpr);
  910.       else if (!pCtx->Put48F(erg.Contents.Float, pCtx))
  911.         LEAVE;
  912.       Cnt = 6;
  913.       Result = True;
  914.       break;
  915.     case TempString:
  916.     {
  917.       unsigned z;
  918.  
  919.       if (MultiCharToInt(&erg, 6))
  920.         goto ToInt;
  921.  
  922.       if (as_chartrans_xlate_nonz_dynstr(CurrTransTable->p_table, &erg.Contents.str, pExpr))
  923.         LEAVE;
  924.  
  925.       for (z = 0; z < erg.Contents.str.len; z++)
  926.         if (!pCtx->Put48I(erg.Contents.str.p_str[z], pCtx))
  927.           LEAVE;
  928.  
  929.       Cnt = erg.Contents.str.len * 6;
  930.       Result = True;
  931.       break;
  932.     }
  933.     case TempReg:
  934.       WrStrErrorPos(ErrNum_StringOrIntOrFloatButReg, pExpr);
  935.       break;
  936.     case TempAll:
  937.       assert(0);
  938.   }
  939.   (void)Cnt;
  940.  
  941. func_exit:
  942.   as_tempres_free(&erg);
  943.   return Result;
  944. }
  945.  
  946. /*****************************************************************************
  947.  * Function:    LayoutQuadWord
  948.  * Purpose:     parse argument, interprete as 64-bit word or
  949.                 double precision float, and put into result buffer
  950.  * Result:      TRUE if no errors occured
  951.  *****************************************************************************/
  952.  
  953. static Boolean Put64I_To_8(LargeWord l, struct sLayoutCtx *pCtx)
  954. {
  955.   if (!IncMaxCodeLen(pCtx, 8))
  956.     return False;
  957.   BAsmCode[pCtx->CurrCodeFill.FullWordCnt + (0 ^ pCtx->LoHiMap)] = (l      ) & 0xff;
  958.   BAsmCode[pCtx->CurrCodeFill.FullWordCnt + (1 ^ pCtx->LoHiMap)] = (l >>  8) & 0xff;
  959.   BAsmCode[pCtx->CurrCodeFill.FullWordCnt + (2 ^ pCtx->LoHiMap)] = (l >> 16) & 0xff;
  960.   BAsmCode[pCtx->CurrCodeFill.FullWordCnt + (3 ^ pCtx->LoHiMap)] = (l >> 24) & 0xff;
  961. #ifdef HAS64
  962.   BAsmCode[pCtx->CurrCodeFill.FullWordCnt + (4 ^ pCtx->LoHiMap)] = (l >> 32) & 0xff;
  963.   BAsmCode[pCtx->CurrCodeFill.FullWordCnt + (5 ^ pCtx->LoHiMap)] = (l >> 40) & 0xff;
  964.   BAsmCode[pCtx->CurrCodeFill.FullWordCnt + (6 ^ pCtx->LoHiMap)] = (l >> 48) & 0xff;
  965.   BAsmCode[pCtx->CurrCodeFill.FullWordCnt + (7 ^ pCtx->LoHiMap)] = (l >> 56) & 0xff;
  966. #else
  967.   /* TempResult is TempInt, so sign-extend */
  968.   BAsmCode[pCtx->CurrCodeFill.FullWordCnt + (4 ^ pCtx->LoHiMap)] =
  969.   BAsmCode[pCtx->CurrCodeFill.FullWordCnt + (5 ^ pCtx->LoHiMap)] =
  970.   BAsmCode[pCtx->CurrCodeFill.FullWordCnt + (6 ^ pCtx->LoHiMap)] =
  971.   BAsmCode[pCtx->CurrCodeFill.FullWordCnt + (7 ^ pCtx->LoHiMap)] = (l & 0x80000000ul) ? 0xff : 0x00;
  972. #endif
  973.   pCtx->CurrCodeFill.FullWordCnt += 8;
  974.   return True;
  975. }
  976.  
  977. static Boolean Put64F_To_8(Double t, struct sLayoutCtx *pCtx)
  978. {
  979.   if (!IncMaxCodeLen(pCtx, 8))
  980.     return False;
  981.   if (pCtx->flags & eIntPseudoFlag_DECFormat)
  982.   {
  983.     int ret = Double_2_dec8(t, WAsmCode + (pCtx->CurrCodeFill.FullWordCnt / 2));
  984.     if (ret)
  985.     {
  986.       check_dec_fp_dispose_result(ret, pCtx->pCurrComp);
  987.       return False;
  988.     }
  989.   }
  990.   else
  991.     Double_2_ieee8(t, BAsmCode + pCtx->CurrCodeFill.FullWordCnt, !!pCtx->LoHiMap);
  992.   pCtx->CurrCodeFill.FullWordCnt += 8;
  993.   return True;
  994. }
  995.  
  996. static Boolean Put64I_To_16(LargeWord l, struct sLayoutCtx *pCtx)
  997. {
  998.   if (!IncMaxCodeLen(pCtx, 4))
  999.     return False;
  1000.   WAsmCode[pCtx->CurrCodeFill.FullWordCnt + (0 ^ pCtx->LoHiMap)] = (l      ) & 0xffff;
  1001.   WAsmCode[pCtx->CurrCodeFill.FullWordCnt + (1 ^ pCtx->LoHiMap)] = (l >> 16) & 0xffff;
  1002. #ifdef HAS64
  1003.   WAsmCode[pCtx->CurrCodeFill.FullWordCnt + (2 ^ pCtx->LoHiMap)] = (l >> 32) & 0xffff;
  1004.   WAsmCode[pCtx->CurrCodeFill.FullWordCnt + (3 ^ pCtx->LoHiMap)] = (l >> 48) & 0xffff;
  1005. #else
  1006.   /* TempResult is TempInt, so sign-extend */
  1007.   WAsmCode[pCtx->CurrCodeFill.FullWordCnt + (2 ^ pCtx->LoHiMap)] =
  1008.   WAsmCode[pCtx->CurrCodeFill.FullWordCnt + (3 ^ pCtx->LoHiMap)] = (l & 0x80000000ul) ? 0xffff : 0x0000;
  1009. #endif
  1010.   pCtx->CurrCodeFill.FullWordCnt += 4;
  1011.   return True;
  1012. }
  1013.  
  1014. static Boolean Put64F_To_16(Double t, struct sLayoutCtx *pCtx)
  1015. {
  1016.   Byte Tmp[8];
  1017.   int LoHiMap = pCtx->LoHiMap & 1;
  1018.  
  1019.   if (!IncMaxCodeLen(pCtx, 4))
  1020.     return False;
  1021.   Double_2_ieee8(t, Tmp, !!pCtx->LoHiMap);
  1022.   WAsmCode[pCtx->CurrCodeFill.FullWordCnt + 0] = ByteInWord(Tmp[0], 0 ^ LoHiMap) | ByteInWord(Tmp[1], 1 ^ LoHiMap);
  1023.   WAsmCode[pCtx->CurrCodeFill.FullWordCnt + 1] = ByteInWord(Tmp[2], 0 ^ LoHiMap) | ByteInWord(Tmp[3], 1 ^ LoHiMap);
  1024.   WAsmCode[pCtx->CurrCodeFill.FullWordCnt + 2] = ByteInWord(Tmp[4], 0 ^ LoHiMap) | ByteInWord(Tmp[5], 1 ^ LoHiMap);
  1025.   WAsmCode[pCtx->CurrCodeFill.FullWordCnt + 3] = ByteInWord(Tmp[6], 0 ^ LoHiMap) | ByteInWord(Tmp[7], 1 ^ LoHiMap);
  1026.   pCtx->CurrCodeFill.FullWordCnt += 4;
  1027.   return True;
  1028. }
  1029.  
  1030. static Boolean LayoutQuadWord(const tStrComp *pExpr, struct sLayoutCtx *pCtx)
  1031. {
  1032.   Boolean Result = False;
  1033.   const Boolean allow_string = !!(pCtx->flags & eIntPseudoFlag_AllowString),
  1034.                 allow_float = !!pCtx->Put64F;
  1035.   TempResult erg;
  1036.   Word Cnt  = 0;
  1037.  
  1038.   as_tempres_ini(&erg);
  1039.   EvalStrExpression(pExpr, &erg);
  1040.   Result = False;
  1041.   switch (erg.Typ)
  1042.   {
  1043.     case TempNone:
  1044.       break;
  1045.     case TempInt:
  1046.     ToInt:
  1047.       if (pCtx->Put64I)
  1048.       {
  1049.         if (!pCtx->Put64I(erg.Contents.Int, pCtx))
  1050.           LEAVE;
  1051.         Cnt = 8;
  1052.         Result = True;
  1053.         break;
  1054.       }
  1055.       else
  1056.         TempResultToFloat(&erg);
  1057.       /* fall-through */
  1058.     case TempFloat:
  1059.       if (!allow_float) WrStrErrorPos(ErrNum_StringOrIntButFloat, pExpr);
  1060.       else if (!pCtx->Put64F(erg.Contents.Float, pCtx))
  1061.         LEAVE;
  1062.       Cnt = 8;
  1063.       Result = True;
  1064.       break;
  1065.     case TempString:
  1066.       if (!allow_string) WrStrErrorPos(allow_float ? ErrNum_IntOrFloatButString : ErrNum_IntButString, pExpr);
  1067.       else
  1068.       {
  1069.          unsigned z;
  1070.  
  1071.         if (MultiCharToInt(&erg, 8))
  1072.           goto ToInt;
  1073.  
  1074.         if (as_chartrans_xlate_nonz_dynstr(CurrTransTable->p_table, &erg.Contents.str, pExpr))
  1075.           LEAVE;
  1076.  
  1077.         for (z = 0; z < erg.Contents.str.len; z++)
  1078.           if (!pCtx->Put64I(erg.Contents.str.p_str[z], pCtx))
  1079.             LEAVE;
  1080.  
  1081.         Cnt = erg.Contents.str.len * 8;
  1082.         Result = True;
  1083.       }
  1084.       break;
  1085.     case TempReg:
  1086.       WrStrErrorPos(ErrNum_StringOrIntOrFloatButReg, pExpr);
  1087.       break;
  1088.     case TempAll:
  1089.       assert(0);
  1090.   }
  1091.   (void)Cnt;
  1092.  
  1093. func_exit:
  1094.   as_tempres_free(&erg);
  1095.   return Result;
  1096. }
  1097.  
  1098. /*****************************************************************************
  1099.  * Function:    LayoutTenBytes
  1100.  * Purpose:     parse argument, interprete extended precision float,
  1101.  *              and put into result buffer
  1102.  * Result:      TRUE if no errors occured
  1103.  *****************************************************************************/
  1104.  
  1105. static Boolean Put80F_To_8(Double t, struct sLayoutCtx *pCtx)
  1106. {
  1107.   if (!IncMaxCodeLen(pCtx, 10))
  1108.     return False;
  1109.   Double_2_ieee10(t, BAsmCode + pCtx->CurrCodeFill.FullWordCnt, !!pCtx->LoHiMap);
  1110.   pCtx->CurrCodeFill.FullWordCnt += 10;
  1111.   return True;
  1112. }
  1113.  
  1114. static Boolean Put80F_To_16(Double t, struct sLayoutCtx *pCtx)
  1115. {
  1116.   Byte Tmp[10];
  1117.   int LoHiMap = pCtx->LoHiMap & 1;
  1118.  
  1119.   if (!IncMaxCodeLen(pCtx, 5))
  1120.     return False;
  1121.   Double_2_ieee10(t, Tmp, !!pCtx->LoHiMap);
  1122.   WAsmCode[pCtx->CurrCodeFill.FullWordCnt + 0] = ByteInWord(Tmp[0], 0 ^ LoHiMap) | ByteInWord(Tmp[1], 1 ^ LoHiMap);
  1123.   WAsmCode[pCtx->CurrCodeFill.FullWordCnt + 1] = ByteInWord(Tmp[2], 0 ^ LoHiMap) | ByteInWord(Tmp[3], 1 ^ LoHiMap);
  1124.   WAsmCode[pCtx->CurrCodeFill.FullWordCnt + 2] = ByteInWord(Tmp[4], 0 ^ LoHiMap) | ByteInWord(Tmp[5], 1 ^ LoHiMap);
  1125.   WAsmCode[pCtx->CurrCodeFill.FullWordCnt + 3] = ByteInWord(Tmp[6], 0 ^ LoHiMap) | ByteInWord(Tmp[7], 1 ^ LoHiMap);
  1126.   WAsmCode[pCtx->CurrCodeFill.FullWordCnt + 4] = ByteInWord(Tmp[8], 0 ^ LoHiMap) | ByteInWord(Tmp[9], 1 ^ LoHiMap);
  1127.   pCtx->CurrCodeFill.FullWordCnt += 5;
  1128.   return True;
  1129. }
  1130.  
  1131. static Boolean LayoutTenBytes(const tStrComp *pExpr, struct sLayoutCtx *pCtx)
  1132. {
  1133.   Boolean Result = False;
  1134.   TempResult erg;
  1135.   Word Cnt;
  1136.  
  1137.   as_tempres_ini(&erg);
  1138.   EvalStrExpression(pExpr, &erg);
  1139.   Result = False;
  1140.   switch(erg.Typ)
  1141.   {
  1142.     case TempNone:
  1143.       break;
  1144.     case TempInt:
  1145.     ToInt:
  1146.       TempResultToFloat(&erg);
  1147.       /* fall-through */
  1148.     case TempFloat:
  1149.       if (!pCtx->Put80F(erg.Contents.Float, pCtx))
  1150.         LEAVE;
  1151.       Cnt = 10;
  1152.       Result = True;
  1153.       break;
  1154.     case TempString:
  1155.     {
  1156.       unsigned z;
  1157.  
  1158.       if (MultiCharToInt(&erg, 4))
  1159.         goto ToInt;
  1160.  
  1161.       if (as_chartrans_xlate_nonz_dynstr(CurrTransTable->p_table, &erg.Contents.str, pExpr))
  1162.         LEAVE;
  1163.  
  1164.       for (z = 0; z < erg.Contents.str.len; z++)
  1165.         if (!pCtx->Put80F(erg.Contents.str.p_str[z], pCtx))
  1166.           LEAVE;
  1167.  
  1168.       Cnt = erg.Contents.str.len * 10;
  1169.       Result = True;
  1170.       break;
  1171.     }
  1172.     case TempReg:
  1173.       WrStrErrorPos(ErrNum_StringOrIntOrFloatButReg, pExpr);
  1174.       break;
  1175.     case TempAll:
  1176.       assert(0);
  1177.   }
  1178.   (void)Cnt;
  1179.  
  1180. func_exit:
  1181.   as_tempres_free(&erg);
  1182.   return Result;
  1183. }
  1184.  
  1185. /*****************************************************************************
  1186.  * Global Functions
  1187.  *****************************************************************************/
  1188.  
  1189. /*****************************************************************************
  1190.  * Function:    DecodeIntelPseudo
  1191.  * Purpose:     handle Intel-style pseudo instructions
  1192.  * Result:      TRUE if mnemonic was handled
  1193.  *****************************************************************************/
  1194.  
  1195. static Boolean DecodeIntelPseudo_ValidSymChar(char ch)
  1196. {
  1197.   ch = as_toupper(ch);
  1198.  
  1199.   return (((ch >= 'A') && (ch <= 'Z'))
  1200.        || ((ch >= '0') && (ch <= '9'))
  1201.        || (ch == '_')
  1202.        || (ch == '.'));
  1203. }
  1204.  
  1205. static void DecodeIntelPseudo_HandleQuote(int *pDepth, Byte *pQuote, char Ch)
  1206. {
  1207.   switch (Ch)
  1208.   {
  1209.     case '(':
  1210.       if (!(*pQuote))
  1211.         (*pDepth)++;
  1212.       break;
  1213.     case ')':
  1214.       if (!(*pQuote))
  1215.         (*pDepth)--;
  1216.       break;
  1217.     case '\'':
  1218.       if (!((*pQuote) & 2))
  1219.         (*pQuote) ^= 1;
  1220.       break;
  1221.     case '"':
  1222.       if (!((*pQuote) & 1))
  1223.         (*pQuote) ^= 2;
  1224.       break;
  1225.   }
  1226. }
  1227.  
  1228. static Boolean DecodeIntelPseudo_LayoutMult(const tStrComp *pArg, struct sLayoutCtx *pCtx)
  1229. {
  1230.   int z, Depth, Len, LastNonBlank;
  1231.   Boolean OK, LastValid, Result;
  1232.   Byte Quote;
  1233.   const char *pDupFnd, *pRun;
  1234.   const tStrComp *pSaveComp;
  1235.  
  1236.   pSaveComp = pCtx->pCurrComp;
  1237.   pCtx->pCurrComp = pArg;
  1238.  
  1239.   /* search for DUP:
  1240.      - Exclude parts in parentheses, and parts in quotation marks.
  1241.      - Assure there is some (non-blank) token before DUP, so if there
  1242.        is e.g. a plain DUP as argument, it will not be interpreted as
  1243.        DUP operator. */
  1244.  
  1245.   Depth = Quote = 0;
  1246.   LastValid = FALSE;
  1247.   LastNonBlank = -1;
  1248.   pDupFnd = NULL; Len = strlen(pArg->str.p_str);
  1249.   for (pRun = pArg->str.p_str; pRun < pArg->str.p_str + Len - 2; pRun++)
  1250.   {
  1251.     DecodeIntelPseudo_HandleQuote(&Depth, &Quote, *pRun);
  1252.     if (!Depth && !Quote)
  1253.     {
  1254.       if (!LastValid
  1255.        && (LastNonBlank >= 0)
  1256.        && !DecodeIntelPseudo_ValidSymChar(pRun[3])
  1257.        && !as_strncasecmp(pRun, "DUP", 3))
  1258.       {
  1259.         pDupFnd = pRun;
  1260.         break;
  1261.       }
  1262.       if (!as_isspace(*pRun))
  1263.         LastNonBlank = pRun - pArg->str.p_str;
  1264.     }
  1265.     LastValid = DecodeIntelPseudo_ValidSymChar(*pRun);
  1266.   }
  1267.  
  1268.   /* found DUP: */
  1269.  
  1270.   if (pDupFnd)
  1271.   {
  1272.     LongInt DupCnt;
  1273.     char *pSep, *pRun;
  1274.     String CopyStr;
  1275.     tStrComp Copy, DupArg, RemArg, ThisRemArg;
  1276.     tCurrCodeFill DUPStartFill, DUPEndFill;
  1277.     tSymbolFlags Flags;
  1278.  
  1279.     /* operate on copy */
  1280.  
  1281.     StrCompMkTemp(&Copy, CopyStr, sizeof(CopyStr));
  1282.     StrCompCopy(&Copy, pArg);
  1283.     pSep = Copy.str.p_str + (pDupFnd - pArg->str.p_str);
  1284.  
  1285.     /* evaluate count */
  1286.  
  1287.     StrCompSplitRef(&DupArg, &RemArg, &Copy, pSep);
  1288.     DupCnt = EvalStrIntExpressionWithFlags(&DupArg, Int32, &OK, &Flags);
  1289.     if (mFirstPassUnknown(Flags))
  1290.     {
  1291.       WrStrErrorPos(ErrNum_FirstPassCalc, &DupArg); return False;
  1292.     }
  1293.     if (!OK)
  1294.     {
  1295.       Result = False;
  1296.       goto func_exit;
  1297.     }
  1298.  
  1299.     /* catch invalid counts */
  1300.  
  1301.     if (DupCnt <= 0)
  1302.     {
  1303.       if (DupCnt < 0)
  1304.         WrStrErrorPos(ErrNum_NegDUP, &DupArg);
  1305.       Result = True;
  1306.       goto func_exit;
  1307.     }
  1308.  
  1309.     /* split into parts and evaluate */
  1310.  
  1311.     StrCompIncRefLeft(&RemArg, 2);
  1312.     KillPrefBlanksStrCompRef(&RemArg);
  1313.     Len = strlen(RemArg.str.p_str);
  1314.     if ((Len >= 2) && (*RemArg.str.p_str == '(') && (RemArg.str.p_str[Len - 1] == ')'))
  1315.     {
  1316.       StrCompIncRefLeft(&RemArg, 1);
  1317.       StrCompShorten(&RemArg, 1);
  1318.       Len -= 2;
  1319.     }
  1320.     DUPStartFill = pCtx->CurrCodeFill;
  1321.     do
  1322.     {
  1323.       pSep = NULL; Quote = Depth = 0;
  1324.       for (pRun = RemArg.str.p_str; *pRun; pRun++)
  1325.       {
  1326.         DecodeIntelPseudo_HandleQuote(&Depth, &Quote, *pRun);
  1327.         if ((!Depth) && (!Quote) && (*pRun == ','))
  1328.         {
  1329.           pSep = pRun;
  1330.           break;
  1331.         }
  1332.       }
  1333.       if (pSep)
  1334.         StrCompSplitRef(&RemArg, &ThisRemArg, &RemArg, pSep);
  1335.       KillPrefBlanksStrCompRef(&RemArg);
  1336.       KillPostBlanksStrComp(&RemArg);
  1337.       if (!DecodeIntelPseudo_LayoutMult(&RemArg, pCtx))
  1338.       {
  1339.         Result = False;
  1340.         goto func_exit;
  1341.       }
  1342.       if (pSep)
  1343.         RemArg = ThisRemArg;
  1344.     }
  1345.     while (pSep);
  1346.     DUPEndFill = pCtx->CurrCodeFill;
  1347.  
  1348.     /* replicate result (data or reserve) */
  1349.  
  1350.     switch (pCtx->DSFlag)
  1351.     {
  1352.       case DSConstant:
  1353.         for (z = 1; z <= DupCnt - 1; z++)
  1354.           if (!pCtx->Replicate(&DUPStartFill, &DUPEndFill, pCtx))
  1355.           {
  1356.             Result = False;
  1357.             goto func_exit;
  1358.           }
  1359.         break;
  1360.       case DSSpace:
  1361.       {
  1362.         tCurrCodeFill Diff;
  1363.  
  1364.         SubCodeFill(&Diff, &DUPEndFill, &DUPStartFill, pCtx);
  1365.         MultCodeFill(&Diff, DupCnt - 1, pCtx);
  1366.         IncCodeFillBy(&pCtx->CurrCodeFill, &Diff, pCtx);
  1367.         break;
  1368.       }
  1369.       default:
  1370.         Result = False;
  1371.         goto func_exit;
  1372.     }
  1373.  
  1374.     Result = True;
  1375.   }
  1376.  
  1377.   /* no DUP: simple expression.  Differentiate space reservation & data disposition */
  1378.  
  1379.   else if (!strcmp(pArg->str.p_str, "?"))
  1380.   {
  1381.     Result = SetDSFlag(pCtx, DSSpace);
  1382.     if (Result)
  1383.       IncCodeFillBy(&pCtx->CurrCodeFill, &pCtx->FillIncPerElem, pCtx);
  1384.   }
  1385.  
  1386.   else
  1387.     Result = SetDSFlag(pCtx, DSConstant) && pCtx->LayoutFunc(pArg, pCtx);
  1388.  
  1389. func_exit:
  1390.   pCtx->pCurrComp = pSaveComp;
  1391.   return Result;
  1392. }
  1393.  
  1394. /*!------------------------------------------------------------------------
  1395.  * \fn     DecodeIntelDx(tLayoutCtx *pLayoutCtx)
  1396.  * \brief  Intel-style constant disposition
  1397.  * \param  pLayoutCtx layout infos & context
  1398.  * ------------------------------------------------------------------------ */
  1399.  
  1400. static void DecodeIntelDx(tLayoutCtx *pLayoutCtx)
  1401. {
  1402.   tStrComp *pArg;
  1403.   Boolean OK;
  1404.  
  1405.   pLayoutCtx->DSFlag = DSNone;
  1406.   pLayoutCtx->FullWordSize = Grans[ActPC];
  1407.   if ((pLayoutCtx->FullWordSize == 1) && !(pLayoutCtx->flags & eIntPseudoFlag_DECFormat))
  1408.     pLayoutCtx->ListGran = 1;
  1409.   else
  1410.     pLayoutCtx->ListGran = ActListGran;
  1411.   pLayoutCtx->ElemsPerFullWord = (8 * pLayoutCtx->FullWordSize) / pLayoutCtx->BaseElemLenBits;
  1412.   if (pLayoutCtx->ElemsPerFullWord > 1)
  1413.   {
  1414.     pLayoutCtx->FillIncPerElem.FullWordCnt = 0;
  1415.     pLayoutCtx->FillIncPerElem.LastWordFill = 1;
  1416.   }
  1417.   else
  1418.   {
  1419.     pLayoutCtx->FillIncPerElem.FullWordCnt = pLayoutCtx->BaseElemLenBits / (8 * pLayoutCtx->FullWordSize);
  1420.     pLayoutCtx->FillIncPerElem.LastWordFill = 0;
  1421.   }
  1422.  
  1423.   OK = True;
  1424.   forallargs(pArg, OK)
  1425.   {
  1426.     if (!*pArg->str.p_str)
  1427.     {
  1428.       OK = FALSE;
  1429.       WrStrErrorPos(ErrNum_EmptyArgument, pArg);
  1430.     }
  1431.     else
  1432.       OK = DecodeIntelPseudo_LayoutMult(pArg, pLayoutCtx);
  1433.   }
  1434.  
  1435.   /* Finalize: add optional padding if fractions of full words
  1436.      remain unused & set code length */
  1437.  
  1438.   if (OK)
  1439.   {
  1440.     if (pLayoutCtx->CurrCodeFill.LastWordFill)
  1441.     {
  1442.       WrError(ErrNum_PaddingAdded);
  1443.       pLayoutCtx->CurrCodeFill.LastWordFill = 0;
  1444.       pLayoutCtx->CurrCodeFill.FullWordCnt++;
  1445.     }
  1446.     CodeLen = pLayoutCtx->CurrCodeFill.FullWordCnt;
  1447.   }
  1448.  
  1449.   DontPrint = (pLayoutCtx->DSFlag == DSSpace);
  1450.   if (DontPrint)
  1451.   {
  1452.     BookKeeping();
  1453.     if (!CodeLen && OK) WrError(ErrNum_NullResMem);
  1454.   }
  1455.   if (OK)
  1456.     ActListGran = pLayoutCtx->ListGran;
  1457. }
  1458.  
  1459. /*!------------------------------------------------------------------------
  1460.  * \fn     DecodeIntelDN(Word Flags)
  1461.  * \brief  Intel-style constant disposition - nibbles
  1462.  * \param  Flags Data Type & Endianess Flags
  1463.  * ------------------------------------------------------------------------ */
  1464.  
  1465. void DecodeIntelDN(Word Flags)
  1466. {
  1467.   tLayoutCtx LayoutCtx;
  1468.  
  1469.   memset(&LayoutCtx, 0, sizeof(LayoutCtx));
  1470.   LayoutCtx.LayoutFunc = LayoutNibble;
  1471.   LayoutCtx.BaseElemLenBits = 4;
  1472.   switch (Grans[ActPC])
  1473.   {
  1474.     case 1:
  1475.       LayoutCtx.Put4I = Put4I_To_8;
  1476.       LayoutCtx.LoHiMap = (Flags & eIntPseudoFlag_BigEndian) ? 1 : 0;
  1477.       LayoutCtx.Replicate = Replicate4_To_8;
  1478.       break;
  1479.     case 2:
  1480.       LayoutCtx.Put4I = Put4I_To_16;
  1481.       LayoutCtx.LoHiMap = (Flags & eIntPseudoFlag_BigEndian) ? 3 : 0;
  1482.       LayoutCtx.Replicate = Replicate4_To_16;
  1483.       break;
  1484.   }
  1485.   DecodeIntelDx(&LayoutCtx);
  1486. }
  1487.  
  1488. /*!------------------------------------------------------------------------
  1489.  * \fn     DecodeIntelDB(Word BigEndian)
  1490.  * \brief  Intel-style constant disposition - bytes
  1491.  * \param  Flags Data Type & Endianess Flags
  1492.  * ------------------------------------------------------------------------ */
  1493.  
  1494. void DecodeIntelDB(Word Flags)
  1495. {
  1496.   tLayoutCtx LayoutCtx;
  1497.  
  1498.   memset(&LayoutCtx, 0, sizeof(LayoutCtx));
  1499.   LayoutCtx.LayoutFunc = LayoutByte;
  1500.   LayoutCtx.BaseElemLenBits = 8;
  1501.   LayoutCtx.flags = Flags;
  1502.   switch (Grans[ActPC])
  1503.   {
  1504.     case 1:
  1505.       LayoutCtx.Put8I = Put8I_To_8;
  1506.       LayoutCtx.Replicate = Replicate8ToN_To_8;
  1507.       break;
  1508.     case 2:
  1509.       LayoutCtx.Put8I = Put8I_To_16;
  1510.       LayoutCtx.LoHiMap = (Flags & eIntPseudoFlag_BigEndian) ? 1 : 0;
  1511.       LayoutCtx.Replicate = Replicate8_To_16;
  1512.       break;
  1513.   }
  1514.   if (*LabPart.str.p_str)
  1515.     SetSymbolOrStructElemSize(&LabPart, eSymbolSize8Bit);
  1516.   DecodeIntelDx(&LayoutCtx);
  1517. }
  1518.  
  1519. /*!------------------------------------------------------------------------
  1520.  * \fn     DecodeIntelDW(Word Flags)
  1521.  * \brief  Intel-style constant disposition - words
  1522.  * \param  Flags Data Type & Endianess Flags
  1523.  * ------------------------------------------------------------------------ */
  1524.  
  1525. void DecodeIntelDW(Word Flags)
  1526. {
  1527.   tLayoutCtx LayoutCtx;
  1528.  
  1529.   memset(&LayoutCtx, 0, sizeof(LayoutCtx));
  1530.   LayoutCtx.LayoutFunc = LayoutWord;
  1531.   LayoutCtx.BaseElemLenBits = 16;
  1532.   LayoutCtx.flags = Flags;
  1533.   switch (Grans[ActPC])
  1534.   {
  1535.     case 1:
  1536.       LayoutCtx.Put16I = (Flags & eIntPseudoFlag_AllowInt) ? Put16I_To_8 : NULL;
  1537.       LayoutCtx.Put16F = (Flags & eIntPseudoFlag_AllowFloat) ? Put16F_To_8 : NULL;
  1538.       LayoutCtx.LoHiMap = (Flags & eIntPseudoFlag_BigEndian) ? 1 : 0;
  1539.       LayoutCtx.Replicate = Replicate8ToN_To_8;
  1540.       break;
  1541.     case 2:
  1542.       LayoutCtx.Put16I = (Flags & eIntPseudoFlag_AllowInt) ? Put16I_To_16 : NULL;
  1543.       LayoutCtx.Put16F = (Flags & eIntPseudoFlag_AllowFloat) ? Put16F_To_16 : NULL;
  1544.       LayoutCtx.Replicate = Replicate16ToN_To_16;
  1545.       break;
  1546.   }
  1547.   if (*LabPart.str.p_str)
  1548.     SetSymbolOrStructElemSize(&LabPart, eSymbolSize16Bit);
  1549.   DecodeIntelDx(&LayoutCtx);
  1550. }
  1551.  
  1552. /*!------------------------------------------------------------------------
  1553.  * \fn     DecodeIntelDD(Word Flags)
  1554.  * \brief  Intel-style constant disposition - 32-bit words
  1555.  * \param  Flags Data Type & Endianess Flags
  1556.  * ------------------------------------------------------------------------ */
  1557.  
  1558. void DecodeIntelDD(Word Flags)
  1559. {
  1560.   tLayoutCtx LayoutCtx;
  1561.  
  1562.   memset(&LayoutCtx, 0, sizeof(LayoutCtx));
  1563.   LayoutCtx.LayoutFunc = LayoutDoubleWord;
  1564.   LayoutCtx.BaseElemLenBits = 32;
  1565.   LayoutCtx.flags = Flags;
  1566.   switch (Grans[ActPC])
  1567.   {
  1568.     case 1:
  1569.       LayoutCtx.Put32I = (Flags & eIntPseudoFlag_AllowInt) ? Put32I_To_8 : NULL;
  1570.       LayoutCtx.Put32F = (Flags & eIntPseudoFlag_AllowFloat) ? Put32F_To_8 : NULL;
  1571.       LayoutCtx.LoHiMap = (Flags & eIntPseudoFlag_BigEndian) ? 3 : 0;
  1572.       LayoutCtx.Replicate = Replicate8ToN_To_8;
  1573.       break;
  1574.     case 2:
  1575.       LayoutCtx.Put32I = (Flags & eIntPseudoFlag_AllowInt) ? Put32I_To_16 : NULL;
  1576.       LayoutCtx.Put32F = (Flags & eIntPseudoFlag_AllowFloat) ? Put32F_To_16 : NULL;
  1577.       LayoutCtx.LoHiMap = (Flags & eIntPseudoFlag_BigEndian) ? 1 : 0;
  1578.       LayoutCtx.Replicate = Replicate16ToN_To_16;
  1579.       break;
  1580.   }
  1581.   if (*LabPart.str.p_str)
  1582.     SetSymbolOrStructElemSize(&LabPart, eSymbolSize32Bit);
  1583.   DecodeIntelDx(&LayoutCtx);
  1584. }
  1585.  
  1586. /*!------------------------------------------------------------------------
  1587.  * \fn     DecodeIntelDM(Word Flags)
  1588.  * \brief  Intel-style constant disposition - 48-bit words
  1589.  * \param  Flags Data Type & Endianess Flags
  1590.  * ------------------------------------------------------------------------ */
  1591.  
  1592. void DecodeIntelDM(Word Flags)
  1593. {
  1594.   tLayoutCtx LayoutCtx;
  1595.  
  1596.   memset(&LayoutCtx, 0, sizeof(LayoutCtx));
  1597.   LayoutCtx.LayoutFunc = LayoutMacAddr;
  1598.   LayoutCtx.BaseElemLenBits = 48;
  1599.   LayoutCtx.flags = Flags;
  1600.   switch (Grans[ActPC])
  1601.   {
  1602.     case 1:
  1603.       LayoutCtx.Put48I = (Flags & eIntPseudoFlag_AllowInt) ? Put48I_To_8 : NULL;
  1604.       LayoutCtx.Put48F = (Flags & eIntPseudoFlag_AllowFloat) ? Put48F_To_8 : NULL;
  1605.       LayoutCtx.LoHiMap = (Flags & eIntPseudoFlag_BigEndian) ? 5 : 0;
  1606.       LayoutCtx.Replicate = Replicate8ToN_To_8;
  1607.       break;
  1608.     case 2:
  1609.       LayoutCtx.Put48I = (Flags & eIntPseudoFlag_AllowInt) ? Put48I_To_16 : NULL;
  1610.       LayoutCtx.Put48F = (Flags & eIntPseudoFlag_AllowFloat) ? Put48F_To_16 : NULL;
  1611.       LayoutCtx.LoHiMap = (Flags & eIntPseudoFlag_BigEndian) ? 2 : 0;
  1612.       LayoutCtx.Replicate = Replicate16ToN_To_16;
  1613.       break;
  1614.   }
  1615.   if (*LabPart.str.p_str)
  1616.     SetSymbolOrStructElemSize(&LabPart, eSymbolSize48Bit);
  1617.   DecodeIntelDx(&LayoutCtx);
  1618. }
  1619.  
  1620. /*!------------------------------------------------------------------------
  1621.  * \fn     DecodeIntelDQ(Word Flags)
  1622.  * \brief  Intel-style constant disposition - 64-bit words
  1623.  * \param  Flags Data Type & Endianess Flags
  1624.  * ------------------------------------------------------------------------ */
  1625.  
  1626. void DecodeIntelDQ(Word Flags)
  1627. {
  1628.   tLayoutCtx LayoutCtx;
  1629.  
  1630.   memset(&LayoutCtx, 0, sizeof(LayoutCtx));
  1631.   LayoutCtx.LayoutFunc = LayoutQuadWord;
  1632.   LayoutCtx.BaseElemLenBits = 64;
  1633.   LayoutCtx.flags = Flags;
  1634.   switch (Grans[ActPC])
  1635.   {
  1636.     case 1:
  1637.       LayoutCtx.Put64I = (Flags & eIntPseudoFlag_AllowInt) ? Put64I_To_8 : NULL;
  1638.       LayoutCtx.Put64F = (Flags & eIntPseudoFlag_AllowFloat) ? Put64F_To_8 : NULL;
  1639.       LayoutCtx.LoHiMap = (Flags & eIntPseudoFlag_BigEndian) ? 7 : 0;
  1640.       LayoutCtx.Replicate = Replicate8ToN_To_8;
  1641.       break;
  1642.     case 2:
  1643.       LayoutCtx.Put64I = (Flags & eIntPseudoFlag_AllowInt) ? Put64I_To_16 : NULL;
  1644.       LayoutCtx.Put64F = (Flags & eIntPseudoFlag_AllowFloat) ? Put64F_To_16 : NULL;
  1645.       LayoutCtx.LoHiMap = (Flags & eIntPseudoFlag_BigEndian) ? 3 : 0;
  1646.       LayoutCtx.Replicate = Replicate16ToN_To_16;
  1647.       break;
  1648.   }
  1649.   if (*LabPart.str.p_str)
  1650.     SetSymbolOrStructElemSize(&LabPart, eSymbolSize64Bit);
  1651.   DecodeIntelDx(&LayoutCtx);
  1652. }
  1653.  
  1654. /*!------------------------------------------------------------------------
  1655.  * \fn     DecodeIntelDT(Word Flags)
  1656.  * \brief  Intel-style constant disposition - 80-bit words
  1657.  * \param  Flags Data Type & Endianess Flags
  1658.  * ------------------------------------------------------------------------ */
  1659.  
  1660. void DecodeIntelDT(Word Flags)
  1661. {
  1662.   tLayoutCtx LayoutCtx;
  1663.  
  1664.   memset(&LayoutCtx, 0, sizeof(LayoutCtx));
  1665.   LayoutCtx.LayoutFunc = LayoutTenBytes;
  1666.   LayoutCtx.BaseElemLenBits = 80;
  1667.   LayoutCtx.flags = Flags;
  1668.   switch (Grans[ActPC])
  1669.   {
  1670.     case 1:
  1671.       LayoutCtx.Put80F = Put80F_To_8;
  1672.       LayoutCtx.LoHiMap = (Flags & eIntPseudoFlag_BigEndian) ? 1 : 0;
  1673.       LayoutCtx.Replicate = Replicate8ToN_To_8;
  1674.       break;
  1675.     case 2:
  1676.       LayoutCtx.Put80F = Put80F_To_16;
  1677.       LayoutCtx.LoHiMap = (Flags & eIntPseudoFlag_BigEndian) ? 1 : 0;
  1678.       LayoutCtx.Replicate = Replicate16ToN_To_16;
  1679.       break;
  1680.   }
  1681.   if (*LabPart.str.p_str)
  1682.     SetSymbolOrStructElemSize(&LabPart, eSymbolSize80Bit);
  1683.   DecodeIntelDx(&LayoutCtx);
  1684. }
  1685.  
  1686. /*!------------------------------------------------------------------------
  1687.  * \fn     DecodeIntelDS(Word item_size)
  1688.  * \brief  Intel-style memory reservation
  1689.  * \param  item_size # of bytes per reserved item
  1690.  * ------------------------------------------------------------------------ */
  1691.  
  1692. void DecodeIntelDS(Word item_size)
  1693. {
  1694.   if (ChkArgCnt(1, 1))
  1695.   {
  1696.     tSymbolFlags Flags;
  1697.     Boolean OK;
  1698.     LongInt HVal = EvalStrIntExpressionWithFlags(&ArgStr[1], Int32, &OK, &Flags);
  1699.  
  1700.     if (mFirstPassUnknown(Flags)) WrError(ErrNum_FirstPassCalc);
  1701.     else if (OK)
  1702.     {
  1703.       DontPrint = True;
  1704.       CodeLen = HVal * (LongInt)item_size;
  1705.       if (!HVal)
  1706.         WrError(ErrNum_NullResMem);
  1707.       BookKeeping();
  1708.     }
  1709.   }
  1710. }
  1711.  
  1712. /*!------------------------------------------------------------------------
  1713.  * \fn     DecodeIntelPseudo(Boolean BigEndian)
  1714.  * \brief  decode Intel-style pseudo instructions
  1715.  * \param  BigEndian target endianess
  1716.  * \return True if instruction found
  1717.  * ------------------------------------------------------------------------ */
  1718.  
  1719. Boolean DecodeIntelPseudo(Boolean BigEndian)
  1720. {
  1721.   static PInstTable InstTables[2] = { NULL, NULL };
  1722.   int Idx = !!BigEndian;
  1723.  
  1724.   if (!InstTables[Idx])
  1725.   {
  1726.     PInstTable InstTable = CreateInstTable(17);
  1727.     Word Flag = BigEndian ? eIntPseudoFlag_BigEndian : eIntPseudoFlag_None;
  1728.  
  1729.     AddInstTable(InstTable, "DN", Flag | eIntPseudoFlag_AllowInt, DecodeIntelDN);
  1730.     AddInstTable(InstTable, "DB", Flag | eIntPseudoFlag_AllowInt | eIntPseudoFlag_AllowString, DecodeIntelDB);
  1731.     AddInstTable(InstTable, "DW", Flag | eIntPseudoFlag_AllowInt | eIntPseudoFlag_AllowString | eIntPseudoFlag_AllowFloat, DecodeIntelDW);
  1732.     AddInstTable(InstTable, "DD", Flag | eIntPseudoFlag_AllowInt | eIntPseudoFlag_AllowString | eIntPseudoFlag_AllowFloat, DecodeIntelDD);
  1733.     AddInstTable(InstTable, "DQ", Flag | eIntPseudoFlag_AllowInt | eIntPseudoFlag_AllowString | eIntPseudoFlag_AllowFloat, DecodeIntelDQ);
  1734.     AddInstTable(InstTable, "DT", Flag | eIntPseudoFlag_AllowInt | eIntPseudoFlag_AllowString | eIntPseudoFlag_AllowFloat, DecodeIntelDT);
  1735.     AddInstTable(InstTable, "DS", 1, DecodeIntelDS);
  1736.     InstTables[Idx] = InstTable;
  1737.   }
  1738.   return LookupInstTable(InstTables[Idx], OpPart.str.p_str);
  1739. }
  1740.  
  1741. /*!------------------------------------------------------------------------
  1742.  * \fn     DecodeZ80SYNTAX(Word Code)
  1743.  * \brief  change Z80 syntax support for target
  1744.  * ------------------------------------------------------------------------ */
  1745.  
  1746. static void DecodeZ80SYNTAX(Word Code)
  1747. {
  1748.   UNUSED(Code);
  1749.  
  1750.   if (ChkArgCnt(1, 1))
  1751.   {
  1752.     tStrComp TmpComp;
  1753.  
  1754.     StrCompMkTemp(&TmpComp, Z80SyntaxName, 0);
  1755.     NLS_UpString(ArgStr[1].str.p_str);
  1756.     if (!as_strcasecmp(ArgStr[1].str.p_str, "OFF"))
  1757.     {
  1758.       CurrZ80Syntax = eSyntax808x;
  1759.       EnterIntSymbol(&TmpComp, 0, SegNone, True);
  1760.     }
  1761.     else if (!as_strcasecmp(ArgStr[1].str.p_str, "ON"))
  1762.     {
  1763.       CurrZ80Syntax = eSyntaxBoth;
  1764.       EnterIntSymbol(&TmpComp, 1, SegNone, True);
  1765.     }
  1766.     else if (!as_strcasecmp(ArgStr[1].str.p_str, "EXCLUSIVE"))
  1767.     {
  1768.       CurrZ80Syntax = eSyntaxZ80;
  1769.       EnterIntSymbol(&TmpComp, 2, SegNone, True);
  1770.     }
  1771.     else
  1772.       WrStrErrorPos(ErrNum_InvArg, &ArgStr[1]);
  1773.   }
  1774. }
  1775.  
  1776. /*!------------------------------------------------------------------------
  1777.  * \fn     ChkZ80Syntax(tZ80Syntax InstrSyntax)
  1778.  * \brief  check whether instruction's syntax (808x/Z80) fits to selected one
  1779.  * \param  InstrSyntax instruction syntax
  1780.  * \return True if all fine
  1781.  * ------------------------------------------------------------------------ */
  1782.  
  1783. Boolean ChkZ80Syntax(tZ80Syntax InstrSyntax)
  1784. {
  1785.   if ((InstrSyntax == eSyntax808x) && (!(CurrZ80Syntax & eSyntax808x)))
  1786.   {
  1787.     WrStrErrorPos(ErrNum_Z80SyntaxExclusive, &OpPart);
  1788.     return False;
  1789.   }
  1790.   else if ((InstrSyntax == eSyntaxZ80) && (!(CurrZ80Syntax & eSyntaxZ80)))
  1791.   {
  1792.     WrStrErrorPos(ErrNum_Z80SyntaxNotEnabled, &OpPart);
  1793.     return False;
  1794.   }
  1795.   else
  1796.     return True;
  1797. }
  1798.  
  1799. /*!------------------------------------------------------------------------
  1800.  * \fn     AddZ80Syntax(struct sInstTable *InstTable)
  1801.  * \brief  add Z80SYNTAX instruction to list & possibly set default
  1802.  * \param  InstTable table to add to
  1803.  * ------------------------------------------------------------------------ */
  1804.  
  1805. void AddZ80Syntax(struct sInstTable *InstTable)
  1806. {
  1807.   if (!onoff_test_and_set(e_onoff_reg_z80syntax))
  1808.   {
  1809.     tStrComp TmpComp;
  1810.  
  1811.     CurrZ80Syntax = eSyntax808x;
  1812.     StrCompMkTemp(&TmpComp, Z80SyntaxName, 0);
  1813.     EnterIntSymbol(&TmpComp, 0, SegNone, True);
  1814.   }
  1815.   AddInstTable(InstTable, "Z80SYNTAX", 0, DecodeZ80SYNTAX);
  1816. }
  1817.