Subversion Repositories pentevo

Rev

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

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