Subversion Repositories pentevo

Rev

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

  1. /* codefmc16.c */
  2. /****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
  4. /*                                                                           */
  5. /* AS, C-Version                                                            */
  6. /*                                                                          */
  7. /* Codegenerator fuer Fujitsu-F2MC16L-Prozessoren                           */
  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 "asmpars.h"
  19. #include "asmsub.h"
  20. #include "asmallg.h"
  21. #include "onoff_common.h"
  22. #include "errmsg.h"
  23. #include "codepseudo.h"
  24. #include "intpseudo.h"
  25. #include "asmitree.h"
  26. #include "codevars.h"
  27. #include "headids.h"
  28. #include "errmsg.h"
  29.  
  30. #include "codefmc16.h"
  31.  
  32. /*--------------------------------------------------------------------------*/
  33. /* Definitionen */
  34.  
  35. #define AccOrderCnt 2
  36. #define MulDivOrderCnt 8
  37.  
  38. typedef struct
  39. {
  40.   Byte Code;
  41.   Word AccCode;
  42. } MulDivOrder;
  43.  
  44. #define ModNone (-1)
  45. #define ModAcc 0
  46. #define MModAcc (1 << ModAcc)
  47. #define ModReg 1
  48. #define MModReg (1 << ModReg)
  49. #define ModMem 2
  50. #define MModMem (1 << ModMem)
  51. #define ModDir 3
  52. #define MModDir (1 << ModDir)
  53. #define ModImm 4
  54. #define MModImm (1 << ModImm)
  55. #define ModCCR 5
  56. #define MModCCR (1 << ModCCR)
  57. #define ModIO 6
  58. #define MModIO (1 << ModIO)
  59. #define ModSeg 7
  60. #define MModSeg (1 << ModSeg)
  61. #define ModIAcc 8
  62. #define MModIAcc (1 << ModIAcc)
  63. #define ModRDisp 9
  64. #define MModRDisp (1 << ModRDisp)
  65. #define ModSpec 10
  66. #define MModSpec (1 << ModSpec)
  67. #define ModRP 11
  68. #define MModRP (1 << ModRP)
  69. #define ModILM 12
  70. #define MModILM (1 << ModILM)
  71. #define ModSP 13
  72. #define MModSP (1 << ModSP)
  73.  
  74. #define ABSMODE 0x1f
  75.  
  76. static CPUVar CPU90500;
  77.  
  78. static MulDivOrder *MulDivOrders;
  79.  
  80. static const char BankNames[4][4] =
  81. {
  82.   "PCB", "DTB", "ADB", "SPB"
  83. };
  84.  
  85. static Byte AdrVals[5], AdrPart, NextDataSeg;
  86. static LongWord CurrBank;
  87. static ShortInt AdrMode, OpSize;
  88.  
  89. static LongInt Reg_PCB, Reg_DTB, Reg_ADB, Reg_USB, Reg_SSB, Reg_DPR;
  90.  
  91. #define ASSUMEF2MC16Count 6
  92. static ASSUMERec ASSUMEF2MC16s[ASSUMEF2MC16Count] =
  93. {
  94.   { "PCB"    , &Reg_PCB,     0x00, 0xff, 0x100, NULL },
  95.   { "DTB"    , &Reg_DTB,     0x00, 0xff, 0x100, NULL },
  96.   { "ADB"    , &Reg_ADB,     0x00, 0xff, 0x100, NULL },
  97.   { "USB"    , &Reg_USB,     0x00, 0xff, 0x100, NULL },
  98.   { "SSB"    , &Reg_SSB,     0x00, 0xff, 0x100, NULL },
  99.   { "DPR"    , &Reg_DPR,     0x00, 0xff, 0x100, NULL }
  100. };
  101.  
  102. /*--------------------------------------------------------------------------*/
  103. /* Adressdekoder */
  104.  
  105. static void SetOpSize(ShortInt NewSize)
  106. {
  107.   if (OpSize == -1)
  108.     OpSize = NewSize;
  109.   else if (OpSize != NewSize)
  110.   {
  111.     WrError(ErrNum_ConfOpSizes);
  112.     AdrMode = ModNone; AdrCnt = 0;
  113.   }
  114. }
  115.  
  116. static Boolean DecodeAdr(const tStrComp *pArg, int Mask)
  117. {
  118.   Integer AdrVal;
  119.   LongWord ImmVal;
  120.   Boolean OK;
  121.   unsigned Index;
  122.   static const char SpecNames[7][4] = {"DTB", "ADB", "SSB", "USB", "DPR", "\a", "PCB"};
  123.  
  124.   AdrMode = ModNone; AdrCnt = 0;
  125.  
  126.   /* 1. Sonderregister: */
  127.  
  128.   if (!as_strcasecmp(pArg->str.p_str, "A"))
  129.   {
  130.     AdrMode = ModAcc;
  131.     goto found;
  132.   }
  133.  
  134.   if (!as_strcasecmp(pArg->str.p_str, "CCR"))
  135.   {
  136.     AdrMode = ModCCR;
  137.     goto found;
  138.   }
  139.  
  140.   if (!as_strcasecmp(pArg->str.p_str, "ILM"))
  141.   {
  142.     AdrMode = ModILM;
  143.     goto found;
  144.   }
  145.  
  146.   if (!as_strcasecmp(pArg->str.p_str, "RP"))
  147.   {
  148.     AdrMode = ModRP;
  149.     goto found;
  150.   }
  151.  
  152.   if (!as_strcasecmp(pArg->str.p_str, "SP"))
  153.   {
  154.     AdrMode = ModSP;
  155.     goto found;
  156.   }
  157.  
  158.   if (Mask & MModSeg)
  159.   {
  160.     for (Index = 0; Index < sizeof(BankNames) / sizeof(BankNames[0]); Index++)
  161.       if (!as_strcasecmp(pArg->str.p_str, BankNames[Index]))
  162.       {
  163.         AdrMode = ModSeg;
  164.         AdrPart = Index;
  165.         goto found;
  166.       }
  167.   }
  168.  
  169.   if (Mask & MModSpec)
  170.   {
  171.     for (Index = 0; Index < sizeof(SpecNames) / sizeof(SpecNames[0]); Index++)
  172.       if (as_strcasecmp(pArg->str.p_str, SpecNames[Index]) == 0)
  173.       {
  174.         AdrMode = ModSpec;
  175.         AdrPart = Index;
  176.         goto found;
  177.       }
  178.   }
  179.  
  180.   /* 2. Register: */
  181.  
  182.   if (as_toupper(*pArg->str.p_str) == 'R')
  183.   {
  184.     switch(as_toupper(pArg->str.p_str[1]))
  185.     {
  186.       case 'W':
  187.         if ((pArg->str.p_str[3] == '\0') && (pArg->str.p_str[2] >= '0') && (pArg->str.p_str[2] <= '7'))
  188.         {
  189.           AdrPart = pArg->str.p_str[2] - '0';
  190.           AdrMode = ModReg;
  191.           SetOpSize(1);
  192.           goto found;
  193.         }
  194.         break;
  195.       case 'L':
  196.         if ((pArg->str.p_str[3] == '\0') && (pArg->str.p_str[2] >= '0') && (pArg->str.p_str[2] <= '3'))
  197.         {
  198.           AdrPart = (pArg->str.p_str[2] - '0') << 1;
  199.           AdrMode = ModReg;
  200.           SetOpSize(2);
  201.           goto found;
  202.         }
  203.         break;
  204.       case '0': case '1': case '2': case '3':
  205.       case '4': case '5': case '6': case '7':
  206.         if (pArg->str.p_str[2] == '\0')
  207.         {
  208.           AdrPart = pArg->str.p_str[1] - '0';
  209.           AdrMode = ModReg;
  210.           SetOpSize(0);
  211.           goto found;
  212.         }
  213.     }
  214.   }
  215.  
  216.   /* 3. 32-Bit-Register indirekt: */
  217.  
  218.   if ((*pArg->str.p_str == '(')
  219.    && (as_toupper(pArg->str.p_str[1]) == 'R')
  220.    && (as_toupper(pArg->str.p_str[2]) == 'L')
  221.    && (pArg->str.p_str[3] >= '0') && (pArg->str.p_str[3] <= '3')
  222.    && (pArg->str.p_str[4] == ')')
  223.    && (pArg->str.p_str[5] == '\0'))
  224.   {
  225.     AdrPart = ((pArg->str.p_str[3] - '0') << 1) + 1;
  226.     AdrMode = ModMem;
  227.     goto found;
  228.   }
  229.  
  230.   /* 4. immediate: */
  231.  
  232.   else if (*pArg->str.p_str == '#')
  233.   {
  234.     if (OpSize == -1) WrError(ErrNum_UndefOpSizes);
  235.     else
  236.     {
  237.       ImmVal = EvalStrIntExpressionOffs(pArg, 1, (OpSize == 2) ? Int32 : ((OpSize == 1) ? Int16 : Int8), &OK);
  238.       if (OK)
  239.       {
  240.         AdrMode = ModImm;
  241.         AdrVals[AdrCnt++] = ImmVal & 0xff;
  242.         if (OpSize >= 1)
  243.           AdrVals[AdrCnt++] = (ImmVal >> 8) & 0xff;
  244.         if (OpSize >= 2)
  245.         {
  246.           AdrVals[AdrCnt++] = (ImmVal >> 16) & 0xff;
  247.           AdrVals[AdrCnt++] = (ImmVal >> 24) & 0xff;
  248.         }
  249.       }
  250.     }
  251.  
  252.     goto found;
  253.   }
  254.  
  255.   /* 5. indirekt: */
  256.  
  257.   if (*pArg->str.p_str == '@')
  258.   {
  259.     tStrComp Arg;
  260.  
  261.     StrCompRefRight(&Arg, pArg, 1);
  262.  
  263.     /* Akku-indirekt: */
  264.  
  265.     if (!as_strcasecmp(Arg.str.p_str, "A"))
  266.     {
  267.       AdrMode = ModIAcc;
  268.     }
  269.  
  270.     /* PC-relativ: */
  271.  
  272.     else if (as_strncasecmp(Arg.str.p_str, "PC", 2) == 0)
  273.     {
  274.       tStrComp RegComp;
  275.  
  276.       StrCompRefRight(&RegComp, &Arg, 2);
  277.       AdrPart = 0x1e;
  278.       if ((*RegComp.str.p_str == '+') || (*RegComp.str.p_str == '-') || (as_isspace(*RegComp.str.p_str)))
  279.       {
  280.         AdrVal = EvalStrIntExpression(&RegComp, SInt16, &OK);
  281.         if (OK)
  282.         {
  283.           AdrVals[0] = AdrVal & 0xff;
  284.           AdrVals[1] = (AdrVal >> 8) & 0xff;
  285.           AdrCnt = 2;
  286.           AdrMode = ModMem;
  287.         }
  288.       }
  289.       else if (*RegComp.str.p_str == '\0')
  290.       {
  291.         AdrVals[0] = AdrVals[1] = 0;
  292.         AdrCnt = 2;
  293.         AdrMode = ModMem;
  294.       }
  295.       else
  296.         WrStrErrorPos(ErrNum_InvReg, &Arg);
  297.     }
  298.  
  299.     /* base register, 32 bit: */
  300.  
  301.     else if ((as_toupper(*Arg.str.p_str) == 'R')
  302.           && (as_toupper(Arg.str.p_str[1]) == 'L')
  303.           && (Arg.str.p_str[2] >= '0') && (Arg.str.p_str[2] <= '3'))
  304.     {
  305.       AdrVal = EvalStrIntExpressionOffs(&Arg, 3, SInt8, &OK);
  306.       if (OK)
  307.       {
  308.         AdrVals[0] = AdrVal & 0xff;
  309.         AdrCnt = 1;
  310.         AdrPart = Arg.str.p_str[2] - '0';
  311.         AdrMode = ModRDisp;
  312.       }
  313.     }
  314.  
  315.     /* base register, 16 bit: */
  316.  
  317.     else if ((as_toupper(*Arg.str.p_str) == 'R') && (as_toupper(Arg.str.p_str[1]) == 'W') &&
  318.              (Arg.str.p_str[2] >= '0') && (Arg.str.p_str[2] <= '7'))
  319.     {
  320.       tStrComp IComp;
  321.  
  322.       AdrPart = Arg.str.p_str[2] - '0';
  323.       StrCompRefRight(&IComp, &Arg, 3);
  324.       switch (*IComp.str.p_str)
  325.       {
  326.         case '\0':                          /* no displacement             */
  327.           if (AdrPart < 4)                  /* RW0..RW3 directly available */
  328.           {
  329.             AdrPart += 8;
  330.             AdrMode = ModMem;
  331.           }
  332.           else                              /* dummy disp for RW4..RW7     */
  333.           {
  334.             AdrPart += 0x10;
  335.             AdrVals[0] = 0; AdrCnt = 1;
  336.             AdrMode = ModMem;
  337.           }
  338.           break;
  339.         case '+':
  340.           if (IComp.str.p_str[1] == '\0')          /* postincrement               */
  341.           {
  342.             if (AdrPart > 3) WrError(ErrNum_InvReg);  /* only allowed for RW0..RW3   */
  343.             else
  344.             {
  345.               AdrPart += 0x0c;
  346.               AdrMode = ModMem;
  347.             }
  348.             break;
  349.           }                               /* run into disp part otherwise*/
  350.           /* else fall-through */
  351.         case ' ':
  352.         case '\t':
  353.         case '-':
  354.           while (as_isspace(*IComp.str.p_str))  /* skip leading spaces         */
  355.             StrCompIncRefLeft(&IComp, 1);
  356.           if (!as_strcasecmp(IComp.str.p_str, "+RW7"))  /* base + RW7 as index         */
  357.           {
  358.             if (AdrPart > 1) WrError(ErrNum_InvReg);
  359.             else
  360.             {
  361.               AdrPart += 0x1c;
  362.               AdrMode = ModMem;
  363.             }
  364.           }
  365.           else                               /* numeric index               */
  366.           {
  367.             AdrVal =                         /* max length depends on base  */
  368.               EvalStrIntExpression(&IComp, (AdrPart > 3) ? SInt8 : SInt16, &OK);
  369.             if (OK)
  370.             {                           /* optimize length             */
  371.               AdrVals[0] = AdrVal & 0xff;
  372.               AdrCnt = 1;
  373.               AdrMode = ModMem;
  374.               AdrPart |= 0x10;
  375.               if ((AdrVal < -0x80) || (AdrVal > 0x7f))
  376.               {
  377.                 AdrVals[AdrCnt++] = (AdrVal >> 8) & 0xff;
  378.                 AdrPart |= 0x08;
  379.               }
  380.             }
  381.           }
  382.           break;
  383.         default:
  384.           WrError(ErrNum_InvAddrMode);
  385.       }
  386.     }
  387.  
  388.     else
  389.       WrStrErrorPos(ErrNum_InvReg, &Arg);
  390.  
  391.     goto found;
  392.   }
  393.  
  394.   /* 6. dann direkt: */
  395.  
  396.   ImmVal = EvalStrIntExpression(pArg, UInt24, &OK);
  397.   if (OK)
  398.   {
  399.     AdrVals[AdrCnt++] = ImmVal & 0xff;
  400.     if (((ImmVal >> 8) == 0) && (Mask & MModIO))
  401.       AdrMode = ModIO;
  402.     else if ((Lo(ImmVal >> 8) == Reg_DPR) && ((ImmVal & 0xffff0000) == CurrBank) && (Mask & MModDir))
  403.       AdrMode = ModDir;
  404.     else
  405.     {
  406.       AdrVals[AdrCnt++] = (ImmVal >> 8) & 0xff;
  407.       AdrPart = ABSMODE;
  408.       AdrMode = ModMem;
  409.       if ((ImmVal & 0xffff0000) != CurrBank) WrError(ErrNum_InAccPage);
  410.     }
  411.   }
  412.  
  413. found:
  414.   if ((AdrMode != ModNone) && ((Mask & (1 << AdrMode)) == 0))
  415.   {
  416.     WrError(ErrNum_InvAddrMode);
  417.     AdrMode = ModNone; AdrCnt = 0;
  418.   }
  419.  
  420.   return (AdrMode != ModNone);
  421. }
  422.  
  423. static Boolean SplitBit(tStrComp *pArg, Byte *Result)
  424. {
  425.   char *pos;
  426.   Boolean Res = FALSE;
  427.  
  428.   pos = RQuotPos(pArg->str.p_str, ':');
  429.   if (pos == NULL)
  430.   {
  431.     *Result = 0;
  432.     WrError(ErrNum_InvBitPos);
  433.   }
  434.   else
  435.   {
  436.     tStrComp BitArg;
  437.  
  438.     StrCompSplitRef(pArg, &BitArg, pArg, pos);
  439.     *Result = EvalStrIntExpression(&BitArg, UInt3, &Res);
  440.   }
  441.  
  442.   return Res;
  443. }
  444.  
  445. static void CopyVals(int Offset)
  446. {
  447.   memcpy(BAsmCode + Offset, AdrVals, AdrCnt);
  448.   CodeLen = Offset + AdrCnt;
  449. }
  450.  
  451. /*--------------------------------------------------------------------------*/
  452. /* Dekoder fuer einzelne Instruktionen */
  453.  
  454. static void DecodeFixed(Word Code)
  455. {
  456.   if (ChkArgCnt(0, 0))
  457.   {
  458.     BAsmCode[0] = Code;
  459.     CodeLen = 1;
  460.   }
  461. }
  462.  
  463. static void DecodeALU8(Word Code)
  464. {
  465.   int HCnt;
  466.  
  467.   if (ChkArgCnt(2, 2))
  468.   {
  469.     SetOpSize(0);
  470.     DecodeAdr(&ArgStr[1], MModAcc | MModReg | MModMem);
  471.     switch (AdrMode)
  472.     {
  473.       case ModAcc:
  474.         DecodeAdr(&ArgStr[2], MModReg | MModMem | MModImm | MModDir);
  475.         switch (AdrMode)
  476.         {
  477.           case ModImm:
  478.            BAsmCode[0] = 0x30 + Code;
  479.            BAsmCode[1] = AdrVals[0];
  480.            CodeLen = 2;
  481.            break;
  482.           case ModDir:
  483.            BAsmCode[0] = 0x20 + Code;
  484.            BAsmCode[1] = AdrVals[0];
  485.            CodeLen = 2;
  486.            break;
  487.           case ModReg:
  488.           case ModMem:
  489.           {
  490.             BAsmCode[0] = 0x74;
  491.             BAsmCode[1] = (Code << 5) | AdrPart;
  492.             memcpy(BAsmCode + 2, AdrVals, AdrCnt);
  493.             CodeLen = 2 + AdrCnt;
  494.           }
  495.         }
  496.         break;
  497.       case ModReg:
  498.       case ModMem:
  499.         HCnt = AdrCnt;
  500.         BAsmCode[1] = (Code << 5) | AdrPart;
  501.         memcpy(BAsmCode + 2, AdrVals, AdrCnt);
  502.         if (DecodeAdr(&ArgStr[2], MModAcc))
  503.         {
  504.           BAsmCode[0] = 0x75;
  505.           CodeLen = 2 + HCnt;
  506.         }
  507.         break;
  508.     }
  509.   }
  510. }
  511.  
  512. static void DecodeLog8(Word Code)
  513. {
  514.   int HCnt;
  515.  
  516.   if (ChkArgCnt(2, 2))
  517.   {
  518.     SetOpSize(0);
  519.     DecodeAdr(&ArgStr[1], MModAcc | MModReg | MModMem | ((Code < 6) ? MModCCR : 0));
  520.     switch (AdrMode)
  521.     {
  522.       case ModAcc:
  523.         DecodeAdr(&ArgStr[2], MModReg | MModMem | MModImm);
  524.         switch (AdrMode)
  525.         {
  526.           case ModImm:
  527.            BAsmCode[0] = 0x30 + Code;
  528.            BAsmCode[1] = AdrVals[0];
  529.            CodeLen = 2;
  530.            break;
  531.           case ModReg:
  532.           case ModMem:
  533.           {
  534.             BAsmCode[0] = 0x74;
  535.             BAsmCode[1] = (Code << 5) | AdrPart;
  536.             memcpy(BAsmCode + 2, AdrVals, AdrCnt);
  537.             CodeLen = 2 + AdrCnt;
  538.           }
  539.         }
  540.         break;
  541.       case ModReg:
  542.       case ModMem:
  543.         HCnt = AdrCnt;
  544.         BAsmCode[1] = (Code << 5) | AdrPart;
  545.         memcpy(BAsmCode + 2, AdrVals, AdrCnt);
  546.         if (DecodeAdr(&ArgStr[2], MModAcc))
  547.         {
  548.           BAsmCode[0] = 0x75;
  549.           CodeLen = 2 + HCnt;
  550.         }
  551.         break;
  552.       case ModCCR:
  553.         if (DecodeAdr(&ArgStr[2], MModImm))
  554.         {
  555.           BAsmCode[0] = 0x20 + Code;
  556.           BAsmCode[1] = AdrVals[0];
  557.           CodeLen = 2;
  558.         }
  559.         break;
  560.     }
  561.   }
  562. }
  563.  
  564. static void DecodeCarry8(Word Index)
  565. {
  566.   if (ChkArgCnt(1, 2)
  567.    && DecodeAdr(&ArgStr[1], MModAcc))
  568.   {
  569.     if (ArgCnt == 1)
  570.     {
  571.       BAsmCode[0] = 0x22 + (Index << 4);
  572.       CodeLen = 1;
  573.     }
  574.     else if (DecodeAdr(&ArgStr[2], MModReg | MModMem))
  575.     {
  576.       BAsmCode[0] = 0x74 + Index;
  577.       BAsmCode[1] = AdrPart | 0x40;
  578.       memcpy(BAsmCode + 2, AdrVals, AdrCnt);
  579.       CodeLen = 2 + AdrCnt;
  580.     }
  581.   }
  582. }
  583.  
  584. static void DecodeCarry16(Word Index)
  585. {
  586.   if (ChkArgCnt(2, 2)
  587.    && DecodeAdr(&ArgStr[1], MModAcc)
  588.    && DecodeAdr(&ArgStr[2], MModReg | MModMem))
  589.   {
  590.     BAsmCode[0] = 0x76 + Index;
  591.     BAsmCode[1] = AdrPart | 0x40;
  592.     memcpy(BAsmCode + 2, AdrVals, AdrCnt);
  593.     CodeLen = 2 + AdrCnt;
  594.   }
  595. }
  596.  
  597. static void DecodeAcc(Word Code)
  598. {
  599.   if (ChkArgCnt(1, 1)
  600.    && DecodeAdr(&ArgStr[1], MModAcc))
  601.   {
  602.     BAsmCode[0] = Code;
  603.     CodeLen = 1;
  604.   }
  605. }
  606.  
  607. static void DecodeShift(Word Code)
  608. {
  609.   if (ChkArgCnt(Hi(Code) ? 1 : 2, 2)
  610.    && DecodeAdr(&ArgStr[1], MModAcc))
  611.   {
  612.     if (ArgCnt == 1)
  613.     {
  614.       BAsmCode[0] = Lo(Code);
  615.       CodeLen = 1;
  616.     }
  617.     else
  618.     {
  619.       SetOpSize(0);
  620.       if (DecodeAdr(&ArgStr[2], MModReg))
  621.       {
  622.         if (AdrPart != 0) WrStrErrorPos(ErrNum_InvReg, &ArgStr[2]);
  623.         else
  624.         {
  625.           BAsmCode[0] = 0x6f;
  626.           BAsmCode[1] = Lo(Code);
  627.           CodeLen = 2;
  628.         }
  629.       }
  630.     }
  631.   }
  632. }
  633.  
  634. static void DecodeAdd32(Word Index)
  635. {
  636.   if (ChkArgCnt(2, 2)
  637.    && DecodeAdr(&ArgStr[1], MModAcc))
  638.   {
  639.     SetOpSize(2);
  640.     if (DecodeAdr(&ArgStr[2], MModImm | MModMem | MModReg))
  641.     {
  642.       switch (AdrMode)
  643.       {
  644.         case ModImm:
  645.           BAsmCode[0] = 0x18 + Index;
  646.           memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  647.           CodeLen = 1 + AdrCnt;
  648.           break;
  649.         case ModReg:
  650.         case ModMem:
  651.           BAsmCode[0] = 0x70;
  652.           BAsmCode[1] = AdrPart | (Index << 5);
  653.           memcpy(BAsmCode + 2, AdrVals, AdrCnt);
  654.           CodeLen = 2 + AdrCnt;
  655.           break;
  656.       }
  657.     }
  658.   }
  659. }
  660.  
  661. static void DecodeLog32(Word Index)
  662. {
  663.   if (ChkArgCnt(2, 2)
  664.    && DecodeAdr(&ArgStr[1], MModAcc))
  665.   {
  666.     if (DecodeAdr(&ArgStr[2], MModMem | MModReg))
  667.     {
  668.       BAsmCode[0] = 0x70;
  669.       BAsmCode[1] = AdrPart | (Index << 5);
  670.       memcpy(BAsmCode + 2, AdrVals, AdrCnt);
  671.       CodeLen = 2 + AdrCnt;
  672.     }
  673.   }
  674. }
  675.  
  676. static void DecodeADDSP(Word Index)
  677. {
  678.   Integer Val;
  679.   Boolean OK;
  680.   UNUSED(Index);
  681.  
  682.   if (!ChkArgCnt(1, 1));
  683.   else if (*ArgStr[1].str.p_str != '#') WrError(ErrNum_OnlyImmAddr);
  684.   else
  685.   {
  686.     Val = EvalStrIntExpressionOffs(&ArgStr[1], 1, Int16, &OK);
  687.     if (OK)
  688.     {
  689.       BAsmCode[CodeLen++] = 0x17;
  690.       BAsmCode[CodeLen++] = Val & 0xff;
  691.       if ((Val > 127) || (Val < -128))
  692.       {
  693.         BAsmCode[CodeLen++] = (Val >> 8) & 0xff;
  694.         BAsmCode[0] |= 8;
  695.       }
  696.     }
  697.   }
  698. }
  699.  
  700. static void DecodeAdd16(Word Index)
  701. {
  702.   int HCnt;
  703.  
  704.   if (!ChkArgCnt(1, 2));
  705.   else if (ArgCnt == 1)
  706.   {
  707.     if (DecodeAdr(&ArgStr[1], MModAcc))
  708.     {
  709.       BAsmCode[0] = 0x28 | Index;
  710.       CodeLen = 1;
  711.     }
  712.   }
  713.   else
  714.   {
  715.     SetOpSize(1);
  716.     DecodeAdr(&ArgStr[1], MModAcc | ((Index != 3) ? (MModMem | MModReg) : 0));
  717.     switch (AdrMode)
  718.     {
  719.       case ModAcc:
  720.         DecodeAdr(&ArgStr[2], MModImm | MModMem | MModReg);
  721.         switch (AdrMode)
  722.         {
  723.           case ModImm:
  724.             BAsmCode[0] = 0x38 | Index;
  725.             memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  726.             CodeLen = 1 + AdrCnt;
  727.             break;
  728.           case ModMem:
  729.           case ModReg:
  730.             BAsmCode[0] = 0x76;
  731.             BAsmCode[1] = AdrPart | (Index << 5);
  732.             memcpy(BAsmCode + 2, AdrVals, AdrCnt);
  733.             CodeLen = 2 + AdrCnt;
  734.             break;
  735.         }
  736.         break;
  737.       case ModMem:
  738.       case ModReg:
  739.         BAsmCode[0] = 0x77;
  740.         BAsmCode[1] = AdrPart | (Index << 5);
  741.         memcpy(BAsmCode + 2, AdrVals, AdrCnt);
  742.         HCnt = 2 + AdrCnt;
  743.         if (DecodeAdr(&ArgStr[2], MModAcc))
  744.           CodeLen = HCnt;
  745.         break;
  746.     }
  747.   }
  748. }
  749.  
  750. static void DecodeBBcc(Word Index)
  751. {
  752.   Byte BitPos, HLen;
  753.   LongInt Addr;
  754.   Boolean OK;
  755.  
  756.   if ((ChkArgCnt(2, 2))
  757.    && (SplitBit(&ArgStr[1], &BitPos)))
  758.   {
  759.     HLen = 0;
  760.     DecodeAdr(&ArgStr[1], MModMem | MModDir | MModIO);
  761.     if (AdrMode != ModNone)
  762.     {
  763.       BAsmCode[HLen++] = 0x6c;
  764.       switch (AdrMode)
  765.       {
  766.         case ModDir:
  767.           BAsmCode[HLen++] = Index + 8 + BitPos;
  768.           BAsmCode[HLen++] = AdrVals[0];
  769.           break;
  770.         case ModIO:
  771.           BAsmCode[HLen++] = Index + BitPos;
  772.           BAsmCode[HLen++] = AdrVals[0];
  773.           break;
  774.         case ModMem:
  775.           if (AdrPart != ABSMODE) WrError(ErrNum_InvAddrMode);
  776.           else
  777.           {
  778.             BAsmCode[HLen++] = Index + 16 + BitPos;
  779.             memcpy(BAsmCode + HLen, AdrVals, AdrCnt);
  780.             HLen += AdrCnt;
  781.           }
  782.           break;
  783.       }
  784.       if (HLen > 1)
  785.       {
  786.         tSymbolFlags Flags;
  787.  
  788.         Addr = EvalStrIntExpressionWithFlags(&ArgStr[2], UInt24, &OK, &Flags) - (EProgCounter() + HLen + 1);
  789.         if (OK)
  790.         {
  791.           if (!mSymbolQuestionable(Flags) && ((Addr < -128) || (Addr > 127))) WrError(ErrNum_JmpDistTooBig);
  792.           else
  793.           {
  794.             BAsmCode[HLen++] = Addr & 0xff;
  795.             CodeLen = HLen;
  796.           }
  797.         }
  798.       }
  799.     }
  800.   }
  801. }
  802.  
  803. static void DecodeBranch(Word Code)
  804. {
  805.   LongInt Addr;
  806.   Boolean OK;
  807.  
  808.   if (ChkArgCnt(1, 1))
  809.   {
  810.     tSymbolFlags Flags;
  811.  
  812.     Addr = EvalStrIntExpressionWithFlags(&ArgStr[1], UInt24, &OK, &Flags) - (EProgCounter() + 2);
  813.     if (OK)
  814.     {
  815.       if (!mSymbolQuestionable(Flags) && ((Addr < -128) || (Addr > 127))) WrError(ErrNum_JmpDistTooBig);
  816.       else
  817.       {
  818.         BAsmCode[0] = Code;
  819.         BAsmCode[1] = Addr & 0xff;
  820.         CodeLen = 2;
  821.       }
  822.     }
  823.   }
  824. }
  825.  
  826. static void DecodeJmp16(Word Index)
  827. {
  828.   LongWord Addr;
  829.   Boolean OK;
  830.  
  831.   if (!ChkArgCnt(1, 1));
  832.   else if (*ArgStr[1].str.p_str == '@')
  833.   {
  834.     tStrComp Arg1;
  835.  
  836.     SetOpSize(1);
  837.     StrCompRefRight(&Arg1, &ArgStr[1], 1);
  838.     DecodeAdr(&Arg1, MModReg | ((Index == 0) ? MModAcc : 0) | MModMem);
  839.     switch (AdrMode)
  840.     {
  841.       case ModAcc:
  842.         BAsmCode[0] = 0x61;
  843.         CodeLen = 1;
  844.         break;
  845.       case ModReg:
  846.       case ModMem:
  847.         BAsmCode[0] = 0x73;
  848.         BAsmCode[1] = (Index << 4) | AdrPart;
  849.         memcpy(BAsmCode + 2, AdrVals, AdrCnt);
  850.         CodeLen = 2 + AdrCnt;
  851.         break;
  852.     }
  853.   }
  854.   else
  855.   {
  856.     Addr = EvalStrIntExpression(&ArgStr[1], UInt24, &OK);
  857.     if (OK)
  858.     {
  859.       BAsmCode[0] = 0x62 + Index;
  860.       BAsmCode[1] = Addr & 0xff;
  861.       BAsmCode[2] = (Addr >> 8) & 0xff;
  862.       CodeLen = 3;
  863.       if (((Addr >> 16) & 0xff) != (LongWord)Reg_PCB)
  864.         WrError(ErrNum_InAccSegment);
  865.     }
  866.   }
  867. }
  868.  
  869. static void DecodeJmp24(Word Index)
  870. {
  871.   LongWord Addr;
  872.   Boolean OK;
  873.  
  874.   if (!ChkArgCnt(1, 1));
  875.   else if (*ArgStr[1].str.p_str == '@')
  876.   {
  877.     tStrComp Arg1;
  878.  
  879.     SetOpSize(2);
  880.     StrCompRefRight(&Arg1, &ArgStr[1], 1);
  881.     if (DecodeAdr(&Arg1, MModReg | MModMem))
  882.     {
  883.       BAsmCode[0] = 0x71;
  884.       BAsmCode[1] = (Index << 4) | AdrPart;
  885.       memcpy(BAsmCode + 2, AdrVals, AdrCnt);
  886.       CodeLen = 2 + AdrCnt;
  887.     }
  888.   }
  889.   else
  890.   {
  891.     Addr = EvalStrIntExpression(&ArgStr[1], UInt24, &OK);
  892.     if (OK)
  893.     {
  894.       BAsmCode[0] = 0x63 + Index;
  895.       BAsmCode[1] = Addr & 0xff;
  896.       BAsmCode[2] = (Addr >> 8) & 0xff;
  897.       BAsmCode[3] = (Addr >> 16) & 0xff;
  898.       CodeLen = 4;
  899.     }
  900.   }
  901. }
  902.  
  903. static void DecodeCALLV(Word Index)
  904. {
  905.   Boolean OK;
  906.   UNUSED(Index);
  907.  
  908.   if (!ChkArgCnt(1, 1));
  909.   else if (*ArgStr[1].str.p_str != '#') WrError(ErrNum_OnlyImmAddr);
  910.   else
  911.   {
  912.     BAsmCode[0] = 0xe0 + EvalStrIntExpressionOffs(&ArgStr[1], 1, UInt4, &OK);
  913.     if (OK) CodeLen = 1;
  914.   }
  915. }
  916.  
  917. static void DecodeCmpBranch(Word Index)
  918. {
  919.   LongInt Addr;
  920.   int HCnt;
  921.   Boolean OK;
  922.  
  923.   if (ChkArgCnt(3, 3))
  924.   {
  925.     SetOpSize(Index); HCnt = 0;
  926.     if (DecodeAdr(&ArgStr[1], MModMem | MModReg | MModAcc))
  927.     {
  928.       OK = TRUE;
  929.       switch (AdrMode)
  930.       {
  931.         case ModAcc:
  932.           BAsmCode[HCnt++] = 0x2a + (Index << 4);
  933.           break;
  934.         case ModReg:
  935.         case ModMem:
  936.           if ((AdrPart >= 0x0c) && (AdrPart <= 0x0f))
  937.           {
  938.             WrError(ErrNum_InvAddrMode); OK = FALSE;
  939.           }
  940.           BAsmCode[HCnt++] = 0x70;
  941.           BAsmCode[HCnt++] = 0xe0 - (Index * 0xa0) + AdrPart;
  942.           memcpy(BAsmCode + HCnt, AdrVals, AdrCnt);
  943.           HCnt += AdrCnt;
  944.           break;
  945.       }
  946.       if ((OK) && (DecodeAdr(&ArgStr[2], MModImm)))
  947.       {
  948.         tSymbolFlags Flags;
  949.  
  950.         memcpy(BAsmCode + HCnt, AdrVals, AdrCnt);
  951.         HCnt += AdrCnt;
  952.         Addr = EvalStrIntExpressionWithFlags(&ArgStr[3], UInt24, &OK, &Flags) - (EProgCounter() + HCnt + 1);
  953.         if (OK)
  954.         {
  955.           if (!mSymbolQuestionable(Flags) && ((Addr > 127) || (Addr < -128))) WrError(ErrNum_JmpDistTooBig);
  956.           else
  957.           {
  958.             BAsmCode[HCnt++] = Addr & 0xff;
  959.             CodeLen = HCnt;
  960.           }
  961.         }
  962.       }
  963.     }
  964.   }
  965. }
  966.  
  967. static void DecodeBit(Word Index)
  968. {
  969.   Byte BitPos;
  970.  
  971.   if ((ChkArgCnt(1, 1))
  972.    && (SplitBit(&ArgStr[1], &BitPos)))
  973.   {
  974.     DecodeAdr(&ArgStr[1], MModMem | MModDir | MModIO);
  975.     if (AdrMode != ModNone)
  976.     {
  977.       BAsmCode[CodeLen++] = 0x6c;
  978.       switch (AdrMode)
  979.       {
  980.         case ModDir:
  981.           BAsmCode[CodeLen++] = Index + 8 + BitPos;
  982.           BAsmCode[CodeLen++] = AdrVals[0];
  983.           break;
  984.         case ModIO:
  985.           BAsmCode[CodeLen++] = Index + BitPos;
  986.           BAsmCode[CodeLen++] = AdrVals[0];
  987.           break;
  988.         case ModMem:
  989.           if (AdrPart != ABSMODE) WrError(ErrNum_InvAddrMode);
  990.           else
  991.           {
  992.             BAsmCode[CodeLen++] = Index + 16 + BitPos;
  993.             memcpy(BAsmCode + CodeLen, AdrVals, AdrCnt);
  994.             CodeLen += AdrCnt;
  995.           }
  996.           break;
  997.       }
  998.     }
  999.   }
  1000. }
  1001.  
  1002. static void DecodeCMP(Word Index)
  1003. {
  1004.   UNUSED(Index);
  1005.  
  1006.   if (ChkArgCnt(1, 2)
  1007.    && DecodeAdr(&ArgStr[1], MModAcc))
  1008.   {
  1009.     if (ArgCnt == 1)
  1010.     {
  1011.       BAsmCode[0] = 0x23;
  1012.       CodeLen = 1;
  1013.     }
  1014.     else
  1015.     {
  1016.       SetOpSize(0);
  1017.       DecodeAdr(&ArgStr[2], MModMem | MModReg | MModImm);
  1018.       switch (AdrMode)
  1019.       {
  1020.         case ModMem:
  1021.         case ModReg:
  1022.           BAsmCode[0] = 0x74;
  1023.           BAsmCode[1] = AdrPart | 0x40;
  1024.           memcpy(BAsmCode + 2, AdrVals, AdrCnt);
  1025.           CodeLen = 2 + AdrCnt;
  1026.           break;
  1027.         case ModImm:
  1028.           BAsmCode[0] = 0x33;
  1029.           BAsmCode[1] = AdrVals[0];
  1030.           CodeLen = 2;
  1031.           break;
  1032.       }
  1033.     }
  1034.   }
  1035. }
  1036.  
  1037. static void DecodeDBNZ(Word Index)
  1038. {
  1039.   LongInt Addr;
  1040.   Boolean OK;
  1041.  
  1042.   if (ChkArgCnt(2, 2))
  1043.   {
  1044.     SetOpSize(Index);
  1045.     if (DecodeAdr(&ArgStr[1], MModReg | MModMem))
  1046.     {
  1047.       tSymbolFlags Flags;
  1048.  
  1049.       Addr = EvalStrIntExpressionWithFlags(&ArgStr[2], UInt16, &OK, &Flags) - (EProgCounter() + 3 + AdrCnt);
  1050.       if (OK)
  1051.       {
  1052.         if (!mSymbolQuestionable(Flags) && ((Addr < -128) || (Addr > 127))) WrError(ErrNum_JmpDistTooBig);
  1053.         else
  1054.         {
  1055.           BAsmCode[0] = 0x74 + (Index << 1);
  1056.           BAsmCode[1] = 0xe0 | AdrPart;
  1057.           memcpy(BAsmCode + 2, AdrVals, AdrCnt);
  1058.           BAsmCode[2 + AdrCnt] = Addr & 0xff;
  1059.           CodeLen = 3 + AdrCnt;
  1060.         }
  1061.       }
  1062.     }
  1063.   }
  1064. }
  1065.  
  1066. static void DecodeIncDec(Word Code)
  1067. {
  1068.   static Byte Sizes[3] = {2, 0, 1};
  1069.  
  1070.   if (ChkArgCnt(1, 1))
  1071.   {
  1072.     SetOpSize(Sizes[(Code & 3) - 1]);
  1073.     if (DecodeAdr(&ArgStr[1], MModMem | MModReg))
  1074.     {
  1075.       BAsmCode[0] = 0x70 | (Code & 15);
  1076.       BAsmCode[1] = (Code & 0xf0) | AdrPart;
  1077.       memcpy(BAsmCode + 2, AdrVals, AdrCnt);
  1078.       CodeLen = 2 + AdrCnt;
  1079.     }
  1080.   }
  1081. }
  1082.  
  1083. static void DecodeMulDiv(Word Index)
  1084. {
  1085.   MulDivOrder *POrder = MulDivOrders + Index;
  1086.  
  1087.   if (ChkArgCnt(1, 2)
  1088.    && DecodeAdr(&ArgStr[1], MModAcc))
  1089.   {
  1090.     if (ArgCnt == 1)
  1091.     {
  1092.       if (POrder->AccCode == 0xfff) WrError(ErrNum_InvAddrMode);
  1093.       else
  1094.       {
  1095.         BAsmCode[CodeLen++] = Lo(POrder->AccCode);
  1096.         if (Hi(POrder->AccCode) != 0)
  1097.          BAsmCode[CodeLen++] = Hi(POrder->AccCode);
  1098.       }
  1099.     }
  1100.     else
  1101.     {
  1102.       SetOpSize((POrder->Code >> 5) & 1);
  1103.       if (DecodeAdr(&ArgStr[2], MModMem | MModReg))
  1104.       {
  1105.         BAsmCode[0] = 0x78;
  1106.         BAsmCode[1] = POrder->Code | AdrPart;
  1107.         memcpy(BAsmCode + 2, AdrVals, AdrCnt);
  1108.         CodeLen = 2 + AdrCnt;
  1109.       }
  1110.     }
  1111.   }
  1112. }
  1113.  
  1114. static void DecodeSeg(Word Code)
  1115. {
  1116.   if (ChkArgCnt(1, 1)
  1117.    && DecodeAdr(&ArgStr[1], MModSeg))
  1118.   {
  1119.     BAsmCode[0] = 0x6e;
  1120.     BAsmCode[1] = Code + AdrPart;
  1121.     CodeLen = 2;
  1122.   }
  1123. }
  1124.  
  1125. static void DecodeString(Word Code)
  1126. {
  1127.   if (ChkArgCnt(2, 2)
  1128.    && DecodeAdr(&ArgStr[1], MModSeg))
  1129.   {
  1130.     BAsmCode[1] = AdrPart << 2;
  1131.     if (DecodeAdr(&ArgStr[2], MModSeg))
  1132.     {
  1133.       BAsmCode[1] += Code + AdrPart;
  1134.       BAsmCode[0] = 0x6e;
  1135.       CodeLen = 2;
  1136.     }
  1137.   }
  1138. }
  1139.  
  1140. static void DecodeINT(Word Index)
  1141. {
  1142.   Boolean OK;
  1143.   LongWord Addr;
  1144.   UNUSED(Index);
  1145.  
  1146.   if (!ChkArgCnt(1, 1));
  1147.   else if (*ArgStr[1].str.p_str == '#')
  1148.   {
  1149.     BAsmCode[1] = EvalStrIntExpressionOffs(&ArgStr[1], 1, UInt8, &OK);
  1150.     if (OK)
  1151.     {
  1152.       BAsmCode[0] = 0x68;
  1153.       CodeLen = 2;
  1154.     }
  1155.   }
  1156.   else
  1157.   {
  1158.     tSymbolFlags Flags;
  1159.  
  1160.     Addr = EvalStrIntExpressionWithFlags(&ArgStr[1], UInt24, &OK, &Flags);
  1161.     if (OK)
  1162.     {
  1163.       if (!mSymbolQuestionable(Flags) && ((Addr & 0xff0000) != 0xff0000))
  1164.         WrError(ErrNum_InAccPage);
  1165.       BAsmCode[0] = 0x69;
  1166.       BAsmCode[1] = Addr & 0xff;
  1167.       BAsmCode[2] = (Addr >> 8) & 0xff;
  1168.       CodeLen = 3;
  1169.     }
  1170.   }
  1171. }
  1172.  
  1173. static void DecodeINTP(Word Index)
  1174. {
  1175.   Boolean OK;
  1176.   LongWord Addr;
  1177.   UNUSED(Index);
  1178.  
  1179.   if (ChkArgCnt(1, 1))
  1180.   {
  1181.     Addr = EvalStrIntExpression(&ArgStr[1], UInt24, &OK);
  1182.     if (OK)
  1183.     {
  1184.       BAsmCode[0] = 0x6a;
  1185.       BAsmCode[1] = Addr & 0xff;
  1186.       BAsmCode[2] = (Addr >> 8) & 0xff;
  1187.       BAsmCode[3] = (Addr >> 16) & 0xff;
  1188.       CodeLen = 4;
  1189.     }
  1190.   }
  1191. }
  1192.  
  1193. static void DecodeJCTX(Word Index)
  1194. {
  1195.   UNUSED(Index);
  1196.  
  1197.   if (!ChkArgCnt(1, 1));
  1198.   else if (*ArgStr[1].str.p_str != '@') WrError(ErrNum_InvAddrMode);
  1199.   else
  1200.   {
  1201.     tStrComp Arg1;
  1202.  
  1203.     StrCompRefRight(&Arg1, &ArgStr[1], 1);
  1204.     if (DecodeAdr(&Arg1, MModAcc))
  1205.     {
  1206.       BAsmCode[0] = 0x13;
  1207.       CodeLen = 1;
  1208.     }
  1209.   }
  1210. }
  1211.  
  1212. static void DecodeLINK(Word Index)
  1213. {
  1214.   UNUSED(Index);
  1215.  
  1216.   if (ChkArgCnt(1, 1))
  1217.   {
  1218.     SetOpSize(0);
  1219.     if (DecodeAdr(&ArgStr[1], MModImm))
  1220.     {
  1221.       BAsmCode[0] = 0x08;
  1222.       BAsmCode[1] = AdrVals[0];
  1223.       CodeLen = 2;
  1224.     }
  1225.   }
  1226. }
  1227.  
  1228. static void DecodeMOV(Word Index)
  1229. {
  1230.   Byte HPart, HCnt;
  1231.   UNUSED(Index);
  1232.  
  1233.   if (!ChkArgCnt(2, 2));
  1234.   else if (((!as_strcasecmp(ArgStr[1].str.p_str, "@AL")) || (!as_strcasecmp(ArgStr[1].str.p_str, "@A")))
  1235.        && ((!as_strcasecmp(ArgStr[2].str.p_str, "AH" )) || (!as_strcasecmp(ArgStr[2].str.p_str, "T" ))))
  1236.   {
  1237.     BAsmCode[0] = 0x6f; BAsmCode[1] = 0x15;
  1238.     CodeLen = 2;
  1239.   }
  1240.   else
  1241.   {
  1242.     SetOpSize(0);
  1243.     DecodeAdr(&ArgStr[1], MModRP | MModILM | MModAcc | MModDir | MModRDisp | MModIO | MModSpec | MModReg | MModMem);
  1244.     switch (AdrMode)
  1245.     {
  1246.       case ModRP:
  1247.       {
  1248.         if (DecodeAdr(&ArgStr[2], MModImm))
  1249.         {
  1250.           BAsmCode[0] = 0x0a;
  1251.           BAsmCode[1] = AdrVals[0];
  1252.           CodeLen = 2;
  1253.         }
  1254.         break;
  1255.       } /* 1 = ModRP */
  1256.       case ModILM:
  1257.       {
  1258.         if (DecodeAdr(&ArgStr[2], MModImm))
  1259.         {
  1260.           BAsmCode[0] = 0x1a;
  1261.           BAsmCode[1] = AdrVals[0];
  1262.           CodeLen = 2;
  1263.         }
  1264.         break;
  1265.       } /* 1 = ModILM */
  1266.       case ModAcc:
  1267.       {
  1268.         DecodeAdr(&ArgStr[2], MModImm | MModIAcc | MModRDisp | MModIO | MModMem | MModReg | MModDir | MModSpec);
  1269.         switch (AdrMode)
  1270.         {
  1271.           case ModImm:
  1272.             BAsmCode[0] = 0x42;
  1273.             BAsmCode[1] = AdrVals[0];
  1274.             CodeLen = 2;
  1275.             break;
  1276.           case ModIAcc:
  1277.             BAsmCode[0] = 0x6f;
  1278.             BAsmCode[1] = 0x05;
  1279.             CodeLen = 2;
  1280.             break;
  1281.           case ModRDisp:
  1282.             BAsmCode[0] = 0x6f;
  1283.             BAsmCode[1] = 0x40 | (AdrPart << 1);
  1284.             BAsmCode[2] = AdrVals[0];
  1285.             CodeLen = 3;
  1286.             break;
  1287.           case ModIO:
  1288.             BAsmCode[0] = 0x50;
  1289.             BAsmCode[1] = AdrVals[0];
  1290.             CodeLen = 2;
  1291.             break;
  1292.           case ModMem:
  1293.             if (AdrPart == ABSMODE) /* 16 bit absolute */
  1294.             {
  1295.               BAsmCode[0] = 0x52;
  1296.               CodeLen = 1;
  1297.             }
  1298.             else
  1299.             {
  1300.               BAsmCode[0] = 0x72;
  1301.               BAsmCode[1] = 0x80 + AdrPart;
  1302.               CodeLen = 2;
  1303.             }
  1304.             memcpy(BAsmCode + CodeLen, AdrVals, AdrCnt);
  1305.             CodeLen += AdrCnt;
  1306.             break;
  1307.           case ModReg:
  1308.             BAsmCode[0] = 0x80 | AdrPart;
  1309.             CodeLen = 1;
  1310.             break;
  1311.           case ModDir:
  1312.             BAsmCode[0] = 0x40;
  1313.             BAsmCode[1] = AdrVals[0];
  1314.             CodeLen = 2;
  1315.             break;
  1316.           case ModSpec:
  1317.             BAsmCode[0] = 0x6f;
  1318.             BAsmCode[1] = 0x00 + AdrPart;
  1319.             CodeLen = 2;
  1320.             break;
  1321.         }
  1322.         break;
  1323.       } /* 1 = ModAcc */
  1324.       case ModDir:
  1325.       {
  1326.         BAsmCode[1] = AdrVals[0];
  1327.         DecodeAdr(&ArgStr[2], MModAcc | MModImm | MModReg);
  1328.         switch (AdrMode)
  1329.         {
  1330.           case ModAcc:
  1331.             BAsmCode[0] = 0x41;
  1332.             CodeLen = 2;
  1333.             break;
  1334.           case ModImm:
  1335.             BAsmCode[0] = 0x44;
  1336.             BAsmCode[2] = AdrVals[0];
  1337.             CodeLen = 3;
  1338.             break;
  1339.           case ModReg:           /* extend to 16 bits */
  1340.             BAsmCode[0] = 0x7c;
  1341.             BAsmCode[2] = BAsmCode[1];
  1342.             BAsmCode[1] = (AdrPart << 5) | ABSMODE;
  1343.             BAsmCode[3] = Reg_DPR;
  1344.             CodeLen = 4;
  1345.             break;
  1346.         }
  1347.         break;
  1348.       } /* 1 = ModDir */
  1349.       case ModRDisp:
  1350.       {
  1351.         BAsmCode[2] = AdrVals[0];
  1352.         DecodeAdr(&ArgStr[2], MModAcc);
  1353.         switch (AdrMode)
  1354.         {
  1355.           case ModAcc:
  1356.             BAsmCode[0] = 0x6f;
  1357.             BAsmCode[1] = 0x30 | (AdrPart << 1);
  1358.             CodeLen = 3;
  1359.             break;
  1360.         }
  1361.         break;
  1362.       } /* 1 = ModRDisp */
  1363.       case ModIO:
  1364.       {
  1365.         BAsmCode[1] = AdrVals[0];
  1366.         DecodeAdr(&ArgStr[2], MModAcc | MModImm | MModReg);
  1367.         switch (AdrMode)
  1368.         {
  1369.           case ModAcc:
  1370.             BAsmCode[0] = 0x51;
  1371.             CodeLen = 2;
  1372.             break;
  1373.           case ModImm:
  1374.             BAsmCode[0] = 0x54;
  1375.             BAsmCode[2] = AdrVals[0];
  1376.             CodeLen = 3;
  1377.             break;
  1378.           case ModReg:           /* extend to 16 bits - will only work when in Bank 0 */
  1379.             BAsmCode[0] = 0x7c;
  1380.             BAsmCode[2] = BAsmCode[1];
  1381.             BAsmCode[1] = (AdrPart << 5) | ABSMODE;
  1382.             BAsmCode[3] = 0;
  1383.             if (CurrBank != 0) WrError(ErrNum_InAccPage);
  1384.             CodeLen = 4;
  1385.             break;
  1386.         }
  1387.         break;
  1388.       } /* 1 = ModIO */
  1389.       case ModSpec:
  1390.         if (AdrPart == 6) WrError(ErrNum_InvAddrMode);
  1391.         else
  1392.         {
  1393.           BAsmCode[1] = 0x10 + AdrPart;
  1394.           DecodeAdr(&ArgStr[2], MModAcc);
  1395.           switch (AdrMode)
  1396.           {
  1397.             case ModAcc:
  1398.               BAsmCode[0] = 0x6f;
  1399.               CodeLen = 2;
  1400.               break;
  1401.           }
  1402.         } /* 1 = ModSpec */
  1403.         break;
  1404.       case ModReg:
  1405.       {
  1406.         BAsmCode[0] = AdrPart;
  1407.         DecodeAdr(&ArgStr[2], MModAcc | MModImm | MModReg | MModMem);
  1408.         switch (AdrMode)
  1409.         {
  1410.           case ModAcc:
  1411.             BAsmCode[0] += 0x90;
  1412.             CodeLen = 1;
  1413.             break;
  1414.           case ModImm:
  1415.             BAsmCode[0] += 0xa0;
  1416.             BAsmCode[1] = AdrVals[0];
  1417.             CodeLen = 2;
  1418.             break;
  1419.           case ModReg:
  1420.           case ModMem:
  1421.             BAsmCode[1] = (BAsmCode[0] << 5) | AdrPart;
  1422.             BAsmCode[0] = 0x7a;
  1423.             memcpy(BAsmCode + 2, AdrVals, AdrCnt);
  1424.             CodeLen = 2 + AdrCnt;
  1425.             break;
  1426.         }
  1427.         break;
  1428.       } /* 1 = ModReg */
  1429.       case ModMem:
  1430.       {
  1431.         HPart = AdrPart; HCnt = AdrCnt;
  1432.         memcpy(BAsmCode + 2, AdrVals, AdrCnt);
  1433.         DecodeAdr(&ArgStr[2], MModAcc | MModImm | MModReg);
  1434.         switch (AdrMode)
  1435.         {
  1436.           case ModAcc:
  1437.             if (HPart == ABSMODE)
  1438.             {
  1439.               memmove(BAsmCode + 1, BAsmCode + 2, 2);
  1440.               BAsmCode[0] = 0x53;
  1441.               CodeLen = 3;
  1442.             }
  1443.             else
  1444.             {
  1445.               BAsmCode[0] = 0x72;
  1446.               BAsmCode[1] = 0xa0 | HPart;
  1447.               CodeLen = 2 + HCnt;
  1448.             }
  1449.             break;
  1450.           case ModImm:
  1451.             BAsmCode[0] = 0x71;
  1452.             BAsmCode[1] = 0xc0 | HPart;
  1453.             BAsmCode[2 + HCnt] = AdrVals[0];
  1454.             CodeLen = 3 + HCnt;
  1455.             break;
  1456.           case ModReg:
  1457.             BAsmCode[0] = 0x7c;
  1458.             BAsmCode[1] = (AdrPart << 5) | HPart;
  1459.             CodeLen = 2 + HCnt;
  1460.         }
  1461.         break;
  1462.       } /* 1 = ModMem */
  1463.     }
  1464.   }
  1465. }
  1466.  
  1467. static void DecodeMOVB(Word Index)
  1468. {
  1469.   if (ChkArgCnt(2, 2))
  1470.   {
  1471.     if (!as_strcasecmp(ArgStr[1].str.p_str, "A"))
  1472.       Index = 2;
  1473.     else if (!as_strcasecmp(ArgStr[2].str.p_str, "A"))
  1474.       Index = 1;
  1475.     else
  1476.       WrError(ErrNum_InvAddrMode);
  1477.     if ((Index > 0)
  1478.      && SplitBit(&ArgStr[Index], BAsmCode + 1)
  1479.      && DecodeAdr(&ArgStr[Index], MModDir | MModIO | MModMem))
  1480.     {
  1481.       BAsmCode[0] = 0x6c;
  1482.       BAsmCode[1] += (2 - Index) << 5;
  1483.       switch (AdrMode)
  1484.       {
  1485.         case ModDir:
  1486.           BAsmCode[1] += 0x08;
  1487.           break;
  1488.         case ModMem:
  1489.           BAsmCode[1] += 0x18;
  1490.           if (AdrPart != ABSMODE)
  1491.           {
  1492.             WrError(ErrNum_InvAddrMode);
  1493.             AdrCnt = 0;
  1494.           }
  1495.           break;
  1496.       }
  1497.       memcpy(BAsmCode + 2, AdrVals, AdrCnt);
  1498.       CodeLen = 2 + AdrCnt;
  1499.     }
  1500.   }
  1501. }
  1502.  
  1503. static void DecodeMOVEA(Word Index)
  1504. {
  1505.   UNUSED(Index);
  1506.  
  1507.   if (ChkArgCnt(2, 2))
  1508.   {
  1509.     SetOpSize(1);
  1510.     DecodeAdr(&ArgStr[1], MModAcc | MModReg);
  1511.     switch (AdrMode)
  1512.     {
  1513.       case ModAcc:
  1514.         if (DecodeAdr(&ArgStr[2], MModMem | MModReg))
  1515.         {
  1516.           BAsmCode[0] = 0x71;
  1517.           BAsmCode[1] = 0xe0 | AdrPart;
  1518.           memcpy(BAsmCode + 2, AdrVals, AdrCnt);
  1519.           CodeLen = 2 + AdrCnt;
  1520.         }
  1521.         break;
  1522.       case ModReg:
  1523.         BAsmCode[1] = AdrPart << 5;
  1524.         if (DecodeAdr(&ArgStr[2], MModMem | MModReg))
  1525.         {
  1526.           BAsmCode[0] = 0x79;
  1527.           BAsmCode[1] += AdrPart;
  1528.           memcpy(BAsmCode + 2, AdrVals, AdrCnt);
  1529.           CodeLen = 2 + AdrCnt;
  1530.         }
  1531.         break;
  1532.     }
  1533.   }
  1534. }
  1535.  
  1536. static void DecodeMOVL(Word Index)
  1537. {
  1538.   Byte HCnt;
  1539.   UNUSED(Index);
  1540.  
  1541.   if (ChkArgCnt(2, 2))
  1542.   {
  1543.     SetOpSize(2);
  1544.     DecodeAdr(&ArgStr[1], MModAcc | MModMem | MModReg);
  1545.     switch (AdrMode)
  1546.     {
  1547.       case ModAcc:
  1548.         DecodeAdr(&ArgStr[2], MModMem | MModReg | MModImm);
  1549.         switch (AdrMode)
  1550.         {
  1551.           case ModImm:
  1552.             BAsmCode[0] = 0x4b;
  1553.             CopyVals(1);
  1554.             break;
  1555.           case ModReg:
  1556.           case ModMem:
  1557.             BAsmCode[0] = 0x71;
  1558.             BAsmCode[1] = 0x80 | AdrPart;
  1559.             CopyVals(2);
  1560.         }
  1561.         break;
  1562.       case ModReg:
  1563.       case ModMem:
  1564.         BAsmCode[1] = 0xa0 | AdrPart;
  1565.         HCnt = AdrCnt;
  1566.         memcpy(BAsmCode + 2, AdrVals, AdrCnt);
  1567.         if (DecodeAdr(&ArgStr[2], MModAcc))
  1568.         {
  1569.           BAsmCode[0] = 0x71;
  1570.           CodeLen = 2 + HCnt;
  1571.         }
  1572.         break;
  1573.     }
  1574.   }
  1575. }
  1576.  
  1577. static void DecodeMOVN(Word Index)
  1578. {
  1579.   Boolean OK;
  1580.   UNUSED(Index);
  1581.  
  1582.   if (ChkArgCnt(2, 2)
  1583.    && DecodeAdr(&ArgStr[1], MModAcc))
  1584.   {
  1585.     if (*ArgStr[2].str.p_str != '#') WrError(ErrNum_OnlyImmAddr);
  1586.     else
  1587.     {
  1588.       BAsmCode[0] = 0xd0 + EvalStrIntExpressionOffs(&ArgStr[2], 1, UInt4, &OK);
  1589.       if (OK)
  1590.        CodeLen = 1;
  1591.     }
  1592.   }
  1593. }
  1594.  
  1595. static void DecodeMOVW(Word Index)
  1596. {
  1597.   Byte HPart, HCnt;
  1598.   UNUSED(Index);
  1599.  
  1600.   if (!ChkArgCnt(2, 2));
  1601.   else if (((!as_strcasecmp(ArgStr[1].str.p_str, "@AL")) || (!as_strcasecmp(ArgStr[1].str.p_str, "@A")))
  1602.        && ((!as_strcasecmp(ArgStr[2].str.p_str, "AH" )) || (!as_strcasecmp(ArgStr[2].str.p_str, "T" ))))
  1603.   {
  1604.     BAsmCode[0] = 0x6f; BAsmCode[1] = 0x1d;
  1605.     CodeLen = 2;
  1606.   }
  1607.   else
  1608.   {
  1609.     SetOpSize(1);
  1610.     DecodeAdr(&ArgStr[1], MModAcc | MModRDisp | MModSP | MModDir | MModIO | MModReg | MModMem);
  1611.     switch (AdrMode)
  1612.     {
  1613.       case ModAcc:
  1614.         DecodeAdr(&ArgStr[2], MModImm | MModIAcc | MModRDisp | MModSP | MModIO | MModMem | MModReg | MModDir);
  1615.         switch (AdrMode)
  1616.         {
  1617.           case ModImm:
  1618.             BAsmCode[0] = 0x4a;
  1619.             CopyVals(1);
  1620.             break;
  1621.           case ModIAcc:
  1622.             BAsmCode[0] = 0x6f;
  1623.             BAsmCode[1] = 0x0d;
  1624.             CodeLen = 2;
  1625.             break;
  1626.           case ModRDisp:
  1627.             BAsmCode[0] = 0x6f;
  1628.             BAsmCode[1] = 0x48 + (AdrPart << 1);
  1629.             CopyVals(2);
  1630.             break;
  1631.           case ModSP:
  1632.             BAsmCode[0] = 0x46;
  1633.             CodeLen = 1;
  1634.             break;
  1635.           case ModIO:
  1636.             BAsmCode[0] = 0x58;
  1637.             CopyVals(1);
  1638.             break;
  1639.           case ModDir:
  1640.             BAsmCode[0] = 0x48;
  1641.             CopyVals(1);
  1642.             break;
  1643.           case ModReg:
  1644.             BAsmCode[0] = 0x88 + AdrPart;
  1645.             CodeLen = 1;
  1646.             break;
  1647.           case ModMem:
  1648.             if (AdrPart == ABSMODE)
  1649.             {
  1650.               BAsmCode[0] = 0x5a;
  1651.               CopyVals(1);
  1652.             }
  1653.             else if ((AdrPart >= 0x10) && (AdrPart <= 0x17))
  1654.             {
  1655.               BAsmCode[0] = 0xa8 + AdrPart;
  1656.               CopyVals(1);
  1657.             }
  1658.             else
  1659.             {
  1660.               BAsmCode[0] = 0x73;
  1661.               BAsmCode[1] = 0x80 + AdrPart;
  1662.               CopyVals(2);
  1663.             }
  1664.             break;
  1665.         }
  1666.         break; /* 1 = ModAcc */
  1667.       case ModRDisp:
  1668.         BAsmCode[1] = 0x38 + (AdrPart << 1);
  1669.         BAsmCode[2] = AdrVals[0];
  1670.         if (DecodeAdr(&ArgStr[2], MModAcc))
  1671.         {
  1672.           BAsmCode[0] = 0x6f;
  1673.           CodeLen = 3;
  1674.         }
  1675.         break; /* 1 = ModRDisp */
  1676.       case ModSP:
  1677.         if (DecodeAdr(&ArgStr[2], MModAcc))
  1678.         {
  1679.           BAsmCode[0] = 0x47;
  1680.           CodeLen = 1;
  1681.         }
  1682.         break; /* 1 = ModSP */
  1683.       case ModDir:
  1684.         BAsmCode[1] = AdrVals[0];
  1685.         DecodeAdr(&ArgStr[2], MModAcc | MModImm | MModReg);
  1686.         switch (AdrMode)
  1687.         {
  1688.           case ModAcc:
  1689.             BAsmCode[0] = 0x49;
  1690.             CodeLen = 2;
  1691.             break;
  1692.           case ModImm:           /* extend to 16 bits */
  1693.             BAsmCode[0] = 0x73;
  1694.             BAsmCode[2] = BAsmCode[1];
  1695.             BAsmCode[1] = 0xc0 | ABSMODE;
  1696.             BAsmCode[3] = Reg_DPR;
  1697.             CopyVals(4);
  1698.             break;
  1699.           case ModReg:           /* extend to 16 bits */
  1700.             BAsmCode[0] = 0x7d;
  1701.             BAsmCode[2] = BAsmCode[1];
  1702.             BAsmCode[1] = (AdrPart << 5) | ABSMODE;
  1703.             BAsmCode[3] = Reg_DPR;
  1704.             CodeLen = 4;
  1705.             break;
  1706.         }
  1707.         break; /* 1 = ModDir */
  1708.       case ModIO:
  1709.         BAsmCode[1] = AdrVals[0];
  1710.         DecodeAdr(&ArgStr[2], MModAcc | MModImm | MModReg);
  1711.         switch (AdrMode)
  1712.         {
  1713.           case ModAcc:
  1714.             BAsmCode[0] = 0x59;
  1715.             CodeLen = 2;
  1716.             break;
  1717.           case ModImm:
  1718.             BAsmCode[0] = 0x56;
  1719.             CopyVals(1);
  1720.             break;
  1721.           case ModReg:           /* extend to 16 bits - will only work when in Bank 0 */
  1722.             BAsmCode[0] = 0x7d;
  1723.             BAsmCode[2] = BAsmCode[1];
  1724.             BAsmCode[1] = (AdrPart << 5) | ABSMODE;
  1725.             BAsmCode[3] = 0;
  1726.             if (CurrBank != 0) WrError(ErrNum_InAccPage);
  1727.             CodeLen = 4;
  1728.             break;
  1729.         }
  1730.         break; /* 1 = ModIO */
  1731.       case ModReg:
  1732.         HPart = AdrPart;
  1733.         DecodeAdr(&ArgStr[2], MModAcc | MModImm | MModReg | MModMem);
  1734.         switch (AdrMode)
  1735.         {
  1736.           case ModAcc:
  1737.             BAsmCode[0] = 0x98 | HPart;
  1738.             CodeLen = 1;
  1739.             break;
  1740.           case ModImm:
  1741.             BAsmCode[0] = 0x98 | HPart;
  1742.             CopyVals(1);
  1743.             break;
  1744.           case ModReg:
  1745.           case ModMem:
  1746.             BAsmCode[0] = 0x7b;
  1747.             BAsmCode[1] = (HPart << 5) | AdrPart;
  1748.             CopyVals(2);
  1749.             break;
  1750.         }
  1751.         break; /* 1 = ModReg */
  1752.       case ModMem:
  1753.         HPart = AdrPart; HCnt = AdrCnt;
  1754.         memcpy(BAsmCode + 2, AdrVals, AdrCnt);
  1755.         DecodeAdr(&ArgStr[2], MModAcc | MModImm | MModReg);
  1756.         switch (AdrMode)
  1757.         {
  1758.           case ModAcc:
  1759.             if (HPart == ABSMODE)
  1760.             {
  1761.               BAsmCode[0] = 0x5b;
  1762.               memmove(BAsmCode + 1, BAsmCode + 2, HCnt);
  1763.               CodeLen = 1 + HCnt;
  1764.             }
  1765.             else if ((HPart >= 0x10) && (HPart <= 0x17))
  1766.             {
  1767.               BAsmCode[0] = 0xb8 + AdrPart;
  1768.               memmove(BAsmCode + 1, BAsmCode + 2, HCnt);
  1769.               CodeLen = 1 + HCnt;
  1770.             }
  1771.             else
  1772.             {
  1773.               BAsmCode[0] = 0x73;
  1774.               BAsmCode[1] = 0xa0 | AdrPart;
  1775.               CodeLen = 2 + HCnt;
  1776.             }
  1777.             break;
  1778.           case ModImm:
  1779.             BAsmCode[0] = 0x73;
  1780.             BAsmCode[1] = 0xc0 | HPart;
  1781.             CopyVals(2 + HCnt);
  1782.             break;
  1783.           case ModReg:
  1784.             BAsmCode[0] = 0x7d;
  1785.             BAsmCode[1] = (AdrPart << 5) | HPart;
  1786.             CodeLen = 2 + HCnt;
  1787.         }
  1788.         break; /* 1 = ModMem */
  1789.     }
  1790.   }
  1791. }
  1792.  
  1793. static void DecodeMOVX(Word Index)
  1794. {
  1795.   UNUSED(Index);
  1796.  
  1797.   if (ChkArgCnt(2, 2)
  1798.    && DecodeAdr(&ArgStr[1], MModAcc))
  1799.   {
  1800.     SetOpSize(0);
  1801.     DecodeAdr(&ArgStr[2], MModImm | MModIAcc | MModRDisp | MModDir | MModIO | MModReg | MModMem);
  1802.     switch (AdrMode)
  1803.     {
  1804.       case ModImm:
  1805.         BAsmCode[0] = 0x43;
  1806.         CopyVals(1);
  1807.         break;
  1808.       case ModIAcc:
  1809.         BAsmCode[0] = 0x6f;
  1810.         BAsmCode[1] = 0x16;
  1811.         CodeLen = 2;
  1812.         break;
  1813.       case ModRDisp:
  1814.         BAsmCode[0] = 0x6f;
  1815.         BAsmCode[1] = 0x20 | (AdrPart << 1);
  1816.         CopyVals(2);
  1817.         break;
  1818.       case ModDir:
  1819.         BAsmCode[0] = 0x45;
  1820.         CopyVals(1);
  1821.         break;
  1822.       case ModIO:
  1823.         BAsmCode[0] = 0x55;
  1824.         CopyVals(1);
  1825.         break;
  1826.       case ModReg:
  1827.         BAsmCode[0] = 0xb0 + AdrPart;
  1828.         CodeLen = 1;
  1829.         break;
  1830.       case ModMem:
  1831.         if (AdrPart == ABSMODE)
  1832.         {
  1833.           BAsmCode[0] = 0x57;
  1834.           CopyVals(1);
  1835.         }
  1836.         else if ((AdrPart >= 0x10) && (AdrPart <= 0x17))
  1837.         {
  1838.           BAsmCode[0] = 0xb0 + AdrPart;
  1839.           CopyVals(1);
  1840.         }
  1841.         else
  1842.         {
  1843.           BAsmCode[0] = 0x72;
  1844.           BAsmCode[1] = 0xc0 | AdrPart;
  1845.           CopyVals(2);
  1846.         }
  1847.         break;
  1848.     }
  1849.   }
  1850. }
  1851.  
  1852. static void DecodeNEGNOT(Word Index)
  1853. {
  1854.   if (ChkArgCnt(1, 1))
  1855.   {
  1856.     SetOpSize((OpPart.str.p_str[3] == 'W') ? 1 : 0);
  1857.     DecodeAdr(&ArgStr[1], MModAcc | MModReg | MModMem);
  1858.     switch (AdrMode)
  1859.     {
  1860.       case ModAcc:
  1861.         BAsmCode[0] = Lo(Index);
  1862.         CodeLen = 1;
  1863.         break;
  1864.       case ModReg:
  1865.       case ModMem:
  1866.         BAsmCode[0] = 0x75 + (OpSize << 1);
  1867.         BAsmCode[1] = Hi(Index) + AdrPart;
  1868.         CopyVals(2);
  1869.         break;
  1870.     }
  1871.   }
  1872. }
  1873.  
  1874. static void DecodeNRML(Word Index)
  1875. {
  1876.   UNUSED(Index);
  1877.  
  1878.   if (ChkArgCnt(2, 2)
  1879.    && DecodeAdr(&ArgStr[1], MModAcc))
  1880.   {
  1881.     SetOpSize(0);
  1882.     if (DecodeAdr(&ArgStr[2], MModReg))
  1883.     {
  1884.       if (AdrPart != 0) WrError(ErrNum_InvAddrMode);
  1885.       else
  1886.       {
  1887.         BAsmCode[0] = 0x6f;
  1888.         BAsmCode[1] = 0x2d;
  1889.         CodeLen = 2;
  1890.       }
  1891.     }
  1892.   }
  1893. }
  1894.  
  1895. static void DecodeStack(Word Index)
  1896. {
  1897.   int z, z2;
  1898.   Byte HReg;
  1899.   char *p;
  1900.  
  1901.   if (!ChkArgCnt(1, ArgCntMax));
  1902.   else if ((ArgCnt == 1) && (!as_strcasecmp(ArgStr[1].str.p_str, "A")))
  1903.   {
  1904.     BAsmCode[0] = Index;
  1905.     CodeLen = 1;
  1906.   }
  1907.   else if ((ArgCnt == 1) && (!as_strcasecmp(ArgStr[1].str.p_str, "AH")))
  1908.   {
  1909.     BAsmCode[0] = Index + 1;
  1910.     CodeLen = 1;
  1911.   }
  1912.   else if ((ArgCnt == 1) && (!as_strcasecmp(ArgStr[1].str.p_str, "PS")))
  1913.   {
  1914.     BAsmCode[0] = Index + 2;
  1915.     CodeLen = 1;
  1916.   }
  1917.   else
  1918.   {
  1919.     tStrComp From, To;
  1920.  
  1921.     BAsmCode[1] = 0; SetOpSize(1);
  1922.     for (z = 1; z <= ArgCnt; z++)
  1923.      if ((p = strchr(ArgStr[z].str.p_str, '-')) != NULL)
  1924.      {
  1925.        StrCompSplitRef(&From, &To, &ArgStr[z], p);
  1926.        if (!DecodeAdr(&From, MModReg)) break;
  1927.        HReg = AdrPart;
  1928.        if (!DecodeAdr(&To, MModReg)) break;
  1929.        if (AdrPart >= HReg)
  1930.        {
  1931.          for (z2 = HReg; z2 <= AdrPart; z2++)
  1932.           BAsmCode[1] |= (1 << z2);
  1933.        }
  1934.        else
  1935.        {
  1936.          for (z2 = HReg; z2 <= 7; z2++)
  1937.           BAsmCode[1] |= (1 << z2);
  1938.          for (z2 = 0; z2 <= AdrPart; z2++)
  1939.           BAsmCode[1] |= (1 << z2);
  1940.        }
  1941.      }
  1942.      else
  1943.      {
  1944.        if (!DecodeAdr(&ArgStr[z], MModReg)) break;
  1945.        BAsmCode[1] |= (1 << AdrPart);
  1946.      }
  1947.     if (z > ArgCnt)
  1948.     {
  1949.       BAsmCode[0] = Index + 3;
  1950.       CodeLen = 2;
  1951.     }
  1952.   }
  1953. }
  1954.  
  1955. static void DecodeRotate(Word Index)
  1956. {
  1957.   if (ChkArgCnt(1, 1))
  1958.   {
  1959.     DecodeAdr(&ArgStr[1], MModAcc | MModReg | MModMem);
  1960.     switch (AdrMode)
  1961.     {
  1962.       case ModAcc:
  1963.         BAsmCode[0] = 0x6f;
  1964.         BAsmCode[1] = 0x07 | (Index << 4);
  1965.         CodeLen = 2;
  1966.         break;
  1967.       case ModReg:
  1968.       case ModMem:
  1969.         BAsmCode[0] = 0x72;
  1970.         BAsmCode[1] = (Index << 5) | AdrPart;
  1971.         CopyVals(2);
  1972.         break;
  1973.     }
  1974.   }
  1975. }
  1976.  
  1977. static void DecodeSBBS(Word Index)
  1978. {
  1979.   LongInt Adr;
  1980.   Boolean OK;
  1981.   UNUSED(Index);
  1982.  
  1983.   if (ChkArgCnt(2, 2)
  1984.    && SplitBit(&ArgStr[1], BAsmCode + 1)
  1985.    && DecodeAdr(&ArgStr[1], MModMem))
  1986.   {
  1987.     if (AdrPart != ABSMODE) WrError(ErrNum_InvAddrMode);
  1988.     else
  1989.     {
  1990.       tSymbolFlags Flags;
  1991.  
  1992.       Adr = EvalStrIntExpressionWithFlags(&ArgStr[2], UInt24, &OK, &Flags) - (EProgCounter() + 5);
  1993.       if (OK)
  1994.       {
  1995.         if (!mSymbolQuestionable(Flags) && ((Adr < -128) || (Adr > 127))) WrError(ErrNum_JmpDistTooBig);
  1996.         else
  1997.         {
  1998.           BAsmCode[0] = 0x6c;
  1999.           BAsmCode[1] += 0xf8;
  2000.           CopyVals(2);
  2001.           BAsmCode[CodeLen++] = Adr & 0xff;
  2002.         }
  2003.       }
  2004.     }
  2005.   }
  2006. }
  2007.  
  2008. static void DecodeWBit(Word Index)
  2009. {
  2010.   if (ChkArgCnt(1, 1)
  2011.    && SplitBit(&ArgStr[1], BAsmCode + 1)
  2012.    && DecodeAdr(&ArgStr[1], MModIO))
  2013.   {
  2014.     BAsmCode[0] = 0x6c;
  2015.     BAsmCode[1] += Index;
  2016.     CopyVals(2);
  2017.   }
  2018. }
  2019.  
  2020. static void DecodeExchange(Word Index)
  2021. {
  2022.   Byte HPart, HCnt;
  2023.  
  2024.   if (ChkArgCnt(2, 2))
  2025.   {
  2026.     SetOpSize(Index);
  2027.     DecodeAdr(&ArgStr[1], MModAcc | MModReg | MModMem);
  2028.     switch (AdrMode)
  2029.     {
  2030.       case ModAcc:
  2031.         if (DecodeAdr(&ArgStr[2], MModReg | MModMem))
  2032.         {
  2033.           BAsmCode[0] = 0x72 + Index;
  2034.           BAsmCode[1] = 0xe0 | AdrPart;
  2035.           CopyVals(2);
  2036.         }
  2037.         break;
  2038.       case ModReg:
  2039.         HPart = AdrPart;
  2040.         DecodeAdr(&ArgStr[2], MModAcc | MModReg | MModMem);
  2041.         switch (AdrMode)
  2042.         {
  2043.           case ModAcc:
  2044.             BAsmCode[0] = 0x72 + Index;
  2045.             BAsmCode[1] = 0xe0 | HPart;
  2046.             CodeLen = 2;
  2047.             break;
  2048.           case ModReg:
  2049.           case ModMem:
  2050.             BAsmCode[0] = 0x7e + Index;
  2051.             BAsmCode[1] = (HPart << 5) | AdrPart;
  2052.             CopyVals(2);
  2053.             break;
  2054.         }
  2055.         break;
  2056.       case ModMem:
  2057.         HPart = AdrPart; HCnt = AdrCnt;
  2058.         memcpy(BAsmCode + 2, AdrVals, AdrCnt);
  2059.         DecodeAdr(&ArgStr[2], MModAcc | MModReg);
  2060.         switch (AdrMode)
  2061.         {
  2062.           case ModAcc:
  2063.             BAsmCode[0] = 0x72 + Index;
  2064.             BAsmCode[1] = 0xe0 | HPart;
  2065.             CodeLen = 2 + HCnt;
  2066.             break;
  2067.          case ModReg:
  2068.             BAsmCode[0] = 0x7e + Index;
  2069.             BAsmCode[1] = (AdrPart << 5) | HPart;
  2070.             CodeLen = 2 + HCnt;
  2071.             break;
  2072.         }
  2073.         break;
  2074.     }
  2075.   }
  2076. }
  2077.  
  2078. static void DecodeBank(Word Index)
  2079. {
  2080.   if (ChkArgCnt(0, 0))
  2081.   {
  2082.     BAsmCode[0] = Index + 4;
  2083.     CodeLen = 1;
  2084.     NextDataSeg = Index;
  2085.   }
  2086. }
  2087.  
  2088. /*--------------------------------------------------------------------------*/
  2089. /* Codetabellen */
  2090.  
  2091. static void AddFixed(const char *NName, Byte NCode)
  2092. {
  2093.   AddInstTable(InstTable, NName, NCode, DecodeFixed);
  2094. }
  2095.  
  2096. static void AddALU8(const char *NName, Byte NCode)
  2097. {
  2098.   AddInstTable(InstTable, NName, NCode, DecodeALU8);
  2099. }
  2100.  
  2101. static void AddLog8(const char *NName, Byte NCode)
  2102. {
  2103.   AddInstTable(InstTable, NName, NCode, DecodeLog8);
  2104. }
  2105.  
  2106. static void AddAcc(const char *NName, Byte NCode)
  2107. {
  2108.   AddInstTable(InstTable, NName, NCode, DecodeAcc);
  2109. }
  2110.  
  2111. static void AddShift(const char *NName, Word NCode, Word NMay)
  2112. {
  2113.   AddInstTable(InstTable, NName, NCode | (NMay << 8), DecodeShift);
  2114. }
  2115.  
  2116. static void AddBranch(const char *NName, Byte NCode)
  2117. {
  2118.   AddInstTable(InstTable, NName, NCode, DecodeBranch);
  2119. }
  2120.  
  2121. static void AddIncDec(const char *NName, Byte NCode)
  2122. {
  2123.   AddInstTable(InstTable, NName, NCode, DecodeIncDec);
  2124. }
  2125.  
  2126. static void AddMulDiv(const char *NName, Byte NCode, Word NAccCode)
  2127. {
  2128.   MulDivOrders[InstrZ].Code = NCode;
  2129.   MulDivOrders[InstrZ].AccCode = NAccCode;
  2130.   AddInstTable(InstTable, NName, InstrZ++, DecodeMulDiv);
  2131. }
  2132.  
  2133. static void AddSeg(const char *NName, Byte NCode)
  2134. {
  2135.   AddInstTable(InstTable, NName, NCode, DecodeSeg);
  2136. }
  2137.  
  2138. static void AddString(const char *NName, Byte NCode)
  2139. {
  2140.   AddInstTable(InstTable, NName, NCode, DecodeString);
  2141. }
  2142.  
  2143. static void InitFields(void)
  2144. {
  2145.   unsigned z;
  2146.  
  2147.   InstTable = CreateInstTable(201);
  2148.  
  2149.   AddFixed("EXT"    , 0x14); AddFixed("EXTW"   , 0x1c);
  2150.   AddFixed("INT9"   , 0x01); AddFixed("NOP"    , 0x00);
  2151.   AddFixed("RET"    , 0x67); AddFixed("RETI"   , 0x6b);
  2152.   AddFixed("RETP"   , 0x66); AddFixed("SWAP"   , 0x16);
  2153.   AddFixed("SWAPW"  , 0x1e); AddFixed("UNLINK" , 0x09);
  2154.   AddFixed("ZEXT"   , 0x15); AddFixed("ZEXTW"  , 0x1d);
  2155.   AddFixed("CMR"    , 0x10); AddFixed("NCC"    , 0x11);
  2156.  
  2157.   AddALU8("ADD"  , 0); AddALU8("SUB"  , 1);
  2158.  
  2159.   AddLog8("AND"  , 4); AddLog8("OR"   , 5);
  2160.   AddLog8("XOR"  , 6);
  2161.  
  2162.   AddAcc("ADDDC"  , 0x02);
  2163.   AddAcc("SUBDC"  , 0x12);
  2164.  
  2165.   AddShift("ASR"  , 0x2e, FALSE); AddShift("ASRL" , 0x1e, FALSE);
  2166.   AddShift("ASRW" , 0x0e, TRUE ); AddShift("LSLW" , 0x0c, TRUE );
  2167.   AddShift("LSRW" , 0x0f, TRUE ); AddShift("LSL"  , 0x2c, FALSE);
  2168.   AddShift("LSR"  , 0x2f, FALSE); AddShift("LSLL" , 0x1c, FALSE);
  2169.   AddShift("LSRL" , 0x1f, FALSE); AddShift("SHLW" , 0x0c, TRUE );
  2170.   AddShift("SHRW" , 0x0f, TRUE );
  2171.  
  2172.   AddBranch("BZ"  , 0xf0); AddBranch("BEQ" , 0xf0); AddBranch("BNZ" , 0xf1);
  2173.   AddBranch("BNE" , 0xf1); AddBranch("BC"  , 0xf2); AddBranch("BLO" , 0xf2);
  2174.   AddBranch("BNC" , 0xf3); AddBranch("BHS" , 0xf3); AddBranch("BN"  , 0xf4);
  2175.   AddBranch("BP"  , 0xf5); AddBranch("BV"  , 0xf6); AddBranch("BNV" , 0xf7);
  2176.   AddBranch("BT"  , 0xf8); AddBranch("BNT" , 0xf9); AddBranch("BLT" , 0xfa);
  2177.   AddBranch("BGE" , 0xfb); AddBranch("BLE" , 0xfc); AddBranch("BGT" , 0xfd);
  2178.   AddBranch("BLS" , 0xfe); AddBranch("BHI" , 0xff); AddBranch("BRA" , 0x60);
  2179.  
  2180.   AddIncDec("INC"  , 0x42); AddIncDec("INCW" , 0x43); AddIncDec("INCL" , 0x41);
  2181.   AddIncDec("DEC"  , 0x62); AddIncDec("DECW" , 0x63); AddIncDec("DECL" , 0x61);
  2182.  
  2183.   MulDivOrders = (MulDivOrder*) malloc(sizeof(MulDivOrder) * MulDivOrderCnt);
  2184.   InstrZ = 0;
  2185.   AddMulDiv("MULU", 0x00, 0x0027); AddMulDiv("MULUW", 0x20, 0x002f);
  2186.   AddMulDiv("MUL" , 0x40, 0x786f); AddMulDiv("MULW" , 0x60, 0x796f);
  2187.   AddMulDiv("DIVU", 0x80, 0x0026); AddMulDiv("DIVUW", 0xa0, 0xffff);
  2188.   AddMulDiv("DIV" , 0xc0, 0x7a6f); AddMulDiv("DIVW" , 0xe0, 0xffff);
  2189.  
  2190.   AddSeg("SCEQI" , 0x80); AddSeg("SCEQD" , 0x90);
  2191.   AddSeg("SCWEQI", 0xa0); AddSeg("SCWEQD", 0xb0);
  2192.   AddSeg("FILSI" , 0xc0); AddSeg("FILS"  , 0xc0);
  2193.   AddSeg("FILSWI", 0xe0); AddSeg("FILSW" , 0xe0);
  2194.   AddSeg("SCEQ"  , 0x80); AddSeg("SCWEQ" , 0xa0);
  2195.  
  2196.   AddString("MOVS" , 0x00); AddString("MOVSI" , 0x00); AddString("MOVSD" , 0x10);
  2197.   AddString("MOVSW", 0x20); AddString("MOVSWI", 0x20); AddString("MOVSWD", 0x30);
  2198.  
  2199.   for (z = 0; z < (int)sizeof(BankNames) / sizeof(*BankNames); z++)
  2200.     AddInstTable(InstTable, BankNames[z], z, DecodeBank);
  2201.  
  2202.   AddInstTable(InstTable, "ADDC", 0, DecodeCarry8);
  2203.   AddInstTable(InstTable, "SUBC", 1, DecodeCarry8);
  2204.   AddInstTable(InstTable, "ADDCW",0, DecodeCarry16);
  2205.   AddInstTable(InstTable, "SUBCW",1, DecodeCarry16);
  2206.   AddInstTable(InstTable, "ADDL", 0, DecodeAdd32);
  2207.   AddInstTable(InstTable, "SUBL", 1, DecodeAdd32);
  2208.   AddInstTable(InstTable, "CMPL", 3, DecodeAdd32);
  2209.   AddInstTable(InstTable, "ADDSP",0, DecodeADDSP);
  2210.   AddInstTable(InstTable, "ADDW", 0, DecodeAdd16);
  2211.   AddInstTable(InstTable, "SUBW", 1, DecodeAdd16);
  2212.   AddInstTable(InstTable, "CMPW", 3, DecodeAdd16);
  2213.   AddInstTable(InstTable, "ANDW", 4, DecodeAdd16);
  2214.   AddInstTable(InstTable, "ORW" , 5, DecodeAdd16);
  2215.   AddInstTable(InstTable, "XORW", 6, DecodeAdd16);
  2216.   AddInstTable(InstTable, "ANDL", 4, DecodeLog32);
  2217.   AddInstTable(InstTable, "ORL",  5, DecodeLog32);
  2218.   AddInstTable(InstTable, "XORL", 6, DecodeLog32);
  2219.   AddInstTable(InstTable, "BBC", 0x80, DecodeBBcc);
  2220.   AddInstTable(InstTable, "BBS", 0xa0, DecodeBBcc);
  2221.   AddInstTable(InstTable, "CALL", 2, DecodeJmp16);
  2222.   AddInstTable(InstTable, "JMP", 0, DecodeJmp16);
  2223.   AddInstTable(InstTable, "CALLP", 2, DecodeJmp24);
  2224.   AddInstTable(InstTable, "JMPP", 0, DecodeJmp24);
  2225.   AddInstTable(InstTable, "CALLV", 0, DecodeCALLV);
  2226.   AddInstTable(InstTable, "CBNE", 0, DecodeCmpBranch);
  2227.   AddInstTable(InstTable, "CWBNE", 1, DecodeCmpBranch);
  2228.   AddInstTable(InstTable, "CLRB", 0x40, DecodeBit);
  2229.   AddInstTable(InstTable, "SETB", 0x60, DecodeBit);
  2230.   AddInstTable(InstTable, "CMP" , 0, DecodeCMP);
  2231.   AddInstTable(InstTable, "DBNZ" , 0, DecodeDBNZ);
  2232.   AddInstTable(InstTable, "DWBNZ" , 1, DecodeDBNZ);
  2233.   AddInstTable(InstTable, "INT", 0, DecodeINT);
  2234.   AddInstTable(InstTable, "INTP", 0, DecodeINTP);
  2235.   AddInstTable(InstTable, "JCTX", 0, DecodeJCTX);
  2236.   AddInstTable(InstTable, "LINK", 0, DecodeLINK);
  2237.   AddInstTable(InstTable, "MOV", 0, DecodeMOV);
  2238.   AddInstTable(InstTable, "MOVB", 0, DecodeMOVB);
  2239.   AddInstTable(InstTable, "MOVEA", 0, DecodeMOVEA);
  2240.   AddInstTable(InstTable, "MOVL", 0, DecodeMOVL);
  2241.   AddInstTable(InstTable, "MOVN", 0, DecodeMOVN);
  2242.   AddInstTable(InstTable, "MOVW", 0, DecodeMOVW);
  2243.   AddInstTable(InstTable, "MOVX", 0, DecodeMOVX);
  2244.   AddInstTable(InstTable, "NOT" , 0xe037, DecodeNEGNOT);
  2245.   AddInstTable(InstTable, "NEG" , 0x6003, DecodeNEGNOT);
  2246.   AddInstTable(InstTable, "NOTW", 0xe03f, DecodeNEGNOT);
  2247.   AddInstTable(InstTable, "NEGW", 0x600b, DecodeNEGNOT);
  2248.   AddInstTable(InstTable, "NRML", 0, DecodeNRML);
  2249.   AddInstTable(InstTable, "PUSHW", 0x40, DecodeStack);
  2250.   AddInstTable(InstTable, "POPW", 0x50, DecodeStack);
  2251.   AddInstTable(InstTable, "ROLC", 0, DecodeRotate);
  2252.   AddInstTable(InstTable, "RORC", 1, DecodeRotate);
  2253.   AddInstTable(InstTable, "SBBS", 1, DecodeSBBS);
  2254.   AddInstTable(InstTable, "WBTS", 0xc0, DecodeWBit);
  2255.   AddInstTable(InstTable, "WBTC", 0xe0, DecodeWBit);
  2256.   AddInstTable(InstTable, "XCH", 0, DecodeExchange);
  2257.   AddInstTable(InstTable, "XCHW", 1, DecodeExchange);
  2258. }
  2259.  
  2260. static void DeinitFields(void)
  2261. {
  2262.   DestroyInstTable(InstTable);
  2263.   free(MulDivOrders);
  2264. }
  2265.  
  2266. /*--------------------------------------------------------------------------*/
  2267. /* Interface zu AS */
  2268.  
  2269. static void MakeCode_F2MC16(void)
  2270. {
  2271.   /* Leeranweisung ignorieren */
  2272.  
  2273.   if (Memo(""))
  2274.     return;
  2275.  
  2276.   /* Pseudoanweisungen */
  2277.  
  2278.   if (DecodeIntelPseudo(False))
  2279.     return;
  2280.  
  2281.   /* akt. Datensegment */
  2282.  
  2283.   switch (NextDataSeg)
  2284.   {
  2285.     case 0:
  2286.       CurrBank = Reg_PCB;
  2287.       break;
  2288.     case 1:
  2289.       CurrBank = Reg_DTB;
  2290.       break;
  2291.     case 2:
  2292.       CurrBank = Reg_ADB;
  2293.       break;
  2294.     case 3:
  2295.       CurrBank = SupAllowed ? Reg_SSB : Reg_USB;
  2296.       break;
  2297.   }
  2298.   CurrBank <<= 16;
  2299.   NextDataSeg = 1; /* = DTB */
  2300.  
  2301.   OpSize = -1;
  2302.  
  2303.   if (!LookupInstTable(InstTable, OpPart.str.p_str))
  2304.     WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
  2305. }
  2306.  
  2307. static Boolean IsDef_F2MC16(void)
  2308. {
  2309.   return FALSE;
  2310. }
  2311.  
  2312. static void InitCode_F2MC16(void)
  2313. {
  2314.   Reg_PCB = 0xff;
  2315.   Reg_DTB = 0x00;
  2316.   Reg_USB = 0x00;
  2317.   Reg_SSB = 0x00;
  2318.   Reg_ADB = 0x00;
  2319.   Reg_DPR = 0x01;
  2320. }
  2321.  
  2322. static void SwitchTo_F2MC16(void)
  2323. {
  2324.   const TFamilyDescr *FoundDescr;
  2325.  
  2326.   FoundDescr = FindFamilyByName("F2MC16");
  2327.  
  2328.   TurnWords = False;
  2329.   SetIntConstMode(eIntConstModeIntel);
  2330.  
  2331.   PCSymbol = "$";
  2332.   HeaderID = FoundDescr->Id;
  2333.   NOPCode=0x00;
  2334.   DivideChars = ",";
  2335.   HasAttrs = False;
  2336.  
  2337.   ValidSegs = 1 << SegCode;
  2338.   Grans[SegCode] = 1;
  2339.   ListGrans[SegCode] = 1;
  2340.   SegInits[SegCode] = 0;
  2341.   SegLimits[SegCode] = 0xffffff;
  2342.  
  2343.   MakeCode = MakeCode_F2MC16;
  2344.   IsDef = IsDef_F2MC16;
  2345.   SwitchFrom = DeinitFields;
  2346.   InitFields();
  2347.  
  2348.   onoff_supmode_add();
  2349.  
  2350.   pASSUMERecs = ASSUMEF2MC16s;
  2351.   ASSUMERecCnt = ASSUMEF2MC16Count;
  2352.  
  2353.   NextDataSeg = 1; /* DTB */
  2354. }
  2355.  
  2356. /*--------------------------------------------------------------------------*/
  2357. /* Initialisierung */
  2358.  
  2359. void codef2mc16_init(void)
  2360. {
  2361.   CPU90500 = AddCPU("MB90500", SwitchTo_F2MC16);
  2362.  
  2363.   AddInitPassProc(InitCode_F2MC16);
  2364. }
  2365.