Subversion Repositories pentevo

Rev

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

  1. /* code87c800.c */
  2. /*****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
  4. /*                                                                           */
  5. /* AS-Portierung                                                             */
  6. /*                                                                           */
  7. /* Codegenerator TLCS-870                                                    */
  8. /*                                                                           */
  9. /*****************************************************************************/
  10.  
  11. #include "stdinc.h"
  12.  
  13. #include <ctype.h>
  14. #include <string.h>
  15.  
  16. #include "nls.h"
  17. #include "bpemu.h"
  18. #include "strutil.h"
  19. #include "asmdef.h"
  20. #include "asmsub.h"
  21. #include "asmpars.h"
  22. #include "asmitree.h"
  23. #include "asmcode.h"
  24. #include "codepseudo.h"
  25. #include "intpseudo.h"
  26. #include "codevars.h"
  27. #include "errmsg.h"
  28.  
  29. #include "code87c800.h"
  30.  
  31. typedef struct
  32. {
  33.   const char *Name;
  34.   Byte Code;
  35. } CondRec;
  36.  
  37. enum
  38. {
  39.   ModNone = -1,
  40.   ModReg8 = 0,
  41.   ModReg16 = 1,
  42.   ModImm = 2,
  43.   ModAbs = 3,
  44.   ModMem = 4
  45. };
  46.  
  47. #define MModReg8 (1 << ModReg8)
  48. #define MModReg16 (1 << ModReg16)
  49. #define MModImm (1 << ModImm)
  50. #define MModAbs (1 << ModAbs)
  51. #define MModMem (1 << ModMem)
  52.  
  53. #define AccReg 0
  54. #define WAReg 0
  55.  
  56. #define COND_CODE_TRUE 6
  57.  
  58. #define Reg8Cnt 8
  59. static const char Reg8Names[] = "AWCBEDLH";
  60.  
  61. static CPUVar CPU87C00, CPU87C20, CPU87C40, CPU87C70;
  62. static ShortInt OpSize;
  63. static Byte AdrVals[4];
  64. static ShortInt AdrType;
  65. static Byte AdrMode;
  66.  
  67. static CondRec *Conditions;
  68.  
  69. /*--------------------------------------------------------------------------*/
  70.  
  71. static void DecodeAdr(const tStrComp *pArg, Byte Erl)
  72. {
  73.   static const char Reg16Names[][3] =
  74.   {
  75.     "WA", "BC", "DE", "HL"
  76.   };
  77.   static const int Reg16Cnt = sizeof(Reg16Names) / sizeof(*Reg16Names);
  78.   static const char AdrRegs[][3] =
  79.   {
  80.     "HL", "DE", "C", "PC", "A"
  81.   };
  82.   static const int AdrRegCnt = sizeof(AdrRegs) / sizeof(*AdrRegs);
  83.  
  84.   int z;
  85.   Byte RegFlag;
  86.   Boolean OK;
  87.   LongInt DispAcc;
  88.  
  89.   AdrType = ModNone;
  90.   AdrCnt = 0;
  91.  
  92.   if (strlen(pArg->str.p_str) == 1)
  93.   {
  94.     for (z = 0; z < Reg8Cnt; z++)
  95.       if (as_toupper(*pArg->str.p_str) == Reg8Names[z])
  96.       {
  97.         AdrType = ModReg8;
  98.         OpSize = 0;
  99.         AdrMode = z;
  100.         goto chk;
  101.       }
  102.   }
  103.  
  104.   for (z = 0; z < Reg16Cnt; z++)
  105.     if (!as_strcasecmp(pArg->str.p_str, Reg16Names[z]))
  106.     {
  107.       AdrType = ModReg16;
  108.       OpSize = 1;
  109.       AdrMode = z;
  110.       goto chk;
  111.     }
  112.  
  113.   if (IsIndirect(pArg->str.p_str))
  114.   {
  115.     tStrComp Arg, Remainder;
  116.     char *EPos;
  117.     Boolean NegFlag, NNegFlag, FirstFlag;
  118.     LongInt DispPart;
  119.  
  120.     StrCompRefRight(&Arg, pArg, 1);
  121.     StrCompShorten(&Arg, 1);
  122.  
  123.     if (!as_strcasecmp(Arg.str.p_str, "-HL"))
  124.     {
  125.       AdrType = ModMem;
  126.       AdrMode = 7;
  127.       goto chk;
  128.     }
  129.     if (!as_strcasecmp(Arg.str.p_str, "HL+"))
  130.     {
  131.       AdrType = ModMem;
  132.       AdrMode = 6;
  133.       goto chk;
  134.     }
  135.  
  136.     RegFlag = 0;
  137.     DispAcc = 0;
  138.     NegFlag = False;
  139.     OK = True;
  140.     FirstFlag = False;
  141.     do
  142.     {
  143.       KillPrefBlanksStrCompRef(&Arg);
  144.       EPos = indir_split_pos(Arg.str.p_str);
  145.       NNegFlag = EPos && (*EPos == '-');
  146.       if (EPos)
  147.         StrCompSplitRef(&Arg, &Remainder, &Arg, EPos);
  148.       KillPostBlanksStrComp(&Arg);
  149.  
  150.       for (z = 0; z < AdrRegCnt; z++)
  151.         if (!as_strcasecmp(Arg.str.p_str, AdrRegs[z]))
  152.           break;
  153.       if (z >= AdrRegCnt)
  154.       {
  155.         tSymbolFlags Flags;
  156.  
  157.         DispPart = EvalStrIntExpressionWithFlags(&Arg, Int32, &OK, &Flags);
  158.         FirstFlag |= mFirstPassUnknown(Flags);
  159.         DispAcc = NegFlag ? DispAcc - DispPart :  DispAcc + DispPart;
  160.       }
  161.       else if ((NegFlag) || (RegFlag & (1 << z)))
  162.       {
  163.         WrError(ErrNum_InvAddrMode);
  164.         OK = False;
  165.       }
  166.       else
  167.         RegFlag |= 1 << z;
  168.  
  169.       NegFlag = NNegFlag;
  170.       if (EPos)
  171.         Arg = Remainder;
  172.     }
  173.     while (EPos && OK);
  174.     if (DispAcc != 0)
  175.       RegFlag |= 1 << AdrRegCnt;
  176.     if (OK)
  177.      switch (RegFlag)
  178.      {
  179.        case 0x20:
  180.          if (FirstFlag)
  181.            DispAcc &= 0xff;
  182.          if (DispAcc > 0xff) WrError(ErrNum_OverRange);
  183.          else
  184.          {
  185.            AdrType = ModAbs;
  186.            AdrMode = 0;
  187.            AdrCnt = 1;
  188.            AdrVals[0] = DispAcc & 0xff;
  189.          }
  190.          break;
  191.        case 0x02:
  192.          AdrType = ModMem;
  193.          AdrMode = 2;
  194.          break;
  195.        case 0x01:
  196.          AdrType = ModMem;
  197.          AdrMode = 3;
  198.          break;
  199.        case 0x21:
  200.          if (FirstFlag)
  201.            DispAcc &= 0x7f;
  202.          if (ChkRange(DispAcc, -128, 127))
  203.          {
  204.            AdrType = ModMem;
  205.            AdrMode = 4;
  206.            AdrCnt = 1;
  207.            AdrVals[0] = DispAcc & 0xff;
  208.          }
  209.          break;
  210.        case 0x05:
  211.          AdrType = ModMem;
  212.          AdrMode = 5;
  213.          break;
  214.        case 0x18:
  215.          AdrType = ModMem;
  216.          AdrMode = 1;
  217.          break;
  218.        default:
  219.          WrError(ErrNum_InvAddrMode);
  220.      }
  221.     goto chk;
  222.   }
  223.   else
  224.    switch (OpSize)
  225.    {
  226.      case -1:
  227.        WrError(ErrNum_UndefOpSizes);
  228.        break;
  229.      case 0:
  230.        AdrVals[0] = EvalStrIntExpression(pArg, Int8, &OK);
  231.        if (OK)
  232.        {
  233.          AdrType = ModImm;
  234.          AdrCnt = 1;
  235.        }
  236.        break;
  237.      case 1:
  238.        DispAcc = EvalStrIntExpression(pArg, Int16, &OK);
  239.        if (OK)
  240.        {
  241.          AdrType = ModImm;
  242.          AdrCnt = 2;
  243.          AdrVals[0] = DispAcc & 0xff;
  244.          AdrVals[1] = (DispAcc >> 8) & 0xff;
  245.        }
  246.        break;
  247.    }
  248.  
  249. chk:
  250.   if ((AdrType != ModNone) && (!((1 << AdrType) & Erl)))
  251.   {
  252.     AdrType = ModNone;
  253.     AdrCnt = 0;
  254.     WrError(ErrNum_InvAddrMode);
  255.   }
  256. }
  257.  
  258. static Boolean SplitBit(tStrComp *pArg, Byte *Erg)
  259. {
  260.   char *p;
  261.   tStrComp BitArg;
  262.  
  263.   p = RQuotPos(pArg->str.p_str, '.');
  264.   if (!p)
  265.     return False;
  266.  
  267.   StrCompSplitRef(pArg, &BitArg, pArg, p);
  268.  
  269.   if (strlen(BitArg.str.p_str) != 1) return False;
  270.   else
  271.    if ((*BitArg.str.p_str >= '0') && (*BitArg.str.p_str <= '7'))
  272.    {
  273.      *Erg = *BitArg.str.p_str - '0';
  274.      return True;
  275.    }
  276.    else
  277.    {
  278.      for (*Erg = 0; *Erg < Reg8Cnt; (*Erg)++)
  279.        if (as_toupper(*BitArg.str.p_str) == Reg8Names[*Erg])
  280.          break;
  281.      if (*Erg < Reg8Cnt)
  282.      {
  283.        *Erg += 8;
  284.        return True;
  285.      }
  286.      else
  287.        return False;
  288.    }
  289. }
  290.  
  291. static void CodeMem(Byte Entry, Byte Opcode)
  292. {
  293.   BAsmCode[0] = Entry + AdrMode;
  294.   memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  295.   BAsmCode[1 + AdrCnt] = Opcode;
  296. }
  297.  
  298. /*!------------------------------------------------------------------------
  299.  * \fn     decode_condition(const char *p_cond_str, Byte *p_cond_code)
  300.  * \brief  parse condition code
  301.  * \param  p_cond_str source argument
  302.  * \param  p_cond_code returns code if found
  303.  * \return True if found
  304.  * ------------------------------------------------------------------------ */
  305.  
  306. static Boolean decode_condition(const char *p_cond_str, Byte *p_cond_code)
  307. {
  308.   int z;
  309.  
  310.   for (z = 0; Conditions[z].Name; z++)
  311.     if (!as_strcasecmp(p_cond_str, Conditions[z].Name))
  312.     {
  313.       *p_cond_code = Conditions[z].Code;
  314.       return True;
  315.     }
  316.  
  317.   return False;
  318. }
  319.  
  320. /*!------------------------------------------------------------------------
  321.  * \fn     cond_code_tf(Byte cond_code)
  322.  * \brief  is condition code True or False?
  323.  * \param  cond_code code to check
  324.  * \return True if yes
  325.  * ------------------------------------------------------------------------ */
  326.  
  327. static Boolean cond_code_tf(Byte cond_code)
  328. {
  329.   return (cond_code == COND_CODE_TRUE)
  330.       || (cond_code == 7);
  331. }
  332.  
  333. /*--------------------------------------------------------------------------*/
  334.  
  335. static void DecodeFixed(Word Code)
  336. {
  337.   if (ChkArgCnt(0, 0))
  338.   {
  339.     CodeLen = 0;
  340.     if (Hi(Code) != 0)
  341.       BAsmCode[CodeLen++] = Hi(Code);
  342.     BAsmCode[CodeLen++] = Lo(Code);
  343.   }
  344. }
  345.  
  346. static void DecodeLD(Word Code)
  347. {
  348.   Boolean OK;
  349.   Byte HReg, HCnt, HMode, HVal;
  350.  
  351.   UNUSED(Code);
  352.  
  353.   if (!ChkArgCnt(2, 2));
  354.   else if (!as_strcasecmp(ArgStr[1].str.p_str, "SP"))
  355.   {
  356.     OpSize=1;
  357.     DecodeAdr(&ArgStr[2], MModImm+MModReg16);
  358.     switch (AdrType)
  359.     {
  360.       case ModReg16:
  361.         CodeLen = 2; BAsmCode[0] = 0xe8 | AdrMode;
  362.         BAsmCode[1] = 0xfa;
  363.         break;
  364.       case ModImm:
  365.         CodeLen = 3;
  366.         BAsmCode[0] = 0xfa;
  367.         memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  368.         break;
  369.     }
  370.   }
  371.   else if (!as_strcasecmp(ArgStr[2].str.p_str, "SP"))
  372.   {
  373.     DecodeAdr(&ArgStr[1], MModReg16);
  374.     switch (AdrType)
  375.     {
  376.       case ModReg16:
  377.         CodeLen = 2;
  378.         BAsmCode[0] = 0xe8 + AdrMode;
  379.         BAsmCode[1] = 0xfb;
  380.         break;
  381.     }
  382.   }
  383.   else if (!as_strcasecmp(ArgStr[1].str.p_str, "RBS"))
  384.   {
  385.     BAsmCode[1] = EvalStrIntExpression(&ArgStr[2], Int4, &OK);
  386.     if (OK)
  387.     {
  388.       CodeLen = 2;
  389.       BAsmCode[0] = 0x0f;
  390.     }
  391.   }
  392.   else if (!as_strcasecmp(ArgStr[1].str.p_str, "CF"))
  393.   {
  394.     if (!SplitBit(&ArgStr[2], &HReg)) WrError(ErrNum_InvBitPos);
  395.     else
  396.     {
  397.       DecodeAdr(&ArgStr[2], MModReg8 | MModAbs | MModMem);
  398.       switch (AdrType)
  399.       {
  400.         case ModReg8:
  401.           if (HReg >= 8) WrError(ErrNum_InvAddrMode);
  402.           else
  403.           {
  404.             CodeLen = 2;
  405.             BAsmCode[0] = 0xe8 | AdrMode;
  406.             BAsmCode[1] = 0xd8 | HReg;
  407.           }
  408.           break;
  409.         case ModAbs:
  410.           if (HReg >= 8) WrError(ErrNum_InvAddrMode);
  411.           else
  412.           {
  413.             CodeLen = 2;
  414.             BAsmCode[0] = 0xd8 | HReg;
  415.             BAsmCode[1] = AdrVals[0];
  416.           }
  417.           break;
  418.         case ModMem:
  419.           if (HReg < 8)
  420.           {
  421.             CodeLen = 2 + AdrCnt;
  422.             CodeMem(0xe0, 0xd8 | HReg);
  423.           }
  424.           else if ((AdrMode != 2) && (AdrMode != 3)) WrError(ErrNum_InvAddrMode);
  425.           else
  426.           {
  427.             CodeLen = 2;
  428.             BAsmCode[0] = 0xe0 | HReg;
  429.             BAsmCode[1] = 0x9c | AdrMode;
  430.           }
  431.           break;
  432.       }
  433.     }
  434.   }
  435.   else if (!as_strcasecmp(ArgStr[2].str.p_str, "CF"))
  436.   {
  437.     if (!SplitBit(&ArgStr[1], &HReg)) WrError(ErrNum_InvBitPos);
  438.     else
  439.     {
  440.       DecodeAdr(&ArgStr[1], MModReg8 | MModAbs | MModMem);
  441.       switch (AdrType)
  442.       {
  443.         case ModReg8:
  444.           if (HReg >= 8) WrError(ErrNum_InvAddrMode);
  445.           else
  446.           {
  447.             CodeLen = 2;
  448.             BAsmCode[0] = 0xe8 | AdrMode;
  449.             BAsmCode[1] = 0xc8 | HReg;
  450.           }
  451.           break;
  452.         case ModAbs:
  453.         case ModMem:
  454.           if (HReg < 8)
  455.           {
  456.             CodeLen = 2 + AdrCnt;
  457.             CodeMem(0xe0, 0xc8 | HReg);
  458.           }
  459.           else if ((AdrMode != 2) && (AdrMode != 3)) WrError(ErrNum_InvAddrMode);
  460.           else
  461.           {
  462.             CodeLen = 2;
  463.             BAsmCode[0] = 0xe0 | HReg;
  464.             BAsmCode[1] = 0x98 | AdrMode;
  465.           }
  466.           break;
  467.       }
  468.     }
  469.   }
  470.   else
  471.   {
  472.     DecodeAdr(&ArgStr[1], MModReg8 | MModReg16 | MModAbs | MModMem);
  473.     switch (AdrType)
  474.     {
  475.       case ModReg8:
  476.         HReg = AdrMode;
  477.         DecodeAdr(&ArgStr[2], MModReg8 | MModAbs | MModMem | MModImm);
  478.         switch (AdrType)
  479.         {
  480.           case ModReg8:
  481.             if (HReg == AccReg)
  482.             {
  483.               CodeLen = 1;
  484.               BAsmCode[0] = 0x50 | AdrMode;
  485.             }
  486.             else if (AdrMode == AccReg)
  487.             {
  488.               CodeLen = 1;
  489.               BAsmCode[0] = 0x58 | HReg;
  490.             }
  491.             else
  492.             {
  493.               CodeLen = 2;
  494.               BAsmCode[0] = 0xe8 | AdrMode;
  495.               BAsmCode[1] = 0x58 | HReg;
  496.             }
  497.             break;
  498.           case ModAbs:
  499.             if (HReg == AccReg)
  500.             {
  501.               CodeLen = 2;
  502.               BAsmCode[0] = 0x22;
  503.               BAsmCode[1] = AdrVals[0];
  504.             }
  505.             else
  506.             {
  507.               CodeLen = 3;
  508.               BAsmCode[0] = 0xe0;
  509.               BAsmCode[1] = AdrVals[0];
  510.               BAsmCode[2] = 0x58 | HReg;
  511.             }
  512.             break;
  513.           case ModMem:
  514.             if ((HReg == AccReg) && (AdrMode == 3))   /* A,(HL) */
  515.             {
  516.               CodeLen = 1;
  517.               BAsmCode[0] = 0x23;
  518.             }
  519.             else
  520.             {
  521.               CodeLen = 2 + AdrCnt;
  522.               CodeMem(0xe0, 0x58 | HReg);
  523.               if ((HReg >= 6) && (AdrMode == 6)) WrError(ErrNum_Unpredictable);
  524.             }
  525.             break;
  526.           case ModImm:
  527.             CodeLen = 2;
  528.             BAsmCode[0] = 0x30 | HReg;
  529.             BAsmCode[1] = AdrVals[0];
  530.             break;
  531.         }
  532.         break;
  533.       case ModReg16:
  534.         HReg = AdrMode;
  535.         DecodeAdr(&ArgStr[2], MModReg16 | MModAbs | MModMem | MModImm);
  536.         switch (AdrType)
  537.         {
  538.           case ModReg16:
  539.             CodeLen = 2;
  540.             BAsmCode[0] = 0xe8 | AdrMode;
  541.             BAsmCode[1] = 0x14 | HReg;
  542.             break;
  543.           case ModAbs:
  544.             CodeLen = 3;
  545.             BAsmCode[0] = 0xe0;
  546.             BAsmCode[1] = AdrVals[0];
  547.             BAsmCode[2] = 0x14 | HReg;
  548.             break;
  549.           case ModMem:
  550.             if (AdrMode > 5) WrError(ErrNum_InvAddrMode);   /* (-HL), (HL+) */
  551.             else
  552.             {
  553.               CodeLen = 2 + AdrCnt;
  554.               BAsmCode[0] = 0xe0 | AdrMode;
  555.               memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  556.               BAsmCode[1 + AdrCnt] = 0x14 + HReg;
  557.             }
  558.             break;
  559.           case ModImm:
  560.             CodeLen = 3;
  561.             BAsmCode[0] = 0x14 | HReg;
  562.             memcpy(BAsmCode + 1, AdrVals, 2);
  563.             break;
  564.         }
  565.         break;
  566.       case ModAbs:
  567.         HReg = AdrVals[0];
  568.         OpSize = 0;
  569.         DecodeAdr(&ArgStr[2], MModReg8 | MModReg16 | MModAbs | MModMem | MModImm);
  570.         switch (AdrType)
  571.         {
  572.           case ModReg8:
  573.             if (AdrMode == AccReg)
  574.             {
  575.               CodeLen = 2;
  576.               BAsmCode[0] = 0x2a;
  577.               BAsmCode[1] = HReg;
  578.             }
  579.             else
  580.             {
  581.               CodeLen = 3;
  582.               BAsmCode[0] = 0xf0;
  583.               BAsmCode[1] = HReg;
  584.               BAsmCode[2] = 0x50 | AdrMode;
  585.             }
  586.             break;
  587.           case ModReg16:
  588.             CodeLen = 3;
  589.             BAsmCode[0] = 0xf0;
  590.             BAsmCode[1] = HReg;
  591.             BAsmCode[2] = 0x10 | AdrMode;
  592.             break;
  593.           case ModAbs:
  594.             CodeLen = 3;
  595.             BAsmCode[0] = 0x26;
  596.             BAsmCode[1] = AdrVals[0];
  597.             BAsmCode[2] = HReg;
  598.             break;
  599.           case ModMem:
  600.             if (AdrMode > 5) WrError(ErrNum_InvAddrMode);      /* (-HL),(HL+) */
  601.             else
  602.             {
  603.               CodeLen = 3 + AdrCnt;
  604.               BAsmCode[0] = 0xe0 | AdrMode;
  605.               memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  606.               BAsmCode[1 + AdrCnt] = 0x26;
  607.               BAsmCode[2 + AdrCnt] = HReg;
  608.             }
  609.             break;
  610.           case ModImm:
  611.             CodeLen = 3;
  612.             BAsmCode[0] = 0x2c;
  613.             BAsmCode[1] = HReg;
  614.             BAsmCode[2] = AdrVals[0];
  615.             break;
  616.         }
  617.         break;
  618.       case ModMem:
  619.         HVal = AdrVals[0];
  620.         HCnt = AdrCnt;
  621.         HMode = AdrMode;
  622.         OpSize = 0;
  623.         DecodeAdr(&ArgStr[2], MModReg8 | MModReg16 | MModAbs | MModMem | MModImm);
  624.         switch (AdrType)
  625.         {
  626.           case ModReg8:
  627.             if ((HMode == 3) && (AdrMode == AccReg))   /* (HL),A */
  628.             {
  629.               CodeLen = 1;
  630.               BAsmCode[0] = 0x2b;
  631.             }
  632.             else if ((HMode == 1) || (HMode == 5)) WrError(ErrNum_InvAddrMode);
  633.             else
  634.             {
  635.               CodeLen = 2 + HCnt;
  636.               BAsmCode[0] = 0xf0 | HMode;
  637.               memcpy(BAsmCode + 1, &HVal, HCnt);
  638.               BAsmCode[1 + HCnt] = 0x50 | AdrMode;
  639.               if ((HMode == 6) && (AdrMode >= 6)) WrError(ErrNum_Unpredictable);
  640.             }
  641.             break;
  642.           case ModReg16:
  643.             if ((HMode < 2) || (HMode > 4)) WrError(ErrNum_InvAddrMode);  /* (HL),(DE),(HL+d) */
  644.             else
  645.             {
  646.               CodeLen = 2 + HCnt;
  647.               BAsmCode[0] = 0xf0 | HMode;
  648.               memcpy(BAsmCode + 1, &HVal, HCnt);
  649.               BAsmCode[1 + HCnt] = 0x10 | AdrMode;
  650.             }
  651.             break;
  652.           case ModAbs:
  653.             if (HMode != 3) WrError(ErrNum_InvAddrMode);  /* (HL) */
  654.             else
  655.             {
  656.               CodeLen = 3;
  657.               BAsmCode[0] = 0xe0;
  658.               BAsmCode[1] = AdrVals[0];
  659.               BAsmCode[2] = 0x27;
  660.             }
  661.             break;
  662.           case ModMem:
  663.             if (HMode != 3) WrError(ErrNum_InvAddrMode);         /* (HL) */
  664.             else if (AdrMode > 5) WrError(ErrNum_InvAddrMode);   /* (-HL),(HL+) */
  665.             else
  666.             {
  667.               CodeLen = 2 + AdrCnt;
  668.               BAsmCode[0] = 0xe0 | AdrMode;
  669.               memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  670.               BAsmCode[1 + AdrCnt] = 0x27;
  671.             }
  672.             break;
  673.           case ModImm:
  674.             if ((HMode == 1) || (HMode == 5)) WrError(ErrNum_InvAddrMode);  /* (HL+C),(PC+A) */
  675.             else if (HMode == 3)               /* (HL) */
  676.             {
  677.               CodeLen = 2;
  678.               BAsmCode[0] = 0x2d;
  679.               BAsmCode[1] = AdrVals[0];
  680.             }
  681.             else
  682.             {
  683.               CodeLen = 3 + HCnt;
  684.               BAsmCode[0] = 0xf0 + HMode;
  685.               memcpy(BAsmCode + 1, &HVal, HCnt);
  686.               BAsmCode[1 + HCnt] = 0x2c;
  687.               BAsmCode[2 + HCnt] = AdrVals[0];
  688.             }
  689.             break;
  690.         }
  691.         break;
  692.     }
  693.   }
  694. }
  695.  
  696. static void DecodeXCH(Word Code)
  697. {
  698.   Byte HReg;
  699.  
  700.   UNUSED(Code);
  701.  
  702.   if (ChkArgCnt(2, 2))
  703.   {
  704.     DecodeAdr(&ArgStr[1], MModReg8 | MModReg16 | MModAbs | MModMem);
  705.     switch (AdrType)
  706.     {
  707.       case ModReg8:
  708.         HReg = AdrMode;
  709.         DecodeAdr(&ArgStr[2], MModReg8 | MModAbs | MModMem);
  710.         switch (AdrType)
  711.         {
  712.           case ModReg8:
  713.             CodeLen = 2;
  714.             BAsmCode[0] = 0xe8 | AdrMode;
  715.             BAsmCode[1] = 0xa8 | HReg;
  716.             break;
  717.           case ModAbs:
  718.           case ModMem:
  719.             CodeLen = 2 + AdrCnt;
  720.             CodeMem(0xe0, 0xa8 | HReg);
  721.             if ((HReg >= 6) && (AdrMode == 6)) WrError(ErrNum_Unpredictable);
  722.             break;
  723.         }
  724.         break;
  725.       case ModReg16:
  726.         HReg = AdrMode;
  727.         DecodeAdr(&ArgStr[2], MModReg16);
  728.         if (AdrType != ModNone)
  729.         {
  730.           CodeLen = 2;
  731.           BAsmCode[0] = 0xe8 | AdrMode;
  732.           BAsmCode[1] = 0x10 | HReg;
  733.         }
  734.         break;
  735.       case ModAbs:
  736.         BAsmCode[1] = AdrVals[0];
  737.         DecodeAdr(&ArgStr[2], MModReg8);
  738.         if (AdrType != ModNone)
  739.         {
  740.           CodeLen = 3;
  741.           BAsmCode[0] = 0xe0;
  742.           BAsmCode[2] = 0xa8 | AdrMode;
  743.         }
  744.         break;
  745.       case ModMem:
  746.         BAsmCode[0] = 0xe0 | AdrMode;
  747.         memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  748.         HReg = AdrCnt;
  749.         DecodeAdr(&ArgStr[2], MModReg8);
  750.         if (AdrType != ModNone)
  751.         {
  752.           CodeLen = 2 + HReg;
  753.           BAsmCode[1 + HReg] = 0xa8 | AdrMode;
  754.           if ((AdrMode >= 6) && ((BAsmCode[0] & 0x0f) == 6)) WrError(ErrNum_Unpredictable);
  755.         }
  756.         break;
  757.     }
  758.   }
  759. }
  760.  
  761. static void DecodeCLR(Word Code)
  762. {
  763.   Byte HReg;;
  764.  
  765.   UNUSED(Code);
  766.  
  767.   if (!ChkArgCnt(1, 1));
  768.   else if (!as_strcasecmp(ArgStr[1].str.p_str, "CF"))
  769.   {
  770.     CodeLen = 1;
  771.     BAsmCode[0] = 0x0c;
  772.   }
  773.   else if (SplitBit(&ArgStr[1], &HReg))
  774.   {
  775.     DecodeAdr(&ArgStr[1], MModReg8 | MModAbs | MModMem);
  776.     switch (AdrType)
  777.     {
  778.       case ModReg8:
  779.         if (HReg >= 8) WrError(ErrNum_InvAddrMode);
  780.         else
  781.         {
  782.           CodeLen = 2;
  783.           BAsmCode[0] = 0xe8 | AdrMode;
  784.           BAsmCode[1] = 0x48 | HReg;
  785.         }
  786.         break;
  787.       case ModAbs:
  788.         if (HReg >= 8) WrError(ErrNum_InvAddrMode);
  789.         else
  790.         {
  791.           CodeLen = 2;
  792.           BAsmCode[0] = 0x48 | HReg;
  793.           BAsmCode[1] = AdrVals[0];
  794.         }
  795.         break;
  796.       case ModMem:
  797.         if (HReg <= 8)
  798.         {
  799.           CodeLen = 2 + AdrCnt;
  800.           CodeMem(0xe0, 0x48 | HReg);
  801.         }
  802.         else if ((AdrMode != 2) && (AdrMode != 3)) WrError(ErrNum_InvAddrMode);
  803.         else
  804.         {
  805.           CodeLen = 2;
  806.           BAsmCode[0] = 0xe0 | HReg;
  807.           BAsmCode[1] = 0x88 | AdrMode;
  808.         }
  809.         break;
  810.     }
  811.   }
  812.   else
  813.   {
  814.     DecodeAdr(&ArgStr[1], MModReg8 | MModReg16 | MModAbs | MModMem);
  815.     switch (AdrType)
  816.     {
  817.       case ModReg8:
  818.         CodeLen = 2;
  819.         BAsmCode[0] = 0x30 | AdrMode;
  820.         BAsmCode[1] = 0;
  821.         break;
  822.       case ModReg16:
  823.         CodeLen = 3;
  824.         BAsmCode[0] = 0x14 | AdrMode;
  825.         BAsmCode[1] = 0;
  826.         BAsmCode[2] = 0;
  827.         break;
  828.       case ModAbs:
  829.         CodeLen = 2;
  830.         BAsmCode[0] = 0x2e;
  831.         BAsmCode[1] = AdrVals[0];
  832.         break;
  833.       case ModMem:
  834.         if ((AdrMode == 5) || (AdrMode == 1)) WrError(ErrNum_InvAddrMode);  /* (PC+A, HL+C) */
  835.         else if (AdrMode == 3)     /* (HL) */
  836.         {
  837.           CodeLen = 1;
  838.           BAsmCode[0] = 0x2f;
  839.         }
  840.         else
  841.         {
  842.           CodeLen = 3 + AdrCnt;
  843.           BAsmCode[0] = 0xf0 | AdrMode;
  844.           memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  845.           BAsmCode[1 + AdrCnt] = 0x2c;
  846.           BAsmCode[2 + AdrCnt] = 0;
  847.         }
  848.         break;
  849.     }
  850.   }
  851. }
  852.  
  853. static void DecodeLDW(Word Code)
  854. {
  855.   UNUSED(Code);
  856.  
  857.   if (ChkArgCnt(2, 2))
  858.   {
  859.     Boolean OK;
  860.     Integer AdrInt = EvalStrIntExpression(&ArgStr[2], Int16, &OK);
  861.     if (OK)
  862.     {
  863.       DecodeAdr(&ArgStr[1], MModReg16 | MModAbs | MModMem);
  864.       switch (AdrType)
  865.       {
  866.         case ModReg16:
  867.           CodeLen = 3;
  868.           BAsmCode[0] = 0x14 | AdrMode;
  869.           BAsmCode[1] = AdrInt & 0xff;
  870.           BAsmCode[2] = AdrInt >> 8;
  871.           break;
  872.         case ModAbs:
  873.           CodeLen = 4;
  874.           BAsmCode[0] = 0x24;
  875.           BAsmCode[1] = AdrVals[0];
  876.           BAsmCode[2] = AdrInt & 0xff;
  877.           BAsmCode[3] = AdrInt >> 8;
  878.           break;
  879.         case ModMem:
  880.           if (AdrMode != 3) WrError(ErrNum_InvAddrMode);  /* (HL) */
  881.           else
  882.           {
  883.             CodeLen = 3;
  884.             BAsmCode[0] = 0x25;
  885.             BAsmCode[1] = AdrInt & 0xff;
  886.             BAsmCode[2] = AdrInt >> 8;
  887.           }
  888.           break;
  889.       }
  890.     }
  891.   }
  892. }
  893.  
  894. static void DecodePUSH_POP(Word Code)
  895. {
  896.   if (!ChkArgCnt(1, 1));
  897.   else if (!as_strcasecmp(ArgStr[1].str.p_str, "PSW"))
  898.   {
  899.     CodeLen = 1;
  900.     BAsmCode[0] = Code;
  901.   }
  902.   else
  903.   {
  904.     DecodeAdr(&ArgStr[1], MModReg16);
  905.     if (AdrType != ModNone)
  906.     {
  907.       CodeLen = 2;
  908.      BAsmCode[0] = 0xe8 | AdrMode;
  909.      BAsmCode[1] = Code;
  910.     }
  911.   }
  912. }
  913.  
  914. static void DecodeTEST_CPL_SET(Word Code)
  915. {
  916.   Byte HReg;
  917.  
  918.   if (!ChkArgCnt(1, 1));
  919.   else if (!as_strcasecmp(ArgStr[1].str.p_str, "CF"))
  920.   {
  921.     if (Code == 0xd8) WrError(ErrNum_InvAddrMode);
  922.     else
  923.     {
  924.       CodeLen = 1;
  925.       BAsmCode[0] = 0x0d + Ord(Code == 0xc0);
  926.     }
  927.   }
  928.   else if (!SplitBit(&ArgStr[1], &HReg)) WrError(ErrNum_InvBitPos);
  929.   else
  930.   {
  931.     DecodeAdr(&ArgStr[1], MModReg8 | MModAbs | MModMem);
  932.     switch (AdrType)
  933.     {
  934.       case ModReg8:
  935.         if (HReg >= 8) WrError(ErrNum_InvAddrMode);
  936.         else
  937.         {
  938.           CodeLen = 2;
  939.           BAsmCode[0] = 0xe8 | AdrMode;
  940.           BAsmCode[1] = Code | HReg;
  941.         }
  942.         break;
  943.       case ModAbs:
  944.         if (HReg >= 8) WrError(ErrNum_InvAddrMode);
  945.         else if (Code == 0xc0)
  946.         {
  947.           CodeLen = 3;
  948.           CodeMem(0xe0, Code | HReg);
  949.         }
  950.         else
  951.         {
  952.           CodeLen = 2;
  953.           BAsmCode[0] = Code | HReg;
  954.           BAsmCode[1] = AdrVals[0];
  955.         }
  956.         break;
  957.       case ModMem:
  958.         if (HReg < 8)
  959.         {
  960.           CodeLen = 2 + AdrCnt;
  961.           CodeMem(0xe0, Code | HReg);
  962.         }
  963.         else if ((AdrMode != 2) && (AdrMode != 3)) WrError(ErrNum_InvAddrMode);
  964.         else
  965.         {
  966.           CodeLen = 2;
  967.           BAsmCode[0] = 0xe0 | HReg;
  968.           BAsmCode[1] = ((Code & 0x18) >> 1) | ((Code & 0x80) >> 3) | 0x80 | AdrMode;
  969.         }
  970.         break;
  971.     }
  972.   }
  973. }
  974.  
  975. static void DecodeReg(Word Code)
  976. {
  977.   if (ChkArgCnt(1, 1))
  978.   {
  979.     DecodeAdr(&ArgStr[1], MModReg8);
  980.     if (AdrType != ModNone)
  981.     {
  982.       if (AdrMode == AccReg)
  983.       {
  984.         CodeLen = 1;
  985.         BAsmCode[0] = Code;
  986.       }
  987.       else
  988.       {
  989.         CodeLen = 2;
  990.         BAsmCode[0] = 0xe8 | AdrMode;
  991.         BAsmCode[1] = Code;
  992.       }
  993.     }
  994.   }
  995. }
  996.  
  997. static void DecodeALU(Word Code)
  998. {
  999.   Byte HReg;
  1000.   Boolean OK;
  1001.  
  1002.   if (!ChkArgCnt(2, 2));
  1003.   else if (!as_strcasecmp(ArgStr[1].str.p_str, "CF"))
  1004.   {
  1005.     if (Code != 5) WrError(ErrNum_InvAddrMode); /* XOR */
  1006.     else if (!SplitBit(&ArgStr[2], &HReg)) WrError(ErrNum_InvBitPos);
  1007.     else if (HReg >= 8) WrError(ErrNum_InvAddrMode);
  1008.     else
  1009.     {
  1010.       DecodeAdr(&ArgStr[2], MModReg8 | MModAbs | MModMem);
  1011.       switch (AdrType)
  1012.       {
  1013.         case ModReg8:
  1014.           CodeLen = 2;
  1015.           BAsmCode[0] = 0xe8 | AdrMode;
  1016.           BAsmCode[1] = 0xd0 | HReg;
  1017.           break;
  1018.         case ModAbs:
  1019.         case ModMem:
  1020.           CodeLen = 2 + AdrCnt;
  1021.           CodeMem(0xe0, 0xd0 | HReg);
  1022.           break;
  1023.       }
  1024.     }
  1025.   }
  1026.   else
  1027.   {
  1028.     DecodeAdr(&ArgStr[1], MModReg8 | MModReg16 | MModMem | MModAbs);
  1029.     switch (AdrType)
  1030.     {
  1031.       case ModReg8:
  1032.         HReg = AdrMode;
  1033.         DecodeAdr(&ArgStr[2], MModReg8 | MModMem | MModAbs | MModImm);
  1034.         switch (AdrType)
  1035.         {
  1036.           case ModReg8:
  1037.             if (HReg == AccReg)
  1038.             {
  1039.               CodeLen = 2;
  1040.               BAsmCode[0] = 0xe8 | AdrMode;
  1041.               BAsmCode[1] = 0x60 | Code;
  1042.             }
  1043.             else if (AdrMode == AccReg)
  1044.             {
  1045.               CodeLen = 2;
  1046.               BAsmCode[0] = 0xe8 | HReg;
  1047.               BAsmCode[1] = 0x68 | Code;
  1048.             }
  1049.             else WrError(ErrNum_InvAddrMode);
  1050.             break;
  1051.           case ModMem:
  1052.             if (HReg != AccReg) WrError(ErrNum_InvAddrMode);
  1053.             else
  1054.             {
  1055.               CodeLen = 2 + AdrCnt;
  1056.               BAsmCode[0] = 0xe0 | AdrMode;
  1057.               memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  1058.               BAsmCode[1 + AdrCnt] = 0x78 | Code;
  1059.             }
  1060.             break;
  1061.           case ModAbs:
  1062.             if (HReg != AccReg) WrError(ErrNum_InvAddrMode);
  1063.             else
  1064.             {
  1065.               CodeLen = 2;
  1066.               BAsmCode[0] = 0x78 | Code;
  1067.               BAsmCode[1] = AdrVals[0];
  1068.             }
  1069.             break;
  1070.           case ModImm:
  1071.             if (HReg == AccReg)
  1072.             {
  1073.               CodeLen = 2;
  1074.               BAsmCode[0] = 0x70 | Code;
  1075.               BAsmCode[1] = AdrVals[0];
  1076.             }
  1077.             else
  1078.             {
  1079.               CodeLen = 3;
  1080.               BAsmCode[0] = 0xe8 | HReg;
  1081.               BAsmCode[1] = 0x70 | Code;
  1082.               BAsmCode[2] = AdrVals[0];
  1083.             }
  1084.             break;
  1085.         }
  1086.         break;
  1087.       case ModReg16:
  1088.         HReg = AdrMode;
  1089.         DecodeAdr(&ArgStr[2], MModImm | MModReg16);
  1090.         switch (AdrType)
  1091.         {
  1092.           case ModImm:
  1093.             CodeLen = 4;
  1094.             BAsmCode[0] = 0xe8 | HReg;
  1095.             BAsmCode[1] = 0x38 | Code;
  1096.             memcpy(BAsmCode + 2, AdrVals, AdrCnt);
  1097.             break;
  1098.           case ModReg16:
  1099.             if (HReg != WAReg) WrError(ErrNum_InvAddrMode);
  1100.             else
  1101.             {
  1102.               CodeLen = 2;
  1103.               BAsmCode[0] = 0xe8 | AdrMode;
  1104.               BAsmCode[1] = 0x30 | Code;
  1105.             }
  1106.             break;
  1107.         }
  1108.         break;
  1109.       case ModAbs:
  1110.         if (!as_strcasecmp(ArgStr[2].str.p_str, "(HL)"))
  1111.         {
  1112.           CodeLen = 3;
  1113.           BAsmCode[0] = 0xe0;
  1114.           BAsmCode[1] = AdrVals[0];
  1115.           BAsmCode[2] = 0x60 | Code;
  1116.         }
  1117.         else
  1118.         {
  1119.           BAsmCode[3] = EvalStrIntExpression(&ArgStr[2], Int8, &OK);
  1120.           if (OK)
  1121.           {
  1122.             CodeLen = 4;
  1123.             BAsmCode[0] = 0xe0;
  1124.             BAsmCode[1] = AdrVals[0];
  1125.             BAsmCode[2] = 0x70 | Code;
  1126.           }
  1127.         }
  1128.         break;
  1129.       case ModMem:
  1130.         if (!as_strcasecmp(ArgStr[2].str.p_str, "(HL)"))
  1131.         {
  1132.           CodeLen = 2 + AdrCnt;
  1133.           BAsmCode[0] = 0xe0 | AdrMode;
  1134.           memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  1135.           BAsmCode[1 + AdrCnt] = 0x60 | Code;
  1136.         }
  1137.         else
  1138.         {
  1139.           BAsmCode[2 + AdrCnt] = EvalStrIntExpression(&ArgStr[2], Int8, &OK);
  1140.           if (OK)
  1141.           {
  1142.             CodeLen = 3 + AdrCnt;
  1143.             BAsmCode[0] = 0xe0 | AdrMode;
  1144.             memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  1145.             BAsmCode[1 + AdrCnt] = 0x70 | Code;
  1146.           }
  1147.         }
  1148.         break;
  1149.     }
  1150.   }
  1151. }
  1152.  
  1153. static void DecodeMCMP(Word Code)
  1154. {
  1155.   Byte HReg;
  1156.   Boolean OK;
  1157.  
  1158.   UNUSED(Code);
  1159.  
  1160.   if (ChkArgCnt(2, 2))
  1161.   {
  1162.     HReg = EvalStrIntExpression(&ArgStr[2], Int8, &OK);
  1163.     if (OK)
  1164.     {
  1165.       DecodeAdr(&ArgStr[1], MModMem | MModAbs);
  1166.       if (AdrType != ModNone)
  1167.       {
  1168.         CodeLen = 3 + AdrCnt;
  1169.         CodeMem(0xe0, 0x2f);
  1170.         BAsmCode[2 + AdrCnt] = HReg;
  1171.       }
  1172.     }
  1173.   }
  1174. }
  1175.  
  1176. static void DecodeINC_DEC(Word Code)
  1177. {
  1178.   if (ChkArgCnt(1, 1))
  1179.   {
  1180.     DecodeAdr(&ArgStr[1], MModReg8 | MModReg16 | MModAbs | MModMem);
  1181.     switch (AdrType)
  1182.     {
  1183.       case ModReg8:
  1184.         CodeLen = 1;
  1185.         BAsmCode[0] = 0x60 | Code | AdrMode;
  1186.         break;
  1187.       case ModReg16:
  1188.         CodeLen = 1;
  1189.         BAsmCode[0] = 0x10 | Code | AdrMode;
  1190.         break;
  1191.       case ModAbs:
  1192.         CodeLen = 2;
  1193.         BAsmCode[0] = 0x20 | Code;
  1194.         BAsmCode[1] = AdrVals[0];
  1195.         break;
  1196.       case ModMem:
  1197.         if (AdrMode == 3)     /* (HL) */
  1198.         {
  1199.           CodeLen = 1;
  1200.           BAsmCode[0] = 0x21 | Code;
  1201.         }
  1202.         else
  1203.         {
  1204.           CodeLen = 2 + AdrCnt;
  1205.           BAsmCode[0] = 0xe0 | AdrMode;
  1206.           memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  1207.           BAsmCode[1 + AdrCnt] = 0x20 | Code;
  1208.         }
  1209.         break;
  1210.     }
  1211.   }
  1212. }
  1213.  
  1214. static void DecodeMUL(Word Code)
  1215. {
  1216.   UNUSED(Code);
  1217.  
  1218.   if (ChkArgCnt(2, 2))
  1219.   {
  1220.     DecodeAdr(&ArgStr[1], MModReg8);
  1221.     if (AdrType == ModReg8)
  1222.     {
  1223.       Byte HReg = AdrMode;
  1224.       DecodeAdr(&ArgStr[2], MModReg8);
  1225.       if (AdrType == ModReg8)
  1226.       {
  1227.         if ((HReg ^ AdrMode) != 1) WrError(ErrNum_InvRegPair);
  1228.         else
  1229.         {
  1230.           HReg = HReg >> 1;
  1231.           if (HReg == 0)
  1232.           {
  1233.             CodeLen = 1;
  1234.             BAsmCode[0] = 0x02;
  1235.           }
  1236.           else
  1237.           {
  1238.             CodeLen = 2;
  1239.             BAsmCode[0] = 0xe8 | HReg;
  1240.             BAsmCode[1] = 0x02;
  1241.           }
  1242.         }
  1243.       }
  1244.     }
  1245.   }
  1246. }
  1247.  
  1248. static void DecodeDIV(Word Code)
  1249. {
  1250.   UNUSED(Code);
  1251.  
  1252.   if (ChkArgCnt(2, 2))
  1253.   {
  1254.     DecodeAdr(&ArgStr[1], MModReg16);
  1255.     if (AdrType == ModReg16)
  1256.     {
  1257.       Byte HReg = AdrMode;
  1258.       DecodeAdr(&ArgStr[2], MModReg8);
  1259.       if (AdrType == ModReg8)
  1260.       {
  1261.         if (AdrMode != 2) WrError(ErrNum_InvAddrMode);  /* C */
  1262.         else if (HReg == 0)
  1263.         {
  1264.           CodeLen = 1;
  1265.           BAsmCode[0] = 0x03;
  1266.         }
  1267.         else
  1268.         {
  1269.           CodeLen = 2;
  1270.           BAsmCode[0] = 0xe8 | HReg;
  1271.           BAsmCode[1] = 0x03;
  1272.           if (HReg == 1)
  1273.             WrError(ErrNum_Unpredictable);
  1274.         }
  1275.       }
  1276.     }
  1277.   }
  1278. }
  1279.  
  1280. static void DecodeROLD_RORD(Word Code)
  1281. {
  1282.   if (!ChkArgCnt(2, 2));
  1283.   else if (as_strcasecmp(ArgStr[1].str.p_str, "A")) WrError(ErrNum_InvAddrMode);
  1284.   else
  1285.   {
  1286.     DecodeAdr(&ArgStr[2], MModAbs | MModMem);
  1287.     if (AdrType != ModNone)
  1288.     {
  1289.       CodeLen = 2 + AdrCnt;
  1290.       CodeMem(0xe0, Code);
  1291.       if (AdrMode == 1)
  1292.         WrError(ErrNum_Unpredictable);
  1293.     }
  1294.   }
  1295. }
  1296.  
  1297. static void DecodeJRS(Word Code)
  1298. {
  1299.   UNUSED(Code);
  1300.  
  1301.   if (ChkArgCnt(2, 2))
  1302.   {
  1303.     Integer AdrInt;
  1304.     Byte cond_code;
  1305.     Boolean OK;
  1306.     tSymbolFlags Flags;
  1307.  
  1308.     if (!decode_condition(ArgStr[1].str.p_str, &cond_code) || !cond_code_tf(cond_code)) WrStrErrorPos(ErrNum_UndefCond, &ArgStr[1]);
  1309.     else
  1310.     {
  1311.       AdrInt = EvalStrIntExpressionWithFlags(&ArgStr[2], Int16, &OK, &Flags) - (EProgCounter() + 2);
  1312.       if (OK)
  1313.       {
  1314.         if (((AdrInt < -16) || (AdrInt > 15)) && !mSymbolQuestionable(Flags)) WrError(ErrNum_JmpDistTooBig);
  1315.         else
  1316.         {
  1317.           CodeLen = 1;
  1318.           BAsmCode[0] = ((cond_code - 2) << 5) | (AdrInt & 0x1f);
  1319.         }
  1320.       }
  1321.     }
  1322.   }
  1323. }
  1324.  
  1325. static void DecodeJR(Word Code)
  1326. {
  1327.   UNUSED(Code);
  1328.  
  1329.   if (ChkArgCnt(1, 2))
  1330.   {
  1331.     Integer AdrInt;
  1332.     Byte cond_code;
  1333.     Boolean OK;
  1334.     tSymbolFlags Flags;
  1335.  
  1336.     if (ArgCnt == 1)
  1337.       cond_code = COND_CODE_TRUE;
  1338.     else if (!decode_condition(ArgStr[1].str.p_str, &cond_code))
  1339.     {
  1340.       WrStrErrorPos(ErrNum_UndefCond, &ArgStr[1]);
  1341.       return;
  1342.     }
  1343.  
  1344.     AdrInt = EvalStrIntExpressionWithFlags(&ArgStr[ArgCnt], Int16, &OK, &Flags) - (EProgCounter() + 2);
  1345.     if (OK)
  1346.     {
  1347.       if (((AdrInt < -128) || (AdrInt > 127)) && !mSymbolQuestionable(Flags)) WrError(ErrNum_JmpDistTooBig);
  1348.       else
  1349.       {
  1350.         CodeLen = 2;
  1351.         BAsmCode[0] = (ArgCnt == 1) ?  0xfb : 0xd0 | cond_code;
  1352.         BAsmCode[1] = AdrInt & 0xff;
  1353.       }
  1354.     }
  1355.   }
  1356. }
  1357.  
  1358. static void DecodeJP_CALL(Word Code)
  1359. {
  1360.   if (ChkArgCnt(1, 1))
  1361.   {
  1362.     OpSize = 1;
  1363.     DecodeAdr(&ArgStr[1], MModReg16 | MModAbs | MModMem | MModImm);
  1364.     switch (AdrType)
  1365.     {
  1366.       case ModReg16:
  1367.         CodeLen = 2;
  1368.         BAsmCode[0] = 0xe8 | AdrMode;
  1369.         BAsmCode[1] = Code;
  1370.         break;
  1371.       case ModAbs:
  1372.         CodeLen = 3;
  1373.         BAsmCode[0] = 0xe0;
  1374.         BAsmCode[1] = AdrVals[0];
  1375.         BAsmCode[2] = Code;
  1376.         break;
  1377.       case ModMem:
  1378.         if (AdrMode > 5) WrError(ErrNum_InvAddrMode);
  1379.         else
  1380.         {
  1381.           CodeLen = 2 + AdrCnt;
  1382.           BAsmCode[0] = 0xe0 | AdrMode;
  1383.           memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  1384.           BAsmCode[1 + AdrCnt] = Code;
  1385.         }
  1386.         break;
  1387.       case ModImm:
  1388.         if ((AdrVals[1] == 0xff) && (Code == 0xfc))
  1389.         {
  1390.           CodeLen = 2;
  1391.           BAsmCode[0] = 0xfd;
  1392.           BAsmCode[1] = AdrVals[0];
  1393.         }
  1394.         else
  1395.         {
  1396.           CodeLen = 3;
  1397.           BAsmCode[0] = Code;
  1398.           memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  1399.         }
  1400.         break;
  1401.     }
  1402.   }
  1403. }
  1404.  
  1405. static void DecodeCALLV(Word Code)
  1406. {
  1407.   UNUSED(Code);
  1408.  
  1409.   if (ChkArgCnt(1, 1))
  1410.   {
  1411.     Boolean OK;
  1412.     Byte HVal = EvalStrIntExpression(&ArgStr[1], Int4, &OK);
  1413.     if (OK)
  1414.     {
  1415.       CodeLen = 1;
  1416.       BAsmCode[0] = 0xc0 | (HVal & 15);
  1417.     }
  1418.   }
  1419. }
  1420.  
  1421. static void DecodeCALLP(Word Code)
  1422. {
  1423.   UNUSED(Code);
  1424.  
  1425.   if (ChkArgCnt(1, 1))
  1426.   {
  1427.     Boolean OK;
  1428.     Integer AdrInt = EvalStrIntExpression(&ArgStr[1], Int16, &OK);
  1429.     if (OK)
  1430.     {
  1431.       if ((Hi(AdrInt) != 0xff) && (Hi(AdrInt) != 0)) WrError(ErrNum_OverRange);
  1432.       else
  1433.       {
  1434.         CodeLen = 2;
  1435.         BAsmCode[0] = 0xfd;
  1436.         BAsmCode[1] = Lo(AdrInt);
  1437.       }
  1438.     }
  1439.   }
  1440. }
  1441.  
  1442. /*--------------------------------------------------------------------------*/
  1443.  
  1444. static void AddFixed(const char *NName, Word NCode)
  1445. {
  1446.   AddInstTable(InstTable, NName, NCode, DecodeFixed);
  1447. }
  1448.  
  1449. static void AddCond(const char *NName, Byte NCode)
  1450. {
  1451.   order_array_rsv_end(Conditions, CondRec);
  1452.   Conditions[InstrZ].Name = NName;
  1453.   Conditions[InstrZ++].Code = NCode;
  1454. }
  1455.  
  1456. static void AddReg(const char *NName, Word NCode)
  1457. {
  1458.   AddInstTable(InstTable, NName, NCode, DecodeReg);
  1459. }
  1460.  
  1461. static void InitFields(void)
  1462. {
  1463.   InstTable = CreateInstTable(203);
  1464.   AddInstTable(InstTable, "LD", 0, DecodeLD);
  1465.   AddInstTable(InstTable, "XCH", 0, DecodeXCH);
  1466.   AddInstTable(InstTable, "CLR", 0, DecodeCLR);
  1467.   AddInstTable(InstTable, "LDW", 0, DecodeLDW);
  1468.   AddInstTable(InstTable, "PUSH", 7, DecodePUSH_POP);
  1469.   AddInstTable(InstTable, "POP", 6, DecodePUSH_POP);
  1470.   AddInstTable(InstTable, "TEST", 0xd8, DecodeTEST_CPL_SET);
  1471.   AddInstTable(InstTable, "CPL", 0xc0, DecodeTEST_CPL_SET);
  1472.   AddInstTable(InstTable, "SET", 0x40, DecodeTEST_CPL_SET);
  1473.   AddInstTable(InstTable, "MCMP", 0, DecodeMCMP);
  1474.   AddInstTable(InstTable, "INC", 0, DecodeINC_DEC);
  1475.   AddInstTable(InstTable, "DEC", 8, DecodeINC_DEC);
  1476.   AddInstTable(InstTable, "MUL", 0, DecodeMUL);
  1477.   AddInstTable(InstTable, "DIV", 0, DecodeDIV);
  1478.   AddInstTable(InstTable, "ROLD", 8, DecodeROLD_RORD);
  1479.   AddInstTable(InstTable, "RORD", 9, DecodeROLD_RORD);
  1480.   AddInstTable(InstTable, "JRS", 0, DecodeJRS);
  1481.   AddInstTable(InstTable, "JR", 0, DecodeJR);
  1482.   AddInstTable(InstTable, "JP", 0xfe, DecodeJP_CALL);
  1483.   AddInstTable(InstTable, "CALL", 0xfc, DecodeJP_CALL);
  1484.   AddInstTable(InstTable, "CALLV", 0, DecodeCALLV);
  1485.   AddInstTable(InstTable, "CALLP", 0, DecodeCALLP);
  1486.  
  1487.   AddFixed("DI"  , 0x483a);
  1488.   AddFixed("EI"  , 0x403a);
  1489.   AddFixed("RET" , 0x0005);
  1490.   AddFixed("RETI", 0x0004);
  1491.   AddFixed("RETN", 0xe804);
  1492.   AddFixed("SWI" , 0x00ff);
  1493.   AddFixed("NOP" , 0x0000);
  1494.  
  1495.   InstrZ = 0;
  1496.   AddCond("EQ", 0); AddCond("Z" , 0);
  1497.   AddCond("NE", 1); AddCond("NZ", 1);
  1498.   AddCond("CS", 2); AddCond("LT", 2);
  1499.   AddCond("CC", 3); AddCond("GE", 3);
  1500.   AddCond("LE", 4); AddCond("GT", 5);
  1501.   AddCond("T" , COND_CODE_TRUE); AddCond("F" , 7);
  1502.   AddCond(NULL, 0);
  1503.  
  1504.   AddReg("DAA" , 0x0a);  AddReg("DAS" , 0x0b);
  1505.   AddReg("SHLC", 0x1c);  AddReg("SHRC", 0x1d);
  1506.   AddReg("ROLC", 0x1e);  AddReg("RORC", 0x1f);
  1507.   AddReg("SWAP", 0x01);
  1508.  
  1509.   InstrZ = 0;
  1510.   AddInstTable(InstTable, "ADDC", InstrZ++, DecodeALU);
  1511.   AddInstTable(InstTable, "ADD" , InstrZ++, DecodeALU);
  1512.   AddInstTable(InstTable, "SUBB", InstrZ++, DecodeALU);
  1513.   AddInstTable(InstTable, "SUB" , InstrZ++, DecodeALU);
  1514.   AddInstTable(InstTable, "AND" , InstrZ++, DecodeALU);
  1515.   AddInstTable(InstTable, "XOR" , InstrZ++, DecodeALU);
  1516.   AddInstTable(InstTable, "OR"  , InstrZ++, DecodeALU);
  1517.   AddInstTable(InstTable, "CMP" , InstrZ++, DecodeALU);
  1518. }
  1519.  
  1520. static void DeinitFields(void)
  1521. {
  1522.   DestroyInstTable(InstTable);
  1523.  
  1524.   order_array_free(Conditions);
  1525. }
  1526.  
  1527. /*--------------------------------------------------------------------------*/
  1528.  
  1529. static void MakeCode_87C800(void)
  1530. {
  1531.   CodeLen = 0;
  1532.   DontPrint = False;
  1533.   OpSize = -1;
  1534.  
  1535.   /* zu ignorierendes */
  1536.  
  1537.   if (Memo(""))
  1538.     return;
  1539.  
  1540.   /* Pseudoanweisungen */
  1541.  
  1542.   if (DecodeIntelPseudo(False))
  1543.     return;
  1544.  
  1545.   if (!LookupInstTable(InstTable, OpPart.str.p_str))
  1546.     WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
  1547. }
  1548.  
  1549. static Boolean IsDef_87C800(void)
  1550. {
  1551.   return False;
  1552. }
  1553.  
  1554. static void SwitchFrom_87C800(void)
  1555. {
  1556.   DeinitFields();
  1557. }
  1558.  
  1559. static Boolean TrueFnc(void)
  1560. {
  1561.   return True;
  1562. }
  1563.  
  1564. static void SwitchTo_87C800(void)
  1565. {
  1566.   TurnWords = False;
  1567.   SetIntConstMode(eIntConstModeIntel);
  1568.   SetIsOccupiedFnc = TrueFnc;
  1569.  
  1570.   PCSymbol = "$";
  1571.   HeaderID = 0x54;
  1572.   NOPCode = 0x00;
  1573.   DivideChars = ",";
  1574.   HasAttrs = False;
  1575.  
  1576.   ValidSegs = 1 << SegCode;
  1577.   Grans[SegCode] = 1;
  1578.   ListGrans[SegCode] = 1;
  1579.   SegInits[SegCode] = 0;
  1580.   SegLimits[SegCode] = 0xffff;
  1581.  
  1582.   MakeCode = MakeCode_87C800;
  1583.   IsDef = IsDef_87C800;
  1584.   SwitchFrom = SwitchFrom_87C800;
  1585.   InitFields();
  1586. }
  1587.  
  1588. void code87c800_init(void)
  1589. {
  1590.   CPU87C00 = AddCPU("87C00", SwitchTo_87C800);
  1591.   CPU87C20 = AddCPU("87C20", SwitchTo_87C800);
  1592.   CPU87C40 = AddCPU("87C40", SwitchTo_87C800);
  1593.   CPU87C70 = AddCPU("87C70", SwitchTo_87C800);
  1594. }
  1595.