Subversion Repositories pentevo

Rev

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

  1. /* code78k4.c */
  2. /*****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
  4. /*                                                                           */
  5. /* AS-Portierung                                                             */
  6. /*                                                                           */
  7. /* Codegenerator 78K4-Familie                                                */
  8. /*                                                                           */
  9. /*****************************************************************************/
  10.  
  11. #include "stdinc.h"
  12. #include <string.h>
  13. #include <ctype.h>
  14. #include <assert.h>
  15.  
  16. #include "bpemu.h"
  17. #include "strutil.h"
  18. #include "asmdef.h"
  19. #include "asmsub.h"
  20. #include "asmpars.h"
  21. #include "asmitree.h"
  22. #include "codepseudo.h"
  23. #include "intpseudo.h"
  24. #include "codevars.h"
  25. #include "headids.h"
  26. #include "errmsg.h"
  27.  
  28. #include "code78k4.h"
  29.  
  30. /*-------------------------------------------------------------------------*/
  31.  
  32. typedef enum
  33. {
  34.   ModNone = -1,
  35.   ModImm = 0,
  36.   ModReg8,
  37.   ModReg8_U16,
  38.   ModReg16,
  39.   ModReg24,
  40.   ModMem,
  41.   ModShort1,
  42.   ModShort2,
  43.   ModSFR,
  44.   ModAbs16,
  45.   ModAbs20,
  46.   ModAbs24,
  47.   ModShortIndir1_16,
  48.   ModShortIndir2_16,
  49.   ModShortIndir1_24,
  50.   ModShortIndir2_24,
  51.   ModSP,
  52.   ModSTBC,
  53.   ModWDM,
  54.   ModPSW  /* no associated mask, only used for PUSH/POP! */
  55. } tAdrMode;
  56.  
  57. typedef enum
  58. {
  59.   eBitTypePSW = 2,
  60.   eBitTypeAX = 3,
  61.   eBitTypeSAddr2_SFR = 4,
  62.   eBitTypeSAddr1 = 5,
  63.   eBitTypeAbs = 6,
  64.   eBitTypeMem = 13
  65. } tBitType;
  66.  
  67. typedef LongWord tAdrModeMask;
  68.  
  69. static const Word PSWLAddr = 0xfffe,
  70.                   PSWHAddr = 0xffff;
  71. static const ShortInt WHLReg = 3;
  72. static const LongWord Bit27 = ((LongWord)1) << 27;
  73.  
  74. static const tAdrModeMask MModImm = (1UL << ModImm),
  75.                           MModReg8 = (1UL << ModReg8),
  76.                           MModReg8_U16 = (1UL << ModReg8_U16),
  77.                           MModReg16 = (1UL << ModReg16),
  78.                           MModReg24 = (1UL << ModReg24),
  79.                           MModMem = (1UL << ModMem),
  80.                           MModShort1 = (1UL << ModShort1),
  81.                           MModShort2 = (1UL << ModShort2),
  82.                           MModSFR = (1UL << ModSFR),
  83.                           MModAbs16 = (1UL << ModAbs16),
  84.                           MModAbs20 = (1UL << ModAbs20),
  85.                           MModAbs24 = (1UL << ModAbs24),
  86.                           MModAbsAll = ((1UL << ModAbs16) | (1UL << ModAbs24)),
  87.                           MModShortIndir1_16 = (1UL << ModShortIndir1_16),
  88.                           MModShortIndir2_16 = (1UL << ModShortIndir2_16),
  89.                           MModShortIndir1_24 = (1UL << ModShortIndir1_24),
  90.                           MModShortIndir2_24 = (1UL << ModShortIndir2_24),
  91.                           MModShortIndir_All = ((1UL << ModShortIndir1_16) | (1UL << ModShortIndir2_16) | (1UL << ModShortIndir1_24) | (1UL << ModShortIndir2_24)),
  92.                           MModSP = (1UL << ModSP),
  93.                           MModSTBC = (1UL << ModSTBC),
  94.                           MModWDM = (1UL << ModWDM);
  95.  
  96. /*-------------------------------------------------------------------------*/
  97.  
  98. static CPUVar CPU784026;
  99.  
  100. typedef struct
  101. {
  102.   tAdrMode AdrMode;
  103.   ShortInt AdrVal;
  104.   int AdrCnt;
  105.   Byte AdrVals[4];
  106.   tSymbolFlags AdrValSymFlags;
  107.   Byte ForceRel;
  108.   Boolean ForceAbs;
  109. } tEncodedAddress;
  110.  
  111. static ShortInt OpSize;
  112. static Boolean AssumeByte;
  113.  
  114. static LongInt Reg_RSS, Reg_LOCATION;
  115. static ASSUMERec ASSUME78K4s[] =
  116. {
  117.   {"RSS"      , &Reg_RSS      , 0,  0x1,  0x0, NULL},
  118.   {"LOCATION" , &Reg_LOCATION , 0,  0xf,  0x0, NULL},
  119. };
  120.  
  121. /*-------------------------------------------------------------------------*/
  122. /* Address Decoders */
  123.  
  124. static Byte AccReg8(void)
  125. {
  126.   return Reg_RSS ? 5 : 1;
  127. }
  128.  
  129. static Byte BReg8(void)
  130. {
  131.   return Reg_RSS ? 7 : 3;
  132. }
  133.  
  134. static Byte CReg8(void)
  135. {
  136.   return Reg_RSS ? 6 : 2;
  137. }
  138.  
  139. static Byte AccReg16(void)
  140. {
  141.   return Reg_RSS ? 2 : 0;
  142. }
  143.  
  144. static Boolean SetOpSize(ShortInt NewSize)
  145. {
  146.   if (OpSize < 0)
  147.   {
  148.     OpSize = NewSize;
  149.     return True;
  150.   }
  151.   else if (OpSize != NewSize)
  152.   {
  153.     char Sizes[30];
  154.  
  155.     as_snprintf(Sizes, sizeof(Sizes), "%d<->%d",
  156.                 (int)((OpSize + 1) * 8), (int)((NewSize + 1) * 8));
  157.     WrXError(ErrNum_ConfOpSizes, Sizes);
  158.     return False;
  159.   }
  160.   else
  161.     return True;
  162. }
  163.  
  164. static void ClearEncodedAddress(tEncodedAddress *pAddress)
  165. {
  166.   pAddress->AdrMode = ModNone;
  167.   pAddress->AdrVal = 0;
  168.   pAddress->AdrCnt = 0;
  169.   pAddress->ForceAbs = 0;
  170.   pAddress->ForceRel = False;
  171. }
  172.  
  173. static ShortInt DecodeReg8(const char *pAsc)
  174. {
  175.   switch (strlen(pAsc))
  176.   {
  177.     case 1:
  178.     {
  179.       static const char Reg8Names[9] = "XACBEDLH";
  180.       const char *pPos = strchr(Reg8Names, as_toupper(*pAsc));
  181.  
  182.       if (pPos)
  183.       {
  184.         ShortInt Result = pPos - Reg8Names;
  185.         /* E/D/L/H maps to R12..R15 */
  186.         if (Result >= 4)
  187.           return Result + 8;
  188.         /* X/A/C/B maps to R4..7 if RSS=1 */
  189.         else if (Reg_RSS)
  190.           return Result + 4;
  191.         else
  192.           return Result;
  193.       }
  194.       else
  195.         return -1;
  196.     }
  197.  
  198.     case 2:
  199.       if ((toupper(pAsc[0]) == 'R') && isdigit(pAsc[1]))
  200.         return pAsc[1] - '0';
  201.       else
  202.         return -1;
  203.  
  204.     case 3:
  205.     {
  206.       static const char Reg8Names[][4] = { "VPL", "VPH", "UPL", "UPH", "R10", "R11", "R12", "R13", "R14", "R15", "" };
  207.       int z;
  208.  
  209.       for (z = 0; *Reg8Names[z]; z++)
  210.         if (!as_strcasecmp(pAsc, Reg8Names[z]))
  211.         {
  212.           /* map to 8..11 resp. 10..15 */
  213.           return (z > 4) ? z + 6 : z + 8;
  214.         }
  215.       return -1;
  216.     }
  217.  
  218.     default:
  219.       return -1;
  220.   }
  221. }
  222.  
  223. static ShortInt DecodeReg8_U16(const char *pAsc)
  224. {
  225.   static const char Reg8Names[5] = "VUTW";
  226.   const char *pPos;
  227.  
  228.   if (strlen(pAsc) != 1)
  229.     return -1;
  230.   pPos = strchr(Reg8Names, as_toupper(*pAsc));
  231.   return pPos ? pPos - Reg8Names : -1;
  232. }
  233.  
  234. static ShortInt DecodeReg16(const char *pAsc)
  235. {
  236.   ShortInt Result = -1;
  237.  
  238.   switch (strlen(pAsc))
  239.   {
  240.     case  2:
  241.     {
  242.       static const char Reg16Names[][3] = { "AX", "BC", "VP", "UP", "DE", "HL", "" };
  243.       int z;
  244.  
  245.       for (z = 0; *Reg16Names[z]; z++)
  246.         if (!as_strcasecmp(Reg16Names[z], pAsc))
  247.         {
  248.           Result = ((z >= 2) || Reg_RSS) ? z + 2 : z;
  249.           break;
  250.         }
  251.       break;
  252.     }
  253.  
  254.     case 3:
  255.     {
  256.       if ((toupper(pAsc[0]) == 'R') && (toupper(pAsc[1]) == 'P')
  257.        && (pAsc[2] >= '0') && (pAsc[2] <= '7'))
  258.         Result = pAsc[2] - '0';
  259.  
  260.       break;
  261.     }
  262.   }
  263.  
  264.   return Result;
  265. }
  266.  
  267. static ShortInt DecodeReg24(const char *pAsc)
  268. {
  269.   static const char Reg24Names[][4] = { "VVP", "UUP", "TDE", "WHL", "RG4", "RG5", "RG6", "RG7", "" };
  270.   int z;
  271.  
  272.   for (z = 0; *Reg24Names[z]; z++)
  273.     if (!as_strcasecmp(Reg24Names[z], pAsc))
  274.       return (z & 3);
  275.  
  276.   return -1;
  277. }
  278.  
  279. static Boolean DecodeRB(const char *pAsc, Byte *pErg)
  280. {
  281.   if ((strlen(pAsc) != 3) || (toupper(*pAsc) != 'R') || (toupper(pAsc[1]) != 'B') || (pAsc[2] < '0') || (pAsc[2] > '7'))
  282.     return False;
  283.   else
  284.   {
  285.     *pErg = pAsc[2] - '0';
  286.     return True;
  287.   }
  288. }
  289.  
  290. static void ExecAssumeByte(void)
  291. {
  292.   if ((OpSize == -1) && AssumeByte)
  293.   {
  294.     SetOpSize(0);
  295.     AssumeByte = False;
  296.   }
  297. }
  298.  
  299. static Boolean ChkSAddr1(LongWord Addr, Byte *pShortAddr)
  300. {
  301.   LongWord Start = 0xfe00 + (Reg_LOCATION << 16);
  302.  
  303.   if ((Addr & 0xffff00) == (Start & 0xffff00))
  304.   {
  305.     *pShortAddr = Addr & 0xff;
  306.     return True;
  307.   }
  308.   else
  309.     return False;
  310. }
  311.  
  312. static Boolean ChkSAddr2(LongWord Addr, Byte *pShortAddr)
  313. {
  314.   LongWord Start1 = 0xff00 + (Reg_LOCATION << 16),
  315.            Start2 = 0xfd00 + (Reg_LOCATION << 16);
  316.  
  317.   if ((Addr & 0xffffe0) == Start1)
  318.   {
  319.     *pShortAddr = Addr & 0x1f;
  320.     return True;
  321.   }
  322.   else if (((Addr & 0xffff00) == Start2) && (Lo(Addr) >= 0x20))
  323.   {
  324.     *pShortAddr = Addr & 0x1f;
  325.     return True;
  326.   }
  327.   else
  328.     return False;
  329. }
  330.  
  331. static Boolean ChkSFR(LongWord Addr, Byte *pShortAddr)
  332. {
  333.   LongWord Start = 0xff00 + (Reg_LOCATION << 16);
  334.  
  335.   if ((Addr & 0xffff00) == (Start & 0xffff00))
  336.   {
  337.     *pShortAddr = Addr & 0xff;
  338.     return True;
  339.   }
  340.   else
  341.     return False;
  342. }
  343.  
  344. static Boolean StripIndirect(tStrComp *pArg)
  345. {
  346.   int ArgLen = strlen(pArg->str.p_str);
  347.  
  348.   if ((ArgLen >= 2) && (*pArg->str.p_str == '[') && (pArg->str.p_str[ArgLen - 1] == ']'))
  349.   {
  350.     strmov(pArg->str.p_str, pArg->str.p_str + 1);
  351.     pArg->str.p_str[ArgLen - 2] = '\0';
  352.     pArg->Pos.StartCol++;
  353.     pArg->Pos.Len -= 2;
  354.     return True;
  355.   }
  356.   else
  357.     return False;
  358. }
  359.  
  360. static Boolean DecodeAdr(const tStrComp *pArg, tAdrModeMask AdrModeMask, tEncodedAddress *pAddress)
  361. {
  362.   int z, ArgLen;
  363.   LongWord Addr;
  364.   ShortInt AddrSize;
  365.   Boolean OK, Is16, IsShort1, IsShort2, IsSFR;
  366.   unsigned Offset;
  367.  
  368.   ClearEncodedAddress(pAddress);
  369.  
  370.   /* 8 bit Register? */
  371.  
  372.   if ((pAddress->AdrVal = DecodeReg8(pArg->str.p_str)) >= 0)
  373.   {
  374.     if (!SetOpSize(0))
  375.       return False;
  376.     pAddress->AdrMode = ModReg8;
  377.     goto AdrFound;
  378.   }
  379.  
  380.   if ((pAddress->AdrVal = DecodeReg8_U16(pArg->str.p_str)) >= 0)
  381.   {
  382.     if (!SetOpSize(0))
  383.       return False;
  384.     pAddress->AdrMode = ModReg8_U16;
  385.     goto AdrFound;
  386.   }
  387.  
  388.   if ((pAddress->AdrVal = DecodeReg16(pArg->str.p_str)) >= 0)
  389.   {
  390.     if (!SetOpSize(1))
  391.       return False;
  392.     pAddress->AdrMode = ModReg16;
  393.     goto AdrFound;
  394.   }
  395.  
  396.   if ((pAddress->AdrVal = DecodeReg24(pArg->str.p_str)) >= 0)
  397.   {
  398.     if (!SetOpSize(2))
  399.       return False;
  400.     pAddress->AdrMode = ModReg24;
  401.     goto AdrFound;
  402.   }
  403.  
  404.   if (!as_strcasecmp(pArg->str.p_str, "SP"))
  405.   {
  406.     if (!SetOpSize(2))
  407.       return False;
  408.     pAddress->AdrMode = ModSP;
  409.     goto AdrFound;
  410.   }
  411.  
  412.   if (!as_strcasecmp(pArg->str.p_str, "STBC"))
  413.   {
  414.     if (!SetOpSize(0))
  415.       return False;
  416.     pAddress->AdrMode = ModSTBC;
  417.     goto AdrFound;
  418.   }
  419.  
  420.   if (!as_strcasecmp(pArg->str.p_str, "WDM"))
  421.   {
  422.     if (!SetOpSize(0))
  423.       return False;
  424.     pAddress->AdrMode = ModWDM;
  425.     goto AdrFound;
  426.   }
  427.  
  428.   /* immediate ? */
  429.  
  430.   if (*pArg->str.p_str == '#')
  431.   {
  432.     ExecAssumeByte();
  433.     if ((OpSize >= 0) && (OpSize < 3))
  434.     {
  435.       static const IntType IntTypes[3] = { Int8, Int16, Int24 };
  436.       Boolean OK;
  437.       LongWord Value = EvalStrIntExpressionOffs(pArg, 1, IntTypes[OpSize], &OK);
  438.       if (OK)
  439.       {
  440.         ShortInt z;
  441.  
  442.         for (z = 0; z <= OpSize; z++)
  443.         {
  444.           pAddress->AdrVals[pAddress->AdrCnt++] = Value & 0xff;
  445.           Value >>= 8;
  446.         }
  447.         pAddress->AdrMode = ModImm;
  448.       }
  449.     }
  450.     else
  451.       WrError(ErrNum_UndefOpSizes);
  452.     goto AdrFound;
  453.   }
  454.  
  455.   /* memory-indirect addressing? */
  456.  
  457.   ArgLen = strlen(pArg->str.p_str);
  458.   if ((ArgLen >= 2) && (pArg->str.p_str[ArgLen - 1] == ']'))
  459.   {
  460.     String Asc;
  461.     tStrComp Arg;
  462.     char *pStart;
  463.  
  464.     StrCompMkTemp(&Arg, Asc, sizeof(Asc));
  465.     StrCompCopy(&Arg, pArg);
  466.  
  467.     /* remove ']' */
  468.  
  469.     StrCompShorten(&Arg, 1);
  470.  
  471.     pStart = RQuotPos(Arg.str.p_str, '[');
  472.     if (!pStart)
  473.     {
  474.       WrError(ErrNum_BrackErr);
  475.       goto AdrFound;
  476.     }
  477.  
  478.     /* purely indirect? */
  479.  
  480.     if (pStart == Arg.str.p_str)
  481.     {
  482.       static const char Modes[][5] = { "TDE+", "WHL+", "TDE-", "WHL-", "TDE", "WHL", "VVP", "UUP",
  483.                                        "RG6+", "RG7+", "RG6-", "RG7-", "RG6", "RG7", "RG4", "RG5" };
  484.       unsigned z;
  485.       char *pSep, Save;
  486.       tStrComp Base, Remainder;
  487.  
  488.       /* skip '[' */
  489.  
  490.       StrCompCutLeft(&Arg, 1);
  491.  
  492.       /* simple expression without displacement? */
  493.  
  494.       for (z = 0; z < sizeof(Modes) / sizeof(*Modes); z++)
  495.         if (!as_strcasecmp(Arg.str.p_str, Modes[z]))
  496.         {
  497.           pAddress->AdrMode = ModMem;
  498.           pAddress->AdrVal = 0x16;
  499.           pAddress->AdrVals[0] = z % (sizeof(Modes) / sizeof(*Modes) / 2);
  500.           pAddress->AdrCnt = 1;
  501.           goto AdrFound;
  502.         }
  503.  
  504.       /* no -> extract base register. Its name ends with the first non-letter,
  505.          which either means +/- or a blank */
  506.  
  507.       for (pSep = Arg.str.p_str; *pSep; pSep++)
  508.         if (!as_isalpha(*pSep))
  509.           break;
  510.  
  511.       /* decode base register.  SP is not otherwise handled. */
  512.  
  513.       Save = StrCompSplitRef(&Base, &Remainder, &Arg, pSep);
  514.       if (!as_strcasecmp(Base.str.p_str, "SP"))
  515.         pAddress->AdrVals[0] = 1;
  516.       else
  517.       {
  518.         int tmp;
  519.  
  520.         tmp = DecodeReg24(Base.str.p_str);
  521.         switch (tmp)
  522.         {
  523.           case -1: pAddress->AdrVals[0] = 0xff; break; /* no register */
  524.           case 0: pAddress->AdrVals[0] = 4; break; /* VVP */
  525.           case 1: pAddress->AdrVals[0] = 3; break; /* UUP */
  526.           case 2: pAddress->AdrVals[0] = 0; break; /* TDE */
  527.           case 3: pAddress->AdrVals[0] = 2; break; /* WHL */
  528.           default:
  529.             WrStrErrorPos(ErrNum_InvReg, &Base);
  530.             goto AdrFound;
  531.         }
  532.       }
  533.       *pSep = Save;
  534.  
  535.       /* no base register detected: purely indirect */
  536.  
  537.       if (0xff == pAddress->AdrVals[0])
  538.       {
  539.         unsigned Is24 = !!(*Arg.str.p_str == '%');
  540.         tSymbolFlags Flags;
  541.  
  542.         Addr = EvalStrIntExpressionOffsWithFlags(&Arg, Is24, UInt24, &OK, &Flags);
  543.         if (OK)
  544.         {
  545.           if (mFirstPassUnknown(Flags))
  546.             Addr = 0xfe20 + (Reg_LOCATION << 16);
  547.           if (ChkSAddr1(Addr, &pAddress->AdrVals[0]))
  548.             pAddress->AdrMode = Is24 ? ModShortIndir1_24 : ModShortIndir1_16;
  549.           if (ChkSAddr2(Addr, &pAddress->AdrVals[0]))
  550.             pAddress->AdrMode = Is24 ? ModShortIndir2_24 : ModShortIndir2_16;
  551.         }
  552.         goto AdrFound;
  553.       }
  554.  
  555.       /* Now that we have the base, prepare displacement.  May
  556.          be an 8/16-bit register in certain combinations, or a number: */
  557.  
  558.       if (*pSep == '+')
  559.       {
  560.         int tmp;
  561.  
  562.         tmp = DecodeReg8(pSep + 1);
  563.         if (tmp == -1); /* no reg at all, go on with 16-bit reg below */
  564.         else if ((tmp == AccReg8()) && (pAddress->AdrVals[0] == 0)) /* TDE + A */
  565.         {
  566.           pAddress->AdrMode = ModMem;
  567.           pAddress->AdrVal = 0x17;
  568.           pAddress->AdrCnt = 1;
  569.           pAddress->AdrVals[0] = 0;
  570.           goto AdrFound;
  571.         }
  572.         else if ((tmp == BReg8()) && (pAddress->AdrVals[0] == 0)) /* TDE + B */
  573.         {
  574.           pAddress->AdrMode = ModMem;
  575.           pAddress->AdrVal = 0x17;
  576.           pAddress->AdrCnt = 1;
  577.           pAddress->AdrVals[0] = 2;
  578.           goto AdrFound;
  579.         }
  580.         else if ((tmp == CReg8()) && (pAddress->AdrVals[0] == 0)) /* TDE + C */
  581.         {
  582.           pAddress->AdrMode = ModMem;
  583.           pAddress->AdrVal = 0x17;
  584.           pAddress->AdrCnt = 1;
  585.           pAddress->AdrVals[0] = 6;
  586.           goto AdrFound;
  587.         }
  588.         else if ((tmp == AccReg8()) && (pAddress->AdrVals[0] == 2)) /* WHL + A */
  589.         {
  590.           pAddress->AdrMode = ModMem;
  591.           pAddress->AdrVal = 0x17;
  592.           pAddress->AdrCnt = 1;
  593.           pAddress->AdrVals[0] = 1;
  594.           goto AdrFound;
  595.         }
  596.         else if ((tmp == BReg8()) && (pAddress->AdrVals[0] == 2)) /* WHL + B */
  597.         {
  598.           pAddress->AdrMode = ModMem;
  599.           pAddress->AdrVal = 0x17;
  600.           pAddress->AdrCnt = 1;
  601.           pAddress->AdrVals[0] = 3;
  602.           goto AdrFound;
  603.         }
  604.         else if ((tmp == CReg8()) && (pAddress->AdrVals[0] == 2)) /* WHL + C */
  605.         {
  606.           pAddress->AdrMode = ModMem;
  607.           pAddress->AdrVal = 0x17;
  608.           pAddress->AdrCnt = 1;
  609.           pAddress->AdrVals[0] = 7;
  610.           goto AdrFound;
  611.         }
  612.         else
  613.         {
  614.           WrError(ErrNum_InvAddrMode);
  615.           goto AdrFound;
  616.         }
  617.         tmp = DecodeReg16(pSep + 1);
  618.         switch (tmp)
  619.         {
  620.           case -1: /* no reg at all */
  621.             break;
  622.           case 6: /* DE */
  623.           case 7: /* HL */
  624.             if (pAddress->AdrVals[0] == 4) /* VVP+DE/HL */
  625.             {
  626.               pAddress->AdrMode = ModMem;
  627.               pAddress->AdrVal = 0x17;
  628.               pAddress->AdrCnt = 1;
  629.               pAddress->AdrVals[0] = tmp - 2;
  630.               goto AdrFound;
  631.             }
  632.             /* fall-through */
  633.           default:
  634.             WrError(ErrNum_InvAddrMode);
  635.             goto AdrFound;
  636.         }
  637.       }
  638.  
  639.       /* it's a number: put a fake 0 in front so displacement expression evaluates correctly! */
  640.  
  641.       if (pSep > Arg.str.p_str)
  642.         pSep--;
  643.       *pSep = '0';
  644.       pAddress->AdrVals[1] = EvalStrIntExpressionOffs(&Arg, pSep - Arg.str.p_str, Int8, &OK);
  645.       if (OK)
  646.       {
  647.         pAddress->AdrMode = ModMem;
  648.         pAddress->AdrVal = 0x06;
  649.         pAddress->AdrCnt = 2;
  650.         goto AdrFound;
  651.       }
  652.     }
  653.  
  654.     /* no -> with outer displacement */
  655.  
  656.     else
  657.     {
  658.       tStrComp RegArg, DispArg;
  659.       int tmp;
  660.  
  661.       /* split displacement + register */
  662.  
  663.       StrCompSplitRef(&DispArg, &RegArg, &Arg, pStart);
  664.  
  665.        /* handle base register */
  666.  
  667.       tmp = DecodeReg8(RegArg.str.p_str);
  668.       if ((tmp == AccReg8()) /* A */
  669.        || (tmp == BReg8())) /* B */
  670.       {
  671.         pAddress->AdrVals[0] = tmp & 3;
  672.       }
  673.       else if (tmp == -1)
  674.       {
  675.         tmp = DecodeReg16(RegArg.str.p_str);
  676.         if (tmp >= 6) /* DE/HL */
  677.         {
  678.           pAddress->AdrVals[0] = (tmp - 6) << 1;
  679.         }
  680.         else
  681.         {
  682.           WrStrErrorPos(ErrNum_InvReg, &RegArg);
  683.           goto AdrFound;
  684.         }
  685.       }
  686.       else
  687.       {
  688.         WrStrErrorPos(ErrNum_InvReg, &RegArg);
  689.         goto AdrFound;
  690.       }
  691.  
  692.       /* compute displacement */
  693.  
  694.       Addr = EvalStrIntExpression(&DispArg, Int24, &OK);
  695.       if (OK)
  696.       {
  697.         pAddress->AdrMode = ModMem;
  698.         pAddress->AdrVal = 0x0a;
  699.         pAddress->AdrVals[1] = (Addr >>  0) & 0xff;
  700.         pAddress->AdrVals[2] = (Addr >>  8) & 0xff;
  701.         pAddress->AdrVals[3] = (Addr >> 16) & 0xff;
  702.         pAddress->AdrCnt = 4;
  703.         goto AdrFound;
  704.       }
  705.     }
  706.   } /* indirect */
  707.  
  708.   /* absolute: */
  709.  
  710.   Offset = 0;
  711.   if (pArg->str.p_str[Offset] == '$')
  712.   {
  713.     pAddress->ForceRel = True;
  714.     Offset++;
  715.   }
  716.   for (AddrSize = 0, z = 0; z < 2; z++)
  717.     if (pArg->str.p_str[Offset] == '!')
  718.     {
  719.       AddrSize++;
  720.       Offset++;
  721.       pAddress->ForceAbs++;
  722.     }
  723.   Addr = EvalStrIntExpressionOffsWithFlags(pArg, Offset, (AdrModeMask & MModAbs20) ? UInt20 : UInt24, &OK, &pAddress->AdrValSymFlags);
  724.   if (!OK)
  725.     return False;
  726.  
  727.   IsShort1 = ChkSAddr1(Addr, &pAddress->AdrVals[0]);
  728.   IsShort2 = ChkSAddr2(Addr, &pAddress->AdrVals[1]);
  729.   IsSFR = ChkSFR(Addr, &pAddress->AdrVals[2]);
  730.   Is16 = Addr <= 0xffff;
  731.  
  732.   if (!AddrSize)
  733.   {
  734.     if (!IsShort1 && !IsShort2 && !IsSFR && !Is16 && (AdrModeMask & (MModAbs24 | MModAbs20)))
  735.       AddrSize = 2;
  736.     else if (!IsShort1 && !IsShort2 && !IsSFR && Is16 && (!(AdrModeMask & MModAbs16)))
  737.       AddrSize = 2;
  738.     else if (!IsShort1 && !IsShort2 && !IsSFR && (AdrModeMask & MModAbs16))
  739.       AddrSize = 1;
  740.   }
  741.  
  742.   switch (AddrSize)
  743.   {
  744.     case 2:
  745.       pAddress->AdrMode = (AdrModeMask & MModAbs20) ? ModAbs20 : ModAbs24;
  746.       pAddress->AdrVals[pAddress->AdrCnt++] = (Addr >>  0) & 0xff;
  747.       pAddress->AdrVals[pAddress->AdrCnt++] = (Addr >>  8) & 0xff;
  748.       pAddress->AdrVals[pAddress->AdrCnt++] = (Addr >> 16) & 0xff;
  749.       break;
  750.     case 1:
  751.       if (!Is16 && mFirstPassUnknown(pAddress->AdrValSymFlags))
  752.       {
  753.         Addr &= 0xffff;
  754.         Is16 = True;
  755.       }
  756.       if (Is16)
  757.       {
  758.         pAddress->AdrMode = ModAbs16;
  759.         pAddress->AdrVals[pAddress->AdrCnt++] = (Addr >>  0) & 0xff;
  760.         pAddress->AdrVals[pAddress->AdrCnt++] = (Addr >>  8) & 0xff;
  761.       }
  762.       else
  763.         WrError(ErrNum_OverRange);
  764.       break;
  765.     case 0:
  766.       if (IsShort1)
  767.       {
  768.         pAddress->AdrMode = ModShort1;
  769.         pAddress->AdrCnt++;
  770.       }
  771.       else if (IsShort2)
  772.       {
  773.         pAddress->AdrMode = ModShort2;
  774.         pAddress->AdrVals[pAddress->AdrCnt++] = pAddress->AdrVals[1];
  775.       }
  776.       else if (IsSFR)
  777.       {
  778.         pAddress->AdrMode = ModSFR;
  779.         pAddress->AdrVals[pAddress->AdrCnt++] = pAddress->AdrVals[2];
  780.       }
  781.       else if (mFirstPassUnknown(pAddress->AdrValSymFlags))
  782.       {
  783.         if (AdrModeMask & MModShort1)
  784.         {
  785.           pAddress->AdrMode = ModShort1;
  786.           pAddress->AdrVals[pAddress->AdrCnt++] = Lo(Addr);
  787.         }
  788.         else if (AdrModeMask & MModShort2)
  789.         {
  790.           pAddress->AdrMode = ModShort2;
  791.           pAddress->AdrVals[pAddress->AdrCnt++] = Lo(Addr);
  792.         }
  793.         else if (AdrModeMask & MModSFR)
  794.         {
  795.           pAddress->AdrMode = ModSFR;
  796.           pAddress->AdrVals[pAddress->AdrCnt++] = Lo(Addr);
  797.         }
  798.         else
  799.           WrError(ErrNum_InvAddrMode);
  800.       }
  801.       else
  802.         WrError(ErrNum_OverRange);
  803.       break;
  804.   }
  805.  
  806. AdrFound:
  807.   if ((pAddress->AdrMode != ModNone) && (!(AdrModeMask & (1UL << pAddress->AdrMode))))
  808.   {
  809.     WrError(ErrNum_InvAddrMode);
  810.     ClearEncodedAddress(pAddress);
  811.     return False;
  812.   }
  813.   return True;
  814. }
  815.  
  816. static Boolean DecodeMem3(const char *pAsc, Byte *pResult)
  817. {
  818.   int l = strlen(pAsc);
  819.   char Reg[10];
  820.   ShortInt BinReg;
  821.  
  822.   if ((l < 3) || (l > 5) || (pAsc[0] != '[') || (pAsc[l - 1] != ']'))
  823.     return False;
  824.   memcpy(Reg, pAsc + 1, l - 2);
  825.   Reg[l - 2] = '\0';
  826.   BinReg = DecodeReg16(Reg);
  827.   if ((BinReg >= 0) && (BinReg <= 3))
  828.   {
  829.     *pResult = (BinReg << 1);
  830.     return True;
  831.   }
  832.   BinReg = DecodeReg24(Reg);
  833.   if ((BinReg >= 0) && (BinReg <= 3))
  834.   {
  835.     *pResult = (BinReg << 1) | 1;
  836.     return True;
  837.   }
  838.   return False;
  839. }
  840.  
  841. static void AppendAdrVals(const tEncodedAddress *pAddress)
  842. {
  843.   /* weird byte order for !!abs24: */
  844.  
  845.   if (pAddress->AdrMode == ModAbs24)
  846.   {
  847.     BAsmCode[CodeLen++] = pAddress->AdrVals[2];
  848.     BAsmCode[CodeLen++] = pAddress->AdrVals[0];
  849.     BAsmCode[CodeLen++] = pAddress->AdrVals[1];
  850.   }
  851.   else
  852.   {
  853.     memcpy(BAsmCode + CodeLen, pAddress->AdrVals, pAddress->AdrCnt);
  854.     CodeLen += pAddress->AdrCnt;
  855.   }
  856. }
  857.  
  858. static void AppendAdrValsMem(const tEncodedAddress *pAddress, Byte LowNibble)
  859. {
  860.   AppendAdrVals(pAddress);
  861.   BAsmCode[CodeLen - pAddress->AdrCnt] = (BAsmCode[CodeLen - pAddress->AdrCnt] << 4) | LowNibble;
  862. }
  863.  
  864. static Byte ModShortVal(tAdrMode AdrMode)
  865. {
  866.   switch (AdrMode)
  867.   {
  868.     case ModShort2:
  869.       return 0;
  870.     case ModShort1:
  871.       return 1;
  872.     case ModSFR:
  873.       return 2;
  874.     default:
  875.       return 255;
  876.   }
  877. }
  878.  
  879. static LongWord GetAbsVal(const tEncodedAddress *pAddress)
  880. {
  881.   LongWord Result = 0;
  882.  
  883.   switch (pAddress->AdrMode)
  884.   {
  885.     case ModAbs24:
  886.     case ModAbs20:
  887.       Result |= (((LongWord)pAddress->AdrVals[2]) << 16);
  888.       /* fall-through */
  889.     case ModAbs16:
  890.       Result |= (((LongWord)pAddress->AdrVals[1]) <<  8);
  891.       Result |= (((LongWord)pAddress->AdrVals[0]) <<  0);
  892.       return Result;
  893.     default:
  894.       return 0xfffffffful;
  895.   }
  896. }
  897.  
  898. static Byte ModIs24(tAdrMode AdrMode)
  899. {
  900.   switch (AdrMode)
  901.   {
  902.     case ModAbs24:
  903.     case ModShortIndir1_24:
  904.     case ModShortIndir2_24:
  905.       return 1;
  906.     case ModAbs16:
  907.     case ModShortIndir1_16:
  908.     case ModShortIndir2_16:
  909.       return 0;
  910.     default:
  911.       return 0xff;
  912.   }
  913. }
  914.  
  915. static Byte ModIsShort1(tAdrMode AdrMode)
  916. {
  917.   switch (AdrMode)
  918.   {
  919.     case ModShort1:
  920.     case ModShortIndir1_24:
  921.     case ModShortIndir1_16:
  922.       return 1;
  923.     case ModShort2:
  924.     case ModShortIndir2_24:
  925.     case ModShortIndir2_16:
  926.       return 0;
  927.     default:
  928.       return 0xff;
  929.   }
  930. }
  931.  
  932. static Boolean DecodeBitAdr(const tStrComp *pArg, LongWord *pResult)
  933. {
  934.   char *pSplit;
  935.   Boolean OK;
  936.  
  937.   pSplit = RQuotPos(pArg->str.p_str, '.');
  938.  
  939.   if (pSplit)
  940.   {
  941.     tEncodedAddress Addr;
  942.     tStrComp AddrArg, BitArg;
  943.  
  944.     StrCompSplitRef(&AddrArg, &BitArg, pArg, pSplit);
  945.     *pResult = EvalStrIntExpression(&BitArg, UInt3, &OK) << 24;
  946.     if (OK)
  947.     {
  948.       DecodeAdr(&AddrArg, MModReg8 | MModSFR | MModShort1 | MModShort2 | MModMem | MModAbsAll, &Addr);
  949.       switch (Addr.AdrMode)
  950.       {
  951.         case ModReg8:
  952.           if ((Addr.AdrVal != AccReg8()) && (Addr.AdrVal != AccReg8() - 1))
  953.           {
  954.             WrStrErrorPos(ErrNum_InvReg, &AddrArg);
  955.             OK = FALSE;
  956.           }
  957.           else
  958.           {
  959.             *pResult |= (((LongWord)eBitTypeAX) << 28);
  960.             if (Addr.AdrVal & 1)
  961.               *pResult |= Bit27;
  962.           }
  963.           break;
  964.         case ModSFR:
  965.           if (Addr.AdrVals[0] == (PSWLAddr & 0xff))
  966.             *pResult |= ((LongWord)eBitTypePSW) << 28;
  967.           else if (Addr.AdrVals[0] == (PSWHAddr & 0xff))
  968.             *pResult |= (((LongWord)eBitTypePSW) << 28) | Bit27;
  969.           else
  970.             *pResult |= Addr.AdrVals[0]
  971.                      | (((LongWord)eBitTypeSAddr2_SFR) << 28)
  972.                      | Bit27;
  973.           break;
  974.         case ModShort1:
  975.           *pResult |= Addr.AdrVals[0]
  976.                    | (((LongWord)eBitTypeSAddr1) << 28);
  977.           break;
  978.         case ModShort2:
  979.           *pResult |= Addr.AdrVals[0]
  980.                    | (((LongWord)eBitTypeSAddr2_SFR) << 28);
  981.           break;
  982.         case ModMem:
  983.           if ((Addr.AdrVal != 0x16) || ((Addr.AdrVals[0] & 0x0e) != 4))
  984.           {
  985.             OK = False;
  986.             WrError(ErrNum_InvAddrMode);
  987.           }
  988.           else
  989.           {
  990.             *pResult |= (((LongWord)eBitTypeMem) << 28);
  991.             if (Addr.AdrVals[0] & 1)
  992.               *pResult |= Bit27;
  993.           }
  994.           break;
  995.         case ModAbs16:
  996.         case ModAbs24:
  997.           *pResult |= ((LongWord)eBitTypeAbs) << 28;
  998.           *pResult |= ((LongWord)Addr.AdrVals[0]) << 0;
  999.           *pResult |= ((LongWord)Addr.AdrVals[1]) << 8;
  1000.           if (Addr.AdrMode == ModAbs24)
  1001.           {
  1002.             *pResult |= Bit27;
  1003.             *pResult |= ((LongWord)Addr.AdrVals[2]) << 16;
  1004.           }
  1005.           break;
  1006.         default:
  1007.           OK = FALSE;
  1008.       }
  1009.     }
  1010.   }
  1011.   else
  1012.     *pResult = EvalStrIntExpression(pArg, UInt32, &OK);
  1013.  
  1014.   return OK;
  1015. }
  1016.  
  1017. static void AppendRel8(const tStrComp *pArg)
  1018. {
  1019.   Boolean OK;
  1020.   LongInt Dist;
  1021.   tSymbolFlags Flags;
  1022.  
  1023.   Dist = EvalStrIntExpressionOffsWithFlags(pArg, !!(*pArg->str.p_str == '$'), UInt20, &OK, &Flags) - (EProgCounter() + CodeLen + 1);
  1024.   if (!OK) CodeLen = 0;
  1025.   else if (!mSymbolQuestionable(Flags) && ((Dist < -0x80) || (Dist > 0x7f)))
  1026.   {
  1027.     WrError(ErrNum_JmpDistTooBig);
  1028.     CodeLen = 0;
  1029.   }
  1030.   else
  1031.     BAsmCode[CodeLen++] = Dist & 0xff;
  1032. }
  1033.  
  1034. /*-------------------------------------------------------------------------*/
  1035. /* Instruction Decoders */
  1036.  
  1037. static void PutCode(Word Code)
  1038. {
  1039.   if (Hi(Code))
  1040.     BAsmCode[CodeLen++] = Hi(Code);
  1041.   BAsmCode[CodeLen++] = Lo(Code);
  1042. }
  1043.  
  1044. static void DecodeFixed(Word Code)
  1045. {
  1046.   if (ChkArgCnt(0, 0))
  1047.     PutCode(Code);
  1048. }
  1049.  
  1050. static void DecodeBitOpCore2(LongWord BitAddr, Word Code)
  1051. {
  1052.   switch ((BitAddr >> 28) & 15)
  1053.   {
  1054.     case eBitTypePSW:
  1055.     case eBitTypeAX:
  1056.       BAsmCode[CodeLen++] = (BitAddr >> 28) & 15;
  1057.       BAsmCode[CodeLen++] = Code | ((BitAddr >> 24) & 15);
  1058.       break;
  1059.     case eBitTypeSAddr1:
  1060.       BAsmCode[CodeLen++] = 0x3c;
  1061.       /* fall-through */
  1062.     case eBitTypeSAddr2_SFR:
  1063.       BAsmCode[CodeLen++] = 0x08;
  1064.       BAsmCode[CodeLen++] = Code | ((BitAddr >> 24) & 15);
  1065.       BAsmCode[CodeLen++] = Lo(BitAddr);
  1066.       break;
  1067.     case eBitTypeMem:
  1068.       BAsmCode[CodeLen++] = 0x3d;
  1069.       BAsmCode[CodeLen++] = Code | ((BitAddr >> 24) & 15);
  1070.       break;
  1071.     case eBitTypeAbs:
  1072.       BAsmCode[CodeLen++] = 0x09;
  1073.       BAsmCode[CodeLen++] = 0xd0;
  1074.       BAsmCode[CodeLen++] = Code | ((BitAddr >> 24) & 15);
  1075.       if (BAsmCode[CodeLen - 1] & 0x08)
  1076.         BAsmCode[CodeLen++] = (BitAddr >> 16) & 255;
  1077.       BAsmCode[CodeLen++] = (BitAddr >> 0) & 255;
  1078.       BAsmCode[CodeLen++] = (BitAddr >> 8) & 255;
  1079.       break;
  1080.     default:
  1081.       WrError(ErrNum_InvAddrMode);
  1082.   }
  1083. }
  1084.  
  1085. static void DecodeBitOpCore(const tStrComp *pBitArg, Word Code)
  1086. {
  1087.   LongWord BitAddr;
  1088.  
  1089.   if (!DecodeBitAdr(pBitArg, &BitAddr))
  1090.     return;
  1091.   DecodeBitOpCore2(BitAddr, Code);
  1092. }
  1093.  
  1094. static void DecodeMOV1(Word Code)
  1095. {
  1096.   UNUSED(Code);
  1097.  
  1098.   if (!ChkArgCnt(2, 2))
  1099.     return;
  1100.   if (!as_strcasecmp(ArgStr[1].str.p_str, "CY"))
  1101.     DecodeBitOpCore(&ArgStr[2], 0x00);
  1102.   else if (!as_strcasecmp(ArgStr[2].str.p_str, "CY"))
  1103.     DecodeBitOpCore(&ArgStr[1], 0x10);
  1104.   else
  1105.   {
  1106.     WrError(ErrNum_InvAddrMode);
  1107.     return;
  1108.   }
  1109. }
  1110.  
  1111. static void DecodeAND1_OR1(Word Code)
  1112. {
  1113.   if (!ChkArgCnt(2, 2))
  1114.     return;
  1115.   if (as_strcasecmp(ArgStr[1].str.p_str, "CY"))
  1116.   {
  1117.     WrError(ErrNum_InvAddrMode);
  1118.     return;
  1119.   }
  1120.   if (*ArgStr[2].str.p_str == '/')
  1121.   {
  1122.     tStrComp BitArg;
  1123.  
  1124.     StrCompRefRight(&BitArg, &ArgStr[2], 1);
  1125.     DecodeBitOpCore(&BitArg, Code | 0x10);
  1126.   }
  1127.   else
  1128.     DecodeBitOpCore(&ArgStr[2], Code);
  1129. }
  1130.  
  1131. static void DecodeXOR1(Word Code)
  1132. {
  1133.   if (!ChkArgCnt(2, 2))
  1134.     return;
  1135.   if (as_strcasecmp(ArgStr[1].str.p_str, "CY"))
  1136.   {
  1137.     WrError(ErrNum_InvAddrMode);
  1138.     return;
  1139.   }
  1140.   DecodeBitOpCore(&ArgStr[2], Code);
  1141. }
  1142.  
  1143. static void DecodeNOT1(Word Code)
  1144. {
  1145.   if (!ChkArgCnt(1, 1))
  1146.     return;
  1147.   if (!as_strcasecmp(ArgStr[1].str.p_str, "CY"))
  1148.     BAsmCode[CodeLen++] = 0x42;
  1149.   else
  1150.     DecodeBitOpCore(&ArgStr[1], Code);
  1151. }
  1152.  
  1153. static void DecodeSET1_CLR1(Word Code)
  1154. {
  1155.   if (!ChkArgCnt(1, 1))
  1156.     return;
  1157.   if (!as_strcasecmp(ArgStr[1].str.p_str, "CY"))
  1158.     BAsmCode[CodeLen++] = 0x41 - ((Code >> 4) & 1);
  1159.   else
  1160.   {
  1161.     LongWord BitAddr;
  1162.  
  1163.     if (!DecodeBitAdr(&ArgStr[1], &BitAddr))
  1164.       return;
  1165.     switch ((BitAddr >> 28) & 15)
  1166.     {
  1167.       case eBitTypeSAddr1:
  1168.         BAsmCode[CodeLen++] = 0x3c;
  1169.         /* fall-through */
  1170.       case eBitTypeSAddr2_SFR:
  1171.         if (!(BitAddr & Bit27))
  1172.         {
  1173.           BAsmCode[CodeLen++] = (0x130 - Code) | ((BitAddr >> 24) & 7);
  1174.           BAsmCode[CodeLen++] = Lo(BitAddr);
  1175.           break;
  1176.         }
  1177.         /* else fall-through */ /* SFR is regularly coded for SET1/CLR1 */
  1178.       default:
  1179.         DecodeBitOpCore2(BitAddr, Code);
  1180.     }
  1181.   }
  1182. }
  1183.  
  1184. static void DecodeMOV(Word ForceOpSize)
  1185. {
  1186.   tEncodedAddress Dest, Src;
  1187.   tAdrModeMask AdrModeMask;
  1188.  
  1189.   if (ForceOpSize)
  1190.     SetOpSize(ForceOpSize);
  1191.  
  1192.   if (!ChkArgCnt(2, 2))
  1193.     return;
  1194.  
  1195.   if (!as_strcasecmp(ArgStr[1].str.p_str, "CY"))
  1196.   {
  1197.     DecodeBitOpCore(&ArgStr[2], 0x00);
  1198.     return;
  1199.   }
  1200.   else if (!as_strcasecmp(ArgStr[2].str.p_str, "CY"))
  1201.   {
  1202.     DecodeBitOpCore(&ArgStr[1], 0x10);
  1203.     return;
  1204.   }
  1205.  
  1206.   AdrModeMask = MModShort1 | MModShort2 | MModAbsAll | MModShortIndir1_24 | MModShortIndir2_24 | MModMem;
  1207.   if (OpSize != 2)
  1208.     AdrModeMask |= MModSFR | MModShortIndir1_16 | MModShortIndir2_16;
  1209.   if ((OpSize == -1) || (OpSize == 0))
  1210.     AdrModeMask |= MModReg8 | MModReg8_U16 | MModSTBC | MModWDM;
  1211.   if ((OpSize == -1) || (OpSize == 1))
  1212.     AdrModeMask |= MModReg16;
  1213.   if ((OpSize == -1) || (OpSize == 2))
  1214.     AdrModeMask |= MModReg24 | MModSP;
  1215.   DecodeAdr(&ArgStr[1], AdrModeMask, &Dest);
  1216.   switch (Dest.AdrMode)
  1217.   {
  1218.     case ModReg8:
  1219.       AdrModeMask = MModImm | MModReg8 | MModShort1 | MModShort2 | MModSFR | MModAbsAll;
  1220.       if (Dest.AdrVal == AccReg8())
  1221.         AdrModeMask |= MModReg8_U16 | MModShortIndir_All | MModMem;
  1222.       DecodeAdr(&ArgStr[2], AdrModeMask, &Src);
  1223.       switch (Src.AdrMode)
  1224.       {
  1225.         case ModReg8:
  1226.           if (Src.AdrVal >= 8)
  1227.           {
  1228.             BAsmCode[CodeLen++] = 0x3c;
  1229.             Src.AdrVal -= 8;
  1230.           }
  1231.           if (Dest.AdrVal == AccReg8())
  1232.             BAsmCode[CodeLen++] = 0xd0 | Src.AdrVal;
  1233.           else
  1234.           {
  1235.             BAsmCode[CodeLen++] = 0x24;
  1236.             BAsmCode[CodeLen++] = (Dest.AdrVal << 4) | Src.AdrVal;
  1237.           }
  1238.           break;
  1239.         case ModReg8_U16:
  1240.           BAsmCode[CodeLen++] = 0x05;
  1241.           BAsmCode[CodeLen++] = 0xc1 | (Src.AdrVal << 1);
  1242.           break;
  1243.         case ModImm:
  1244.           if (Dest.AdrVal >= 8)
  1245.           {
  1246.             BAsmCode[CodeLen++] = 0x3c;
  1247.             Dest.AdrVal -= 8;
  1248.           }
  1249.           BAsmCode[CodeLen++] = 0xb8 | Dest.AdrVal;
  1250.           BAsmCode[CodeLen++] = Src.AdrVals[0];
  1251.           break;
  1252.         case ModShort2:
  1253.           if (Dest.AdrVal == AccReg8())
  1254.           {
  1255.             BAsmCode[CodeLen++] = 0x20;
  1256.             BAsmCode[CodeLen++] = Src.AdrVals[0];
  1257.             break;
  1258.           }
  1259.           else
  1260.             goto CommonReg8ModShort;
  1261.         case ModSFR:
  1262.           if (Dest.AdrVal == AccReg8())
  1263.           {
  1264.             BAsmCode[CodeLen++] = 0x10;
  1265.             BAsmCode[CodeLen++] = Src.AdrVals[0];
  1266.             break;
  1267.           }
  1268.           else
  1269.             goto CommonReg8ModShort;
  1270.         CommonReg8ModShort:
  1271.         case ModShort1:
  1272.           BAsmCode[CodeLen++] = 0x38;
  1273.           BAsmCode[CodeLen++] = 0x00 | ModShortVal(Src.AdrMode) | (Dest.AdrVal << 4);
  1274.           BAsmCode[CodeLen++] = Src.AdrVals[0];
  1275.           break;
  1276.         case ModAbs16:
  1277.         case ModAbs24:
  1278.           BAsmCode[CodeLen++] = 0x3e;
  1279.           BAsmCode[CodeLen++] = 0x00 | (ModIs24(Src.AdrMode) << 1) | (Dest.AdrVal << 4);
  1280.           AppendAdrVals(&Src);
  1281.           break;
  1282.         case ModShortIndir1_16:
  1283.         case ModShortIndir2_16:
  1284.         case ModShortIndir1_24:
  1285.         case ModShortIndir2_24:
  1286.           if (ModIsShort1(Src.AdrMode))
  1287.             BAsmCode[CodeLen++] = 0x3c;
  1288.           if (ModIs24(Src.AdrMode))
  1289.           {
  1290.             BAsmCode[CodeLen++] = 0x07;
  1291.             BAsmCode[CodeLen++] = 0x30;
  1292.           }
  1293.           else
  1294.             BAsmCode[CodeLen++] = 0x18;
  1295.           BAsmCode[CodeLen++] = Src.AdrVals[0];
  1296.           break;
  1297.         case ModMem:
  1298.           if ((Src.AdrVal == 0x16) && (Src.AdrVals[0] < 6))
  1299.             BAsmCode[CodeLen++] = 0x58 + Src.AdrVals[0];
  1300.           else
  1301.           {
  1302.             BAsmCode[CodeLen++] = Src.AdrVal;
  1303.             AppendAdrValsMem(&Src, 0x00);
  1304.           }
  1305.           break;
  1306.         case ModNone:
  1307.           break;
  1308.         default:
  1309.           WrError(ErrNum_InvAddrMode);
  1310.       }
  1311.       break;
  1312.  
  1313.     case ModReg8_U16:
  1314.       DecodeAdr(&ArgStr[2], MModImm | MModReg8, &Src);
  1315.       switch (Src.AdrMode)
  1316.       {
  1317.         case ModReg8:
  1318.           if (Src.AdrVal == AccReg8())
  1319.           {
  1320.             BAsmCode[CodeLen++] = 0x05;
  1321.             BAsmCode[CodeLen++] = 0xc9 | (Dest.AdrVal << 1);
  1322.           }
  1323.           break;
  1324.         case ModImm:
  1325.           BAsmCode[CodeLen++] = 0x07;
  1326.           BAsmCode[CodeLen++] = 0x61 | (Dest.AdrVal << 1);
  1327.           BAsmCode[CodeLen++] = Src.AdrVals[0];
  1328.           break;
  1329.         case ModNone:
  1330.           break;
  1331.         default:
  1332.           WrError(ErrNum_InvAddrMode);
  1333.       }
  1334.       break;
  1335.  
  1336.     case ModReg16:
  1337.       AdrModeMask = MModImm | MModReg16 | MModShort1 | MModShort2 | MModSFR | MModAbsAll;
  1338.       if (Dest.AdrVal == AccReg16())
  1339.         AdrModeMask |= MModShortIndir_All | MModMem;
  1340.       DecodeAdr(&ArgStr[2], AdrModeMask, &Src);
  1341.       switch (Src.AdrMode)
  1342.       {
  1343.         case ModImm:
  1344.           BAsmCode[CodeLen++] = 0x60 | Dest.AdrVal;
  1345.           AppendAdrVals(&Src);
  1346.           break;
  1347.         case ModReg16:
  1348.           BAsmCode[CodeLen++] = 0x24;
  1349.           BAsmCode[CodeLen++] = 0x08 | (Src.AdrVal << 5) | Dest.AdrVal;
  1350.           AppendAdrVals(&Src);
  1351.           break;
  1352.         case ModShort2:
  1353.           if (Dest.AdrVal == AccReg16())
  1354.           {
  1355.             BAsmCode[CodeLen++] = 0x1c;
  1356.             BAsmCode[CodeLen++] = Src.AdrVals[0];
  1357.             break;
  1358.           }
  1359.           else
  1360.             goto CommonReg16ModShort;
  1361.         case ModSFR:
  1362.           if (Dest.AdrVal == AccReg16())
  1363.           {
  1364.             BAsmCode[CodeLen++] = 0x11;
  1365.             BAsmCode[CodeLen++] = Src.AdrVals[0];
  1366.             break;
  1367.           }
  1368.             goto CommonReg16ModShort;
  1369.         CommonReg16ModShort:
  1370.         case ModShort1:
  1371.           BAsmCode[CodeLen++] = 0x38;
  1372.           BAsmCode[CodeLen++] = 0x08 | ModShortVal(Src.AdrMode) | (Dest.AdrVal << 5);
  1373.           BAsmCode[CodeLen++] = Src.AdrVals[0];
  1374.           break;
  1375.         case ModAbs16:
  1376.         case ModAbs24:
  1377.           BAsmCode[CodeLen++] = 0x3e;
  1378.           BAsmCode[CodeLen++] = 0x08 | (ModIs24(Src.AdrMode) << 1) | (Dest.AdrVal << 5);
  1379.           AppendAdrVals(&Src);
  1380.           break;
  1381.         case ModShortIndir1_16:
  1382.           BAsmCode[CodeLen++] = 0x3c;
  1383.           /* fall-through */
  1384.         case ModShortIndir2_16:
  1385.           BAsmCode[CodeLen++] = 0x07;
  1386.           BAsmCode[CodeLen++] = 0x21;
  1387.           BAsmCode[CodeLen++] = Src.AdrVals[0];
  1388.           break;
  1389.         case ModShortIndir1_24:
  1390.           BAsmCode[CodeLen++] = 0x3c;
  1391.           /* fall-through */
  1392.         case ModShortIndir2_24:
  1393.           BAsmCode[CodeLen++] = 0x07;
  1394.           BAsmCode[CodeLen++] = 0x31;
  1395.           BAsmCode[CodeLen++] = Src.AdrVals[0];
  1396.           break;
  1397.         case ModMem:
  1398.           BAsmCode[CodeLen++] = Src.AdrVal;
  1399.           AppendAdrValsMem(&Src, 0x01);
  1400.           break;
  1401.         case ModNone:
  1402.           break;
  1403.         default:
  1404.           WrError(ErrNum_InvAddrMode);
  1405.       }
  1406.       break;
  1407.  
  1408.     case ModReg24:
  1409.       AdrModeMask = MModImm | MModReg24 | MModAbs24 | MModShort1 | MModShort2;
  1410.       if (Dest.AdrVal == WHLReg)
  1411.         AdrModeMask |= MModShortIndir1_24 | MModShortIndir2_24 | MModMem | MModSP;
  1412.       DecodeAdr(&ArgStr[2], AdrModeMask, &Src);
  1413.       switch (Src.AdrMode)
  1414.       {
  1415.         case ModImm:
  1416.           BAsmCode[CodeLen++] = 0x38;
  1417.           BAsmCode[CodeLen++] = 0x9b | (Dest.AdrVal << 5);
  1418.           AppendAdrVals(&Src);
  1419.           break;
  1420.         case ModReg24:
  1421.           BAsmCode[CodeLen++] = 0x24;
  1422.           BAsmCode[CodeLen++] = 0x99 | (Dest.AdrVal << 5) | (Src.AdrVal << 1);
  1423.           AppendAdrVals(&Src);
  1424.           break;
  1425.         case ModAbs24:
  1426.           BAsmCode[CodeLen++] = 0x3e;
  1427.           BAsmCode[CodeLen++] = 0x9a | (Dest.AdrVal << 5);
  1428.           AppendAdrVals(&Src);
  1429.           break;
  1430.         case ModShort1:
  1431.         case ModShort2:
  1432.           BAsmCode[CodeLen++] = 0x38;
  1433.           BAsmCode[CodeLen++] = 0x98 | ModShortVal(Src.AdrMode) | (Dest.AdrVal << 5);
  1434.           BAsmCode[CodeLen++] = Src.AdrVals[0];
  1435.           break;
  1436.         case ModShortIndir1_24:
  1437.           BAsmCode[CodeLen++] = 0x3c;
  1438.           /* fall-through */
  1439.         case ModShortIndir2_24:
  1440.           BAsmCode[CodeLen++] = 0x07;
  1441.           BAsmCode[CodeLen++] = 0x32;
  1442.           BAsmCode[CodeLen++] = Src.AdrVals[0];
  1443.           break;
  1444.         case ModMem:
  1445.           if ((Src.AdrVal == 0x16) && ((Src.AdrVals[0] == 1) || (Src.AdrVals[0] == 3))) WrError(ErrNum_InvAddrMode);
  1446.           else
  1447.           {
  1448.             BAsmCode[CodeLen++] = Src.AdrVal;
  1449.             AppendAdrValsMem(&Src, 0x02);
  1450.           }
  1451.           break;
  1452.         case ModSP:
  1453.           BAsmCode[CodeLen++] = 0x05;
  1454.           BAsmCode[CodeLen++] = 0xfa;
  1455.           break;
  1456.         case ModNone:
  1457.           break;
  1458.         default:
  1459.           WrError(ErrNum_InvAddrMode);
  1460.       }
  1461.       break;
  1462.  
  1463.     case ModSP:
  1464.       DecodeAdr(&ArgStr[2], MModImm | MModReg24, &Src);
  1465.       switch (Src.AdrMode)
  1466.       {
  1467.         case ModImm:
  1468.           BAsmCode[CodeLen++] = 0x09;
  1469.           BAsmCode[CodeLen++] = 0x20;
  1470.           AppendAdrVals(&Src);
  1471.           break;
  1472.         case ModReg24:
  1473.           if (Src.AdrVal != WHLReg) WrError(ErrNum_InvAddrMode);
  1474.           else
  1475.           {
  1476.             BAsmCode[CodeLen++] = 0x05;
  1477.             BAsmCode[CodeLen++] = 0xfb;
  1478.           }
  1479.           break;
  1480.         case ModNone:
  1481.           break;
  1482.         default:
  1483.           WrError(ErrNum_InvAddrMode);
  1484.       }
  1485.       break;
  1486.  
  1487.     case ModSTBC:
  1488.     case ModWDM:
  1489.       if (DecodeAdr(&ArgStr[2], MModImm, &Src))
  1490.       {
  1491.         BAsmCode[CodeLen++] = 0x09;
  1492.         BAsmCode[CodeLen++] = (Dest.AdrMode == ModSTBC) ? 0xc0: 0xc2;
  1493.         BAsmCode[CodeLen++] = ~Src.AdrVals[0];
  1494.         BAsmCode[CodeLen++] = Src.AdrVals[0];
  1495.       }
  1496.       break;
  1497.  
  1498.     case ModShort1:
  1499.       AssumeByte = True;
  1500.       AdrModeMask = 0;
  1501.       if (OpSize != 2) AdrModeMask |= MModImm | MModShort2 | MModShort1;
  1502.       if ((OpSize == -1) || (OpSize == 0)) AdrModeMask |= MModReg8;
  1503.       if ((OpSize == -1) || (OpSize == 1)) AdrModeMask |= MModReg16;
  1504.       if ((OpSize == -1) || (OpSize == 2)) AdrModeMask |= MModReg24;
  1505.       DecodeAdr(&ArgStr[2], AdrModeMask, &Src);
  1506.       switch (Src.AdrMode)
  1507.       {
  1508.         case ModImm:
  1509.           BAsmCode[CodeLen++] = 0x3c;
  1510.           BAsmCode[CodeLen++] = OpSize ? 0x0c : 0x3a;
  1511.           BAsmCode[CodeLen++] = Dest.AdrVals[0];
  1512.           AppendAdrVals(&Src);
  1513.           break;
  1514.         case ModReg8:
  1515.           BAsmCode[CodeLen++] = 0x38;
  1516.           BAsmCode[CodeLen++] = 0x05 | (Src.AdrVal << 4);
  1517.           BAsmCode[CodeLen++] = Dest.AdrVals[0];
  1518.           break;
  1519.         case ModReg16:
  1520.           BAsmCode[CodeLen++] = 0x38;
  1521.           BAsmCode[CodeLen++] = 0x0d | (Src.AdrVal << 5);
  1522.           BAsmCode[CodeLen++] = Dest.AdrVals[0];
  1523.           break;
  1524.         case ModReg24:
  1525.           BAsmCode[CodeLen++] = 0x38;
  1526.           BAsmCode[CodeLen++] = 0x9d | (Src.AdrVal << 5);
  1527.           BAsmCode[CodeLen++] = Dest.AdrVals[0];
  1528.           break;
  1529.         case ModShort1:
  1530.           ExecAssumeByte();
  1531.           BAsmCode[CodeLen++] = 0x2a;
  1532.           BAsmCode[CodeLen++] = 0x30 | (OpSize << 7);
  1533.           BAsmCode[CodeLen++] = Src.AdrVals[0];
  1534.           BAsmCode[CodeLen++] = Dest.AdrVals[0];
  1535.           break;
  1536.         case ModShort2:
  1537.           ExecAssumeByte();
  1538.           BAsmCode[CodeLen++] = 0x2a;
  1539.           BAsmCode[CodeLen++] = 0x20 | (OpSize << 7);
  1540.           BAsmCode[CodeLen++] = Src.AdrVals[0];
  1541.           BAsmCode[CodeLen++] = Dest.AdrVals[0];
  1542.           break;
  1543.         case ModNone:
  1544.           break;
  1545.         default:
  1546.           WrError(ErrNum_InvAddrMode);
  1547.       }
  1548.       break;
  1549.  
  1550.     case ModShort2:
  1551.       AssumeByte = True;
  1552.       AdrModeMask = 0;
  1553.       if (OpSize != 2) AdrModeMask |= MModImm | MModShort2 | MModShort1;
  1554.       if ((OpSize == -1) || (OpSize == 0)) AdrModeMask |= MModReg8;
  1555.       if ((OpSize == -1) || (OpSize == 1)) AdrModeMask |= MModReg16;
  1556.       if ((OpSize == -1) || (OpSize == 2)) AdrModeMask |= MModReg24;
  1557.       DecodeAdr(&ArgStr[2], AdrModeMask, &Src);
  1558.       switch (Src.AdrMode)
  1559.       {
  1560.         case ModImm:
  1561.           BAsmCode[CodeLen++] = OpSize ? 0x0c : 0x3a;
  1562.           BAsmCode[CodeLen++] = Dest.AdrVals[0];
  1563.           AppendAdrVals(&Src);
  1564.           break;
  1565.         case ModReg8:
  1566.           if (Src.AdrVal == AccReg8())
  1567.             BAsmCode[CodeLen++] = 0x22;
  1568.           else
  1569.           {
  1570.             BAsmCode[CodeLen++] = 0x38;
  1571.             BAsmCode[CodeLen++] = 0x04 | (Src.AdrVal << 4);
  1572.           }
  1573.           BAsmCode[CodeLen++] = Dest.AdrVals[0];
  1574.           break;
  1575.         case ModReg16:
  1576.           if (Src.AdrVal == AccReg16())
  1577.             BAsmCode[CodeLen++] = 0x1a;
  1578.           else
  1579.           {
  1580.             BAsmCode[CodeLen++] = 0x38;
  1581.             BAsmCode[CodeLen++] = 0x0c | (Src.AdrVal << 5);
  1582.           }
  1583.           BAsmCode[CodeLen++] = Dest.AdrVals[0];
  1584.           break;
  1585.         case ModReg24:
  1586.           BAsmCode[CodeLen++] = 0x38;
  1587.           BAsmCode[CodeLen++] = 0x9c | (Src.AdrVal << 5);
  1588.           BAsmCode[CodeLen++] = Dest.AdrVals[0];
  1589.           break;
  1590.         case ModShort2:
  1591.           ExecAssumeByte();
  1592.           BAsmCode[CodeLen++] = 0x2a;
  1593.           BAsmCode[CodeLen++] = OpSize << 7;
  1594.           BAsmCode[CodeLen++] = Src.AdrVals[0];
  1595.           BAsmCode[CodeLen++] = Dest.AdrVals[0];
  1596.           break;
  1597.         case ModShort1:
  1598.           ExecAssumeByte();
  1599.           BAsmCode[CodeLen++] = 0x2a;
  1600.           BAsmCode[CodeLen++] = 0x10 | (OpSize << 7);
  1601.           BAsmCode[CodeLen++] = Src.AdrVals[0];
  1602.           BAsmCode[CodeLen++] = Dest.AdrVals[0];
  1603.           break;
  1604.         case ModNone:
  1605.           break;
  1606.         default:
  1607.           WrError(ErrNum_InvAddrMode);
  1608.       }
  1609.       break;
  1610.  
  1611.     case ModSFR:
  1612.       AssumeByte = True;
  1613.       AdrModeMask = 0;
  1614.       if (OpSize != 2) AdrModeMask |= MModImm;
  1615.       if ((OpSize == -1) || (OpSize == 0)) AdrModeMask |= MModReg8;
  1616.       if ((OpSize == -1) || (OpSize == 1)) AdrModeMask |= MModReg16;
  1617.       DecodeAdr(&ArgStr[2], AdrModeMask, &Src);
  1618.       switch (Src.AdrMode)
  1619.       {
  1620.         case ModImm:
  1621.           BAsmCode[CodeLen++] = OpSize ? 0x0b : 0x2b;
  1622.           BAsmCode[CodeLen++] = Dest.AdrVals[0];
  1623.           AppendAdrVals(&Src);
  1624.           break;
  1625.         case ModReg8:
  1626.           if (Src.AdrVal == AccReg8())
  1627.             BAsmCode[CodeLen++] = 0x12;
  1628.           else
  1629.           {
  1630.             BAsmCode[CodeLen++] = 0x38;
  1631.             BAsmCode[CodeLen++] = 0x06 | (Src.AdrVal << 4);
  1632.           }
  1633.           BAsmCode[CodeLen++] = Dest.AdrVals[0];
  1634.           break;
  1635.         case ModReg16:
  1636.           if (Src.AdrVal == AccReg8())
  1637.             BAsmCode[CodeLen++] = 0x13;
  1638.           else
  1639.           {
  1640.             BAsmCode[CodeLen++] = 0x38;
  1641.             BAsmCode[CodeLen++] = 0x0e | (Src.AdrVal << 5);
  1642.           }
  1643.           BAsmCode[CodeLen++] = Dest.AdrVals[0];
  1644.           break;
  1645.         case ModNone:
  1646.           break;
  1647.         default:
  1648.           WrError(ErrNum_InvAddrMode);
  1649.       }
  1650.       break;
  1651.  
  1652.     case ModAbs16:
  1653.     case ModAbs24:
  1654.       AssumeByte = True;
  1655.       AdrModeMask = 0;
  1656.       if (OpSize != 2) AdrModeMask |= MModImm;
  1657.       if ((OpSize == -1) || (OpSize == 0)) AdrModeMask |= MModReg8;
  1658.       if ((OpSize == -1) || (OpSize == 1)) AdrModeMask |= MModReg16;
  1659.       if ((OpSize == -1) || (OpSize == 2)) AdrModeMask |= MModReg24;
  1660.       DecodeAdr(&ArgStr[2], AdrModeMask, &Src);
  1661.       switch (Src.AdrMode)
  1662.       {
  1663.         case ModImm:
  1664.           BAsmCode[CodeLen++] = 0x09;
  1665.           BAsmCode[CodeLen++] = 0x40 | (ModIs24(Dest.AdrMode) << 4) | OpSize;
  1666.           AppendAdrVals(&Dest);
  1667.           AppendAdrVals(&Src);
  1668.           break;
  1669.         case ModReg8:
  1670.           BAsmCode[CodeLen++] = 0x3e;
  1671.           BAsmCode[CodeLen++] = 0x01 | (ModIs24(Dest.AdrMode) << 1) | (Src.AdrVal << 4);
  1672.           AppendAdrVals(&Dest);
  1673.           break;
  1674.         case ModReg16:
  1675.           BAsmCode[CodeLen++] = 0x3e;
  1676.           BAsmCode[CodeLen++] = 0x09 | (ModIs24(Dest.AdrMode) << 1) | (Src.AdrVal << 5);
  1677.           AppendAdrVals(&Dest);
  1678.           break;
  1679.         case ModReg24:
  1680.           BAsmCode[CodeLen++] = 0x3e;
  1681.           BAsmCode[CodeLen++] = 0x9b | (Src.AdrVal << 5);
  1682.           if (Dest.AdrMode == ModAbs16)
  1683.             BAsmCode[CodeLen++] = 0x00;
  1684.           AppendAdrVals(&Dest);
  1685.           break;
  1686.         case ModNone:
  1687.           break;
  1688.         default:
  1689.           WrError(ErrNum_InvAddrMode);
  1690.       }
  1691.       break;
  1692.  
  1693.     case ModShortIndir2_16:
  1694.     case ModShortIndir1_16:
  1695.       AssumeByte = True;
  1696.       AdrModeMask = 0;
  1697.       if ((OpSize == -1) || (OpSize == 0)) AdrModeMask |= MModReg8;
  1698.       if ((OpSize == -1) || (OpSize == 1)) AdrModeMask |= MModReg16;
  1699.       DecodeAdr(&ArgStr[2], AdrModeMask, &Src);
  1700.       switch (Src.AdrMode)
  1701.       {
  1702.         case ModReg8:
  1703.           if (Src.AdrVal != AccReg8()) WrError(ErrNum_InvAddrMode);
  1704.           else
  1705.           {
  1706.             if (ModIsShort1(Dest.AdrMode))
  1707.               BAsmCode[CodeLen++] = 0x3c;
  1708.             BAsmCode[CodeLen++] = 0x19;
  1709.             BAsmCode[CodeLen++] = Dest.AdrVals[0];
  1710.           }
  1711.           break;
  1712.         case ModReg16:
  1713.           if (Src.AdrVal != AccReg16()) WrError(ErrNum_InvAddrMode);
  1714.           else
  1715.           {
  1716.             if (ModIsShort1(Dest.AdrMode))
  1717.               BAsmCode[CodeLen++] = 0x3c;
  1718.             BAsmCode[CodeLen++] = 0x07;
  1719.             BAsmCode[CodeLen++] = 0xa1;
  1720.             BAsmCode[CodeLen++] = Dest.AdrVals[0];
  1721.           }
  1722.           break;
  1723.         case ModNone:
  1724.           break;
  1725.         default:
  1726.           WrError(ErrNum_InvAddrMode);
  1727.       }
  1728.       break;
  1729.  
  1730.     case ModShortIndir2_24:
  1731.     case ModShortIndir1_24:
  1732.       AssumeByte = True;
  1733.       AdrModeMask = 0;
  1734.       if ((OpSize == -1) || (OpSize == 0)) AdrModeMask |= MModReg8;
  1735.       if ((OpSize == -1) || (OpSize == 1)) AdrModeMask |= MModReg16;
  1736.       if ((OpSize == -1) || (OpSize == 2)) AdrModeMask |= MModReg24;
  1737.       DecodeAdr(&ArgStr[2], AdrModeMask, &Src);
  1738.       switch (Src.AdrMode)
  1739.       {
  1740.         case ModReg8:
  1741.           if (Src.AdrVal != AccReg8()) WrError(ErrNum_InvAddrMode);
  1742.           else
  1743.             goto CommonRegIndir;
  1744.           break;
  1745.         case ModReg16:
  1746.           if (Src.AdrVal != AccReg16()) WrError(ErrNum_InvAddrMode);
  1747.           else
  1748.             goto CommonRegIndir;
  1749.           break;
  1750.         case ModReg24:
  1751.           if (Src.AdrVal != WHLReg) WrError(ErrNum_InvAddrMode);
  1752.           else
  1753.             goto CommonRegIndir;
  1754.           break;
  1755.         CommonRegIndir:
  1756.           if (ModIsShort1(Dest.AdrMode))
  1757.             BAsmCode[CodeLen++] = 0x3c;
  1758.           BAsmCode[CodeLen++] = 0x07;
  1759.           BAsmCode[CodeLen++] = 0xb0 + OpSize;
  1760.           BAsmCode[CodeLen++] = Dest.AdrVals[0];
  1761.           break;
  1762.         case ModNone:
  1763.           break;
  1764.         default:
  1765.           WrError(ErrNum_InvAddrMode);
  1766.       }
  1767.       break;
  1768.  
  1769.     case ModMem:
  1770.       AssumeByte = True;
  1771.       AdrModeMask = 0;
  1772.       if ((OpSize == -1) || (OpSize == 0)) AdrModeMask |= MModReg8;
  1773.       if ((OpSize == -1) || (OpSize == 1)) AdrModeMask |= MModReg16;
  1774.       if ((OpSize == -1) || (OpSize == 2)) AdrModeMask |= MModReg24;
  1775.       DecodeAdr(&ArgStr[2], AdrModeMask, &Src);
  1776.       switch (Src.AdrMode)
  1777.       {
  1778.         case ModReg8:
  1779.           if (Src.AdrVal != AccReg8()) WrError(ErrNum_InvAddrMode);
  1780.           else if ((Dest.AdrVal == 0x16) && (Dest.AdrVals[0] < 6))
  1781.             BAsmCode[CodeLen++] = 0x50 + Dest.AdrVals[0];
  1782.           else
  1783.             goto CommonRegMem;
  1784.           break;
  1785.         case ModReg16:
  1786.           if (Src.AdrVal != AccReg16()) WrError(ErrNum_InvAddrMode);
  1787.           else
  1788.             goto CommonRegMem;
  1789.           break;
  1790.         case ModReg24:
  1791.           if (Src.AdrVal != WHLReg) WrError(ErrNum_InvAddrMode);
  1792.           else
  1793.             goto CommonRegMem;
  1794.           break;
  1795.         CommonRegMem:
  1796.           BAsmCode[CodeLen++] = Dest.AdrVal;
  1797.           AppendAdrValsMem(&Dest, 0x80 + OpSize);
  1798.           break;
  1799.         case ModNone:
  1800.           break;
  1801.         default:
  1802.           WrError(ErrNum_InvAddrMode);
  1803.       }
  1804.       break;
  1805.     case ModNone:
  1806.       break;
  1807.     default:
  1808.       WrError(ErrNum_InvAddrMode);
  1809.   }
  1810. }
  1811.  
  1812. static void DecodeXCH(Word ForceOpSize)
  1813. {
  1814.   tEncodedAddress Dest, Src;
  1815.   tAdrModeMask AdrModeMask;
  1816.  
  1817.   if (ForceOpSize)
  1818.     SetOpSize(ForceOpSize);
  1819.  
  1820.   if (!ChkArgCnt(2, 2))
  1821.     return;
  1822.  
  1823.   AdrModeMask = MModShort1 | MModShort2 | MModSFR | MModAbsAll | MModShortIndir_All | MModMem;
  1824.   if ((OpSize == -1) || (OpSize == 0)) AdrModeMask |= MModReg8;
  1825.   if ((OpSize == -1) || (OpSize == 1)) AdrModeMask |= MModReg16;
  1826.   DecodeAdr(&ArgStr[1], AdrModeMask, &Dest);
  1827.   switch (Dest.AdrMode)
  1828.   {
  1829.     case ModReg8:
  1830.       AdrModeMask = MModReg8 | MModShort2 | MModShort1 | MModSFR | MModAbsAll;
  1831.       if (Dest.AdrVal == AccReg8())
  1832.         AdrModeMask |= MModShortIndir_All | MModMem;
  1833.       DecodeAdr(&ArgStr[2], AdrModeMask, &Src);
  1834.       switch (Src.AdrMode)
  1835.       {
  1836.         case ModReg8:
  1837.           if (Dest.AdrVal == AccReg8())
  1838.           {
  1839.             if (Src.AdrVal >= 8)
  1840.               BAsmCode[CodeLen++] = 0x3c;
  1841.             BAsmCode[CodeLen++] = 0xd8 | (Src.AdrVal & 7);
  1842.           }
  1843.           else if (Src.AdrVal == AccReg8())
  1844.           {
  1845.             if (Dest.AdrVal >= 8)
  1846.               BAsmCode[CodeLen++] = 0x3c;
  1847.             BAsmCode[CodeLen++] = 0xd8 | (Dest.AdrVal & 7);
  1848.           }
  1849.           else
  1850.           {
  1851.             if (Src.AdrVal >= 8)
  1852.               BAsmCode[CodeLen++] = 0x3c;
  1853.             BAsmCode[CodeLen++] = 0x25;
  1854.             BAsmCode[CodeLen++] = (Dest.AdrVal << 4) | (Src.AdrVal & 7);
  1855.           }
  1856.           break;
  1857.         case ModShort2:
  1858.           if (Dest.AdrVal == AccReg8())
  1859.           {
  1860.             BAsmCode[CodeLen++] = 0x21;
  1861.             BAsmCode[CodeLen++] = Src.AdrVals[0];
  1862.             break;
  1863.           }
  1864.           /* fall-through */
  1865.         case ModShort1:
  1866.         case ModSFR:
  1867.           BAsmCode[CodeLen++] = 0x39;
  1868.           BAsmCode[CodeLen++] = 0x00 | ModShortVal(Src.AdrMode) | (Dest.AdrVal << 4);
  1869.           BAsmCode[CodeLen++] = Src.AdrVals[0];
  1870.           break;
  1871.         case ModAbs16:
  1872.         case ModAbs24:
  1873.           BAsmCode[CodeLen++] = 0x3e;
  1874.           BAsmCode[CodeLen++] = 0x04 | (ModIs24(Src.AdrMode) << 1) | (Dest.AdrVal << 4);
  1875.           AppendAdrVals(&Src);
  1876.           break;
  1877.         case ModShortIndir1_16:
  1878.         case ModShortIndir2_16:
  1879.         case ModShortIndir1_24:
  1880.         case ModShortIndir2_24:
  1881.           if (ModIsShort1(Src.AdrMode))
  1882.             BAsmCode[CodeLen++] = 0x3c;
  1883.           if (ModIs24(Src.AdrMode))
  1884.           {
  1885.             BAsmCode[CodeLen++] = 0x07;
  1886.             BAsmCode[CodeLen++] = 0x34;
  1887.           }
  1888.           else
  1889.             BAsmCode[CodeLen++] = 0x23;
  1890.           BAsmCode[CodeLen++] = Src.AdrVals[0];
  1891.           break;
  1892.         case ModMem:
  1893.           BAsmCode[CodeLen++] = Src.AdrVal;
  1894.           AppendAdrValsMem(&Src, 0x04);
  1895.           break;
  1896.         case ModNone:
  1897.           break;
  1898.         default:
  1899.           WrError(ErrNum_InvAddrMode);
  1900.       }
  1901.       break;
  1902.  
  1903.     case ModReg16:
  1904.       AdrModeMask = MModReg16 | MModShort1 | MModShort2 | MModSFR;
  1905.       if (Dest.AdrVal == AccReg16())
  1906.         AdrModeMask |= MModShortIndir_All | MModAbsAll | MModMem;
  1907.       DecodeAdr(&ArgStr[2], AdrModeMask, &Src);
  1908.       switch (Src.AdrMode)
  1909.       {
  1910.         case ModReg16:
  1911.           BAsmCode[CodeLen++] = 0x25;
  1912.           BAsmCode[CodeLen++] = 0x08 | (Src.AdrVal << 5) | Dest.AdrVal;
  1913.           break;
  1914.         case ModShort2:
  1915.           if (Dest.AdrVal == AccReg16())
  1916.           {
  1917.             BAsmCode[CodeLen++] = 0x1b;
  1918.             BAsmCode[CodeLen++] = Src.AdrVals[0];
  1919.             break;
  1920.           }
  1921.           /* fall-through */
  1922.         case ModShort1:
  1923.         case ModSFR:
  1924.           BAsmCode[CodeLen++] = 0x39;
  1925.           BAsmCode[CodeLen++] = 0x08 | ModShortVal(Src.AdrMode) | (Dest.AdrVal << 5);
  1926.           BAsmCode[CodeLen++] = Src.AdrVals[0];
  1927.           break;
  1928.         case ModShortIndir1_16:
  1929.         case ModShortIndir2_16:
  1930.         case ModShortIndir1_24:
  1931.         case ModShortIndir2_24:
  1932.           if (ModIsShort1(Src.AdrMode))
  1933.             BAsmCode[CodeLen++] = 0x3c;
  1934.           BAsmCode[CodeLen++] = 0x07;
  1935.           BAsmCode[CodeLen++] = 0x25 | (ModIs24(Src.AdrMode) << 4);
  1936.           BAsmCode[CodeLen++] = Src.AdrVals[0];
  1937.           break;
  1938.         case ModAbs16:
  1939.         case ModAbs24:
  1940.           BAsmCode[CodeLen++] = 0x0a;
  1941.           BAsmCode[CodeLen++] = 0x45 | (ModIs24(Src.AdrMode) << 4);
  1942.           AppendAdrVals(&Src);
  1943.           break;
  1944.         case ModMem:
  1945.           BAsmCode[CodeLen++] = Src.AdrVal;
  1946.           AppendAdrValsMem(&Src, 0x05);
  1947.           break;
  1948.         case ModNone:
  1949.           break;
  1950.         default:
  1951.           WrError(ErrNum_InvAddrMode);
  1952.       }
  1953.       break;
  1954.  
  1955.     case ModShort2:
  1956.       AssumeByte = True;
  1957.       AdrModeMask = MModShort2 | MModShort1;
  1958.       if ((OpSize == -1) || (OpSize == 0)) AdrModeMask |= MModReg8;
  1959.       if ((OpSize == -1) || (OpSize == 1)) AdrModeMask |= MModReg16;
  1960.       DecodeAdr(&ArgStr[2], AdrModeMask, &Src);
  1961.       switch (Src.AdrMode)
  1962.       {
  1963.         case ModReg8:
  1964.           if (Src.AdrVal == AccReg8())
  1965.             BAsmCode[CodeLen++] = 0x21;
  1966.           else
  1967.           {
  1968.             BAsmCode[CodeLen++] = 0x39;
  1969.             BAsmCode[CodeLen++] = 0x00 | (Src.AdrVal << 4);
  1970.           }
  1971.           BAsmCode[CodeLen++] = Dest.AdrVals[0];
  1972.           break;
  1973.         case ModReg16:
  1974.           if (Src.AdrVal == AccReg16())
  1975.             BAsmCode[CodeLen++] = 0x1b;
  1976.           else
  1977.           {
  1978.             BAsmCode[CodeLen++] = 0x39;
  1979.             BAsmCode[CodeLen++] = 0x08 | (Src.AdrVal << 5);
  1980.           }
  1981.           BAsmCode[CodeLen++] = Dest.AdrVals[0];
  1982.           break;
  1983.         case ModShort2:
  1984.         case ModShort1:
  1985.           ExecAssumeByte();
  1986.           BAsmCode[CodeLen++] = 0x2a;
  1987.           BAsmCode[CodeLen++] = (OpSize << 7) | ((Src.AdrMode == ModShort1) ? 0x14 : 0x04);
  1988.           BAsmCode[CodeLen++] = Src.AdrVals[0];
  1989.           BAsmCode[CodeLen++] = Dest.AdrVals[0];
  1990.           break;
  1991.         case ModNone:
  1992.           break;
  1993.         default:
  1994.           WrError(ErrNum_InvAddrMode);
  1995.       }
  1996.       break;
  1997.  
  1998.     case ModShort1:
  1999.       AssumeByte = True;
  2000.       AdrModeMask = MModShort2 | MModShort1;
  2001.       if ((OpSize == -1) || (OpSize == 0)) AdrModeMask |= MModReg8;
  2002.       if ((OpSize == -1) || (OpSize == 1)) AdrModeMask |= MModReg16;
  2003.       DecodeAdr(&ArgStr[2], AdrModeMask, &Src);
  2004.       switch (Src.AdrMode)
  2005.       {
  2006.         case ModReg8:
  2007.           BAsmCode[CodeLen++] = 0x39;
  2008.           BAsmCode[CodeLen++] = 0x01 | (Src.AdrVal << 4);
  2009.           BAsmCode[CodeLen++] = Dest.AdrVals[0];
  2010.           break;
  2011.         case ModReg16:
  2012.           BAsmCode[CodeLen++] = 0x39;
  2013.           BAsmCode[CodeLen++] = 0x09 | (Src.AdrVal << 5);
  2014.           BAsmCode[CodeLen++] = Dest.AdrVals[0];
  2015.           break;
  2016.         case ModShort2:
  2017.         case ModShort1:
  2018.           ExecAssumeByte();
  2019.           BAsmCode[CodeLen++] = 0x2a;
  2020.           BAsmCode[CodeLen++] = (OpSize << 7) | ((Src.AdrMode == ModShort1) ? 0x34 : 0x24);
  2021.           BAsmCode[CodeLen++] = Src.AdrVals[0];
  2022.           BAsmCode[CodeLen++] = Dest.AdrVals[0];
  2023.           break;
  2024.         case ModNone:
  2025.           break;
  2026.         default:
  2027.           WrError(ErrNum_InvAddrMode);
  2028.       }
  2029.       break;
  2030.  
  2031.     case ModSFR:
  2032.       AdrModeMask = 0;
  2033.       if ((OpSize == -1) || (OpSize == 0)) AdrModeMask |= MModReg8;
  2034.       if ((OpSize == -1) || (OpSize == 1)) AdrModeMask |= MModReg16;
  2035.       DecodeAdr(&ArgStr[2], AdrModeMask, &Src);
  2036.       switch (Src.AdrMode)
  2037.       {
  2038.         case ModReg8:
  2039.           BAsmCode[CodeLen++] = 0x39;
  2040.           BAsmCode[CodeLen++] = 0x02 | (Src.AdrVal << 4);
  2041.           BAsmCode[CodeLen++] = Dest.AdrVals[0];
  2042.           break;
  2043.         case ModReg16:
  2044.           BAsmCode[CodeLen++] = 0x39;
  2045.           BAsmCode[CodeLen++] = 0x0a | (Src.AdrVal << 5);
  2046.           BAsmCode[CodeLen++] = Dest.AdrVals[0];
  2047.           break;
  2048.         case ModNone:
  2049.           break;
  2050.         default:
  2051.           WrError(ErrNum_InvAddrMode);
  2052.       }
  2053.       break;
  2054.  
  2055.     case ModAbs16:
  2056.     case ModAbs24:
  2057.       AdrModeMask = 0;
  2058.       if ((OpSize == -1) || (OpSize == 0)) AdrModeMask |= MModReg8;
  2059.       if ((OpSize == -1) || (OpSize == 1)) AdrModeMask |= MModReg16;
  2060.       DecodeAdr(&ArgStr[2], AdrModeMask, &Src);
  2061.       switch (Src.AdrMode)
  2062.       {
  2063.         case ModReg8:
  2064.           BAsmCode[CodeLen++] = 0x3e;
  2065.           BAsmCode[CodeLen++] = 0x04 | (ModIs24(Dest.AdrMode) << 1) | (Src.AdrVal << 4);
  2066.           AppendAdrVals(&Dest);
  2067.           break;
  2068.         case ModReg16:
  2069.           if (Src.AdrVal != AccReg16()) WrError(ErrNum_InvAddrMode);
  2070.           else
  2071.           {
  2072.             BAsmCode[CodeLen++] = 0x0a;
  2073.             BAsmCode[CodeLen++] = 0x45 | (ModIs24(Dest.AdrMode) << 4);
  2074.             AppendAdrVals(&Dest);
  2075.           }
  2076.           break;
  2077.         case ModNone:
  2078.           break;
  2079.         default:
  2080.           WrError(ErrNum_InvAddrMode);
  2081.       }
  2082.       break;
  2083.  
  2084.     case ModShortIndir2_16:
  2085.     case ModShortIndir1_16:
  2086.     case ModShortIndir2_24:
  2087.     case ModShortIndir1_24:
  2088.       AdrModeMask = 0;
  2089.       if ((OpSize == -1) || (OpSize == 0)) AdrModeMask |= MModReg8;
  2090.       if ((OpSize == -1) || (OpSize == 1)) AdrModeMask |= MModReg16;
  2091.       DecodeAdr(&ArgStr[2], AdrModeMask, &Src);
  2092.       switch (Src.AdrMode)
  2093.       {
  2094.         case ModReg8:
  2095.           if (Src.AdrVal != AccReg8()) WrError(ErrNum_InvAddrMode);
  2096.           else
  2097.           {
  2098.             if (ModIsShort1(Dest.AdrMode))
  2099.               BAsmCode[CodeLen++] = 0x3c;
  2100.             if (ModIs24(Dest.AdrMode))
  2101.             {
  2102.               BAsmCode[CodeLen++] = 0x07;
  2103.               BAsmCode[CodeLen++] = 0x34;
  2104.             }
  2105.             else
  2106.               BAsmCode[CodeLen++] = 0x23;
  2107.             BAsmCode[CodeLen++] = Dest.AdrVals[0];
  2108.           }
  2109.           break;
  2110.         case ModReg16:
  2111.           if (Src.AdrVal != AccReg16()) WrError(ErrNum_InvAddrMode);
  2112.           else
  2113.           {
  2114.             if (ModIsShort1(Dest.AdrMode))
  2115.               BAsmCode[CodeLen++] = 0x3c;
  2116.             BAsmCode[CodeLen++] = 0x07;
  2117.             BAsmCode[CodeLen++] = ModIs24(Dest.AdrMode) ? 0x35 : 0x25;
  2118.             BAsmCode[CodeLen++] = Dest.AdrVals[0];
  2119.           }
  2120.           break;
  2121.         case ModNone:
  2122.           break;
  2123.         default:
  2124.           WrError(ErrNum_InvAddrMode);
  2125.       }
  2126.       break;
  2127.  
  2128.     case ModMem:
  2129.       AdrModeMask = 0;
  2130.       if ((OpSize == -1) || (OpSize == 0)) AdrModeMask |= MModReg8;
  2131.       if ((OpSize == -1) || (OpSize == 1)) AdrModeMask |= MModReg16;
  2132.       DecodeAdr(&ArgStr[2], AdrModeMask, &Src);
  2133.       switch (Src.AdrMode)
  2134.       {
  2135.         case ModReg8:
  2136.           if (Src.AdrVal != AccReg8()) WrError(ErrNum_InvAddrMode);
  2137.           else
  2138.           {
  2139.             BAsmCode[CodeLen++] = Dest.AdrVal;
  2140.             AppendAdrValsMem(&Dest, 0x04);
  2141.           }
  2142.           break;
  2143.         case ModReg16:
  2144.           if (Src.AdrVal != AccReg16()) WrError(ErrNum_InvAddrMode);
  2145.           else
  2146.           {
  2147.             BAsmCode[CodeLen++] = Dest.AdrVal;
  2148.             AppendAdrValsMem(&Dest, 0x05);
  2149.           }
  2150.           break;
  2151.         case ModNone:
  2152.           break;
  2153.         default:
  2154.           WrError(ErrNum_InvAddrMode);
  2155.       }
  2156.       break;
  2157.  
  2158.     case ModNone:
  2159.       break;
  2160.     default:
  2161.       WrError(ErrNum_InvAddrMode);
  2162.   }
  2163. }
  2164.  
  2165. static void DecodeALU(Word Code)
  2166. {
  2167.   tEncodedAddress Dest, Src;
  2168.   tAdrModeMask AdrModeMask;
  2169.   Byte Code16, Code16_AX, Code24;
  2170.  
  2171.   if (Code & 15)
  2172.     SetOpSize(Code & 15);
  2173.   Code16 = (Code >> 8) & 15;
  2174.   Code24 = (Code >> 12) & 15;
  2175.   Code16_AX = (Code16 == 0 ? 0x0d : (Code16 == 2 ? 0x0e : 0x0f));
  2176.   Code = (Code >> 4) & 15;
  2177.  
  2178.   if (!ChkArgCnt(2, 2))
  2179.     return;
  2180.  
  2181.   if ((OpSize == -1) && (!as_strcasecmp(ArgStr[1].str.p_str, "CY")))
  2182.   {
  2183.     switch (Code)
  2184.     {
  2185.       case 4: /* AND CY,... -> AND1 CY,...*/
  2186.         DecodeAND1_OR1(0x20);
  2187.         return;
  2188.       case 6: /* OR CY,...  -> OR1 CY,...*/
  2189.         DecodeAND1_OR1(0x40);
  2190.         return;
  2191.       case 5: /* XOR CY,... -> XOR1 CY,...*/
  2192.         DecodeXOR1(0x60);
  2193.         return;
  2194.     }
  2195.   }
  2196.  
  2197.   AdrModeMask = 0;
  2198.   if ((OpSize == -1) || (OpSize == 0) || (OpSize == 1))
  2199.     AdrModeMask = MModShort1 | MModShort2 | MModSFR;
  2200.   if ((OpSize == -1) || (OpSize == 0))
  2201.     AdrModeMask |= MModReg8 | MModShortIndir_All | MModAbsAll | MModMem;
  2202.   if ((Code16 != 15) && ((OpSize == -1) || (OpSize == 1)))
  2203.     AdrModeMask |= MModReg16;
  2204.   if ((Code24 != 15) && ((OpSize == -1) || (OpSize == 2)))
  2205.     AdrModeMask |= MModReg24 | MModSP;
  2206.   DecodeAdr(&ArgStr[1], AdrModeMask, &Dest);
  2207.   switch (Dest.AdrMode)
  2208.   {
  2209.     case ModReg8:
  2210.       AdrModeMask = MModImm | MModReg8 | MModShort1 | MModShort2 | MModSFR | MModAbsAll;
  2211.       if (Dest.AdrVal == AccReg8())
  2212.         AdrModeMask |= MModShortIndir_All | MModMem;
  2213.       DecodeAdr(&ArgStr[2], AdrModeMask, &Src);
  2214.       switch (Src.AdrMode)
  2215.       {
  2216.         case ModImm:
  2217.           if (Dest.AdrVal == AccReg8())
  2218.             BAsmCode[CodeLen++] = 0xa8 | Code;
  2219.           else
  2220.           {
  2221.             BAsmCode[CodeLen++] = 0x78 | Code;
  2222.             BAsmCode[CodeLen++] = 0x03 | (Dest.AdrVal << 4);
  2223.           }
  2224.           BAsmCode[CodeLen++] = Src.AdrVals[0];
  2225.           break;
  2226.         case ModReg8:
  2227.           if (Src.AdrVal >= 8)
  2228.             BAsmCode[CodeLen++] = 0x3c;
  2229.           BAsmCode[CodeLen++] = 0x88 | Code;
  2230.           BAsmCode[CodeLen++] = (Dest.AdrVal << 4) | (Src.AdrVal & 7);
  2231.           break;
  2232.         case ModShort2:
  2233.           if (Dest.AdrVal == AccReg8())
  2234.           {
  2235.             BAsmCode[CodeLen++] = 0x98 | Code;
  2236.             BAsmCode[CodeLen++] = Src.AdrVals[0];
  2237.             break;
  2238.           }
  2239.           /* else fall-through */
  2240.         case ModShort1:
  2241.         case ModSFR:
  2242.           BAsmCode[CodeLen++] = 0x78 | Code;
  2243.           BAsmCode[CodeLen++] = (Dest.AdrVal << 4) | ModShortVal(Src.AdrMode);
  2244.           BAsmCode[CodeLen++] = Src.AdrVals[0];
  2245.           break;
  2246.         case ModShortIndir1_16:
  2247.         case ModShortIndir2_16:
  2248.         case ModShortIndir1_24:
  2249.         case ModShortIndir2_24:
  2250.           if (ModIsShort1(Src.AdrMode))
  2251.             BAsmCode[CodeLen++] = 0x3c;
  2252.           BAsmCode[CodeLen++] = 0x07;
  2253.           BAsmCode[CodeLen++] = 0x28 | (ModIs24(Src.AdrMode) << 4) | Code;
  2254.           BAsmCode[CodeLen++] = Src.AdrVals[0];
  2255.           break;
  2256.         case ModAbs16:
  2257.         case ModAbs24:
  2258.           BAsmCode[CodeLen++] = 0x0a;
  2259.           BAsmCode[CodeLen++] = 0x48 | (ModIs24(Src.AdrMode) << 4) | Code;
  2260.           AppendAdrVals(&Src);
  2261.           break;
  2262.         case ModMem:
  2263.           BAsmCode[CodeLen++] = Src.AdrVal;
  2264.           AppendAdrValsMem(&Src, 0x08 | Code);
  2265.           break;
  2266.         case ModNone:
  2267.           break;
  2268.         default:
  2269.           WrError(ErrNum_InvAddrMode);
  2270.       }
  2271.       break;
  2272.  
  2273.     case ModReg16:
  2274.       AdrModeMask = MModImm | MModReg16 | MModShort1 | MModShort2 | MModSFR;
  2275.       DecodeAdr(&ArgStr[2], AdrModeMask, &Src);
  2276.       switch (Src.AdrMode)
  2277.       {
  2278.         case ModImm:
  2279.           if (Dest.AdrVal == AccReg16())
  2280.             BAsmCode[CodeLen++] = 0x20 | Code16_AX;
  2281.           else
  2282.           {
  2283.             BAsmCode[CodeLen++] = 0x78 | Code16;
  2284.             BAsmCode[CodeLen++] = 0x0d | (Dest.AdrVal << 5);
  2285.           }
  2286.           AppendAdrVals(&Src);
  2287.           break;
  2288.         case ModReg16:
  2289.           BAsmCode[CodeLen++] = 0x88 | Code16;
  2290.           BAsmCode[CodeLen++] = (Src.AdrVal << 5) | 0x08 | Dest.AdrVal;
  2291.           break;
  2292.         case ModShort2:
  2293.           if (Dest.AdrVal == AccReg16())
  2294.           {
  2295.             BAsmCode[CodeLen++] = 0x10 | Code16_AX;
  2296.             BAsmCode[CodeLen++] = Src.AdrVals[0];
  2297.             break;
  2298.           }
  2299.           /* else fall-through */
  2300.         case ModShort1:
  2301.         case ModSFR:
  2302.           BAsmCode[CodeLen++] = 0x78 | Code16;
  2303.           BAsmCode[CodeLen++] = 0x08 | ModShortVal(Src.AdrMode) | (Dest.AdrVal << 5);
  2304.           BAsmCode[CodeLen++] = Src.AdrVals[0];
  2305.           break;
  2306.         case ModNone:
  2307.           break;
  2308.         default:
  2309.           WrError(ErrNum_InvAddrMode);
  2310.       }
  2311.       break;
  2312.  
  2313.     case ModReg24:
  2314.       AdrModeMask = MModImm | MModReg24;
  2315.       if (Dest.AdrVal == WHLReg)
  2316.         AdrModeMask |= MModShort1 | MModShort2;
  2317.       DecodeAdr(&ArgStr[2], AdrModeMask, &Src);
  2318.       switch (Src.AdrMode)
  2319.       {
  2320.         case ModReg24:
  2321.           BAsmCode[CodeLen++] = 0x88 | Code24;
  2322.           BAsmCode[CodeLen++] = 0x99 | (Dest.AdrVal << 5) | (Src.AdrVal << 1);
  2323.           break;
  2324.         case ModImm:
  2325.           BAsmCode[CodeLen++] = 0x78 | Code24;
  2326.           BAsmCode[CodeLen++] = 0x9b | (Dest.AdrVal << 5);
  2327.           AppendAdrVals(&Src);
  2328.           break;
  2329.         case ModShort1:
  2330.         case ModShort2:
  2331.           BAsmCode[CodeLen++] = 0x78 | Code24;
  2332.           BAsmCode[CodeLen++] = 0xf8 | ModShortVal(Src.AdrMode);
  2333.           BAsmCode[CodeLen++] = Src.AdrVals[0];
  2334.           break;
  2335.         case ModNone:
  2336.           break;
  2337.         default:
  2338.           WrError(ErrNum_InvAddrMode);
  2339.       }
  2340.       break;
  2341.  
  2342.     case ModSP:
  2343.       OpSize = 1; /* !!! ADDWG/SUBWG, i.e. 24-bit dest & 16-bit src */
  2344.       DecodeAdr(&ArgStr[2], MModImm, &Src);
  2345.       switch (Src.AdrMode)
  2346.       {
  2347.         case ModImm:
  2348.           BAsmCode[CodeLen++] = 0x09;
  2349.           BAsmCode[CodeLen++] = 0x28 | Code24;
  2350.           AppendAdrVals(&Src);
  2351.           break;
  2352.         case ModNone:
  2353.           break;
  2354.         default:
  2355.           WrError(ErrNum_InvAddrMode);
  2356.       }
  2357.       break;
  2358.  
  2359.     case ModShort2:
  2360.       AssumeByte = True;
  2361.       AdrModeMask = MModImm | MModShort1 | MModShort2;
  2362.       if ((OpSize == -1) || (OpSize == 0)) AdrModeMask |= MModReg8;
  2363.       if ((OpSize == -1) || (OpSize == 1)) AdrModeMask |= MModReg16;
  2364.       DecodeAdr(&ArgStr[2], AdrModeMask, &Src);
  2365.       switch (Src.AdrMode)
  2366.       {
  2367.         case ModImm:
  2368.           BAsmCode[CodeLen++] = OpSize ? Code16_AX : (0x68 | Code);
  2369.           BAsmCode[CodeLen++] = Dest.AdrVals[0];
  2370.           AppendAdrVals(&Src);
  2371.           break;
  2372.         case ModReg8:
  2373.           BAsmCode[CodeLen++] = 0x78 | Code;
  2374.           BAsmCode[CodeLen++] = 0x04 | (Src.AdrVal << 4);
  2375.           BAsmCode[CodeLen++] = Dest.AdrVals[0];
  2376.           break;
  2377.         case ModReg16:
  2378.           BAsmCode[CodeLen++] = 0x78 | Code;
  2379.           BAsmCode[CodeLen++] = 0x0c | (Src.AdrVal << 5);
  2380.           BAsmCode[CodeLen++] = Dest.AdrVals[0];
  2381.           break;
  2382.         case ModShort1:
  2383.         case ModShort2:
  2384.           ExecAssumeByte();
  2385.           BAsmCode[CodeLen++] = 0x2a;
  2386.           if (OpSize)
  2387.             BAsmCode[CodeLen++] = 0x80 | (ModShortVal(Src.AdrMode) << 4) | Code16_AX;
  2388.           else
  2389.             BAsmCode[CodeLen++] = 0x08 | (ModShortVal(Src.AdrMode) << 4) | Code;
  2390.           BAsmCode[CodeLen++] = Src.AdrVals[0];
  2391.           BAsmCode[CodeLen++] = Dest.AdrVals[0];
  2392.           break;
  2393.         case ModNone:
  2394.           break;
  2395.         default:
  2396.           WrError(ErrNum_InvAddrMode);
  2397.       }
  2398.       break;
  2399.  
  2400.     case ModShort1:
  2401.       AssumeByte = True;
  2402.       AdrModeMask = MModImm | MModShort1 | MModShort2;
  2403.       if ((OpSize == -1) || (OpSize == 0)) AdrModeMask |= MModReg8;
  2404.       if ((OpSize == -1) || (OpSize == 1)) AdrModeMask |= MModReg16;
  2405.       DecodeAdr(&ArgStr[2], AdrModeMask, &Src);
  2406.       switch (Src.AdrMode)
  2407.       {
  2408.         case ModImm:
  2409.           BAsmCode[CodeLen++] = 0x3c;
  2410.           BAsmCode[CodeLen++] = OpSize ? Code16_AX : (0x68 | Code);
  2411.           BAsmCode[CodeLen++] = Dest.AdrVals[0];
  2412.           AppendAdrVals(&Src);
  2413.           break;
  2414.         case ModReg8:
  2415.           BAsmCode[CodeLen++] = 0x78 | Code;
  2416.           BAsmCode[CodeLen++] = 0x05 | (Src.AdrVal << 4);
  2417.           BAsmCode[CodeLen++] = Dest.AdrVals[0];
  2418.           break;
  2419.         case ModReg16:
  2420.           BAsmCode[CodeLen++] = 0x78 | Code;
  2421.           BAsmCode[CodeLen++] = 0x0d | (Src.AdrVal << 5);
  2422.           BAsmCode[CodeLen++] = Dest.AdrVals[0];
  2423.           break;
  2424.         case ModShort1:
  2425.         case ModShort2:
  2426.           ExecAssumeByte();
  2427.           BAsmCode[CodeLen++] = 0x2a;
  2428.           if (OpSize)
  2429.             BAsmCode[CodeLen++] = 0xa0 | (ModShortVal(Src.AdrMode) << 4) | Code16_AX;
  2430.           else
  2431.             BAsmCode[CodeLen++] = 0x28 | (ModShortVal(Src.AdrMode) << 4) | Code;
  2432.           BAsmCode[CodeLen++] = Src.AdrVals[0];
  2433.           BAsmCode[CodeLen++] = Dest.AdrVals[0];
  2434.           break;
  2435.         case ModNone:
  2436.           break;
  2437.         default:
  2438.           WrError(ErrNum_InvAddrMode);
  2439.       }
  2440.       break;
  2441.  
  2442.     case ModSFR:
  2443.       AssumeByte = True;
  2444.       AdrModeMask = MModImm;
  2445.       if ((OpSize == -1) || (OpSize == 0)) AdrModeMask |= MModReg8;
  2446.       if ((OpSize == -1) || (OpSize == 1)) AdrModeMask |= MModReg16;
  2447.       DecodeAdr(&ArgStr[2], AdrModeMask, &Src);
  2448.       switch (Src.AdrMode)
  2449.       {
  2450.         case ModImm:
  2451.           BAsmCode[CodeLen++] = 0x01;
  2452.           BAsmCode[CodeLen++] = OpSize ? Code16_AX : (0x68 | Code);
  2453.           BAsmCode[CodeLen++] = Dest.AdrVals[0];
  2454.           AppendAdrVals(&Src);
  2455.           break;
  2456.         case ModReg8:
  2457.           BAsmCode[CodeLen++] = 0x78 | Code;
  2458.           BAsmCode[CodeLen++] = 0x06 | (Src.AdrVal << 4);
  2459.           BAsmCode[CodeLen++] = Dest.AdrVals[0];
  2460.           break;
  2461.         case ModReg16:
  2462.           BAsmCode[CodeLen++] = 0x78 | Code;
  2463.           BAsmCode[CodeLen++] = 0x0e | (Src.AdrVal << 5);
  2464.           BAsmCode[CodeLen++] = Dest.AdrVals[0];
  2465.           break;
  2466.         case ModNone:
  2467.           break;
  2468.         default:
  2469.           WrError(ErrNum_InvAddrMode);
  2470.       }
  2471.       break;
  2472.  
  2473.     case ModShortIndir2_16:
  2474.     case ModShortIndir1_16:
  2475.     case ModShortIndir2_24:
  2476.     case ModShortIndir1_24:
  2477.       AdrModeMask = 0;
  2478.       if ((OpSize == -1) || (OpSize == 0)) AdrModeMask |= MModReg8;
  2479.       DecodeAdr(&ArgStr[2], AdrModeMask, &Src);
  2480.       switch (Src.AdrMode)
  2481.       {
  2482.         case ModReg8:
  2483.           if (Src.AdrVal != AccReg8()) WrError(ErrNum_InvAddrMode);
  2484.           else
  2485.           {
  2486.             if (ModIsShort1(Dest.AdrMode))
  2487.               BAsmCode[CodeLen++] = 0x3c;
  2488.             BAsmCode[CodeLen++] = 0x07;
  2489.             BAsmCode[CodeLen++] = 0xa8 | (ModIs24(Dest.AdrMode) << 4) | Code;
  2490.             BAsmCode[CodeLen++] = Dest.AdrVals[0];
  2491.           }
  2492.           break;
  2493.         case ModNone:
  2494.           break;
  2495.         default:
  2496.           WrError(ErrNum_InvAddrMode);
  2497.       }
  2498.       break;
  2499.  
  2500.     case ModAbs16:
  2501.     case ModAbs24:
  2502.       AdrModeMask = 0;
  2503.       if ((OpSize == -1) || (OpSize == 0)) AdrModeMask |= MModReg8;
  2504.       DecodeAdr(&ArgStr[2], AdrModeMask, &Src);
  2505.       switch (Src.AdrMode)
  2506.       {
  2507.         case ModReg8:
  2508.           if (Src.AdrVal != AccReg8()) WrError(ErrNum_InvAddrMode);
  2509.           else
  2510.           {
  2511.             BAsmCode[CodeLen++] = 0x0a;
  2512.             BAsmCode[CodeLen++] = 0xc8 | (ModIs24(Dest.AdrMode) << 4) | Code;
  2513.             AppendAdrVals(&Dest);
  2514.           }
  2515.           break;
  2516.         case ModNone:
  2517.           break;
  2518.         default:
  2519.           WrError(ErrNum_InvAddrMode);
  2520.       }
  2521.       break;
  2522.  
  2523.     case ModMem:
  2524.       AdrModeMask = 0;
  2525.       if ((OpSize == -1) || (OpSize == 0)) AdrModeMask |= MModReg8;
  2526.       DecodeAdr(&ArgStr[2], AdrModeMask, &Src);
  2527.       switch (Src.AdrMode)
  2528.       {
  2529.         case ModReg8:
  2530.           if (Src.AdrVal != AccReg8()) WrError(ErrNum_InvAddrMode);
  2531.           else
  2532.           {
  2533.             BAsmCode[CodeLen++] = Dest.AdrVal;
  2534.             AppendAdrValsMem(&Dest, 0x88 | Code);
  2535.           }
  2536.           break;
  2537.         case ModNone:
  2538.           break;
  2539.         default:
  2540.           WrError(ErrNum_InvAddrMode);
  2541.       }
  2542.       break;
  2543.     case ModNone:
  2544.       break;
  2545.     default:
  2546.       WrError(ErrNum_InvAddrMode);
  2547.   }
  2548. }
  2549.  
  2550. static void DecodeADDWG_SUBWG(Word Code)
  2551. {
  2552.   tEncodedAddress Addr;
  2553.  
  2554.   if (ChkArgCnt(2, 2))
  2555.   {
  2556.     OpSize = 2;
  2557.     if (DecodeAdr(&ArgStr[1], MModSP, &Addr))
  2558.     {
  2559.       OpSize = 1; /* !!! ADDWG/SUBWG, i.e. 24-bit dest & 16-bit src */
  2560.       if (DecodeAdr(&ArgStr[2], MModImm, &Addr))
  2561.       {
  2562.         BAsmCode[CodeLen++] = 0x09;
  2563.         BAsmCode[CodeLen++] = 0x28 | Code;
  2564.         AppendAdrVals(&Addr);
  2565.       }
  2566.     }
  2567.   }
  2568. }
  2569.  
  2570. static void DecodeMULU(Word Code)
  2571. {
  2572.   tEncodedAddress Src;
  2573.   tAdrModeMask AdrModeMask;
  2574.  
  2575.   if (Code & 15)
  2576.     SetOpSize(Code & 15);
  2577.  
  2578.   if (!ChkArgCnt(1, 1))
  2579.     return;
  2580.  
  2581.   AdrModeMask = 0;
  2582.   if ((OpSize == -1) || (OpSize == 0))
  2583.     AdrModeMask |= MModReg8;
  2584.   if ((OpSize == -1) || (OpSize == 1))
  2585.     AdrModeMask |= MModReg16;
  2586.   DecodeAdr(&ArgStr[1], AdrModeMask, &Src);
  2587.   switch (Src.AdrMode)
  2588.   {
  2589.     case ModReg8:
  2590.       if (Src.AdrVal >= 8)
  2591.         BAsmCode[CodeLen++] = 0x3c;
  2592.       BAsmCode[CodeLen++] = 0x05;
  2593.       BAsmCode[CodeLen++] = 0x08 | (Src.AdrVal & 7);
  2594.       break;
  2595.     case ModReg16:
  2596.       BAsmCode[CodeLen++] = 0x05;
  2597.       BAsmCode[CodeLen++] = 0x28 | Src.AdrVal;
  2598.       break;
  2599.     case ModNone:
  2600.       break;
  2601.     default:
  2602.       WrError(ErrNum_InvAddrMode);
  2603.   }
  2604. }
  2605.  
  2606. static void DecodeDIVUW(Word Code)
  2607. {
  2608.   tEncodedAddress Src;
  2609.   UNUSED(Code);
  2610.  
  2611.   if (ChkArgCnt(1, 1)
  2612.    && DecodeAdr(&ArgStr[1], MModReg8, &Src))
  2613.   {
  2614.     if (Src.AdrVal >= 8)
  2615.       BAsmCode[CodeLen++] = 0x3c;
  2616.     BAsmCode[CodeLen++] = 0x05;
  2617.     BAsmCode[CodeLen++] = 0x18 | (Src.AdrVal & 7);
  2618.   }
  2619. }
  2620.  
  2621. static void DecodeMULW_DIVUX(Word Code)
  2622. {
  2623.   tEncodedAddress Src;
  2624.  
  2625.   if (ChkArgCnt(1, 1)
  2626.    && DecodeAdr(&ArgStr[1], MModReg16, &Src))
  2627.   {
  2628.     BAsmCode[CodeLen++] = 0x05;
  2629.     BAsmCode[CodeLen++] = Code | Src.AdrVal;
  2630.   }
  2631. }
  2632.  
  2633. static void DecodeMACW_MACSW(Word Code)
  2634. {
  2635.   if (ChkArgCnt(1, 1))
  2636.   {
  2637.     Boolean OK;
  2638.  
  2639.     BAsmCode[2] = EvalStrIntExpression(&ArgStr[1], UInt8, &OK);
  2640.     if (OK)
  2641.     {
  2642.       BAsmCode[CodeLen++] = 0x07;
  2643.       BAsmCode[CodeLen++] = Code;
  2644.       CodeLen++;
  2645.     }
  2646.   }
  2647. }
  2648.  
  2649. static void DecodeSACW(Word Code)
  2650. {
  2651.   tEncodedAddress Addr;
  2652.   UNUSED(Code);
  2653.  
  2654.   if (ChkArgCnt(2, 2)
  2655.    && DecodeAdr(&ArgStr[1], MModMem, &Addr))
  2656.   {
  2657.     if ((Addr.AdrVal != 0x16) || (Addr.AdrVals[0] != 0x00)) WrError(ErrNum_InvAddrMode);
  2658.     else if (DecodeAdr(&ArgStr[2], MModMem, &Addr))
  2659.     {
  2660.       if ((Addr.AdrVal != 0x16) || (Addr.AdrVals[0] != 0x01)) WrError(ErrNum_InvAddrMode);
  2661.       else
  2662.       {
  2663.         BAsmCode[CodeLen++] = 0x09;
  2664.         BAsmCode[CodeLen++] = 0x64;
  2665.         BAsmCode[CodeLen++] = 0x41;
  2666.         BAsmCode[CodeLen++] = 0x46;
  2667.       }
  2668.     }
  2669.   }
  2670. }
  2671.  
  2672. static void DecodeINCDEC(Word Code)
  2673. {
  2674.   tEncodedAddress Addr;
  2675.   tAdrModeMask AdrModeMask;
  2676.  
  2677.   if (Code & 15)
  2678.     SetOpSize(Code & 15);
  2679.   Code >>= 4;
  2680.  
  2681.   if (!ChkArgCnt(1, 1))
  2682.     return;
  2683.  
  2684.   AdrModeMask = 0;
  2685.   if ((OpSize == -1) || (OpSize == 0)) AdrModeMask |= MModReg8 | MModShort1 | MModShort2;
  2686.   if ((OpSize == -1) || (OpSize == 1)) AdrModeMask |= MModReg16 | MModShort1 | MModShort2;
  2687.   if ((OpSize == -1) || (OpSize == 2)) AdrModeMask |= MModReg24 | MModSP;
  2688.   AssumeByte = True;
  2689.   DecodeAdr(&ArgStr[1], AdrModeMask, &Addr);
  2690.   switch (Addr.AdrMode)
  2691.   {
  2692.     case ModReg8:
  2693.       if (Addr.AdrVal >= 8)
  2694.         BAsmCode[CodeLen++] = 0x3c;
  2695.       BAsmCode[CodeLen++] = 0xc0 | (Code << 3) | (Addr.AdrVal & 7);
  2696.       break;
  2697.     case ModReg16:
  2698.       if (Addr.AdrVal >= 4)
  2699.         BAsmCode[CodeLen++] = 0x40 | (Code << 3) | Addr.AdrVal;
  2700.       else
  2701.       {
  2702.         BAsmCode[CodeLen++] = 0x3e;
  2703.         BAsmCode[CodeLen++] = 0x0d | (Code << 1) | (Addr.AdrVal << 5);
  2704.       }
  2705.       break;
  2706.     case ModReg24:
  2707.       BAsmCode[CodeLen++] = 0x3e;
  2708.       BAsmCode[CodeLen++] = 0x9d | (Code << 1) | (Addr.AdrVal << 5);
  2709.       break;
  2710.     case ModSP:
  2711.       BAsmCode[CodeLen++] = 0x05;
  2712.       BAsmCode[CodeLen++] = 0xf8 | Code;
  2713.       break;
  2714.     case ModShort1:
  2715.       BAsmCode[CodeLen++] = 0x3c;
  2716.       /* fall-through */
  2717.     case ModShort2:
  2718.       ExecAssumeByte();
  2719.       if (OpSize)
  2720.       {
  2721.         BAsmCode[CodeLen++] = 0x07;
  2722.         BAsmCode[CodeLen++] = 0xe8 | Code;
  2723.       }
  2724.       else
  2725.         BAsmCode[CodeLen++] = 0x26 | Code;
  2726.       BAsmCode[CodeLen++] = Addr.AdrVals[0];
  2727.       break;
  2728.     case ModNone:
  2729.       break;
  2730.     default:
  2731.       WrError(ErrNum_InvAddrMode);
  2732.   }
  2733. }
  2734.  
  2735. static void DecodeShift(Word Code)
  2736. {
  2737.   tEncodedAddress Addr;
  2738.   Boolean OK;
  2739.   Byte Shift;
  2740.   tAdrModeMask AdrModeMask;
  2741.  
  2742.   if (!ChkArgCnt(2, 2))
  2743.     return;
  2744.   Shift = EvalStrIntExpression(&ArgStr[2], UInt3, &OK);
  2745.   if (!OK)
  2746.     return;
  2747.  
  2748.   if (Code & 15)
  2749.     SetOpSize(Code & 15);
  2750.   AdrModeMask = 0;
  2751.   if ((OpSize == -1) || (OpSize == 0)) AdrModeMask |= MModReg8;
  2752.   if ((Code & 0x8000) && ((OpSize == -1) || (OpSize == 1))) AdrModeMask |= MModReg16;
  2753.   DecodeAdr(&ArgStr[1], AdrModeMask, &Addr);
  2754.   switch (Addr.AdrMode)
  2755.   {
  2756.     case ModReg8:
  2757.       if (Addr.AdrVal >= 8)
  2758.         BAsmCode[CodeLen++] = 0x3c;
  2759.       BAsmCode[CodeLen++] = Hi(Code) & 0x7f;
  2760.       BAsmCode[CodeLen++] = (Lo(Code) & 0xc0) | (Shift << 3) | (Addr.AdrVal & 7);
  2761.       break;
  2762.     case ModReg16:
  2763.       BAsmCode[CodeLen++] = Hi(Code) & 0x7f;
  2764.       BAsmCode[CodeLen++] = 0x40 | (Lo(Code) & 0xc0) | (Shift << 3) | (Addr.AdrVal & 7);
  2765.       break;
  2766.     case ModNone:
  2767.       break;
  2768.     default:
  2769.       WrError(ErrNum_InvAddrMode);
  2770.   }
  2771. }
  2772.  
  2773. static void DecodeROR4_ROL4(Word Code)
  2774. {
  2775.   if (!ChkArgCnt(1, 1));
  2776.   else if (!DecodeMem3(ArgStr[1].str.p_str, BAsmCode + 1)) WrError(ErrNum_InvAddrMode);
  2777.   else
  2778.   {
  2779.     BAsmCode[CodeLen++] = 0x05;
  2780.     BAsmCode[CodeLen] |= Code; CodeLen++;
  2781.   }
  2782. }
  2783.  
  2784. static void DecodeBIT(Word Code)
  2785. {
  2786.   LongWord Result;
  2787.  
  2788.   UNUSED(Code);
  2789.  
  2790.   if (!ChkArgCnt(1, 1));
  2791.   else if (DecodeBitAdr(&ArgStr[1], &Result))
  2792.   {
  2793.     TempResult t;
  2794.  
  2795.     as_tempres_ini(&t);
  2796.     as_tempres_set_int(&t, Result);
  2797.     SetListLineVal(&t);
  2798.     EnterIntSymbol(&LabPart, Result, SegNone, False);
  2799.     as_tempres_free(&t);
  2800.   }
  2801. }
  2802.  
  2803. static void DecodePUSH_POP(Word Code)
  2804. {
  2805.   tEncodedAddress Address, SumAddress;
  2806.   int z;
  2807.   Boolean IsU, IsPUSH;
  2808.  
  2809.   if (Code & 15)
  2810.     SetOpSize(Code & 15);
  2811.  
  2812.   Code = (Code >> 4) & 0xff;
  2813.   IsU = (Code == 0x37) || (Code == 0x36),
  2814.   IsPUSH = (Code == 0x35);
  2815.  
  2816.   if (!ChkArgCnt(1, ArgCntMax))
  2817.     return;
  2818.  
  2819.   ClearEncodedAddress(&SumAddress);
  2820.   for (z = 1; z <= ArgCnt; z++)
  2821.   {
  2822.     ClearEncodedAddress(&Address);
  2823.     if (!as_strcasecmp(ArgStr[z].str.p_str, "PSW"))
  2824.     {
  2825.       /* PSW replaces UP in bitmask for PUSHU/POPU */
  2826.       if (IsU)
  2827.       {
  2828.         Address.AdrMode = ModReg16;
  2829.         Address.AdrVal = 5;
  2830.       }
  2831.       /* PSW only allowed a single (first) arg on for PUSH/POP */
  2832.       else if (z == 1)
  2833.         Address.AdrMode = ModPSW;
  2834.       else
  2835.       {
  2836.         WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[z]);
  2837.         return;
  2838.       }
  2839.       if (!SetOpSize(1))
  2840.         return;
  2841.     }
  2842.     else
  2843.     {
  2844.       tAdrModeMask AdrModeMask = MModReg16;
  2845.  
  2846.       /* sfr/sfrp/rg only allowed as single (first) argument, and only for PUSH/POP */
  2847.  
  2848.       if ((z == 1) && (!IsU))
  2849.         AdrModeMask |= MModSFR | MModReg24;
  2850.       if (!DecodeAdr(&ArgStr[z], AdrModeMask, &Address))
  2851.         return;
  2852.  
  2853.       /* UP not allowed for PUSHU(POPU */
  2854.  
  2855.       if (IsU && (Address.AdrVal == 5))
  2856.       {
  2857.         WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[z]);
  2858.         return;
  2859.       }
  2860.     }
  2861.  
  2862.     /* merge this argument with rest so far: */
  2863.  
  2864.     if (SumAddress.AdrMode == ModNone)
  2865.     {
  2866.       SumAddress = Address;
  2867.       if (Address.AdrMode == ModReg16)
  2868.         SumAddress.AdrVals[0] = 1 << Address.AdrVal;
  2869.     }
  2870.     else if ((Address.AdrMode != SumAddress.AdrMode) || (SumAddress.AdrMode != ModReg16))
  2871.     {
  2872.       WrError(ErrNum_InvAddrMode);
  2873.       return;
  2874.     }
  2875.     else
  2876.       SumAddress.AdrVals[0] |= 1 << Address.AdrVal;
  2877.   }
  2878.  
  2879.   AssumeByte = True;
  2880.   switch (SumAddress.AdrMode)
  2881.   {
  2882.     case ModReg16:
  2883.       BAsmCode[CodeLen++] = Code;
  2884.       BAsmCode[CodeLen++] = SumAddress.AdrVals[0];
  2885.       break;
  2886.     case ModPSW:
  2887.       BAsmCode[CodeLen++] = IsPUSH ? 0x49 : 0x48;
  2888.       break;
  2889.     case ModSFR:
  2890.       ExecAssumeByte();
  2891.       BAsmCode[CodeLen++] = 0x07;
  2892.       BAsmCode[CodeLen++] = (IsPUSH ? 0xdb: 0xda) - (OpSize << 1);
  2893.       BAsmCode[CodeLen++] = SumAddress.AdrVals[0];
  2894.       break;
  2895.     case ModReg24:
  2896.       BAsmCode[CodeLen++] = 0x09;
  2897.       BAsmCode[CodeLen++] = (IsPUSH ? 0x89 : 0x99) | (SumAddress.AdrVal << 1);
  2898.       break;
  2899.     case ModNone:
  2900.       break;
  2901.     default:
  2902.       WrError(ErrNum_InvAddrMode);
  2903.   }
  2904. }
  2905.  
  2906. static void DecodeCALL_BR(Word IsCALL)
  2907. {
  2908.   tEncodedAddress Addr;
  2909.  
  2910.   if (ChkArgCnt(1, 1)
  2911.    && StripIndirect(&ArgStr[1]))
  2912.   {
  2913.     DecodeAdr(&ArgStr[1], MModReg16 | MModReg24, &Addr);
  2914.     switch (Addr.AdrMode)
  2915.     {
  2916.       case ModReg16:
  2917.         BAsmCode[CodeLen++] = 0x05;
  2918.         BAsmCode[CodeLen++] = 0x68 | (IsCALL << 4) | Addr.AdrVal;
  2919.         break;
  2920.       case ModReg24:
  2921.         BAsmCode[CodeLen++] = 0x05;
  2922.         BAsmCode[CodeLen++] = 0x61 | (IsCALL << 4) | (Addr.AdrVal << 1);
  2923.         break;
  2924.       case ModNone:
  2925.         break;
  2926.       default:
  2927.         WrError(ErrNum_InvAddrMode);
  2928.     }
  2929.   }
  2930.   else
  2931.   {
  2932.     DecodeAdr(&ArgStr[1], MModReg16 | MModReg24 | MModAbs16 | MModAbs20, &Addr);
  2933.     switch (Addr.AdrMode)
  2934.     {
  2935.       case ModReg16:
  2936.         BAsmCode[CodeLen++] = 0x05;
  2937.         BAsmCode[CodeLen++] = 0x48 | (IsCALL << 4) | Addr.AdrVal;
  2938.         break;
  2939.       case ModReg24:
  2940.         BAsmCode[CodeLen++] = 0x05;
  2941.         BAsmCode[CodeLen++] = 0x41 | (IsCALL << 4) | (Addr.AdrVal << 1);
  2942.         break;
  2943.       case ModAbs16:
  2944.       case ModAbs20:
  2945.       {
  2946.         LongWord Dest = GetAbsVal(&Addr);
  2947.         LongInt Dist16 = Dest - (EProgCounter() + 3),
  2948.                 Dist8 = Dest - (EProgCounter() + 2);
  2949.         Boolean Dist16OK = (Dist16 >= -0x8000l) && (Dist16 <= 0x7fffl),
  2950.                 Dist8OK = (Dist8 >= -0x80) && (Dist8 <= 0x7f);
  2951.  
  2952.         if (!Addr.ForceAbs && !Addr.ForceRel)
  2953.         {
  2954.           if (Dist8OK && !IsCALL)
  2955.           {
  2956.             Addr.ForceRel = True; Addr.ForceAbs = False;
  2957.           }
  2958.           else if (Dist16OK)
  2959.           {
  2960.             Addr.ForceRel = Addr.ForceAbs = True;
  2961.           }
  2962.           else
  2963.           {
  2964.             Addr.ForceAbs = True; Addr.ForceRel = False;
  2965.           }
  2966.         }
  2967.  
  2968.         if (!Addr.ForceRel)
  2969.         {
  2970.           if (Addr.AdrMode == ModAbs20)
  2971.           {
  2972.             BAsmCode[CodeLen++] = 0x09;
  2973.             BAsmCode[CodeLen++] = 0xe0 | (IsCALL << 4) | Lo(Addr.AdrVals[2]);
  2974.           }
  2975.           else
  2976.             BAsmCode[CodeLen++] = IsCALL ? 0x28 : 0x2c;
  2977.           BAsmCode[CodeLen++] = Addr.AdrVals[0];
  2978.           BAsmCode[CodeLen++] = Addr.AdrVals[1];
  2979.         }
  2980.         else if (IsCALL || Addr.ForceAbs)
  2981.         {
  2982.           if (!mFirstPassUnknown(Addr.AdrValSymFlags) && !Dist16OK) WrError(ErrNum_JmpDistTooBig);
  2983.           else
  2984.           {
  2985.             BAsmCode[CodeLen++] = IsCALL ? 0x3f : 0x43;
  2986.             BAsmCode[CodeLen++] = Dist16 & 0xff;
  2987.             BAsmCode[CodeLen++] = (Dist16 >> 8) & 0xff;
  2988.           }
  2989.         }
  2990.         else
  2991.         {
  2992.           if (!mFirstPassUnknown(Addr.AdrValSymFlags) && !Dist8OK) WrError(ErrNum_JmpDistTooBig);
  2993.           else
  2994.           {
  2995.             BAsmCode[CodeLen++] = 0x14;
  2996.             BAsmCode[CodeLen++] = Dist8 & 0xff;
  2997.           }
  2998.         }
  2999.  
  3000.         break;
  3001.       }
  3002.       case ModNone:
  3003.         break;
  3004.       default:
  3005.         WrError(ErrNum_InvAddrMode);
  3006.     }
  3007.   }
  3008. }
  3009.  
  3010. static void DecodeCALLF(Word Code)
  3011. {
  3012.   UNUSED(Code);
  3013.  
  3014.   if (ArgCnt != 1) WrError(ErrNum_InvAddrMode);
  3015.   else
  3016.   {
  3017.     Boolean OK;
  3018.     Word Addr;
  3019.     tSymbolFlags Flags;
  3020.  
  3021.     Addr = EvalStrIntExpressionOffsWithFlags(&ArgStr[1], !!(*ArgStr[1].str.p_str == '!'), UInt12, &OK, &Flags);
  3022.     if (mFirstPassUnknown(Flags))
  3023.       Addr |= 0x800;
  3024.     if (OK && ChkRange(Addr, 0x800, 0xfff))
  3025.     {
  3026.       BAsmCode[CodeLen++] = 0x90 | ((Addr >> 8) & 7);
  3027.       BAsmCode[CodeLen++] = Lo(Addr);
  3028.     }
  3029.   }
  3030. }
  3031.  
  3032. static void DecodeCALLT(Word Code)
  3033. {
  3034.   UNUSED(Code);
  3035.  
  3036.   if (ArgCnt != 1) WrError(ErrNum_InvAddrMode);
  3037.   else if (!StripIndirect(&ArgStr[1])) WrError(ErrNum_InvAddrMode);
  3038.   else
  3039.   {
  3040.     Boolean OK;
  3041.     Word Addr;
  3042.     tSymbolFlags Flags;
  3043.  
  3044.     Addr = EvalStrIntExpressionOffsWithFlags(&ArgStr[1], !!(*ArgStr[1].str.p_str == '!'), UInt7, &OK, &Flags);
  3045.     if (mFirstPassUnknown(Flags))
  3046.       Addr = (Addr | 0x40) & 0xfe;
  3047.     if (OK && (Addr & 1)) WrError(ErrNum_NotAligned);
  3048.     else if (OK && ChkRange(Addr, 0x40, 0xff))
  3049.     {
  3050.       BAsmCode[CodeLen++] = 0xe0 | ((Addr >> 1) & 0x1f);
  3051.     }
  3052.   }
  3053. }
  3054.  
  3055. static void DecodeBRKCS(Word Code)
  3056. {
  3057.   UNUSED(Code);
  3058.  
  3059.   if (!ChkArgCnt(1, 1));
  3060.   else if (!DecodeRB(ArgStr[1].str.p_str, BAsmCode + 1)) WrStrErrorPos(ErrNum_InvReg, &ArgStr[1]);
  3061.   else
  3062.   {
  3063.     BAsmCode[CodeLen++] = 0x05;
  3064.     BAsmCode[CodeLen++] = BAsmCode[1] | 0xd8;
  3065.   }
  3066. }
  3067.  
  3068. static void DecodeRETCS(Word Code)
  3069. {
  3070.   if (ArgCnt != 1) WrError(ErrNum_InvAddrMode);
  3071.   else
  3072.   {
  3073.     Boolean OK;
  3074.     Word Addr;
  3075.  
  3076.     Addr = EvalStrIntExpressionOffs(&ArgStr[1], !!(*ArgStr[1].str.p_str == '!'), UInt16, &OK);
  3077.     if (OK)
  3078.     {
  3079.       PutCode(Code);
  3080.       BAsmCode[CodeLen++] = Lo(Addr);
  3081.       BAsmCode[CodeLen++] = Hi(Addr);
  3082.     }
  3083.   }
  3084. }
  3085.  
  3086. static void DecodeRel(Word Code)
  3087. {
  3088.   if (ArgCnt != 1) WrError(ErrNum_InvAddrMode);
  3089.   else
  3090.   {
  3091.     PutCode(Code);
  3092.     AppendRel8(&ArgStr[1]);
  3093.   }
  3094. }
  3095.  
  3096. static void DecodeBitRel(Word Code)
  3097. {
  3098.   LongWord BitAddr;
  3099.  
  3100.   if (ArgCnt != 2) WrError(ErrNum_InvAddrMode);
  3101.   else if (DecodeBitAdr(&ArgStr[1], &BitAddr))
  3102.   {
  3103.     switch ((BitAddr >> 28) & 15)
  3104.     {
  3105.       case eBitTypeSAddr1:
  3106.         if (Code != 0xb0)
  3107.           goto Common;
  3108.         BAsmCode[CodeLen++] = 0x3c;
  3109.         BAsmCode[CodeLen++] = 0x70 | ((BitAddr >> 24) & 7);
  3110.         BAsmCode[CodeLen++] = BitAddr & 0xff;
  3111.         break;
  3112.       case eBitTypeSAddr2_SFR:
  3113.         if ((Code != 0xb0) || (BitAddr & Bit27))
  3114.           goto Common;
  3115.         BAsmCode[CodeLen++] = 0x70 | ((BitAddr >> 24) & 7);
  3116.         BAsmCode[CodeLen++] = BitAddr & 0xff;
  3117.         break;
  3118.       Common:
  3119.       default:
  3120.         DecodeBitOpCore2(BitAddr, Code);
  3121.     }
  3122.  
  3123.     AppendRel8(&ArgStr[2]);
  3124.   }
  3125. }
  3126.  
  3127. static void DecodeDBNZ(Word Code)
  3128. {
  3129.   tEncodedAddress Addr;
  3130.  
  3131.   UNUSED(Code);
  3132.  
  3133.   if (ArgCnt != 2)
  3134.   {
  3135.     WrError(ErrNum_InvAddrMode);
  3136.     return;
  3137.   }
  3138.  
  3139.   DecodeAdr(&ArgStr[1], MModShort1 | MModShort2 | MModReg8, &Addr);
  3140.   switch (Addr.AdrMode)
  3141.   {
  3142.     case ModShort1:
  3143.       BAsmCode[CodeLen++] = 0x3c;
  3144.       /* fall-through */
  3145.     case ModShort2:
  3146.       BAsmCode[CodeLen++] = 0x3b;
  3147.       BAsmCode[CodeLen++] = Addr.AdrVals[0];
  3148.       break;
  3149.     case ModReg8:
  3150.       if (Addr.AdrVal == BReg8())
  3151.         BAsmCode[CodeLen++] = 0x33;
  3152.       else if (Addr.AdrVal == CReg8())
  3153.         BAsmCode[CodeLen++] = 0x32;
  3154.       else
  3155.       {
  3156.         WrError(ErrNum_InvAddrMode);
  3157.         return;
  3158.       }
  3159.       break;
  3160.     case ModNone:
  3161.       return;
  3162.     default:
  3163.       WrError(ErrNum_InvAddrMode);
  3164.       return;
  3165.   }
  3166.  
  3167.   AppendRel8(&ArgStr[2]);
  3168. }
  3169.  
  3170. static void DecodeLOCATION(Word Code)
  3171. {
  3172.   Byte Val;
  3173.   Boolean OK;
  3174.   tSymbolFlags Flags;
  3175.  
  3176.   UNUSED(Code);
  3177.  
  3178.   if (!ChkArgCnt(1, 1))
  3179.     return;
  3180.  
  3181.   Val = EvalStrIntExpressionWithFlags(&ArgStr[1], UInt4, &OK, &Flags);
  3182.   if (!OK)
  3183.     return;
  3184.   if (mFirstPassUnknown(Flags))
  3185.     Val = 0;
  3186.   switch (Val)
  3187.   {
  3188.     case 0:
  3189.       BAsmCode[CodeLen++] = 0x09;
  3190.       BAsmCode[CodeLen++] = 0xc1;
  3191.       BAsmCode[CodeLen++] = 0xfe;
  3192.       BAsmCode[CodeLen++] = 0x01;
  3193.       break;
  3194.     case 15:
  3195.       BAsmCode[CodeLen++] = 0x09;
  3196.       BAsmCode[CodeLen++] = 0xc1;
  3197.       BAsmCode[CodeLen++] = 0xff;
  3198.       BAsmCode[CodeLen++] = 0x00;
  3199.       break;
  3200.     default:
  3201.       WrError(ErrNum_OverRange);
  3202.   }
  3203. }
  3204.  
  3205. static void DecodeSEL(Word Code)
  3206. {
  3207.   Byte Bank;
  3208.  
  3209.   UNUSED(Code);
  3210.  
  3211.   if ((ArgCnt == 2) && (as_strcasecmp(ArgStr[2].str.p_str, "ALT")))
  3212.   {
  3213.     WrError(ErrNum_InvAddrMode);
  3214.     return;
  3215.   }
  3216.   if (!ChkArgCnt(1, 2))
  3217.     return;
  3218.  
  3219.   if (!DecodeRB(ArgStr[1].str.p_str, &Bank)) WrStrErrorPos(ErrNum_InvReg, &ArgStr[1]);
  3220.   else
  3221.   {
  3222.     BAsmCode[CodeLen++] = 0x05;
  3223.     BAsmCode[CodeLen++] = 0xa8 | ((ArgCnt - 1) << 4) | Bank;
  3224.   }
  3225. }
  3226.  
  3227. static void DecodeCHK(Word Code)
  3228. {
  3229.   tEncodedAddress Address;
  3230.  
  3231.   if (ChkArgCnt(1, 1)
  3232.    && DecodeAdr(&ArgStr[1], MModSFR, &Address))
  3233.   {
  3234.     PutCode(Code);
  3235.     BAsmCode[CodeLen++] = Address.AdrVals[0];
  3236.   }
  3237. }
  3238.  
  3239. static void DecodeMOVTBLW(Word Code)
  3240. {
  3241.   Byte Addr, Value;
  3242.   Boolean OK;
  3243.  
  3244.   UNUSED(Code);
  3245.  
  3246.   if (ChkArgCnt(2, 2))
  3247.   {
  3248.     Addr = EvalStrIntExpressionOffs(&ArgStr[1], !!(*ArgStr[1].str.p_str == '!'), UInt8, &OK);
  3249.     if (OK)
  3250.     {
  3251.       Value = EvalStrIntExpression(&ArgStr[2], Int8, &OK);
  3252.       if (OK)
  3253.       {
  3254.         BAsmCode[CodeLen++] = 0x09;
  3255.         BAsmCode[CodeLen++] = 0xa0;
  3256.         BAsmCode[CodeLen++] = Addr;
  3257.         BAsmCode[CodeLen++] = Value;
  3258.       }
  3259.     }
  3260.   }
  3261. }
  3262.  
  3263. static void DecodeStringAcc(Word Code)
  3264. {
  3265.   tEncodedAddress Addr;
  3266.  
  3267.   if (ChkArgCnt(2, 2)
  3268.    && DecodeAdr(&ArgStr[2], MModReg8, &Addr))
  3269.   {
  3270.     if (Addr.AdrVal != AccReg8()) WrError(ErrNum_InvAddrMode);
  3271.     else if (DecodeAdr(&ArgStr[1], MModMem, &Addr))
  3272.     {
  3273.       if (Addr.AdrVal != 0x16) WrError(ErrNum_InvAddrMode);
  3274.       else if ((Addr.AdrVals[0] & 0xfd) != 0) WrError(ErrNum_InvAddrMode);
  3275.       else
  3276.         PutCode(Code | ((Addr.AdrVals[0] & 2) << 3));
  3277.     }
  3278.   }
  3279. }
  3280.  
  3281. static void DecodeStringString(Word Code)
  3282. {
  3283.   tEncodedAddress Addr;
  3284.  
  3285.   if (ChkArgCnt(2, 2)
  3286.    && DecodeAdr(&ArgStr[1], MModMem, &Addr))
  3287.   {
  3288.     Byte Dir = Addr.AdrVals[0];
  3289.  
  3290.     if (Addr.AdrVal != 0x16) WrError(ErrNum_InvAddrMode);
  3291.     else if ((Addr.AdrVals[0] & 0xfd) != 0) WrError(ErrNum_InvAddrMode);
  3292.     else if (DecodeAdr(&ArgStr[2], MModMem, &Addr))
  3293.     {
  3294.       if (Addr.AdrVal != 0x16) WrError(ErrNum_InvAddrMode);
  3295.       else if (Addr.AdrVals[0] != Dir + 1) WrError(ErrNum_InvAddrMode);
  3296.       else
  3297.         PutCode(Code | ((Dir & 2) << 3));
  3298.     }
  3299.   }
  3300. }
  3301.  
  3302. /*-------------------------------------------------------------------------*/
  3303. /* dynamic code table handling */
  3304.  
  3305. static void AddInstr(const char *pInstr, InstProc Proc, Word Code, unsigned SizeMask)
  3306. {
  3307.   char Instr[20];
  3308.  
  3309.   Code <<= 4;
  3310.  
  3311.   if (SizeMask & 1)
  3312.     AddInstTable(InstTable, pInstr, Code, Proc);
  3313.   if (SizeMask & 2)
  3314.   {
  3315.     as_snprintf(Instr, sizeof(Instr), "%sW", pInstr);
  3316.     AddInstTable(InstTable, Instr, Code + 1, Proc);
  3317.   }
  3318.   if (SizeMask & 4)
  3319.   {
  3320.     as_snprintf(Instr, sizeof(Instr), "%sG", pInstr);
  3321.     AddInstTable(InstTable, Instr, Code + 2, Proc);
  3322.   }
  3323. }
  3324.  
  3325. static void InitFields(void)
  3326. {
  3327.   InstTable = CreateInstTable(301);
  3328.   SetDynamicInstTable(InstTable);
  3329.  
  3330.   AddInstr("MOV"  , DecodeMOV, 0x000, 0x07);
  3331.   AddInstr("XCH"  , DecodeXCH, 0x000, 0x03);
  3332.   AddInstr("ADD"  , DecodeALU, 0x000, 0x07);
  3333.   AddInstr("ADDC" , DecodeALU, 0xff1, 0x01);
  3334.   AddInstr("SUB"  , DecodeALU, 0x222, 0x07);
  3335.   AddInstr("SUBC" , DecodeALU, 0xff3, 0x01);
  3336.   AddInstr("CMP"  , DecodeALU, 0xf77, 0x03);
  3337.   AddInstr("AND"  , DecodeALU, 0xff4, 0x01);
  3338.   AddInstr("OR"   , DecodeALU, 0xff6, 0x01);
  3339.   AddInstr("XOR"  , DecodeALU, 0xff5, 0x01);
  3340.   AddInstr("MULU" , DecodeMULU,0x000, 0x03);
  3341.   AddInstTable(InstTable, "DIVUW", 0, DecodeDIVUW);
  3342.   AddInstTable(InstTable, "MULW",  0x38, DecodeMULW_DIVUX);
  3343.   AddInstTable(InstTable, "DIVUX", 0xe8, DecodeMULW_DIVUX);
  3344.   AddInstTable(InstTable, "MACW" , 0x85, DecodeMACW_MACSW);
  3345.   AddInstTable(InstTable, "MACSW", 0x95, DecodeMACW_MACSW);
  3346.   AddInstTable(InstTable, "SACW",  0, DecodeSACW);
  3347.   AddInstr("INC"  , DecodeINCDEC, 0, 0x07);
  3348.   AddInstr("DEC"  , DecodeINCDEC, 1, 0x07);
  3349.   AddInstTable(InstTable, "ADJBA", 0x05fe, DecodeFixed);
  3350.   AddInstTable(InstTable, "ADJBS", 0x05ff, DecodeFixed);
  3351.   AddInstTable(InstTable, "CVTBW", 0x0004, DecodeFixed);
  3352.   AddInstr("ROR"  , DecodeShift, 0x304, 0x01);
  3353.   AddInstr("ROL"  , DecodeShift, 0x314, 0x01);
  3354.   AddInstr("RORC" , DecodeShift, 0x300, 0x01);
  3355.   AddInstr("ROLC" , DecodeShift, 0x310, 0x01);
  3356.   AddInstr("SHR"  , DecodeShift, 0xb08, 0x03);
  3357.   AddInstr("SHL"  , DecodeShift, 0xb18, 0x03);
  3358.   AddInstTable(InstTable, "ROR4", 0x88, DecodeROR4_ROL4);
  3359.   AddInstTable(InstTable, "ROL4", 0x98, DecodeROR4_ROL4);
  3360.   AddInstTable(InstTable, "MOV1", 0, DecodeMOV1);
  3361.   AddInstTable(InstTable, "AND1", 0x20, DecodeAND1_OR1);
  3362.   AddInstTable(InstTable, "OR1",  0x40, DecodeAND1_OR1);
  3363.   AddInstTable(InstTable, "XOR1", 0x60, DecodeXOR1);
  3364.   AddInstTable(InstTable, "NOT1", 0x70, DecodeNOT1);
  3365.   AddInstTable(InstTable, "SET1", 0x80, DecodeSET1_CLR1);
  3366.   AddInstTable(InstTable, "CLR1", 0x90, DecodeSET1_CLR1);
  3367.   AddInstr("PUSH", DecodePUSH_POP, 0x35, 0x07);
  3368.   AddInstr("PUSHU",DecodePUSH_POP, 0x37, 0x03);
  3369.   AddInstr("POP" , DecodePUSH_POP, 0x34, 0x07);
  3370.   AddInstr("POPU", DecodePUSH_POP, 0x36, 0x03);
  3371.   AddInstTable(InstTable, "ADDWG", 0, DecodeADDWG_SUBWG);
  3372.   AddInstTable(InstTable, "SUBWG", 2, DecodeADDWG_SUBWG);
  3373.  
  3374.   AddInstTable(InstTable, "CALL", 1, DecodeCALL_BR);
  3375.   AddInstTable(InstTable, "BR"  , 0, DecodeCALL_BR);
  3376.   AddInstTable(InstTable, "CALLF", 0, DecodeCALLF);
  3377.   AddInstTable(InstTable, "CALLT", 0, DecodeCALLT);
  3378.   AddInstTable(InstTable, "BRK", 0x5e, DecodeFixed);
  3379.   AddInstTable(InstTable, "BRKCS", 0, DecodeBRKCS);
  3380.   AddInstTable(InstTable, "RET", 0x56, DecodeFixed);
  3381.   AddInstTable(InstTable, "RETI", 0x57, DecodeFixed);
  3382.   AddInstTable(InstTable, "RETB", 0x5f, DecodeFixed);
  3383.   AddInstTable(InstTable, "RETCS", 0x29, DecodeRETCS);
  3384.   AddInstTable(InstTable, "RETCSB", 0x09b0, DecodeRETCS);
  3385.  
  3386.   AddInstTable(InstTable, "BNZ", 0x80, DecodeRel);
  3387.   AddInstTable(InstTable, "BNE", 0x80, DecodeRel);
  3388.   AddInstTable(InstTable, "BZ", 0x81, DecodeRel);
  3389.   AddInstTable(InstTable, "BE", 0x81, DecodeRel);
  3390.   AddInstTable(InstTable, "BNC", 0x82, DecodeRel);
  3391.   AddInstTable(InstTable, "BNL", 0x82, DecodeRel);
  3392.   AddInstTable(InstTable, "BC", 0x83, DecodeRel);
  3393.   AddInstTable(InstTable, "BL", 0x83, DecodeRel);
  3394.   AddInstTable(InstTable, "BNV", 0x84, DecodeRel);
  3395.   AddInstTable(InstTable, "BPO", 0x84, DecodeRel);
  3396.   AddInstTable(InstTable, "BV", 0x85, DecodeRel);
  3397.   AddInstTable(InstTable, "BPE", 0x85, DecodeRel);
  3398.   AddInstTable(InstTable, "BP", 0x86, DecodeRel);
  3399.   AddInstTable(InstTable, "BN", 0x87, DecodeRel);
  3400.   AddInstTable(InstTable, "BLT", 0x07f8, DecodeRel);
  3401.   AddInstTable(InstTable, "BGE", 0x07f9, DecodeRel);
  3402.   AddInstTable(InstTable, "BLE", 0x07fa, DecodeRel);
  3403.   AddInstTable(InstTable, "BGT", 0x07fb, DecodeRel);
  3404.   AddInstTable(InstTable, "BNH", 0x07fc, DecodeRel);
  3405.   AddInstTable(InstTable, "BH", 0x07fd, DecodeRel);
  3406.   AddInstTable(InstTable, "BF", 0xa0, DecodeBitRel);
  3407.   AddInstTable(InstTable, "BT", 0xb0, DecodeBitRel);
  3408.   AddInstTable(InstTable, "BTCLR", 0xd0, DecodeBitRel);
  3409.   AddInstTable(InstTable, "BFSET", 0xc0, DecodeBitRel);
  3410.   AddInstTable(InstTable, "DBNZ", 0, DecodeDBNZ);
  3411.  
  3412.   AddInstTable(InstTable, "LOCATION", 0, DecodeLOCATION);
  3413.   AddInstTable(InstTable, "SEL", 0, DecodeSEL);
  3414.   AddInstTable(InstTable, "SWRS", 0x05fc, DecodeFixed);
  3415.   AddInstTable(InstTable, "NOP", 0x00, DecodeFixed);
  3416.   AddInstTable(InstTable, "EI", 0x4b, DecodeFixed);
  3417.   AddInstTable(InstTable, "DI", 0x4a, DecodeFixed);
  3418.  
  3419.   AddInstTable(InstTable, "CHKL", 0x07c8, DecodeCHK);
  3420.   AddInstTable(InstTable, "CHKLA", 0x07c9, DecodeCHK);
  3421.  
  3422.   AddInstTable(InstTable, "MOVTBLW", 0, DecodeMOVTBLW);
  3423.   AddInstTable(InstTable, "MOVM"   , 0x1500, DecodeStringAcc);
  3424.   AddInstTable(InstTable, "MOVBK"  , 0x1520, DecodeStringString);
  3425.   AddInstTable(InstTable, "XCHM"   , 0x1501, DecodeStringAcc);
  3426.   AddInstTable(InstTable, "XCHBK"  , 0x1521, DecodeStringString);
  3427.   AddInstTable(InstTable, "CMPME"  , 0x1504, DecodeStringAcc);
  3428.   AddInstTable(InstTable, "CMPBKE" , 0x1524, DecodeStringString);
  3429.   AddInstTable(InstTable, "CMPMNE" , 0x1505, DecodeStringAcc);
  3430.   AddInstTable(InstTable, "CMPBKNE", 0x1525, DecodeStringString);
  3431.   AddInstTable(InstTable, "CMPMC"  , 0x1507, DecodeStringAcc);
  3432.   AddInstTable(InstTable, "CMPBKC" , 0x1527, DecodeStringString);
  3433.   AddInstTable(InstTable, "CMPMNC" , 0x1506, DecodeStringAcc);
  3434.   AddInstTable(InstTable, "CMPBKNC", 0x1526, DecodeStringString);
  3435.  
  3436.   AddInstTable(InstTable, "BIT", 0, DecodeBIT);
  3437. }
  3438.  
  3439. static void DeinitFields(void)
  3440. {
  3441.   DestroyInstTable(InstTable);
  3442. }
  3443.  
  3444. /*-------------------------------------------------------------------------*/
  3445. /* interface to common layer */
  3446.  
  3447. static void MakeCode_78K4(void)
  3448. {
  3449.   CodeLen = 0; DontPrint = False; OpSize = -1;
  3450.   AssumeByte = False;
  3451.  
  3452.   /* zu ignorierendes */
  3453.  
  3454.   if (Memo(""))
  3455.     return;
  3456.  
  3457.   /* Pseudoanweisungen */
  3458.  
  3459.   if (DecodeIntelPseudo(False))
  3460.     return;
  3461.  
  3462.   if (!LookupInstTable(InstTable, OpPart.str.p_str))
  3463.     WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
  3464. }
  3465.  
  3466. static Boolean IsDef_78K4(void)
  3467. {
  3468.   return Memo("BIT");
  3469. }
  3470.  
  3471. static void InternSymbol_78K4(char *pAsc, TempResult *pErg)
  3472. {
  3473.   if ((!as_strcasecmp(pAsc, "PSWL"))
  3474.    || (!as_strcasecmp(pAsc, "PSW")))
  3475.     as_tempres_set_int(pErg, PSWLAddr);
  3476.   else if (!as_strcasecmp(pAsc, "PSWH"))
  3477.     as_tempres_set_int(pErg, PSWHAddr);
  3478. }
  3479.  
  3480. static void SwitchFrom_78K4(void)
  3481. {
  3482.   DeinitFields();
  3483. }
  3484.  
  3485. static void SwitchTo_78K4(void)
  3486. {
  3487.   const TFamilyDescr *pDescr;
  3488.  
  3489.   pDescr = FindFamilyByName("78K4");
  3490.  
  3491.   TurnWords = False;
  3492.   SetIntConstMode(eIntConstModeIntel);
  3493.  
  3494.   PCSymbol = "PC";
  3495.   HeaderID = pDescr->Id;
  3496.   NOPCode = 0x00;
  3497.   DivideChars = ",";
  3498.   HasAttrs = False;
  3499.  
  3500.   ValidSegs = 1 << SegCode;
  3501.   Grans[SegCode] = 1; ListGrans[SegCode] = 1; SegInits[SegCode] = 0;
  3502.   SegLimits[SegCode] = 0xffffff;
  3503.  
  3504.   pASSUMERecs = ASSUME78K4s;
  3505.   ASSUMERecCnt = sizeof(ASSUME78K4s) / sizeof(ASSUME78K4s[0]);
  3506.  
  3507.   MakeCode = MakeCode_78K4;
  3508.   IsDef = IsDef_78K4;
  3509.   InternSymbol = InternSymbol_78K4;
  3510.   SwitchFrom = SwitchFrom_78K4; InitFields();
  3511. }
  3512.  
  3513. void code78k4_init(void)
  3514. {
  3515.   CPU784026 = AddCPU("784026", SwitchTo_78K4);
  3516. }
  3517.