Subversion Repositories pentevo

Rev

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

  1. /* code78k2.c */
  2. /*****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
  4. /*                                                                           */
  5. /* AS-Portierung                                                             */
  6. /*                                                                           */
  7. /* Codegenerator 78K2-Familie                                                */
  8. /*                                                                           */
  9. /*****************************************************************************/
  10.  
  11. #include "stdinc.h"
  12. #include <string.h>
  13. #include <ctype.h>
  14.  
  15. #include "bpemu.h"
  16. #include "strutil.h"
  17. #include "asmdef.h"
  18. #include "asmsub.h"
  19. #include "asmpars.h"
  20. #include "asmitree.h"
  21. #include "codepseudo.h"
  22. #include "intpseudo.h"
  23. #include "codevars.h"
  24. #include "headids.h"
  25. #include "errmsg.h"
  26.  
  27. #include "code78k2.h"
  28.  
  29. /*-------------------------------------------------------------------------*/
  30.  
  31. enum
  32. {
  33.   ModNone = -1,
  34.   ModImm = 0,
  35.   ModReg8 = 1,
  36.   ModReg16 = 2,
  37.   ModMem = 3,
  38.   ModAbs = 4,
  39.   ModShort = 5,
  40.   ModSFR = 6,
  41.   ModPSW = 7,
  42.   ModSP = 8,
  43.   ModSTBC = 9
  44. };
  45.  
  46. #define MModImm (1 << ModImm)
  47. #define MModReg8 (1 << ModReg8)
  48. #define MModReg16 (1 << ModReg16)
  49. #define MModMem (1 << ModMem)
  50. #define MModAbs (1 << ModAbs)
  51. #define MModShort (1 << ModShort)
  52. #define MModSFR (1 << ModSFR)
  53. #define MModPSW (1 << ModPSW)
  54. #define MModSP (1 << ModSP)
  55. #define MModSTBC (1 << ModSTBC)
  56.  
  57. #define AccReg8 1
  58. #define AccReg16 0
  59.  
  60. #define SFR_SP 0xfc
  61. #define SFR_PSW 0xfe
  62.  
  63. /*-------------------------------------------------------------------------*/
  64.  
  65. static CPUVar CPU78214;
  66.  
  67. typedef struct
  68. {
  69.   ShortInt Mode, Val;
  70.   Byte Vals[3];
  71.   tSymbolFlags ValSymFlags;
  72.   Boolean AltBank;
  73.   int Cnt;
  74. } tAdrResult;
  75.  
  76. static ShortInt OpSize;
  77. static Byte *pCode;
  78. static LongInt Reg_P6, Reg_PM6;
  79.  
  80. /*-------------------------------------------------------------------------*/
  81. /* address decoders */
  82.  
  83. static Boolean SetOpSize(ShortInt NewSize)
  84. {
  85.   if (OpSize < 0)
  86.   {
  87.     OpSize = NewSize;
  88.     return True;
  89.   }
  90.   else if (OpSize != NewSize)
  91.   {
  92.     WrError(ErrNum_ConfOpSizes);
  93.     return False;
  94.   }
  95.   else
  96.     return True;
  97. }
  98.  
  99. static ShortInt DecodeReg8(char *pAsc)
  100. {
  101.   ShortInt Result = -1;
  102.   int l = strlen(pAsc);
  103.  
  104.   if (l == 1)
  105.   {
  106.     static const char Reg8Names[9] = "XACBEDLH";
  107.     const char *pPos = strchr(Reg8Names, as_toupper(*pAsc));
  108.  
  109.     if (pPos)
  110.       Result = pPos - Reg8Names;
  111.   }
  112.  
  113.   else if ((l == 2) && (toupper(pAsc[0]) == 'R'))
  114.   {
  115.     if ((pAsc[1] >= '0') && (pAsc[1] <= '7'))
  116.       Result = pAsc[1] - '0';
  117.   }
  118.  
  119.   return Result;
  120. }
  121.  
  122. static ShortInt DecodeReg16(char *pAsc)
  123. {
  124.   ShortInt Result = -1;
  125.   int l = strlen(pAsc);
  126.  
  127.   if (l == 2)
  128.   {
  129.     static const char Reg16Names[4][3] = {"AX", "BC", "DE", "HL"};
  130.     int z;
  131.  
  132.     for (z = 0; z < 4; z++)
  133.       if (!as_strcasecmp(Reg16Names[z], pAsc))
  134.       {
  135.         Result = z;
  136.         break;
  137.       }
  138.   }
  139.  
  140.   else if ((l == 3) && (toupper(pAsc[0]) == 'R') && (toupper(pAsc[1]) == 'P'))
  141.   {
  142.     if ((pAsc[2] >= '0') && (pAsc[2] <= '3'))
  143.       Result = pAsc[2] - '0';
  144.   }
  145.  
  146.   return Result;
  147. }
  148.  
  149. static ShortInt DecodeAdr(const tStrComp *pArg, Word Mask, tAdrResult *pResult)
  150. {
  151.   Word WordOp;
  152.   LongWord LongOp;
  153.   Boolean OK;
  154.   tStrComp Arg;
  155.   unsigned ForceLong;
  156.   int ArgLen;
  157.  
  158.   pResult->Mode = ModNone;
  159.   pResult->AltBank = False;
  160.   pResult->Cnt = 0;
  161.  
  162.   /* immediate ? */
  163.  
  164.   if (*pArg->str.p_str == '#')
  165.   {
  166.     switch (OpSize)
  167.     {
  168.       case 0:
  169.         pResult->Vals[0] = EvalStrIntExpressionOffs(pArg, 1, Int8, &OK);
  170.         if (OK)
  171.         {
  172.           pResult->Cnt = 1;
  173.           pResult->Mode = ModImm;
  174.         }
  175.         break;
  176.       case 1:
  177.         WordOp = EvalStrIntExpressionOffs(pArg, 1, Int16, &OK);
  178.         if (OK)
  179.         {
  180.           pResult->Vals[0] = Lo(WordOp);
  181.           pResult->Vals[1] = Hi(WordOp);
  182.           pResult->Cnt = 2;
  183.           pResult->Mode = ModImm;
  184.         }
  185.         break;
  186.       default:
  187.         WrError(ErrNum_UndefOpSizes);
  188.     }
  189.     goto AdrFound;
  190.   }
  191.  
  192.   /* 8 bit registers? */
  193.  
  194.   if ((pResult->Val = DecodeReg8(pArg->str.p_str)) >= 0)
  195.   {
  196.     pResult->Mode = ModReg8;
  197.     SetOpSize(0);
  198.     goto AdrFound;
  199.   }
  200.  
  201.   if (!as_strcasecmp(pArg->str.p_str, "PSW"))
  202.   {
  203.     pResult->Mode = ModPSW;
  204.     SetOpSize(0);
  205.     goto AdrFound;
  206.   }
  207.  
  208.   if (!as_strcasecmp(pArg->str.p_str, "STBC"))
  209.   {
  210.     pResult->Mode = ModSTBC;
  211.     SetOpSize(0);
  212.     goto AdrFound;
  213.   }
  214.  
  215.   /* 16 bit registers? */
  216.  
  217.   if ((pResult->Val = DecodeReg16(pArg->str.p_str)) >= 0)
  218.   {
  219.     pResult->Mode = ModReg16;
  220.     SetOpSize(1);
  221.     goto AdrFound;
  222.   }
  223.  
  224.   if (!as_strcasecmp(pArg->str.p_str, "SP"))
  225.   {
  226.     pResult->Mode = ModSP;
  227.     SetOpSize(1);
  228.     goto AdrFound;
  229.   }
  230.  
  231.   /* OK, everything that follows is memory: alternate bank ? */
  232.  
  233.   StrCompRefRight(&Arg, pArg, 0);
  234.   if (*Arg.str.p_str == '&')
  235.   {
  236.     pResult->AltBank = True;
  237.     StrCompIncRefLeft(&Arg, 1);
  238.   }
  239.  
  240.   /* memory-indirect addressing? */
  241.  
  242.   ArgLen = strlen(Arg.str.p_str);
  243.   if ((ArgLen >= 2) && (Arg.str.p_str[ArgLen - 1] == ']'))
  244.   {
  245.     tStrComp Base, Remainder;
  246.     char *pStart;
  247.  
  248.     /* remove ']' */
  249.  
  250.     StrCompShorten(&Arg, 1);
  251.  
  252.     pStart = RQuotPos(Arg.str.p_str, '[');
  253.     if (!pStart)
  254.     {
  255.       WrError(ErrNum_BrackErr);
  256.       goto AdrFound;
  257.     }
  258.  
  259.     /* purely indirect? */
  260.  
  261.     if (pStart == Arg.str.p_str)
  262.     {
  263.       static const char Modes[][5] = { "DE+",  "HL+",  "DE-",  "HL-",  "DE",  "HL",
  264.                                        "RP2+", "RP3+", "RP2-", "RP3-", "RP2", "RP3" };
  265.       unsigned z;
  266.       char *pSep, Save;
  267.  
  268.       /* skip '[' */
  269.  
  270.       StrCompIncRefLeft(&Arg, 1);
  271.  
  272.       /* simple expression without displacement? */
  273.  
  274.       for (z = 0; z < sizeof(Modes) / sizeof(*Modes); z++)
  275.         if (!as_strcasecmp(Arg.str.p_str, Modes[z]))
  276.         {
  277.           pResult->Mode = ModMem; pResult->Val = 0x16;
  278.           pResult->Vals[0] = z % (sizeof(Modes) / sizeof(*Modes) / 2);
  279.           pResult->Cnt = 1;
  280.           goto AdrFound;
  281.         }
  282.  
  283.       /* no -> extract base register. Its name ends with the first non-letter,
  284.          which either means +/- or a blank */
  285.  
  286.       for (pSep = Arg.str.p_str; *pSep; pSep++)
  287.         if (!as_isalpha(*pSep))
  288.           break;
  289.  
  290.       /* decode base register.  SP is not otherwise handled. */
  291.  
  292.       Save = StrCompSplitRef(&Base, &Remainder, &Arg, pSep);
  293.       if (!as_strcasecmp(Base.str.p_str, "SP"))
  294.         pResult->Vals[0] = 1;
  295.       else
  296.       {
  297.         int tmp;
  298.  
  299.         tmp = DecodeReg16(Base.str.p_str);
  300.         if (tmp == 2) /* DE */
  301.           pResult->Vals[0] = 0;
  302.         else if (tmp == 3) /* HL */
  303.           pResult->Vals[0] = 2;
  304.         else
  305.         {
  306.           WrStrErrorPos(ErrNum_InvReg, &Base);
  307.           goto AdrFound;
  308.         }
  309.       }
  310.  
  311.       /* now that we have the base, prepare displacement. */
  312.  
  313.       *pSep = Save;
  314.       if (pSep > Arg.str.p_str)
  315.         pSep--;
  316.       *pSep = '0';
  317.       pResult->Vals[1] = EvalStrIntExpressionOffs(&Arg, pSep - Arg.str.p_str, Int8, &OK);
  318.       if (OK)
  319.       {
  320.         pResult->Mode = ModMem; pResult->Val = 0x06;
  321.         pResult->Cnt = 2;
  322.         goto AdrFound;
  323.       }
  324.     }
  325.  
  326.     /* no -> with outer displacement */
  327.  
  328.     else
  329.     {
  330.       tStrComp Disp, Reg;
  331.       int tmp;
  332.  
  333.       /* split displacement + register */
  334.  
  335.       StrCompSplitRef(&Disp, &Reg, &Arg, pStart);
  336.  
  337.        /* handle base register */
  338.  
  339.       tmp = DecodeReg8(Reg.str.p_str);
  340.       switch (tmp)
  341.       {
  342.         case 1: /* A/B */
  343.         case 3:
  344.           pResult->Vals[0] = tmp;
  345.           break;
  346.         case -1:
  347.           tmp = DecodeReg16(Reg.str.p_str);
  348.           if (tmp >= 2) /* DE/HL */
  349.           {
  350.             pResult->Vals[0] = (tmp - 2) << 1;
  351.             break;
  352.           }
  353.           /* else fall-through */
  354.         default:
  355.           WrStrErrorPos(ErrNum_InvReg, &Reg);
  356.           goto AdrFound;
  357.       }
  358.  
  359.       /* compute displacement */
  360.  
  361.       WordOp = EvalStrIntExpression(&Disp, Int16, &OK);
  362.       if (OK)
  363.       {
  364.         pResult->Mode = ModMem; pResult->Val = 0x0a;
  365.         pResult->Vals[1] = Lo(WordOp); pResult->Vals[2] = Hi(WordOp);
  366.         pResult->Cnt = 3;
  367.         goto AdrFound;
  368.       }
  369.     }
  370.  
  371.   }
  372.  
  373.   /* OK, nothing but absolute left...exclamation mark enforces 16-bit addressing */
  374.  
  375.   ForceLong = !!(*Arg.str.p_str == '!');
  376.  
  377.   LongOp = EvalStrIntExpressionOffsWithFlags(&Arg, ForceLong, UInt20, &OK, &pResult->ValSymFlags);
  378.   if (OK)
  379.   {
  380.     if (!mFirstPassUnknown(pResult->ValSymFlags))
  381.     {
  382.       LongWord CompBank = pResult->AltBank ? Reg_P6 : Reg_PM6;
  383.       if (CompBank != (LongOp >> 16)) WrError(ErrNum_InAccPage);
  384.     }
  385.  
  386.     WordOp = LongOp & 0xffff;
  387.  
  388.     if ((Mask & MModShort) && (!ForceLong) && ((WordOp >= 0xfe20) && (WordOp <= 0xff1f)))
  389.     {
  390.       pResult->Mode = ModShort; pResult->Cnt = 1;
  391.       pResult->Vals[0] = Lo(WordOp);
  392.     }
  393.     else if ((Mask & MModSFR) && (!ForceLong) && (Hi(WordOp) == 0xff))
  394.     {
  395.       pResult->Mode = ModSFR; pResult->Cnt = 1;
  396.       pResult->Vals[0] = Lo(WordOp);
  397.     }
  398.     else
  399.     {
  400.       pResult->Mode = ModAbs; pResult->Cnt = 2;
  401.       pResult->Vals[0] = Lo(WordOp); pResult->Vals[1] = Hi(WordOp);
  402.     }
  403.   }
  404.  
  405. AdrFound:
  406.  
  407.   if ((pResult->Mode != ModNone) && (!(Mask & (1 << pResult->Mode))))
  408.   {
  409.     WrError(ErrNum_InvAddrMode);
  410.     pResult->Mode = ModNone; pResult->Cnt = 0; pResult->AltBank = False;
  411.   }
  412.   return pResult->Mode;
  413. }
  414.  
  415. static Boolean ChkAcc(const tStrComp *pArg)
  416. {
  417.   tAdrResult Result;
  418.  
  419.   if (DecodeAdr(pArg, OpSize ? MModReg16 : MModReg8, &Result) == ModNone)
  420.     return False;
  421.  
  422.   if (((OpSize) && (Result.Val != AccReg16))
  423.    || ((!OpSize) && (Result.Val != AccReg8)))
  424.   {
  425.     WrError(ErrNum_InvAddrMode);
  426.     return False;
  427.   }
  428.  
  429.   return True;
  430. }
  431.  
  432. static Boolean ChkMem1(const tAdrResult *pResult)
  433. {
  434.   return (pResult->Val == 0x16) && (*pResult->Vals >= 4);
  435. }
  436.  
  437. static Boolean DecodeBitAdr(const tStrComp *pArg, LongWord *pResult)
  438. {
  439.   char *pSplit;
  440.   Boolean OK;
  441.  
  442.   pSplit = RQuotPos(pArg->str.p_str, '.');
  443.  
  444.   if (pSplit)
  445.   {
  446.     tStrComp Reg, Bit;
  447.  
  448.     StrCompSplitRef(&Reg, &Bit, pArg, pSplit);
  449.  
  450.     *pResult = EvalStrIntExpression(&Bit, UInt3, &OK) << 8;
  451.     if (OK)
  452.     {
  453.       tAdrResult Result;
  454.  
  455.       switch (DecodeAdr(&Reg, MModReg8 | MModPSW | MModSFR | MModShort, &Result))
  456.       {
  457.         case ModReg8:
  458.           if (Result.Val >= 2)
  459.           {
  460.             WrStrErrorPos(ErrNum_InvReg, &Reg);
  461.             OK = FALSE;
  462.           }
  463.           else
  464.             *pResult |= (((LongWord)Result.Val) << 11) | 0x00030000;
  465.           break;
  466.         case ModPSW:
  467.           *pResult |= 0x00020000;
  468.           break;
  469.         case ModSFR:
  470.           *pResult |= 0x01080800 | *Result.Vals;
  471.           break;
  472.         case ModShort:
  473.           *pResult |= 0x01080000 | *Result.Vals;
  474.           break;
  475.         default:
  476.           OK = FALSE;
  477.       }
  478.     }
  479.   }
  480.   else
  481.     *pResult = EvalStrIntExpression(pArg, UInt32, &OK);
  482.  
  483.   return OK;
  484. }
  485.  
  486. /*-------------------------------------------------------------------------*/
  487. /* instruction decoders */
  488.  
  489. static void DecodeFixed(Word Index)
  490. {
  491.   if (ChkArgCnt(0, 0))
  492.     *pCode++ = Index;
  493. }
  494.  
  495. static void DecodeMOV(Word Index)
  496. {
  497.   UNUSED(Index);
  498.  
  499.   SetOpSize(0);
  500.   if (ChkArgCnt(2, 2))
  501.   {
  502.     tAdrResult DestResult;
  503.  
  504.     switch (DecodeAdr(&ArgStr[1], MModReg8 | MModShort | MModSFR | MModMem | MModAbs | MModPSW | MModSTBC, &DestResult))
  505.     {
  506.       case ModReg8:
  507.       {
  508.         tAdrResult SrcResult;
  509.  
  510.         switch (DecodeAdr(&ArgStr[2], MModImm | MModReg8 | (DestResult.Val == AccReg8 ? (MModShort | MModSFR | MModAbs | MModMem | MModPSW) : 0), &SrcResult))
  511.         {
  512.           case ModImm:
  513.             *pCode++ = 0xb8 | DestResult.Val;
  514.             *pCode++ = *SrcResult.Vals;
  515.             break;
  516.           case ModReg8:
  517.             if (DestResult.Val == AccReg8)
  518.               *pCode++ = 0xd0 | SrcResult.Val;
  519.             else
  520.             {
  521.               *pCode++ = 0x24;
  522.               *pCode++ = (DestResult.Val << 4) | SrcResult.Val;
  523.             }
  524.             break;
  525.           case ModSFR:
  526.             *pCode++ = 0x10;
  527.             *pCode++ = *SrcResult.Vals;
  528.             break;
  529.           case ModShort:
  530.             *pCode++ = 0x20;
  531.             *pCode++ = *SrcResult.Vals;
  532.             break;
  533.           case ModAbs:
  534.             if (SrcResult.AltBank)
  535.               *pCode++ = 0x01;
  536.             *pCode++ = 0x09;
  537.             *pCode++ = 0xf0;
  538.             *pCode++ = *SrcResult.Vals;
  539.             *pCode++ = 1[SrcResult.Vals];
  540.             break;
  541.           case ModMem:
  542.             if (SrcResult.AltBank)
  543.               *pCode++ = 0x01;
  544.             if (SrcResult.Val == 0x16)
  545.               *pCode++ = 0x58 | *SrcResult.Vals;
  546.             else
  547.             {
  548.               *pCode++ = 0x00 | SrcResult.Val;
  549.               *pCode++ = *SrcResult.Vals << 4;
  550.               memcpy(pCode, SrcResult.Vals + 1, SrcResult.Cnt - 1);
  551.               pCode += SrcResult.Cnt - 1;
  552.             }
  553.             break;
  554.           case ModPSW:
  555.             *pCode++ = 0x10;
  556.             *pCode++ = SFR_PSW;
  557.             break;
  558.         }
  559.         break;
  560.       }
  561.  
  562.       case ModShort:
  563.       {
  564.         tAdrResult SrcResult;
  565.  
  566.         switch (DecodeAdr(&ArgStr[2], MModImm | MModReg8 | MModShort, &SrcResult))
  567.         {
  568.           case ModImm:
  569.             *pCode++ = 0x3a;
  570.             *pCode++ = *DestResult.Vals;
  571.             *pCode++ = *SrcResult.Vals;
  572.             break;
  573.           case ModReg8:
  574.             if (SrcResult.Val != AccReg8) WrError(ErrNum_InvAddrMode);
  575.             else
  576.             {
  577.               *pCode++ = 0x22;
  578.               *pCode++ = *DestResult.Vals;
  579.             }
  580.             break;
  581.           case ModShort:
  582.             *pCode++ = 0x38;
  583.             *pCode++ = *DestResult.Vals;
  584.             *pCode++ = *SrcResult.Vals;
  585.             break;
  586.         }
  587.         break;
  588.       }
  589.  
  590.       case ModSFR:
  591.       {
  592.         tAdrResult SrcResult;
  593.  
  594.         switch (DecodeAdr(&ArgStr[2], MModImm | MModReg8, &SrcResult))
  595.         {
  596.           case ModImm:
  597.             *pCode++ = 0x2b;
  598.             *pCode++ = *DestResult.Vals;
  599.             *pCode++ = *SrcResult.Vals;
  600.             break;
  601.           case ModReg8:
  602.             if (SrcResult.Val != AccReg8) WrError(ErrNum_InvAddrMode);
  603.             else
  604.             {
  605.               *pCode++ = 0x12;
  606.               *pCode++ = *DestResult.Vals;
  607.             }
  608.             break;
  609.         }
  610.         break;
  611.       }
  612.  
  613.       case ModPSW:
  614.       {
  615.         tAdrResult SrcResult;
  616.  
  617.         switch (DecodeAdr(&ArgStr[2], MModImm | MModReg8, &SrcResult))
  618.         {
  619.           case ModImm:
  620.             *pCode++ = 0x2b;
  621.             *pCode++ = SFR_PSW;
  622.             *pCode++ = *SrcResult.Vals;
  623.             break;
  624.           case ModReg8:
  625.             if (SrcResult.Val != AccReg8) WrError(ErrNum_InvAddrMode);
  626.             else
  627.             {
  628.               *pCode++ = 0x12;
  629.               *pCode++ = SFR_PSW;
  630.             }
  631.             break;
  632.         }
  633.         break;
  634.       }
  635.  
  636.       case ModSTBC:
  637.       {
  638.         tAdrResult SrcResult;
  639.  
  640.         switch (DecodeAdr(&ArgStr[2], MModImm, &SrcResult))
  641.         {
  642.           case ModImm:
  643.             *pCode++ = 0x09;
  644.             *pCode++ = 0xc0;
  645.             *pCode++ = *SrcResult.Vals;
  646.             *pCode++ = ~(*SrcResult.Vals);
  647.             break;
  648.         }
  649.         break;
  650.       }
  651.  
  652.       /* only works against ACC - dump result first, since DecodeAdr
  653.          destroys values */
  654.  
  655.       case ModMem:
  656.         if (DestResult.AltBank)
  657.           *pCode++ = 0x01;
  658.         if (DestResult.Val == 0x16)
  659.           *pCode++ = 0x50 | *DestResult.Vals;
  660.         else
  661.         {
  662.           *pCode++ = 0x00 | DestResult.Val;
  663.           *pCode++ = 0x80 | (*DestResult.Vals << 4);
  664.           memcpy(pCode, DestResult.Vals + 1, DestResult.Cnt - 1);
  665.           pCode += DestResult.Cnt - 1;
  666.         }
  667.         if (!ChkAcc(&ArgStr[2]))
  668.           pCode = BAsmCode;
  669.         break;
  670.  
  671.       case ModAbs:
  672.         if (DestResult.AltBank)
  673.           *pCode++ = 0x01;
  674.         *pCode++ = 0x09;
  675.         *pCode++ = 0xf1;
  676.         *pCode++ = *DestResult.Vals;
  677.         *pCode++ = 1[DestResult.Vals];
  678.         if (!ChkAcc(&ArgStr[2]))
  679.           pCode = BAsmCode;
  680.         break;
  681.     }
  682.   }
  683. }
  684.  
  685. static void DecodeXCH(Word Index)
  686. {
  687.   UNUSED(Index);
  688.  
  689.   SetOpSize(0);
  690.   if (ChkArgCnt(2, 2))
  691.   {
  692.     tAdrResult DestResult;
  693.  
  694.     switch (DecodeAdr(&ArgStr[1], MModReg8 | MModShort | MModSFR | MModMem, &DestResult))
  695.     {
  696.       case ModReg8:
  697.       {
  698.         tAdrResult SrcResult;
  699.  
  700.         switch (DecodeAdr(&ArgStr[2], MModReg8 | ((DestResult.Val == AccReg8) ? (MModShort | MModSFR | MModMem) : 0), &SrcResult))
  701.         {
  702.           case ModReg8:
  703.             if (DestResult.Val == AccReg8)
  704.               *pCode++ = 0xd8 | SrcResult.Val;
  705.             else if (SrcResult.Val == AccReg8)
  706.               *pCode++ = 0xd8 | DestResult.Val;
  707.             else
  708.             {
  709.               *pCode++ = 0x25;
  710.               *pCode++ = (DestResult.Val << 4) | SrcResult.Val;
  711.             }
  712.             break;
  713.           case ModShort:
  714.             *pCode++ = 0x21;
  715.             *pCode++ = *SrcResult.Vals;
  716.             break;
  717.           case ModSFR:
  718.             *pCode++ = 0x01;
  719.             *pCode++ = 0x21;
  720.             *pCode++ = *SrcResult.Vals;
  721.             break;
  722.           case ModMem:
  723.             if (SrcResult.AltBank)
  724.               *pCode++ = 0x01;
  725.             *pCode++ = SrcResult.Val;
  726.             *pCode++ = (*SrcResult.Vals << 4) | 0x04;
  727.             memcpy(pCode, SrcResult.Vals + 1, SrcResult.Cnt - 1);
  728.             pCode += SrcResult.Cnt - 1;
  729.             break;
  730.         }
  731.         break;
  732.       }
  733.  
  734.       case ModShort:
  735.       {
  736.         tAdrResult SrcResult;
  737.  
  738.         switch (DecodeAdr(&ArgStr[2], MModReg8 | MModShort, &SrcResult))
  739.         {
  740.           case ModReg8:
  741.             if (SrcResult.Val != AccReg8) WrError(ErrNum_InvAddrMode);
  742.             else
  743.             {
  744.               *pCode++ = 0x21;
  745.               *pCode++ = *DestResult.Vals;
  746.             }
  747.             break;
  748.           case ModShort:
  749.             *pCode++ = 0x39;
  750.             *pCode++ = *DestResult.Vals;
  751.             *pCode++ = *SrcResult.Vals;
  752.             break;
  753.         }
  754.         break;
  755.       }
  756.  
  757.       case ModSFR:
  758.         if (ChkAcc(&ArgStr[2]))
  759.         {
  760.           *pCode++ = 0x01;
  761.           *pCode++ = 0x21;
  762.           *pCode++ = *DestResult.Vals;
  763.         }
  764.         break;
  765.  
  766.       case ModMem:
  767.         if (DestResult.AltBank)
  768.           *pCode++ = 0x01;
  769.         *pCode++ = DestResult.Val;
  770.         *pCode++ = (*DestResult.Vals << 4) | 0x04;
  771.         memcpy(pCode, DestResult.Vals + 1, DestResult.Cnt - 1);
  772.         pCode += DestResult.Cnt - 1;
  773.         if (!ChkAcc(&ArgStr[2]))
  774.           pCode = BAsmCode;
  775.         break;
  776.     }
  777.   }
  778. }
  779.  
  780. static void DecodeMOVW(Word Index)
  781. {
  782.   UNUSED(Index);
  783.  
  784.   SetOpSize(1);
  785.   if (ChkArgCnt(2, 2))
  786.   {
  787.     tAdrResult DestResult;
  788.  
  789.     switch (DecodeAdr(&ArgStr[1], MModReg16 | MModSP | MModShort | MModSFR | MModMem, &DestResult))
  790.     {
  791.       case ModReg16:
  792.       {
  793.         tAdrResult SrcResult;
  794.  
  795.         switch (DecodeAdr(&ArgStr[2], MModReg16 | MModImm | ((DestResult.Val == AccReg16) ? (MModSP | MModShort | MModSFR | MModMem) : 0), &SrcResult))
  796.         {
  797.           case ModReg16:
  798.             *pCode++ = 0x24;
  799.             *pCode++ = 0x08 | (DestResult.Val << 5) | (SrcResult.Val << 1);
  800.             break;
  801.           case ModImm:
  802.             *pCode++ = 0x60 | (DestResult.Val << 1);
  803.             *pCode++ = *SrcResult.Vals;
  804.             *pCode++ = 1[SrcResult.Vals];
  805.             break;
  806.           case ModShort:
  807.             *pCode++ = 0x1c;
  808.             *pCode++ = *SrcResult.Vals;
  809.             break;
  810.           case ModSFR:
  811.             *pCode++ = 0x11;
  812.             *pCode++ = *SrcResult.Vals;
  813.             break;
  814.           case ModSP:
  815.             *pCode++ = 0x11;
  816.             *pCode++ = SFR_SP;
  817.             break;
  818.           case ModMem:
  819.             if (ChkMem1(&SrcResult))
  820.             {
  821.               if (SrcResult.AltBank)
  822.                 *pCode++ = 0x01;
  823.               *pCode++ = 0x05;
  824.               *pCode++ = 0xe2 | (*SrcResult.Vals & 0x01);
  825.             }
  826.             break;
  827.         }
  828.         break;
  829.       }
  830.  
  831.       case ModSP:
  832.       {
  833.         tAdrResult SrcResult;
  834.  
  835.         switch (DecodeAdr(&ArgStr[2], MModReg16 | MModImm, &SrcResult))
  836.         {
  837.           case ModReg16:
  838.             if (SrcResult.Val != AccReg16) WrError(ErrNum_InvAddrMode);
  839.             else
  840.             {
  841.               *pCode++ = 0x13;
  842.               *pCode++ = SFR_SP;
  843.             }
  844.             break;
  845.           case ModImm:
  846.             *pCode++ = 0x0b;
  847.             *pCode++ = SFR_SP;
  848.             *pCode++ = *SrcResult.Vals;
  849.             *pCode++ = 1[SrcResult.Vals];
  850.             break;
  851.         }
  852.         break;
  853.       }
  854.  
  855.       case ModShort:
  856.       {
  857.         tAdrResult SrcResult;
  858.  
  859.         switch (DecodeAdr(&ArgStr[2], MModReg16 | MModImm, &SrcResult))
  860.         {
  861.           case ModReg16:
  862.             if (SrcResult.Val != AccReg16) WrError(ErrNum_InvAddrMode);
  863.             else
  864.             {
  865.               *pCode++ = 0x1a;
  866.               *pCode++ = *DestResult.Vals;
  867.             }
  868.             break;
  869.           case ModImm:
  870.             *pCode++ = 0x0c;
  871.             *pCode++ = *DestResult.Vals;
  872.             *pCode++ = *SrcResult.Vals;
  873.             *pCode++ = 1[SrcResult.Vals];
  874.             break;
  875.         }
  876.         break;
  877.       }
  878.  
  879.       case ModSFR:
  880.       {
  881.         tAdrResult SrcResult;
  882.  
  883.         switch (DecodeAdr(&ArgStr[2], MModReg16 | MModImm, &SrcResult))
  884.         {
  885.           case ModReg16:
  886.             if (SrcResult.Val != AccReg16) WrError(ErrNum_InvAddrMode);
  887.             else
  888.             {
  889.               *pCode++ = 0x13;
  890.               *pCode++ = *DestResult.Vals;
  891.             }
  892.             break;
  893.           case ModImm:
  894.             *pCode++ = 0x0b;
  895.             *pCode++ = *DestResult.Vals;
  896.             *pCode++ = *SrcResult.Vals;
  897.             *pCode++ = 1[SrcResult.Vals];
  898.             break;
  899.         }
  900.         break;
  901.       }
  902.  
  903.       case ModMem:
  904.         if (ChkMem1(&DestResult))
  905.         {
  906.           if (DestResult.AltBank)
  907.             *pCode++ = 0x01;
  908.           *pCode++ = 0x05;
  909.           *pCode++ = 0xe6 | (*DestResult.Vals & 0x01);
  910.           if (!ChkAcc(&ArgStr[2]))
  911.             pCode = BAsmCode;
  912.         }
  913.         break;
  914.     }
  915.   }
  916. }
  917.  
  918. static void DecodeALU(Word Index)
  919. {
  920.   SetOpSize(0);
  921.   if (ChkArgCnt(2, 2))
  922.   {
  923.     tAdrResult DestResult;
  924.  
  925.     switch (DecodeAdr(&ArgStr[1], MModReg8 | MModShort | MModSFR, &DestResult))
  926.     {
  927.       case ModReg8:
  928.       {
  929.         tAdrResult SrcResult;
  930.  
  931.         switch (DecodeAdr(&ArgStr[2], MModReg8 | ((DestResult.Val == AccReg8) ? (MModImm | MModShort | MModSFR | MModMem): 0), &SrcResult))
  932.         {
  933.           case ModReg8:
  934.             *pCode++ = 0x88 | Index;
  935.             *pCode++ = (DestResult.Val << 4) | SrcResult.Val;
  936.             break;
  937.           case ModImm:
  938.             *pCode++ = 0xa8 | Index;
  939.             *pCode++ = *SrcResult.Vals;
  940.             break;
  941.           case ModShort:
  942.             *pCode++ = 0x98 | Index;
  943.             *pCode++ = *SrcResult.Vals;
  944.             break;
  945.           case ModSFR:
  946.             *pCode++ = 0x01;
  947.             *pCode++ = 0x98 | Index;
  948.             *pCode++ = *SrcResult.Vals;
  949.             break;
  950.           case ModMem:
  951.             if (SrcResult.AltBank)
  952.               *pCode++ = 0x01;
  953.             *pCode++ = 0x00 | SrcResult.Val;
  954.             *pCode++ = 0x08 | (*SrcResult.Vals << 4) | Index;
  955.             memcpy(pCode, SrcResult.Vals + 1, SrcResult.Cnt - 1);
  956.             pCode += SrcResult.Cnt - 1;
  957.             break;
  958.         }
  959.         break;
  960.       }
  961.  
  962.       case ModShort:
  963.       {
  964.         tAdrResult SrcResult;
  965.  
  966.         switch (DecodeAdr(&ArgStr[2], MModImm | MModShort, &SrcResult))
  967.         {
  968.           case ModImm:
  969.             *pCode++ = 0x68 | Index;
  970.             *pCode++ = *DestResult.Vals;
  971.             *pCode++ = *SrcResult.Vals;
  972.             break;
  973.           case ModShort:
  974.             *pCode++ = 0x78 | Index;
  975.             *pCode++ = *SrcResult.Vals;
  976.             *pCode++ = *DestResult.Vals;
  977.             break;
  978.         }
  979.         break;
  980.       }
  981.  
  982.       case ModSFR:
  983.       {
  984.         tAdrResult SrcResult;
  985.  
  986.         switch (DecodeAdr(&ArgStr[2], MModImm, &SrcResult))
  987.         {
  988.           case ModImm:
  989.             *pCode++ = 0x01;
  990.             *pCode++ = 0x68 | Index;
  991.             *pCode++ = *DestResult.Vals;
  992.             *pCode++ = *SrcResult.Vals;
  993.             break;
  994.         }
  995.         break;
  996.       }
  997.     }
  998.   }
  999. }
  1000.  
  1001. static void DecodeALU16(Word Index)
  1002. {
  1003.   static Byte Vals[3] = { 0, 2, 7 };
  1004.  
  1005.   if (ChkArgCnt(2, 2))
  1006.   {
  1007.     SetOpSize(1);
  1008.     if (ChkAcc(&ArgStr[1]))
  1009.     {
  1010.       tAdrResult Result;
  1011.  
  1012.       switch (DecodeAdr(&ArgStr[2], MModImm | MModReg16 | MModShort | MModSFR, &Result))
  1013.       {
  1014.         case ModImm:
  1015.           *pCode++ = 0x2c | Index;
  1016.           *pCode++ = *Result.Vals;
  1017.           *pCode++ = 1[Result.Vals];
  1018.           break;
  1019.         case ModReg16:
  1020.           *pCode++ = 0x88 | Vals[Index - 1];
  1021.           *pCode++ = 0x08 | (Result.Val << 1);
  1022.           break;
  1023.         case ModShort:
  1024.           *pCode++ = 0x1c | Index;
  1025.           *pCode++ = *Result.Vals;
  1026.           break;
  1027.         case ModSFR:
  1028.           *pCode++ = 0x01;
  1029.           *pCode++ = 0x1c | Index;
  1030.           *pCode++ = *Result.Vals;
  1031.           break;
  1032.       }
  1033.     }
  1034.   }
  1035. }
  1036.  
  1037. static void DecodeMULDIV(Word Index)
  1038. {
  1039.   if (ChkArgCnt(1, 1))
  1040.   {
  1041.     tAdrResult Result;
  1042.  
  1043.     switch (DecodeAdr(&ArgStr[1], MModReg8, &Result))
  1044.     {
  1045.       case ModReg8:
  1046.         *pCode++ = 0x05;
  1047.         *pCode++ = Index | Result.Val;
  1048.         break;
  1049.     }
  1050.   }
  1051. }
  1052.  
  1053. static void DecodeINCDEC(Word Index)
  1054. {
  1055.   if (ChkArgCnt(1, 1))
  1056.   {
  1057.     tAdrResult Result;
  1058.  
  1059.     switch (DecodeAdr(&ArgStr[1], MModReg8 | MModShort, &Result))
  1060.     {
  1061.       case ModReg8:
  1062.         *pCode++ = 0xc0 | (Index << 3) | Result.Val;
  1063.         break;
  1064.       case ModShort:
  1065.         *pCode++ = 0x26 | Index;
  1066.         *pCode++ = *Result.Vals;
  1067.         break;
  1068.     }
  1069.   }
  1070. }
  1071.  
  1072. static void DecodeINCDECW(Word Index)
  1073. {
  1074.   if (ChkArgCnt(1, 1))
  1075.   {
  1076.     tAdrResult Result;
  1077.  
  1078.     switch (DecodeAdr(&ArgStr[1], MModReg16 | MModSP, &Result))
  1079.     {
  1080.       case ModReg16:
  1081.         *pCode++ = 0x44 | (Index << 3) | Result.Val;
  1082.         break;
  1083.       case ModSP:
  1084.         *pCode++ = 0x05;
  1085.         *pCode++ = 0xc0 | Index;
  1086.         break;
  1087.     }
  1088.   }
  1089. }
  1090.  
  1091. static void DecodeShift8(Word Index)
  1092. {
  1093.   Boolean OK;
  1094.   Byte Shift;
  1095.  
  1096.   if (ChkArgCnt(2, 2))
  1097.   {
  1098.     tAdrResult Result;
  1099.  
  1100.     switch (DecodeAdr(&ArgStr[1], MModReg8, &Result))
  1101.     {
  1102.       case ModReg8:
  1103.         Shift = EvalStrIntExpression(&ArgStr[2], UInt3, &OK);
  1104.         if (OK)
  1105.         {
  1106.           *pCode++ = 0x30 | Hi(Index);
  1107.           *pCode++ = Lo(Index) | (Shift << 3) | Result.Val;
  1108.         }
  1109.         break;
  1110.     }
  1111.   }
  1112. }
  1113.  
  1114. static void DecodeShift16(Word Index)
  1115. {
  1116.   Boolean OK;
  1117.   Byte Shift;
  1118.  
  1119.   if (ChkArgCnt(2, 2))
  1120.   {
  1121.     tAdrResult Result;
  1122.  
  1123.     switch (DecodeAdr(&ArgStr[1], MModReg16, &Result))
  1124.     {
  1125.       case ModReg16:
  1126.         Shift = EvalStrIntExpression(&ArgStr[2], UInt3, &OK);
  1127.         if (OK)
  1128.         {
  1129.           *pCode++ = 0x30 | Hi(Index);
  1130.           *pCode++ = Lo(Index) | (Shift << 3) | (Result.Val << 1);
  1131.         }
  1132.         break;
  1133.     }
  1134.   }
  1135. }
  1136.  
  1137. static void DecodeShift4(Word Index)
  1138. {
  1139.   if (ChkArgCnt(1, 1))
  1140.   {
  1141.     tAdrResult Result;
  1142.  
  1143.     switch (DecodeAdr(&ArgStr[1], MModMem, &Result))
  1144.     {
  1145.       case ModMem:
  1146.         if (ChkMem1(&Result))
  1147.         {
  1148.           if (Index)
  1149.             *pCode++ = 0x01;
  1150.           *pCode++ = 0x05;
  1151.           *pCode++ = 0x8c | ((*Result.Vals & 1) << 1);
  1152.         }
  1153.         break;
  1154.     }
  1155.   }
  1156. }
  1157.  
  1158. static void DecodePUSHPOP(Word Index)
  1159. {
  1160.   if (ChkArgCnt(1, 1))
  1161.   {
  1162.     tAdrResult Result;
  1163.  
  1164.     switch (DecodeAdr(&ArgStr[1], MModReg16 | MModPSW | MModSFR, &Result))
  1165.     {
  1166.       case ModReg16:
  1167.         *pCode++ = 0x34 | (Index << 3) | Result.Val;
  1168.         break;
  1169.       case ModPSW:
  1170.         *pCode++ = 0x48 | Index;
  1171.         break;
  1172.       case ModSFR:
  1173.         *pCode++ = Index ? 0x29 : 0x43;
  1174.         *pCode++ = *Result.Vals;
  1175.         break;
  1176.     }
  1177.   }
  1178. }
  1179.  
  1180. static void DecodeCALL(Word Index)
  1181. {
  1182.   UNUSED(Index);
  1183.  
  1184.   if (ChkArgCnt(1, 1))
  1185.   {
  1186.     tAdrResult Result;
  1187.  
  1188.     switch (DecodeAdr(&ArgStr[1], MModAbs | MModReg16, &Result))
  1189.     {
  1190.       case ModAbs:
  1191.         *pCode++ = 0x28;
  1192.         *pCode++ = *Result.Vals;
  1193.         *pCode++ = 1[Result.Vals];
  1194.         break;
  1195.       case ModReg16:
  1196.         *pCode++ = 0x05;
  1197.         *pCode++ = 0x58 | (Result.Val << 1);
  1198.         break;
  1199.     }
  1200.   }
  1201. }
  1202.  
  1203. static void DecodeCALLF(Word Index)
  1204. {
  1205.   Word AdrWord;
  1206.   Boolean OK;
  1207.  
  1208.   UNUSED(Index);
  1209.  
  1210.   if (ChkArgCnt(1, 1))
  1211.   {
  1212.     tSymbolFlags Flags;
  1213.  
  1214.     AdrWord = EvalStrIntExpressionOffsWithFlags(&ArgStr[1], !!(*ArgStr[1].str.p_str == '!'), UInt12, &OK, &Flags);
  1215.     if (OK)
  1216.     {
  1217.       if (mFirstPassUnknown(Flags))
  1218.         AdrWord |= 0x800;
  1219.       if (AdrWord < 0x800) WrError(ErrNum_UnderRange);
  1220.       else
  1221.       {
  1222.         *pCode++ = 0x90 | (Hi(AdrWord) & 7);
  1223.         *pCode++ = Lo(AdrWord);
  1224.       }
  1225.     }
  1226.   }
  1227. }
  1228.  
  1229. static void DecodeCALLT(Word Index)
  1230. {
  1231.   Word AdrWord;
  1232.   Boolean OK;
  1233.   int ArgLen;
  1234.   tStrComp Arg;
  1235.  
  1236.   UNUSED(Index);
  1237.  
  1238.   if (ChkArgCnt(1, 1))
  1239.   {
  1240.     StrCompRefRight(&Arg, &ArgStr[1], 0); ArgLen = strlen(Arg.str.p_str);
  1241.     if ((*Arg.str.p_str != '[') || (Arg.str.p_str[ArgLen - 1] != ']')) WrError(ErrNum_InvAddrMode);
  1242.     else
  1243.     {
  1244.       tSymbolFlags Flags;
  1245.  
  1246.       StrCompIncRefLeft(&Arg, 1);
  1247.       StrCompShorten(&Arg, 1);
  1248.       AdrWord = EvalStrIntExpressionWithFlags(&Arg, UInt7, &OK, &Flags);
  1249.       if (OK)
  1250.       {
  1251.         if (mFirstPassUnknown(Flags))
  1252.         AdrWord = 0x40;
  1253.         if (ChkRange(AdrWord, 0x40, 0x7e))
  1254.         {
  1255.           if (AdrWord & 1) WrError(ErrNum_AddrMustBeEven);
  1256.           else
  1257.           {
  1258.             *pCode++ = 0xe0 | ((AdrWord - 0x40) >> 1);
  1259.           }
  1260.         }
  1261.       }
  1262.     }
  1263.   }
  1264. }
  1265.  
  1266. static void DecodeBR(Word Index)
  1267. {
  1268.   Boolean Rel;
  1269.  
  1270.   UNUSED(Index);
  1271.  
  1272.   if (ChkArgCnt(1, 1))
  1273.   {
  1274.     tAdrResult Result;
  1275.     tStrComp Arg;
  1276.  
  1277.     StrCompRefRight(&Arg, &ArgStr[1], 0);
  1278.     Rel = (*Arg.str.p_str == '$');
  1279.     if (Rel)
  1280.       StrCompIncRefLeft(&Arg, 1);
  1281.     switch (DecodeAdr(&Arg, MModAbs | MModReg16, &Result))
  1282.     {
  1283.       case ModAbs:
  1284.         if (Rel)
  1285.         {
  1286.           LongInt Addr = (((Word)1[Result.Vals]) << 8) | (*Result.Vals);
  1287.  
  1288.           Addr -= EProgCounter() + 2;
  1289.           if (!mSymbolQuestionable(Result.ValSymFlags) && ((Addr < -128) || (Addr > 127))) WrError(ErrNum_JmpDistTooBig);
  1290.           else
  1291.           {
  1292.             *pCode++ = 0x14;
  1293.             *pCode++ = Addr & 0xff;
  1294.           }
  1295.         }
  1296.         else
  1297.         {
  1298.           *pCode++ = 0x2c;
  1299.           *pCode++ = *Result.Vals;
  1300.           *pCode++ = 1[Result.Vals];
  1301.         }
  1302.         break;
  1303.       case ModReg16:
  1304.         *pCode++ = 0x05;
  1305.         *pCode++ = 0x48 | (Result.Val << 1);
  1306.         break;
  1307.     }
  1308.   }
  1309. }
  1310.  
  1311. static void DecodeBranch(Word Index)
  1312. {
  1313.   LongInt Addr;
  1314.   Boolean OK;
  1315.  
  1316.   if (ChkArgCnt(1, 1))
  1317.   {
  1318.     tSymbolFlags Flags;
  1319.  
  1320.     Addr = EvalStrIntExpressionOffsWithFlags(&ArgStr[1], !!(*ArgStr[1].str.p_str == '$'), UInt16, &OK, &Flags) - (EProgCounter() + 2);
  1321.     if (OK)
  1322.     {
  1323.       if (!mSymbolQuestionable(Flags) && ((Addr < -128) || (Addr > 127))) WrError(ErrNum_JmpDistTooBig);
  1324.       else
  1325.       {
  1326.         *pCode++ = Index;
  1327.         *pCode++ = Addr & 0xff;
  1328.       }
  1329.     }
  1330.   }
  1331. }
  1332.  
  1333. static void DecodeDBNZ(Word Index)
  1334. {
  1335.   LongInt Addr;
  1336.   Boolean OK;
  1337.  
  1338.   UNUSED(Index);
  1339.  
  1340.   if (ChkArgCnt(2, 2))
  1341.   {
  1342.     tAdrResult Result;
  1343.  
  1344.     switch (DecodeAdr(&ArgStr[1], MModShort | MModReg8, &Result))
  1345.     {
  1346.       case ModShort:
  1347.         *pCode++ = 0x3b;
  1348.         *pCode++ = *Result.Vals;
  1349.         break;
  1350.       case ModReg8:
  1351.         if ((Result.Val < 2) || (Result.Val > 3))
  1352.         {
  1353.           WrError(ErrNum_InvAddrMode);
  1354.           Result.Mode = ModNone;
  1355.         }
  1356.         else
  1357.           *pCode++ = 0x30 | Result.Val;
  1358.         break;
  1359.     }
  1360.     if (Result.Mode != ModNone)
  1361.     {
  1362.       tSymbolFlags Flags;
  1363.  
  1364.       Addr = EvalStrIntExpressionOffsWithFlags(&ArgStr[2], !!(*ArgStr[2].str.p_str == '$'), UInt16, &OK, &Flags) - (EProgCounter() + (pCode - BAsmCode) + 1);
  1365.       if (!mSymbolQuestionable(Flags) && ((Addr < -128) || (Addr > 127)))
  1366.       {
  1367.         WrError(ErrNum_JmpDistTooBig);
  1368.         pCode = BAsmCode;
  1369.       }
  1370.       else
  1371.         *pCode++ = Addr & 0xff;
  1372.     }
  1373.   }
  1374. }
  1375.  
  1376. static void DecodeSEL(Word Index)
  1377. {
  1378.   Boolean OK;
  1379.   Byte Bank;
  1380.  
  1381.   UNUSED(Index);
  1382.  
  1383.   if (!ChkArgCnt(1, 1));
  1384.   else if (as_strncasecmp(ArgStr[1].str.p_str, "RB", 2)) WrError(ErrNum_InvAddrMode);
  1385.   else
  1386.   {
  1387.     Bank = EvalStrIntExpressionOffs(&ArgStr[1], 2, UInt2, &OK);
  1388.     if (OK)
  1389.     {
  1390.       *pCode++ = 0x05;
  1391.       *pCode++ = 0xa8 | Bank;
  1392.     }
  1393.   }
  1394. }
  1395.  
  1396. static void DecodeBIT(Word Index)
  1397. {
  1398.   LongWord Result;
  1399.  
  1400.   UNUSED(Index);
  1401.  
  1402.   if (!ChkArgCnt(1, 1));
  1403.   else if (DecodeBitAdr(&ArgStr[1], &Result))
  1404.     EnterIntSymbol(&LabPart, Result, SegNone, False);
  1405. }
  1406.  
  1407. static void DecodeMOV1(Word Index)
  1408. {
  1409.   LongWord Bit;
  1410.   int ArgPos;
  1411.  
  1412.   UNUSED(Index);
  1413.  
  1414.   if (ChkArgCnt(2, 2))
  1415.   {
  1416.     if (!as_strcasecmp(ArgStr[1].str.p_str, "CY"))
  1417.       ArgPos = 2;
  1418.     else if (!as_strcasecmp(ArgStr[2].str.p_str, "CY"))
  1419.       ArgPos = 1;
  1420.     else
  1421.     {
  1422.       WrError(ErrNum_InvAddrMode);
  1423.       return;
  1424.     }
  1425.     if (DecodeBitAdr(&ArgStr[ArgPos], &Bit))
  1426.     {
  1427.       *pCode++ = 0x00 | ((Bit >> 16) & 0xff);
  1428.       *pCode++ = ((2 - ArgPos) << 4) | ((Bit >> 8) & 0xff);
  1429.       if (Bit & 0x1000000)
  1430.         *pCode++ = Bit & 0xff;
  1431.     }
  1432.   }
  1433. }
  1434.  
  1435. static void DecodeANDOR1(Word Index)
  1436. {
  1437.   LongWord Bit;
  1438.  
  1439.   if (!ChkArgCnt(2, 2));
  1440.   else if (as_strcasecmp(ArgStr[1].str.p_str, "CY")) WrError(ErrNum_InvAddrMode);
  1441.   else
  1442.   {
  1443.     tStrComp *pArg = &ArgStr[2], BitArg;
  1444.  
  1445.     if (*pArg->str.p_str == '/')
  1446.     {
  1447.       StrCompRefRight(&BitArg, &ArgStr[2], 1);
  1448.       pArg = &BitArg;
  1449.       Index |= 0x10;
  1450.     }
  1451.     if (DecodeBitAdr(pArg, &Bit))
  1452.     {
  1453.       *pCode++ = 0x00 | ((Bit >> 16) & 0xff);
  1454.       *pCode++ = Index  | ((Bit >> 8) & 0xff);
  1455.       if (Bit & 0x1000000)
  1456.         *pCode++ = Bit & 0xff;
  1457.     }
  1458.   }
  1459. }
  1460.  
  1461. static void DecodeXOR1(Word Index)
  1462. {
  1463.   LongWord Bit;
  1464.  
  1465.   UNUSED(Index);
  1466.  
  1467.   if (!ChkArgCnt(2, 2));
  1468.   else if (as_strcasecmp(ArgStr[1].str.p_str, "CY")) WrError(ErrNum_InvAddrMode);
  1469.   else
  1470.   {
  1471.     if (DecodeBitAdr(&ArgStr[2], &Bit))
  1472.     {
  1473.       *pCode++ = 0x00 | ((Bit >> 16) & 0xff);
  1474.       *pCode++ = 0x60 | ((Bit >> 8) & 0xff);
  1475.       if (Bit & 0x1000000)
  1476.         *pCode++ = Bit & 0xff;
  1477.     }
  1478.   }
  1479. }
  1480.  
  1481. static void DecodeBit1(Word Index)
  1482. {
  1483.   LongWord Bit;
  1484.  
  1485.   UNUSED(Index);
  1486.  
  1487.   if (!ChkArgCnt(1, 1));
  1488.   else if (!as_strcasecmp(ArgStr[1].str.p_str, "CY"))
  1489.   {
  1490.     *pCode++ = 0x40 | (9 - (Index >> 4));
  1491.   }
  1492.   else if (DecodeBitAdr(&ArgStr[1], &Bit))
  1493.   {
  1494.     if ((Index >= 0x80) && ((Bit & 0xfffff800) == 0x01080000))
  1495.     {
  1496.       *pCode++ = (0x130 - Index) | ((Bit >> 8) & 7);
  1497.       *pCode++ = Bit & 0xff;
  1498.     }
  1499.     else
  1500.     {
  1501.       *pCode++ = 0x00 | ((Bit >> 16) & 0xff);
  1502.       *pCode++ = Index | ((Bit >> 8) & 0xff);
  1503.       if (Bit & 0x1000000)
  1504.         *pCode++ = Bit & 0xff;
  1505.     }
  1506.   }
  1507. }
  1508.  
  1509. static void DecodeBrBit(Word Index)
  1510. {
  1511.   LongWord Bit;
  1512.  
  1513.   LongInt Addr;
  1514.   Boolean OK;
  1515.  
  1516.   UNUSED(Index);
  1517.  
  1518.   if (ChkArgCnt(2, 2)
  1519.    && DecodeBitAdr(&ArgStr[1], &Bit))
  1520.   {
  1521.     tSymbolFlags Flags;
  1522.  
  1523.     if ((Bit & 0xfffff800) == 0x01080000)
  1524.     {
  1525.       if (Index == 0x80)
  1526.       {
  1527.         *pCode++ = 0x70 | ((Bit >> 8) & 7);
  1528.         *pCode++ = Bit & 0xff;
  1529.       }
  1530.       else
  1531.       {
  1532.         *pCode++ = 0x00 | ((Bit >> 16) & 0xff);
  1533.         *pCode++ = (0x130 - Index) | ((Bit >> 8) & 0xff);
  1534.         if (Bit & 0x1000000)
  1535.           *pCode++ = Bit & 0xff;
  1536.       }
  1537.     }
  1538.     else
  1539.     {
  1540.       *pCode++ = 0x00 | ((Bit >> 16) & 0xff);
  1541.       *pCode++ = (0x130 - Index) | ((Bit >> 8) & 0xff);
  1542.       if (Bit & 0x1000000)
  1543.         *pCode++ = Bit & 0xff;
  1544.     }
  1545.  
  1546.     Addr = EvalStrIntExpressionOffsWithFlags(&ArgStr[2], !!(*ArgStr[2].str.p_str == '$'), UInt16, &OK, &Flags) - (EProgCounter() + (pCode - BAsmCode) + 1);
  1547.     if (!mSymbolQuestionable(Flags) && ((Addr < -128) || (Addr > 127)))
  1548.     {
  1549.       WrError(ErrNum_JmpDistTooBig);
  1550.       pCode = BAsmCode;
  1551.     }
  1552.     else
  1553.       *pCode++ = Addr & 0xff;
  1554.   }
  1555. }
  1556.  
  1557. /*-------------------------------------------------------------------------*/
  1558. /* dynamic code table handling */
  1559.  
  1560. static void AddFixed(const char *NName, Word NCode)
  1561. {
  1562.   AddInstTable(InstTable, NName, NCode, DecodeFixed);
  1563. }
  1564.  
  1565. static void InitFields(void)
  1566. {
  1567.   InstTable = CreateInstTable(201);
  1568.  
  1569.   AddInstTable(InstTable, "MOV", 0, DecodeMOV);
  1570.   AddInstTable(InstTable, "XCH", 0, DecodeXCH);
  1571.   AddInstTable(InstTable, "MOVW", 0, DecodeMOVW);
  1572.  
  1573.   AddInstTable(InstTable, "ADD"  , 0, DecodeALU);
  1574.   AddInstTable(InstTable, "ADDC" , 1, DecodeALU);
  1575.   AddInstTable(InstTable, "SUB"  , 2, DecodeALU);
  1576.   AddInstTable(InstTable, "SUBC" , 3, DecodeALU);
  1577.   AddInstTable(InstTable, "AND"  , 4, DecodeALU);
  1578.   AddInstTable(InstTable, "OR"   , 6, DecodeALU);
  1579.   AddInstTable(InstTable, "XOR"  , 5, DecodeALU);
  1580.   AddInstTable(InstTable, "CMP"  , 7, DecodeALU);
  1581.  
  1582.   AddInstTable(InstTable, "ADDW", 1, DecodeALU16);
  1583.   AddInstTable(InstTable, "SUBW", 2, DecodeALU16);
  1584.   AddInstTable(InstTable, "CMPW", 3, DecodeALU16);
  1585.  
  1586.   AddInstTable(InstTable, "MULU" , 0x08, DecodeMULDIV);
  1587.   AddInstTable(InstTable, "DIVUW", 0x18, DecodeMULDIV);
  1588.  
  1589.   AddInstTable(InstTable, "INC", 0, DecodeINCDEC);
  1590.   AddInstTable(InstTable, "DEC", 1, DecodeINCDEC);
  1591.  
  1592.   AddInstTable(InstTable, "INCW", 0, DecodeINCDECW);
  1593.   AddInstTable(InstTable, "DECW", 1, DecodeINCDECW);
  1594.  
  1595.   AddInstTable(InstTable, "ROR"  , 0x040, DecodeShift8);
  1596.   AddInstTable(InstTable, "ROL"  , 0x140, DecodeShift8);
  1597.   AddInstTable(InstTable, "RORC" , 0x000, DecodeShift8);
  1598.   AddInstTable(InstTable, "ROLC" , 0x100, DecodeShift8);
  1599.   AddInstTable(InstTable, "SHR"  , 0x080, DecodeShift8);
  1600.   AddInstTable(InstTable, "SHL"  , 0x180, DecodeShift8);
  1601.  
  1602.   AddInstTable(InstTable, "SHRW" , 0x0c0, DecodeShift16);
  1603.   AddInstTable(InstTable, "SHLW" , 0x1c0, DecodeShift16);
  1604.  
  1605.   AddInstTable(InstTable, "ROR4" , 0, DecodeShift4);
  1606.   AddInstTable(InstTable, "ROL4" , 1, DecodeShift4);
  1607.  
  1608.   AddInstTable(InstTable, "POP"  , 0, DecodePUSHPOP);
  1609.   AddInstTable(InstTable, "PUSH" , 1, DecodePUSHPOP);
  1610.  
  1611.   AddInstTable(InstTable, "CALL" , 0, DecodeCALL);
  1612.   AddInstTable(InstTable, "CALLF", 0, DecodeCALLF);
  1613.   AddInstTable(InstTable, "CALLT", 0, DecodeCALLT);
  1614.  
  1615.   AddInstTable(InstTable, "BR"   , 0, DecodeBR);
  1616.  
  1617.   AddInstTable(InstTable, "BC"   , 0x83, DecodeBranch);
  1618.   AddInstTable(InstTable, "BL"   , 0x83, DecodeBranch);
  1619.   AddInstTable(InstTable, "BNC"  , 0x82, DecodeBranch);
  1620.   AddInstTable(InstTable, "BNL"  , 0x82, DecodeBranch);
  1621.   AddInstTable(InstTable, "BZ"   , 0x81, DecodeBranch);
  1622.   AddInstTable(InstTable, "BE"   , 0x81, DecodeBranch);
  1623.   AddInstTable(InstTable, "BNZ"  , 0x80, DecodeBranch);
  1624.   AddInstTable(InstTable, "BNE"  , 0x80, DecodeBranch);
  1625.  
  1626.   AddInstTable(InstTable, "DBNZ" , 0, DecodeDBNZ);
  1627.  
  1628.   AddInstTable(InstTable, "SEL", 0, DecodeSEL);
  1629.  
  1630.   AddInstTable(InstTable, "MOV1", 0, DecodeMOV1);
  1631.   AddInstTable(InstTable, "AND1", 0x20, DecodeANDOR1);
  1632.   AddInstTable(InstTable, "OR1" , 0x40, DecodeANDOR1);
  1633.   AddInstTable(InstTable, "XOR1" , 0, DecodeXOR1);
  1634.  
  1635.   AddInstTable(InstTable, "SET1", 0x80, DecodeBit1);
  1636.   AddInstTable(InstTable, "CLR1", 0x90, DecodeBit1);
  1637.   AddInstTable(InstTable, "NOT1", 0x70, DecodeBit1);
  1638.  
  1639.   AddInstTable(InstTable, "BT"    , 0x80, DecodeBrBit);
  1640.   AddInstTable(InstTable, "BF"    , 0x90, DecodeBrBit);
  1641.   AddInstTable(InstTable, "BTCLR" , 0x60, DecodeBrBit);
  1642.  
  1643.   AddFixed("NOP",   0x00);
  1644.   AddFixed("DI",    0x4a);
  1645.   AddFixed("EI",    0x4b);
  1646.   AddFixed("BRK",   0x5e);
  1647.   AddFixed("RET",   0x56);
  1648.   AddFixed("RETI",  0x57);
  1649.   AddFixed("RETB",  0x5f);
  1650.   AddFixed("ADJBA", 0x0e);
  1651.   AddFixed("ADJBS", 0x0f);
  1652.  
  1653.   AddInstTable(InstTable, "BIT", 0, DecodeBIT);
  1654. }
  1655.  
  1656. static void DeinitFields(void)
  1657. {
  1658.   DestroyInstTable(InstTable);
  1659. }
  1660.  
  1661. /*-------------------------------------------------------------------------*/
  1662. /* interface to common layer */
  1663.  
  1664. static void MakeCode_78K2(void)
  1665. {
  1666.   CodeLen = 0; DontPrint = False; OpSize = -1;
  1667.  
  1668.   /* zu ignorierendes */
  1669.  
  1670.   if (Memo("")) return;
  1671.  
  1672.   /* Pseudoanweisungen */
  1673.  
  1674.   if (DecodeIntelPseudo(False)) return;
  1675.  
  1676.   pCode = BAsmCode;
  1677.   if (!LookupInstTable(InstTable, OpPart.str.p_str))
  1678.     WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
  1679.   else
  1680.     CodeLen = pCode - BAsmCode;
  1681. }
  1682.  
  1683. static void InitCode_78K2(void)
  1684. {
  1685.   Reg_PM6 = 0;
  1686.   Reg_P6  = 0;
  1687. }
  1688.  
  1689. static Boolean IsDef_78K2(void)
  1690. {
  1691.   return Memo("BIT");
  1692. }
  1693.  
  1694. static void SwitchFrom_78K2(void)
  1695. {
  1696.   DeinitFields();
  1697. }
  1698.  
  1699. static void SwitchTo_78K2(void)
  1700. {
  1701.   static const ASSUMERec ASSUME78K2s[] =
  1702.   {
  1703.     {"P6"  , &Reg_P6  , 0,  0xf,  0x10, NULL},
  1704.     {"PM6" , &Reg_PM6 , 0,  0xf,  0x10, NULL}
  1705.   };
  1706.   const TFamilyDescr *pDescr;
  1707.  
  1708.   pDescr = FindFamilyByName("78K2");
  1709.  
  1710.   TurnWords = False;
  1711.   SetIntConstMode(eIntConstModeIntel);
  1712.  
  1713.   PCSymbol = "PC";
  1714.   HeaderID = pDescr->Id;
  1715.   NOPCode = 0x00;
  1716.   DivideChars = ",";
  1717.   HasAttrs = False;
  1718.  
  1719.   ValidSegs = 1 << SegCode;
  1720.   Grans[SegCode] = 1; ListGrans[SegCode] = 1; SegInits[SegCode] = 0;
  1721.   SegLimits[SegCode] = 0xfffff;
  1722.  
  1723.   pASSUMERecs = ASSUME78K2s;
  1724.   ASSUMERecCnt = sizeof(ASSUME78K2s) / sizeof(ASSUME78K2s[0]);
  1725.  
  1726.   MakeCode = MakeCode_78K2; IsDef = IsDef_78K2;
  1727.   SwitchFrom = SwitchFrom_78K2; InitFields();
  1728. }
  1729.  
  1730. void code78k2_init(void)
  1731. {
  1732.   CPU78214 = AddCPU("78214", SwitchTo_78K2);
  1733.  
  1734.   AddInitPassProc(InitCode_78K2);
  1735. }
  1736.