Subversion Repositories pentevo

Rev

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

  1. /* code90c141.c */
  2. /*****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
  4. /*                                                                           */
  5. /* AS-Portierung                                                             */
  6. /*                                                                           */
  7. /* Codegenerator Toshiba TLCS-90                                             */
  8. /*                                                                           */
  9. /*****************************************************************************/
  10.  
  11. #include "stdinc.h"
  12. #include <string.h>
  13. #include <ctype.h>
  14.  
  15. #include "nls.h"
  16. #include "bpemu.h"
  17. #include "strutil.h"
  18. #include "asmdef.h"
  19. #include "asmsub.h"
  20. #include "asmpars.h"
  21. #include "asmitree.h"
  22. #include "asmcode.h"
  23. #include "codepseudo.h"
  24. #include "intpseudo.h"
  25. #include "codevars.h"
  26. #include "errmsg.h"
  27.  
  28. #include "code90c141.h"
  29.  
  30. typedef struct
  31. {
  32.   const char *Name;
  33.   Byte Code;
  34. } Condition;
  35.  
  36. #define AccReg 6
  37. #define HLReg 2
  38.  
  39. #define COND_CODE_TRUE 8
  40.  
  41. enum
  42. {
  43.   ModNone = -1,
  44.   ModReg8 = 0,
  45.   ModReg16 = 1,
  46.   ModIReg16 = 2,
  47.   ModIndReg = 3,
  48.   ModIdxReg = 4,
  49.   ModDir = 5,
  50.   ModMem = 6,
  51.   ModImm = 7
  52. };
  53.  
  54. #define MModReg8   (1 << ModReg8)
  55. #define MModReg16  (1 << ModReg16)
  56. #define MModIReg16 (1 << ModIReg16)
  57. #define MModIndReg (1 << ModIndReg)
  58. #define MModIdxReg (1 << ModIdxReg)
  59. #define MModDir    (1 << ModDir)
  60. #define MModMem    (1 << ModMem)
  61. #define MModImm    (1 << ModImm)
  62. #define MAssumeInd (1 << 12)
  63.  
  64. static ShortInt AdrType;
  65. static Byte AdrMode;
  66. static ShortInt OpSize;
  67. static Byte AdrVals[10];
  68. static Boolean MinOneIs0;
  69.  
  70. static Condition *Conditions;
  71.  
  72. static CPUVar CPU90C141;
  73.  
  74. /*---------------------------------------------------------------------------*/
  75.  
  76. static void SetOpSize(ShortInt New)
  77. {
  78.   if (OpSize == -1)
  79.     OpSize = New;
  80.   else if (OpSize != New)
  81.   {
  82.     WrError(ErrNum_ConfOpSizes);
  83.     AdrType = ModNone;
  84.     AdrCnt = 0;
  85.   }
  86. }
  87.  
  88.   static const char Reg16Names[][3] = { "BC", "DE", "HL", "\0", "IX", "IY", "SP" };
  89.  
  90. typedef struct
  91. {
  92.   as_eval_cb_data_t cb_data;
  93.   Byte occ_flag, base_reg;
  94. } tlcs90_eval_cb_data_t;
  95.  
  96. DECLARE_AS_EVAL_CB(tlcs90_eval_cb)
  97. {
  98.   tlcs90_eval_cb_data_t *p_tlcs90_eval_cb_data = (tlcs90_eval_cb_data_t*)p_data;
  99.   size_t z;
  100.  
  101.   if (!as_strcasecmp(p_arg->str.p_str, "A"))
  102.   {
  103.     if ((p_tlcs90_eval_cb_data->occ_flag & 1)
  104.      || !as_eval_cb_data_stack_plain_add(p_data->p_stack))
  105.     {
  106.       WrStrErrorPos(ErrNum_InvAddrMode, p_arg);
  107.       return e_eval_fail;
  108.     }
  109.     p_tlcs90_eval_cb_data->occ_flag |= 1;
  110.     as_tempres_set_int(p_res, 0);
  111.     return e_eval_ok;
  112.   }
  113.  
  114.   for (z = 0; z < as_array_size(Reg16Names); z++)
  115.     if (!as_strcasecmp(p_arg->str.p_str, Reg16Names[z]))
  116.     {
  117.       if ((p_tlcs90_eval_cb_data->occ_flag & 2)
  118.        || !as_eval_cb_data_stack_plain_add(p_data->p_stack))
  119.       {
  120.         WrStrErrorPos(ErrNum_InvAddrMode, p_arg);
  121.         return e_eval_fail;
  122.       }
  123.       p_tlcs90_eval_cb_data->occ_flag |= 2;
  124.       p_tlcs90_eval_cb_data->base_reg = z;
  125.       as_tempres_set_int(p_res, 0);
  126.       return e_eval_ok;
  127.     }
  128.   return e_eval_none;
  129. }
  130.  
  131. static void DecodeAdr(const tStrComp *pArg, Word Erl)
  132. {
  133.   static const char Reg8Names[][2] = { "B", "C", "D", "E", "H", "L", "A" };
  134.   static const int Reg8Cnt = sizeof(Reg8Names) / sizeof(*Reg8Names);
  135.   static const int Reg16Cnt = sizeof(Reg16Names) / sizeof(*Reg16Names);
  136.   static const char IReg16Names[][3] =  {"IX", "IY", "SP" };
  137.   static const int IReg16Cnt = sizeof(IReg16Names) / sizeof(*IReg16Names);
  138.  
  139.   int z;
  140.   Boolean ok, is_indirect;
  141.  
  142.   AdrType = ModNone; AdrCnt = 0;
  143.  
  144.   /* 1. 8-Bit-Register */
  145.  
  146.   for (z = 0; z < Reg8Cnt; z++)
  147.     if (!as_strcasecmp(pArg->str.p_str, Reg8Names[z]))
  148.     {
  149.       AdrType = ModReg8;
  150.       AdrMode = z;
  151.       SetOpSize(0);
  152.       goto chk;
  153.     }
  154.  
  155.   /* 2. 16-Bit-Register, indiziert */
  156.  
  157.   if (Erl & MModIReg16)
  158.   {
  159.     for (z = 0; z < IReg16Cnt; z++)
  160.       if (!as_strcasecmp(pArg->str.p_str, IReg16Names[z]))
  161.       {
  162.         AdrType = ModIReg16;
  163.         AdrMode = z;
  164.         SetOpSize(1);
  165.         goto chk;
  166.       }
  167.   }
  168.  
  169.   /* 3. 16-Bit-Register, normal */
  170.  
  171.   if (Erl & MModReg16)
  172.   {
  173.     for (z = 0; z < Reg16Cnt; z++)
  174.      if (!as_strcasecmp(pArg->str.p_str, Reg16Names[z]))
  175.      {
  176.        AdrType = ModReg16;
  177.        AdrMode = z;
  178.        SetOpSize(1);
  179.        goto chk;
  180.      }
  181.   }
  182.  
  183.   /* Speicheradresse */
  184.  
  185.   is_indirect = IsIndirect(pArg->str.p_str);
  186.   if (is_indirect || (Erl & MAssumeInd))
  187.   {
  188.     tlcs90_eval_cb_data_t tlcs90_eval_cb_data;
  189.     LongInt DispAcc;
  190.     tStrComp Arg;
  191.     tEvalResult eval_result;
  192.  
  193.     StrCompRefRight(&Arg, pArg, !!is_indirect);
  194.     if (is_indirect)
  195.       StrCompShorten(&Arg, 1);
  196.     KillPrefBlanksStrCompRef(&Arg);
  197.     KillPostBlanksStrComp(&Arg);
  198.  
  199.     as_eval_cb_data_ini(&tlcs90_eval_cb_data.cb_data, tlcs90_eval_cb);
  200.     tlcs90_eval_cb_data.occ_flag = 0;
  201.     tlcs90_eval_cb_data.base_reg = 0;
  202.     DispAcc = EvalStrIntExprWithResultAndCallback(&Arg, Int32, &eval_result, &tlcs90_eval_cb_data.cb_data);
  203.     if (!eval_result.OK)
  204.       return;
  205.     if (mFirstPassUnknown(eval_result.Flags))
  206.       DispAcc &= 0x7f;
  207.  
  208.     switch (tlcs90_eval_cb_data.occ_flag)
  209.     {
  210.       case 1:
  211.         WrError(ErrNum_InvAddrMode);
  212.         break;
  213.       case 3:
  214.         if ((tlcs90_eval_cb_data.base_reg != 2) || DispAcc) WrError(ErrNum_InvAddrMode);
  215.         else
  216.         {
  217.           AdrType = ModIdxReg;
  218.           AdrMode = 3;
  219.         }
  220.         break;
  221.       case 2:
  222.         if ((DispAcc > 127) || (DispAcc < -128)) WrError(ErrNum_OverRange);
  223.         else if (DispAcc == 0)
  224.         {
  225.           AdrType = ModIndReg;
  226.           AdrMode = tlcs90_eval_cb_data.base_reg;
  227.         }
  228.         else if (tlcs90_eval_cb_data.base_reg < 4) WrError(ErrNum_InvAddrMode);
  229.         else
  230.         {
  231.           AdrType = ModIdxReg;
  232.           AdrMode = tlcs90_eval_cb_data.base_reg - 4;
  233.           AdrCnt = 1;
  234.           AdrVals[0] = DispAcc & 0xff;
  235.         }
  236.         break;
  237.       case 0:
  238.         if (DispAcc > 0xffff) WrError(ErrNum_AdrOverflow);
  239.         else if ((Hi(DispAcc) == 0xff) && (Erl & MModDir))
  240.         {
  241.           AdrType = ModDir;
  242.           AdrCnt = 1;
  243.           AdrVals[0] = Lo(DispAcc);
  244.         }
  245.         else
  246.         {
  247.           AdrType = ModMem;
  248.           AdrCnt = 2;
  249.           AdrVals[0] = Lo(DispAcc);
  250.           AdrVals[1] = Hi(DispAcc);
  251.         }
  252.         break;
  253.     }
  254.   }
  255.  
  256.   /* immediate */
  257.  
  258.   else
  259.   {
  260.     if ((OpSize == -1) && (MinOneIs0))
  261.       OpSize = 0;
  262.     switch (OpSize)
  263.     {
  264.       case -1:
  265.         WrError(ErrNum_InvOpSize);
  266.         break;
  267.       case 0:
  268.         AdrVals[0] = EvalStrIntExpression(pArg, Int8, &ok);
  269.         if (ok)
  270.         {
  271.           AdrType = ModImm;
  272.           AdrCnt = 1;
  273.         }
  274.         break;
  275.       case 1:
  276.       {
  277.         LongInt DispVal = EvalStrIntExpression(pArg, Int16, &ok);
  278.         if (ok)
  279.         {
  280.           AdrType = ModImm;
  281.           AdrCnt = 2;
  282.           AdrVals[0] = Lo(DispVal);
  283.           AdrVals[1] = Hi(DispVal);
  284.         }
  285.         break;
  286.       }
  287.     }
  288.   }
  289.  
  290.   /* gefunden */
  291.  
  292. chk:
  293.   if ((AdrType != ModNone) && (!((1 << AdrType) & Erl)))
  294.   {
  295.     WrError(ErrNum_InvAddrMode);
  296.     AdrType = ModNone;
  297.     AdrCnt = 0;
  298.   }
  299. }
  300.  
  301. static Boolean ArgPair(const char *Arg1, const char *Arg2)
  302. {
  303.   return  (((!as_strcasecmp(ArgStr[1].str.p_str, Arg1)) && (!as_strcasecmp(ArgStr[2].str.p_str, Arg2)))
  304.         || ((!as_strcasecmp(ArgStr[1].str.p_str, Arg2)) && (!as_strcasecmp(ArgStr[2].str.p_str, Arg1))));
  305. }
  306.  
  307. /*!------------------------------------------------------------------------
  308.  * \fn     decode_condition(const char *p_cond_str, Byte *p_cond_code)
  309.  * \brief  parse condition code
  310.  * \param  p_cond_str source argument
  311.  * \param  p_cond_code returns machine code of condition if found
  312.  * \return True if found
  313.  * ------------------------------------------------------------------------ */
  314.  
  315. static Boolean decode_condition(const char *p_cond_str, Byte *p_cond_code)
  316. {
  317.   int z;
  318.  
  319.   for (z = 0; Conditions[z].Name; z++)
  320.     if (!as_strcasecmp(p_cond_str, Conditions[z].Name))
  321.     {
  322.       *p_cond_code = Conditions[z].Code;
  323.       return True;
  324.     }
  325.   return False;
  326. }
  327.  
  328. /*-------------------------------------------------------------------------*/
  329.  
  330. /* ohne Argument */
  331.  
  332. static void DecodeFixed(Word Code)
  333. {
  334.   if (ChkArgCnt(0, 0))
  335.   {
  336.     CodeLen = 1;
  337.     BAsmCode[0] = Code;
  338.   }
  339. }
  340.  
  341. static void DecodeMove(Word Code)
  342. {
  343.   if (ChkArgCnt(0, 0))
  344.   {
  345.     CodeLen = 2;
  346.     BAsmCode[0] = 0xfe;
  347.     BAsmCode[1] = Code;
  348.   }
  349. }
  350.  
  351. static void DecodeShift(Word Code)
  352. {
  353.   if (ChkArgCnt(1, 1))
  354.   {
  355.     DecodeAdr(&ArgStr[1], (Hi(Code) ? MModReg8 : 0) | MModIndReg | MModIdxReg | MModMem | MModDir);
  356.     switch (AdrType)
  357.     {
  358.       case ModReg8:
  359.         CodeLen = 2;
  360.         BAsmCode[0] = 0xf8 + AdrMode;
  361.         BAsmCode[1] = Lo(Code);
  362.         if (AdrMode == AccReg)
  363.           WrError(ErrNum_ShortAddrPossible);
  364.         break;
  365.       case ModIndReg:
  366.         CodeLen = 2;
  367.         BAsmCode[0] = 0xe0 + AdrMode;
  368.         BAsmCode[1] = Lo(Code);
  369.         break;
  370.       case ModIdxReg:
  371.         CodeLen = 2 + AdrCnt;
  372.         BAsmCode[0] = 0xf0 + AdrMode;
  373.         memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  374.         BAsmCode[1 + AdrCnt] = Lo(Code);
  375.         break;
  376.       case ModDir:
  377.         CodeLen = 3;
  378.         BAsmCode[0] = 0xe7;
  379.         BAsmCode[1] = AdrVals[0];
  380.         BAsmCode[2] = Lo(Code);
  381.         break;
  382.       case ModMem:
  383.         CodeLen = 4;
  384.         BAsmCode[0] = 0xe3;
  385.         memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  386.         BAsmCode[3] = Lo(Code);
  387.         break;
  388.     }
  389.   }
  390. }
  391.  
  392. /* Logik */
  393.  
  394. static void DecodeBit(Word Code)
  395. {
  396.   Byte BitPos;
  397.   Boolean OK;
  398.  
  399.   if (ChkArgCnt(2, 2))
  400.   {
  401.     BitPos = EvalStrIntExpression(&ArgStr[1], UInt3, &OK);
  402.     if (OK)
  403.     {
  404.       DecodeAdr(&ArgStr[2], MModReg8 | MModIndReg | MModIdxReg | MModMem | MModDir);
  405.       switch (AdrType)
  406.       {
  407.         case ModReg8:
  408.           CodeLen = 2;
  409.           BAsmCode[0] = 0xf8 + AdrMode;
  410.           BAsmCode[1] = Code + BitPos;
  411.           break;
  412.         case ModIndReg:
  413.           CodeLen = 2;
  414.           BAsmCode[0] = 0xe0 + AdrMode;
  415.           BAsmCode[1] = Code + BitPos;
  416.           break;
  417.         case ModIdxReg:
  418.           CodeLen = 2 + AdrCnt;
  419.           memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  420.           BAsmCode[0] = 0xf0 + AdrMode;
  421.           BAsmCode[1 + AdrCnt] = Code + BitPos;
  422.           break;
  423.         case ModMem:
  424.           CodeLen = 4;
  425.           memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  426.           BAsmCode[0] = 0xe3;
  427.           BAsmCode[1 + AdrCnt] = Code + BitPos;
  428.           break;
  429.         case ModDir:
  430.           BAsmCode[1] = AdrVals[0];
  431.           if (Code == 0x18)
  432.           {
  433.             BAsmCode[0] = 0xe7;
  434.             BAsmCode[2] = Code + BitPos;
  435.             CodeLen = 3;
  436.           }
  437.           else
  438.           {
  439.             BAsmCode[0] = Code + BitPos;
  440.             CodeLen = 2;
  441.           }
  442.           break;
  443.       }
  444.     }
  445.   }
  446. }
  447.  
  448. static void DecodeAcc(Word Code)
  449. {
  450.   if (!ChkArgCnt(1, 1));
  451.   else if (as_strcasecmp(ArgStr[1].str.p_str, "A")) WrError(ErrNum_InvAddrMode);
  452.   else
  453.   {
  454.     CodeLen = 1;
  455.     BAsmCode[0] = Code;
  456.   }
  457. }
  458.  
  459. static void DecodeALU2(Word Code)
  460. {
  461.   Byte HReg;
  462.  
  463.   if (ChkArgCnt(2, 2))
  464.   {
  465.     DecodeAdr(&ArgStr[1], MModReg8 | MModReg16 | MModIdxReg | MModIndReg | MModDir | MModMem);
  466.     switch (AdrType)
  467.     {
  468.       case ModReg8:
  469.         DecodeAdr(&ArgStr[2], MModImm | (((HReg = AdrMode) == AccReg) ? MModReg8 | MModIndReg | MModIdxReg | MModDir | MModMem:0));
  470.         switch(AdrType)
  471.         {
  472.           case ModReg8:
  473.             CodeLen = 2;
  474.             BAsmCode[0] = 0xf8 | AdrMode;
  475.             BAsmCode[1] = 0x60 | Code;
  476.             break;
  477.           case ModIndReg:
  478.             CodeLen = 2;
  479.             BAsmCode[0] = 0xe0 | AdrMode; BAsmCode[1] = 0x60 | Code;
  480.             break;
  481.           case ModIdxReg:
  482.             CodeLen = 2 + AdrCnt;
  483.             BAsmCode[0] = 0xf0 | AdrMode;
  484.             memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  485.             BAsmCode[1 + AdrCnt] = 0x60 | Code;
  486.             break;
  487.           case ModDir:
  488.             CodeLen = 2;
  489.             BAsmCode[0] = 0x60 | Code;
  490.             BAsmCode[1] = AdrVals[0];
  491.             break;
  492.           case ModMem:
  493.             CodeLen = 4;
  494.             BAsmCode[0] = 0xe3;
  495.             BAsmCode[3] = 0x60 | Code;
  496.             memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  497.             break;
  498.           case ModImm:
  499.             if (HReg == AccReg)
  500.             {
  501.               CodeLen = 2;
  502.               BAsmCode[0] = 0x68 | Code;
  503.               BAsmCode[1] = AdrVals[0];
  504.             }
  505.             else
  506.             {
  507.               CodeLen = 3;
  508.               BAsmCode[0] = 0xf8 | HReg;
  509.               BAsmCode[1] = 0x68 | Code;
  510.               BAsmCode[2] = AdrVals[0];
  511.             }
  512.             break;
  513.         }
  514.         break;
  515.       case ModReg16:
  516.         if ((AdrMode == 2) || ((Code == 0) && (AdrMode >= 4)))
  517.         {
  518.           HReg = AdrMode;
  519.           DecodeAdr(&ArgStr[2], MModReg16 | MModIndReg | MModIdxReg | MModDir | MModMem | MModImm);
  520.           switch (AdrType)
  521.           {
  522.             case ModReg16:
  523.               CodeLen = 2;
  524.               BAsmCode[0] = 0xf8 | AdrMode;
  525.               BAsmCode[1] = (HReg >= 4) ? 0x14 + HReg - 4 : 0x70 + Code;
  526.               break;
  527.             case ModIndReg:
  528.               CodeLen = 2;
  529.               BAsmCode[0] = 0xe0 | AdrMode;
  530.               BAsmCode[1] = (HReg >= 4) ? 0x14 + HReg - 4 : 0x70 + Code;
  531.               break;
  532.             case ModIdxReg:
  533.               CodeLen = 2 + AdrCnt;
  534.               BAsmCode[0] = 0xf0 | AdrMode;
  535.               memcpy(BAsmCode + 1,AdrVals, AdrCnt);
  536.               BAsmCode[1 + AdrCnt] = (HReg >= 4) ? 0x14 + HReg - 4 : 0x70 + Code;
  537.               break;
  538.             case ModDir:
  539.               if (HReg >= 4)
  540.               {
  541.                 CodeLen = 3;
  542.                 BAsmCode[0] = 0xe7;
  543.                 BAsmCode[1] = AdrVals[0];
  544.                 BAsmCode[2] = 0x10 | HReg;
  545.               }
  546.               else
  547.               {
  548.                 CodeLen = 2;
  549.                 BAsmCode[0] = 0x70 | Code;
  550.                 BAsmCode[1] = AdrVals[0];
  551.               }
  552.               break;
  553.             case ModMem:
  554.               CodeLen = 4;
  555.               BAsmCode[0] = 0xe3;
  556.               memcpy(BAsmCode + 1, AdrVals, 2);
  557.               BAsmCode[3] = (HReg >= 4) ? 0x14 + HReg - 4 : 0x70 + Code;
  558.               break;
  559.             case ModImm:
  560.               CodeLen = 3;
  561.               BAsmCode[0] = (HReg >= 4) ? 0x14 + HReg - 4 : 0x78 + Code;
  562.               memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  563.               break;
  564.           }
  565.         }
  566.         else WrError(ErrNum_InvAddrMode);
  567.         break;
  568.       case ModIndReg:
  569.       case ModIdxReg:
  570.       case ModDir:
  571.       case ModMem:
  572.         OpSize = 0;
  573.         switch (AdrType)
  574.         {
  575.           case ModIndReg:
  576.             HReg = 3;
  577.             BAsmCode[0] = 0xe8 | AdrMode;
  578.             BAsmCode[1] = 0x68 | Code;
  579.             break;
  580.           case ModIdxReg:
  581.             HReg = 3 + AdrCnt;
  582.             BAsmCode[0] = 0xf4 | AdrMode;
  583.             BAsmCode[1 + AdrCnt] = 0x68 | Code;
  584.             memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  585.             break;
  586.           case ModDir:
  587.             HReg = 4;
  588.             BAsmCode[0] = 0xef;
  589.             BAsmCode[1] = AdrVals[0];
  590.             BAsmCode[2] = 0x68 | Code;
  591.             break;
  592.           case ModMem:
  593.             HReg = 5;
  594.             BAsmCode[0] = 0xeb;
  595.             memcpy(BAsmCode + 1, AdrVals, 2);
  596.             BAsmCode[3] = 0x68 | Code;
  597.             break;
  598.           default:
  599.             HReg = 0;
  600.         }
  601.         DecodeAdr(&ArgStr[2], MModImm);
  602.         if (AdrType == ModImm)
  603.         {
  604.           BAsmCode[HReg-1] = AdrVals[0];
  605.           CodeLen = HReg;
  606.         }
  607.         break;
  608.     }
  609.   }
  610. }
  611.  
  612. static void DecodeLD(Word Code)
  613. {
  614.   Byte HReg;
  615.  
  616.   if (Hi(Code))
  617.     SetOpSize(1);
  618.  
  619.   if (ChkArgCnt(2, 2))
  620.   {
  621.     DecodeAdr(&ArgStr[1], MModReg8 | MModReg16 | MModIndReg | MModIdxReg | MModDir | MModMem);
  622.     switch (AdrType)
  623.     {
  624.       case ModReg8:
  625.         HReg = AdrMode;
  626.         DecodeAdr(&ArgStr[2], MModReg8 | MModIndReg | MModIdxReg | MModDir | MModMem | MModImm);
  627.         switch (AdrType)
  628.         {
  629.           case ModReg8:
  630.             if (HReg == AccReg)
  631.             {
  632.               CodeLen = 1;
  633.               BAsmCode[0] = 0x20 | AdrMode;
  634.             }
  635.             else if (AdrMode == AccReg)
  636.             {
  637.               CodeLen = 1;
  638.               BAsmCode[0] = 0x28 | HReg;
  639.             }
  640.             else
  641.             {
  642.               CodeLen = 2;
  643.               BAsmCode[0] = 0xf8 | AdrMode;
  644.               BAsmCode[1] = 0x30 | HReg;
  645.             }
  646.             break;
  647.           case ModIndReg:
  648.             CodeLen = 2;
  649.             BAsmCode[0] = 0xe0 | AdrMode;
  650.             BAsmCode[1] = 0x28 | HReg;
  651.             break;
  652.           case ModIdxReg:
  653.             CodeLen = 2 + AdrCnt;
  654.             BAsmCode[0] = 0xf0 | AdrMode;
  655.             memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  656.             BAsmCode[1 + AdrCnt] = 0x28 | HReg;
  657.             break;
  658.           case ModDir:
  659.             if (HReg == AccReg)
  660.             {
  661.               CodeLen = 2;
  662.               BAsmCode[0] = 0x27;
  663.               BAsmCode[1] = AdrVals[0];
  664.             }
  665.             else
  666.             {
  667.               CodeLen = 3;
  668.               BAsmCode[0] = 0xe7;
  669.               BAsmCode[1] = AdrVals[0];
  670.               BAsmCode[2] = 0x28 | HReg;
  671.             }
  672.             break;
  673.           case ModMem:
  674.             CodeLen = 4;
  675.             BAsmCode[0] = 0xe3;
  676.             memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  677.             BAsmCode[3] = 0x28 | HReg;
  678.             break;
  679.           case ModImm:
  680.             CodeLen = 2;
  681.             BAsmCode[0] = 0x30 | HReg;
  682.             BAsmCode[1] = AdrVals[0];
  683.             break;
  684.         }
  685.         break;
  686.       case ModReg16:
  687.         HReg = AdrMode;
  688.         DecodeAdr(&ArgStr[2], MModReg16 | MModIndReg | MModIdxReg | MModDir | MModMem | MModImm);
  689.         switch (AdrType)
  690.         {
  691.           case ModReg16:
  692.             if (HReg == HLReg)
  693.             {
  694.               CodeLen = 1;
  695.               BAsmCode[0] = 0x40 | AdrMode;
  696.             }
  697.             else if (AdrMode == HLReg)
  698.             {
  699.               CodeLen = 1;
  700.               BAsmCode[0] = 0x48 | HReg;
  701.             }
  702.             else
  703.             {
  704.               CodeLen = 2;
  705.               BAsmCode[0] = 0xf8 | AdrMode;
  706.               BAsmCode[1] = 0x38 | HReg;
  707.             }
  708.             break;
  709.           case ModIndReg:
  710.             CodeLen = 2;
  711.             BAsmCode[0] = 0xe0 | AdrMode;
  712.             BAsmCode[1] = 0x48 | HReg;
  713.             break;
  714.           case ModIdxReg:
  715.             CodeLen = 2 + AdrCnt;
  716.             BAsmCode[0] = 0xf0 | AdrMode;
  717.             memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  718.             BAsmCode[1 + AdrCnt] = 0x48 | HReg;
  719.             break;
  720.           case ModDir:
  721.             if (HReg == HLReg)
  722.             {
  723.               CodeLen = 2;
  724.               BAsmCode[0] = 0x47;
  725.               BAsmCode[1] = AdrVals[0];
  726.             }
  727.             else
  728.             {
  729.               CodeLen = 3;
  730.               BAsmCode[0] = 0xe7;
  731.               BAsmCode[1] = AdrVals[0];
  732.               BAsmCode[2] = 0x48 | HReg;
  733.             }
  734.             break;
  735.           case ModMem:
  736.             CodeLen = 4;
  737.             BAsmCode[0] = 0xe3;
  738.             BAsmCode[3] = 0x48 | HReg;
  739.             memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  740.             break;
  741.           case ModImm:
  742.             CodeLen = 3;
  743.             BAsmCode[0] = 0x38 | HReg;
  744.             memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  745.             break;
  746.         }
  747.         break;
  748.       case ModIndReg:
  749.       case ModIdxReg:
  750.       case ModDir:
  751.       case ModMem:
  752.         MinOneIs0 = True;
  753.         HReg = AdrCnt;
  754.         memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  755.         switch (AdrType)
  756.         {
  757.           case ModIndReg:
  758.             BAsmCode[0] = 0xe8 | AdrMode;
  759.             break;
  760.           case ModIdxReg:
  761.             BAsmCode[0] = 0xf4 | AdrMode;
  762.             break;
  763.           case ModMem:
  764.             BAsmCode[0] = 0xeb;
  765.             break;
  766.           case ModDir:
  767.             BAsmCode[0] = 0x0f;
  768.             break;
  769.         }
  770.         DecodeAdr(&ArgStr[2], MModReg16 | MModReg8 | MModImm);
  771.         if (BAsmCode[0] == 0x0f)
  772.          switch (AdrType)
  773.          {
  774.            case ModReg8:
  775.              if (AdrMode == AccReg)
  776.              {
  777.                CodeLen = 2;
  778.                BAsmCode[0] = 0x2f;
  779.              }
  780.              else
  781.              {
  782.                CodeLen = 3;
  783.                BAsmCode[0] = 0xef;
  784.                BAsmCode[2] = 0x20 | AdrMode;
  785.              }
  786.              break;
  787.            case ModReg16:
  788.              if (AdrMode == HLReg)
  789.              {
  790.                CodeLen = 2;
  791.                BAsmCode[0] = 0x4f;
  792.              }
  793.              else
  794.              {
  795.                CodeLen = 3;
  796.                BAsmCode[0] = 0xef;
  797.                BAsmCode[2] = 0x40 | AdrMode;
  798.              }
  799.              break;
  800.            case ModImm:
  801.              CodeLen = 3 + OpSize;
  802.              BAsmCode[0] = 0x37 | (OpSize << 3);
  803.              memcpy(BAsmCode + 2, AdrVals, AdrCnt);
  804.              break;
  805.          }
  806.          else
  807.          {
  808.            switch (AdrType)
  809.            {
  810.              case ModReg8:
  811.                BAsmCode[1 + HReg] = 0x20 | AdrMode;
  812.                break;
  813.              case ModReg16:
  814.                BAsmCode[1 + HReg] = 0x40 | AdrMode;
  815.                break;
  816.              case ModImm:
  817.                BAsmCode[1 + HReg] = 0x37 | (OpSize << 3);
  818.                break;
  819.            }
  820.            memcpy(BAsmCode + 2 + HReg, AdrVals, AdrCnt);
  821.            CodeLen = 1 + HReg + 1 + AdrCnt;
  822.          }
  823.         break;
  824.     }
  825.   }
  826. }
  827.  
  828. static void DecodePUSH_POP(Word Code)
  829. {
  830.   if (ChkArgCnt(1, 1))
  831.   {
  832.     if (!as_strcasecmp(ArgStr[1].str.p_str, "AF"))
  833.     {
  834.       CodeLen = 1;
  835.       BAsmCode[0] = 0x56 | Code;
  836.     }
  837.     else
  838.     {
  839.       DecodeAdr(&ArgStr[1], MModReg16);
  840.       if (AdrType == ModReg16)
  841.       {
  842.         if (AdrMode == 6) WrError(ErrNum_InvAddrMode);
  843.         else
  844.         {
  845.           CodeLen = 1;
  846.           BAsmCode[0] = 0x50 | Code | AdrMode;
  847.         }
  848.       }
  849.     }
  850.   }
  851. }
  852.  
  853. static void DecodeLDA(Word Code)
  854. {
  855.   Byte HReg;
  856.  
  857.   UNUSED(Code);
  858.  
  859.   if (ChkArgCnt(2, 2))
  860.   {
  861.     DecodeAdr(&ArgStr[1], MModReg16);
  862.     if (AdrType == ModReg16)
  863.     {
  864.       HReg = 0x38 + AdrMode;
  865.       DecodeAdr(&ArgStr[2], MModIndReg | MModIdxReg | MAssumeInd);
  866.       switch (AdrType)
  867.       {
  868.         case ModIndReg:
  869.           if (AdrMode < 4) WrError(ErrNum_InvAddrMode);
  870.           else
  871.           {
  872.             CodeLen = 3;
  873.             BAsmCode[0] = 0xf0 | AdrMode;
  874.             BAsmCode[1] = 0;
  875.             BAsmCode[2] = HReg;
  876.           }
  877.           break;
  878.         case ModIdxReg:
  879.           CodeLen = 2 + AdrCnt;
  880.           BAsmCode[0] = 0xf4 + AdrMode;
  881.           memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  882.           BAsmCode[1 + AdrCnt] = HReg;
  883.           break;
  884.       }
  885.     }
  886.   }
  887. }
  888.  
  889. static void DecodeLDAR(Word Code)
  890. {
  891.   UNUSED(Code);
  892.  
  893.   if (!ChkArgCnt(2, 2));
  894.   else if (as_strcasecmp(ArgStr[1].str.p_str, "HL")) WrError(ErrNum_InvAddrMode);
  895.   else
  896.   {
  897.     Boolean OK;
  898.     Integer AdrInt = EvalStrIntExpression(&ArgStr[2], Int16, &OK) - (EProgCounter() + 2);
  899.     if (OK)
  900.     {
  901.       CodeLen = 3;
  902.       BAsmCode[0] = 0x17;
  903.       BAsmCode[1] = Lo(AdrInt);
  904.       BAsmCode[2] = Hi(AdrInt);
  905.     }
  906.   }
  907. }
  908.  
  909. static void DecodeEX(Word Code)
  910. {
  911.   Byte HReg;
  912.  
  913.   UNUSED(Code);
  914.  
  915.   /* work around the parser problem related to the ' character */
  916.  
  917.   if (!as_strncasecmp(ArgStr[2].str.p_str, "AF\'", 3))
  918.     ArgStr[2].str.p_str[3] = '\0';
  919.  
  920.   if (!ChkArgCnt(2, 2));
  921.   else if (ArgPair("DE", "HL"))
  922.   {
  923.     CodeLen = 1;
  924.     BAsmCode[0] = 0x08;
  925.   }
  926.   else if ((ArgPair("AF", "AF\'")) || (ArgPair("AF", "AF`")))
  927.   {
  928.     CodeLen = 1;
  929.     BAsmCode[0] = 0x09;
  930.   }
  931.   else
  932.   {
  933.     DecodeAdr(&ArgStr[1], MModReg16 | MModIndReg | MModIdxReg | MModMem | MModDir);
  934.     switch (AdrType)
  935.     {
  936.       case ModReg16:
  937.         HReg = 0x50 | AdrMode;
  938.         DecodeAdr(&ArgStr[2], MModIndReg | MModIdxReg | MModMem | MModDir);
  939.         switch (AdrType)
  940.         {
  941.           case ModIndReg:
  942.             CodeLen = 2;
  943.             BAsmCode[0] = 0xe0 | AdrMode;
  944.             BAsmCode[1] = HReg;
  945.             break;
  946.           case ModIdxReg:
  947.             CodeLen = 2 + AdrCnt;
  948.             BAsmCode[0] = 0xf0 | AdrMode;
  949.             memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  950.             BAsmCode[1 + AdrCnt] = HReg;
  951.             break;
  952.           case ModDir:
  953.             CodeLen = 3;
  954.             BAsmCode[0] = 0xe7;
  955.             BAsmCode[1] = AdrVals[0];
  956.             BAsmCode[2] = HReg;
  957.             break;
  958.           case ModMem:
  959.             CodeLen = 4;
  960.             BAsmCode[0] = 0xe3;
  961.             memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  962.             BAsmCode[3] = HReg;
  963.             break;
  964.         }
  965.         break;
  966.       case ModIndReg:
  967.       case ModIdxReg:
  968.       case ModDir:
  969.       case ModMem:
  970.         switch (AdrType)
  971.         {
  972.           case ModIndReg:
  973.             BAsmCode[0] = 0xe0 | AdrMode;
  974.             break;
  975.           case ModIdxReg:
  976.             BAsmCode[0] = 0xf0 | AdrMode;
  977.             break;
  978.           case ModDir:
  979.             BAsmCode[0] = 0xe7;
  980.             break;
  981.           case ModMem:
  982.             BAsmCode[0] = 0xe3;
  983.             break;
  984.         }
  985.         memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  986.         HReg = 2 + AdrCnt;
  987.         DecodeAdr(&ArgStr[2], MModReg16);
  988.         if (AdrType == ModReg16)
  989.         {
  990.           BAsmCode[HReg - 1] = 0x50 | AdrMode;
  991.           CodeLen = HReg;
  992.         }
  993.         break;
  994.     }
  995.   }
  996. }
  997.  
  998. static void DecodeINC_DEC(Word Code)
  999. {
  1000.   if (Hi(Code))
  1001.     SetOpSize(1);
  1002.  
  1003.   if (ChkArgCnt(1, 1))
  1004.   {
  1005.     DecodeAdr(&ArgStr[1], MModReg8 | MModReg16 | MModIndReg | MModIdxReg | MModDir | MModMem);
  1006.     if (OpSize==-1)
  1007.       OpSize = 0;
  1008.     switch (AdrType)
  1009.     {
  1010.       case ModReg8:
  1011.         CodeLen = 1;
  1012.         BAsmCode[0] = 0x80 | Lo(Code) | AdrMode;
  1013.         break;
  1014.       case ModReg16:
  1015.         CodeLen = 1;
  1016.         BAsmCode[0] = 0x90 | Lo(Code) | AdrMode;
  1017.         break;
  1018.       case ModIndReg:
  1019.         CodeLen = 2;
  1020.         BAsmCode[0] = 0xe0 | AdrMode;
  1021.         BAsmCode[1] = 0x87 | (OpSize << 4) | Lo(Code);
  1022.         break;
  1023.       case ModIdxReg:
  1024.         CodeLen = 2 + AdrCnt;
  1025.         BAsmCode[0] = 0xf0 | AdrMode;
  1026.         memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  1027.         BAsmCode[1 + AdrCnt] = 0x87 | (OpSize << 4) | Lo(Code);
  1028.         break;
  1029.       case ModDir:
  1030.         CodeLen = 2;
  1031.         BAsmCode[0] = 0x87 | (OpSize << 4) | Lo(Code);
  1032.         BAsmCode[1] = AdrVals[0];
  1033.         break;
  1034.       case ModMem:
  1035.         CodeLen = 4;
  1036.         BAsmCode[0] = 0xe3;
  1037.         memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  1038.         BAsmCode[3] = 0x87 | (OpSize << 4) | Lo(Code);
  1039.         BAsmCode[1] = AdrVals[0];
  1040.         break;
  1041.     }
  1042.   }
  1043. }
  1044.  
  1045. static void DecodeINCX_DECX(Word Code)
  1046. {
  1047.   if (ChkArgCnt(1, 1))
  1048.   {
  1049.     DecodeAdr(&ArgStr[1], MModDir);
  1050.     if (AdrType == ModDir)
  1051.     {
  1052.       CodeLen = 2;
  1053.       BAsmCode[0] = Code;
  1054.       BAsmCode[1] = AdrVals[0];
  1055.     }
  1056.   }
  1057. }
  1058.  
  1059. static void DecodeMUL_DIV(Word Code)
  1060. {
  1061.   if (!ChkArgCnt(2, 2));
  1062.   else if (as_strcasecmp(ArgStr[1].str.p_str, "HL")) WrError(ErrNum_InvAddrMode);
  1063.   else
  1064.   {
  1065.     OpSize = 0;
  1066.     DecodeAdr(&ArgStr[2], MModReg8 | MModIndReg | MModIdxReg | MModDir | MModMem | MModImm);
  1067.     switch (AdrType)
  1068.     {
  1069.       case ModReg8:
  1070.         CodeLen = 2;
  1071.         BAsmCode[0] = 0xf8 + AdrMode;
  1072.         BAsmCode[1] = Code;
  1073.         break;
  1074.       case ModIndReg:
  1075.         CodeLen = 2;
  1076.         BAsmCode[0] = 0xe0 + AdrMode;
  1077.         BAsmCode[1] = Code;
  1078.         break;
  1079.       case ModIdxReg:
  1080.         CodeLen = 2 + AdrCnt;
  1081.         BAsmCode[0] = 0xf0 + AdrMode;
  1082.         BAsmCode[1 + AdrCnt] = Code;
  1083.         memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  1084.         break;
  1085.       case ModDir:
  1086.         CodeLen = 3;
  1087.         BAsmCode[0] = 0xe7;
  1088.         BAsmCode[1] = AdrVals[0];
  1089.         BAsmCode[2] = Code;
  1090.         break;
  1091.       case ModMem:
  1092.         CodeLen = 4;
  1093.         BAsmCode[0] = 0xe3;
  1094.         BAsmCode[3] = Code;
  1095.         memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  1096.         break;
  1097.       case ModImm:
  1098.         CodeLen = 2;
  1099.         BAsmCode[0] = Code;
  1100.         BAsmCode[1] = AdrVals[0];
  1101.         break;
  1102.     }
  1103.   }
  1104. }
  1105.  
  1106. static void DecodeJR(Word Code)
  1107. {
  1108.   UNUSED(Code);
  1109.  
  1110.   if (ChkArgCnt(1, 2))
  1111.   {
  1112.     Byte cond_code;
  1113.     Boolean OK;
  1114.     tSymbolFlags Flags;
  1115.     Integer AdrInt;
  1116.  
  1117.     if (ArgCnt == 1)
  1118.       cond_code = COND_CODE_TRUE;
  1119.     else if (!decode_condition(ArgStr[1].str.p_str, &cond_code))
  1120.     {
  1121.       WrStrErrorPos(ErrNum_UndefCond, &ArgStr[1]);
  1122.       return;
  1123.     }
  1124.  
  1125.     AdrInt = EvalStrIntExpressionWithFlags(&ArgStr[ArgCnt], Int16, &OK, &Flags) - (EProgCounter() + 2);
  1126.     if (OK)
  1127.     {
  1128.       if (!mSymbolQuestionable(Flags) && ((AdrInt > 127) || (AdrInt < -128))) WrError(ErrNum_JmpDistTooBig);
  1129.       else
  1130.       {
  1131.         CodeLen = 2;
  1132.         BAsmCode[0] = 0xc0 | cond_code;
  1133.         BAsmCode[1] = AdrInt & 0xff;
  1134.       }
  1135.     }
  1136.   }
  1137. }
  1138.  
  1139. static void DecodeCALL_JP(Word Code)
  1140. {
  1141.   if (ChkArgCnt(1, 2))
  1142.   {
  1143.     Byte cond_code;
  1144.  
  1145.     if (ArgCnt == 1)
  1146.       cond_code = COND_CODE_TRUE;
  1147.     else if (!decode_condition(ArgStr[1].str.p_str, &cond_code))
  1148.     {
  1149.       WrStrErrorPos(ErrNum_UndefCond, &ArgStr[1]);
  1150.       return;
  1151.     }
  1152.  
  1153.     OpSize = 1;
  1154.     DecodeAdr(&ArgStr[ArgCnt], MModIndReg | MModIdxReg | MModMem | MAssumeInd);
  1155.     switch (AdrType)
  1156.     {
  1157.       case ModIndReg:
  1158.         CodeLen = 2;
  1159.         BAsmCode[0] = 0xe8 | AdrMode;
  1160.         BAsmCode[1] = 0xc0 | (Code << 4) | cond_code;
  1161.         break;
  1162.       case ModIdxReg:
  1163.         CodeLen = 2 + AdrCnt;
  1164.         BAsmCode[0] = 0xf4 | AdrMode;
  1165.         memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  1166.         BAsmCode[1 + AdrCnt] = 0xc0 | (Code << 4) | cond_code;
  1167.         break;
  1168.       case ModMem:
  1169.         if (cond_code == COND_CODE_TRUE)
  1170.         {
  1171.           CodeLen = 3;
  1172.           BAsmCode[0] = 0x1a + (Code << 1);
  1173.           memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  1174.         }
  1175.         else
  1176.         {
  1177.           CodeLen = 4;
  1178.           BAsmCode[0] = 0xeb;
  1179.           memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  1180.           BAsmCode[3] = 0xc0 | (Code << 4) | cond_code;
  1181.         }
  1182.         break;
  1183.     }
  1184.   }
  1185. }
  1186.  
  1187. static void DecodeRET(Word Code)
  1188. {
  1189.   UNUSED(Code);
  1190.  
  1191.   if (ChkArgCnt(0, 1))
  1192.   {
  1193.     Byte cond_code;
  1194.  
  1195.     if (ArgCnt == 0)
  1196.       cond_code = COND_CODE_TRUE;
  1197.     else if (!decode_condition(ArgStr[1].str.p_str, &cond_code))
  1198.     {
  1199.       WrStrErrorPos(ErrNum_UndefCond, &ArgStr[1]);
  1200.       return;
  1201.     }
  1202.  
  1203.     if (cond_code == COND_CODE_TRUE)
  1204.     {
  1205.       CodeLen = 1;
  1206.       BAsmCode[0] = 0x1e;
  1207.     }
  1208.     else
  1209.     {
  1210.       CodeLen = 2;
  1211.       BAsmCode[0] = 0xfe;
  1212.       BAsmCode[1] = 0xd0 | cond_code;
  1213.     }
  1214.   }
  1215. }
  1216.  
  1217. static void DecodeDJNZ(Word Code)
  1218. {
  1219.   UNUSED(Code);
  1220.  
  1221.   if (ChkArgCnt(1, 2))
  1222.   {
  1223.     if (ArgCnt == 1)
  1224.     {
  1225.       AdrType = ModReg8;
  1226.       AdrMode = 0;
  1227.       OpSize = 0;
  1228.     }
  1229.     else
  1230.       DecodeAdr(&ArgStr[1], MModReg8 | MModReg16);
  1231.     if (AdrType != ModNone)
  1232.     {
  1233.       if (AdrMode != 0) WrError(ErrNum_InvAddrMode);
  1234.       else
  1235.       {
  1236.         Boolean OK;
  1237.         tSymbolFlags Flags;
  1238.         Integer AdrInt = EvalStrIntExpressionWithFlags(&ArgStr[ArgCnt], Int16, &OK, &Flags) - (EProgCounter() + 2);
  1239.  
  1240.         if (OK)
  1241.         {
  1242.           if (!mSymbolQuestionable(Flags) && ((AdrInt > 127) || (AdrInt < -128))) WrError(ErrNum_JmpDistTooBig);
  1243.           else
  1244.           {
  1245.             CodeLen = 2;
  1246.             BAsmCode[0] = 0x18 | OpSize;
  1247.             BAsmCode[1] = AdrInt & 0xff;
  1248.           }
  1249.         }
  1250.       }
  1251.     }
  1252.   }
  1253. }
  1254.  
  1255. static void DecodeJRL_CALR(Word Code)
  1256. {
  1257.   if (ChkArgCnt(1, 1))
  1258.   {
  1259.     Boolean OK;
  1260.     Integer AdrInt = EvalStrIntExpression(&ArgStr[1], Int16, &OK) - (EProgCounter() + 2);
  1261.     if (OK)
  1262.     {
  1263.       CodeLen = 3;
  1264.       BAsmCode[0] = Code;
  1265.       if ((Code == 0x1b)
  1266.        && (AdrInt >= -128)
  1267.        && (AdrInt <= 127))
  1268.         WrError(ErrNum_ShortJumpPossible);
  1269.       BAsmCode[1] = Lo(AdrInt);
  1270.       BAsmCode[2] = Hi(AdrInt);
  1271.     }
  1272.   }
  1273. }
  1274.  
  1275. /*-------------------------------------------------------------------------*/
  1276.  
  1277. static void AddW(const char *Name, Word Code, InstProc Proc)
  1278. {
  1279.   char Str[20];
  1280.  
  1281.   AddInstTable(InstTable, Name, Code, Proc);
  1282.   as_snprintf(Str, sizeof(Str), "%sW", Name);
  1283.   AddInstTable(InstTable, Str, Code | 0x100, Proc);
  1284. }
  1285.  
  1286. static void AddFixed(const char *NName, Byte NCode)
  1287. {
  1288.   AddInstTable(InstTable, NName, NCode, DecodeFixed);
  1289. }
  1290.  
  1291. static void AddMove(const char *NName, Byte NCode)
  1292. {
  1293.   AddInstTable(InstTable, NName, NCode, DecodeMove);
  1294. }
  1295.  
  1296. static void AddShift(const char *NName, Word NCode, Boolean NMay)
  1297. {
  1298.   AddInstTable(InstTable, NName, NCode | (NMay ? 0x100 : 0), DecodeShift);
  1299. }
  1300.  
  1301. static void AddBit(const char *NName, Byte NCode)
  1302. {
  1303.   AddInstTable(InstTable, NName, NCode, DecodeBit);
  1304. }
  1305.  
  1306. static void AddAcc(const char *NName, Byte NCode)
  1307. {
  1308.   AddInstTable(InstTable, NName, NCode, DecodeAcc);
  1309. }
  1310.  
  1311. static void AddCondition(const char *NName, Byte NCode)
  1312. {
  1313.   order_array_rsv_end(Conditions, Condition);
  1314.   Conditions[InstrZ].Name = NName;
  1315.   Conditions[InstrZ++].Code = NCode;
  1316. }
  1317.  
  1318. static void InitFields(void)
  1319. {
  1320.   InstTable = CreateInstTable(207);
  1321.   SetDynamicInstTable(InstTable);
  1322.  
  1323.   add_null_pseudo(InstTable);
  1324.  
  1325.   AddW("LD", 0, DecodeLD);
  1326.   AddInstTable(InstTable, "PUSH", 0, DecodePUSH_POP);
  1327.   AddInstTable(InstTable, "POP" , 8, DecodePUSH_POP);
  1328.   AddInstTable(InstTable, "LDA", 0, DecodeLDA);
  1329.   AddInstTable(InstTable, "LDAR", 0, DecodeLDAR);
  1330.   AddInstTable(InstTable, "EX", 0, DecodeEX);
  1331.   AddW("INC", 0, DecodeINC_DEC);
  1332.   AddW("DEC", 8, DecodeINC_DEC);
  1333.   AddInstTable(InstTable, "INCX", 0x07, DecodeINCX_DECX);
  1334.   AddInstTable(InstTable, "DECX", 0x0f, DecodeINCX_DECX);
  1335.   AddInstTable(InstTable, "MUL", 0x12, DecodeMUL_DIV);
  1336.   AddInstTable(InstTable, "DIV", 0x13, DecodeMUL_DIV);
  1337.   AddInstTable(InstTable, "JR", 0, DecodeJR);
  1338.   AddInstTable(InstTable, "CALL", 1, DecodeCALL_JP);
  1339.   AddInstTable(InstTable, "JP", 0, DecodeCALL_JP);
  1340.   AddInstTable(InstTable, "RET", 0, DecodeRET);
  1341.   AddInstTable(InstTable, "DJNZ", 0, DecodeDJNZ);
  1342.   AddInstTable(InstTable, "JRL", 0x1b, DecodeJRL_CALR);
  1343.   AddInstTable(InstTable, "CALR", 0x1d, DecodeJRL_CALR);
  1344.  
  1345.   AddFixed("EXX" , 0x0a); AddFixed("CCF" , 0x0e);
  1346.   AddFixed("SCF" , 0x0d); AddFixed("RCF" , 0x0c);
  1347.   AddFixed("NOP" , 0x00); AddFixed("HALT", 0x01);
  1348.   AddFixed("DI"  , 0x02); AddFixed("EI"  , 0x03);
  1349.   AddFixed("SWI" , 0xff); AddFixed("RLCA", 0xa0);
  1350.   AddFixed("RRCA", 0xa1); AddFixed("RLA" , 0xa2);
  1351.   AddFixed("RRA" , 0xa3); AddFixed("SLAA", 0xa4);
  1352.   AddFixed("SRAA", 0xa5); AddFixed("SLLA", 0xa6);
  1353.   AddFixed("SRLA", 0xa7); AddFixed("RETI", 0x1f);
  1354.  
  1355.   AddMove("LDI" , 0x58);
  1356.   AddMove("LDIR", 0x59);
  1357.   AddMove("LDD" , 0x5a);
  1358.   AddMove("LDDR", 0x5b);
  1359.   AddMove("CPI" , 0x5c);
  1360.   AddMove("CPIR", 0x5d);
  1361.   AddMove("CPD" , 0x5e);
  1362.   AddMove("CPDR", 0x5f);
  1363.  
  1364.   AddShift("RLC", 0xa0, True );
  1365.   AddShift("RRC", 0xa1, True );
  1366.   AddShift("RL" , 0xa2, True );
  1367.   AddShift("RR" , 0xa3, True );
  1368.   AddShift("SLA", 0xa4, True );
  1369.   AddShift("SRA", 0xa5, True );
  1370.   AddShift("SLL", 0xa6, True );
  1371.   AddShift("SRL", 0xa7, True );
  1372.   AddShift("RLD", 0x10, False);
  1373.   AddShift("RRD", 0x11, False);
  1374.  
  1375.   AddBit("BIT" , 0xa8);
  1376.   AddBit("SET" , 0xb8);
  1377.   AddBit("RES" , 0xb0);
  1378.   AddBit("TSET", 0x18);
  1379.  
  1380.   AddAcc("DAA", 0x0b);
  1381.   AddAcc("CPL", 0x10);
  1382.   AddAcc("NEG", 0x11);
  1383.  
  1384.   InstrZ = 0;
  1385.   AddInstTable(InstTable, "ADD", InstrZ++, DecodeALU2);
  1386.   AddInstTable(InstTable, "ADC", InstrZ++, DecodeALU2);
  1387.   AddInstTable(InstTable, "SUB", InstrZ++, DecodeALU2);
  1388.   AddInstTable(InstTable, "SBC", InstrZ++, DecodeALU2);
  1389.   AddInstTable(InstTable, "AND", InstrZ++, DecodeALU2);
  1390.   AddInstTable(InstTable, "XOR", InstrZ++, DecodeALU2);
  1391.   AddInstTable(InstTable, "OR" , InstrZ++, DecodeALU2);
  1392.   AddInstTable(InstTable, "CP" , InstrZ++, DecodeALU2);
  1393.  
  1394.   InstrZ = 0;
  1395.   AddCondition("F"  ,  0); AddCondition("T"  , COND_CODE_TRUE);
  1396.   AddCondition("Z"  ,  6); AddCondition("NZ" , 14);
  1397.   AddCondition("C"  ,  7); AddCondition("NC" , 15);
  1398.   AddCondition("PL" , 13); AddCondition("MI" ,  5);
  1399.   AddCondition("P"  , 13); AddCondition("M"  ,  5);
  1400.   AddCondition("NE" , 14); AddCondition("EQ" ,  6);
  1401.   AddCondition("OV" ,  4); AddCondition("NOV", 12);
  1402.   AddCondition("PE" ,  4); AddCondition("PO" , 12);
  1403.   AddCondition("GE" ,  9); AddCondition("LT" ,  1);
  1404.   AddCondition("GT" , 10); AddCondition("LE" ,  2);
  1405.   AddCondition("UGE", 15); AddCondition("ULT",  7);
  1406.   AddCondition("UGT", 11); AddCondition("ULE",  3);
  1407.   AddCondition(NULL ,  0);
  1408.  
  1409.   AddIntelPseudo(InstTable, eIntPseudoFlag_LittleEndian);
  1410. }
  1411.  
  1412. static void DeinitFields(void)
  1413. {
  1414.   DestroyInstTable(InstTable);
  1415.  
  1416.   order_array_free(Conditions);
  1417. }
  1418.  
  1419. static void MakeCode_90C141(void)
  1420. {
  1421.   OpSize = eSymbolSizeUnknown;
  1422.  
  1423.   if (!LookupInstTable(InstTable, OpPart.str.p_str))
  1424.     WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
  1425. }
  1426.  
  1427. /*-------------------------------------------------------------------------*/
  1428.  
  1429. static Boolean IsDef_90C141(void)
  1430. {
  1431.   return False;
  1432. }
  1433.  
  1434. static void SwitchFrom_90C141(void)
  1435. {
  1436.   DeinitFields();
  1437. }
  1438.  
  1439. static Boolean ChkMoreOneArg(void)
  1440. {
  1441.   return (ArgCnt > 1);
  1442. }
  1443.  
  1444. static void SwitchTo_90C141(void)
  1445. {
  1446.   TurnWords = False;
  1447.   SetIntConstMode(eIntConstModeIntel);
  1448.   SetIsOccupiedFnc = ChkMoreOneArg;
  1449.  
  1450.   PCSymbol = "$";
  1451.   HeaderID = 0x53;
  1452.   NOPCode = 0x00;
  1453.   DivideChars = ",";
  1454.   HasAttrs = False;
  1455.  
  1456.   ValidSegs = 1 << SegCode;
  1457.   Grans[SegCode] = 1;
  1458.   ListGrans[SegCode] = 1;
  1459.   SegInits[SegCode] = 0;
  1460.   SegLimits[SegCode] = 0xffff;
  1461.  
  1462.   MakeCode = MakeCode_90C141;
  1463.   IsDef = IsDef_90C141;
  1464.   SwitchFrom = SwitchFrom_90C141;
  1465.   InitFields();
  1466. }
  1467.  
  1468. void code90c141_init(void)
  1469. {
  1470.   CPU90C141 = AddCPU("90C141", SwitchTo_90C141);
  1471. }
  1472.