Subversion Repositories pentevo

Rev

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

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