Subversion Repositories pentevo

Rev

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

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