Subversion Repositories pentevo

Rev

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

  1. /* codest9.c */
  2. /*****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
  4. /*                                                                           */
  5. /* AS-Portierung                                                             */
  6. /*                                                                           */
  7. /* Codegenerator SGS-Thomson ST9                                             */
  8. /*                                                                           */
  9. /*****************************************************************************/
  10.  
  11. #include "stdinc.h"
  12. #include <ctype.h>
  13. #include <string.h>
  14.  
  15. #include "bpemu.h"
  16. #include "strutil.h"
  17. #include "asmdef.h"
  18. #include "asmsub.h"
  19. #include "asmpars.h"
  20. #include "asmitree.h"
  21. #include "codepseudo.h"
  22. #include "intpseudo.h"
  23. #include "codevars.h"
  24. #include "errmsg.h"
  25.  
  26. #include "codest9.h"
  27.  
  28. typedef struct
  29. {
  30.   char *Name;
  31.   Word Code;
  32. } FixedOrder;
  33.  
  34.  
  35. #define WorkOfs 0xd0
  36.  
  37. #define ModNone (-1)
  38. #define ModReg 0
  39. #define MModReg (1l << ModReg)                  /* Rn */
  40. #define ModWReg 1
  41. #define MModWReg (1l << ModWReg)                /* rn */
  42. #define ModRReg 2
  43. #define MModRReg (1l << ModRReg)                /* RRn */
  44. #define ModWRReg 3
  45. #define MModWRReg (1l << ModWRReg)              /* rrn */
  46. #define ModIReg 4
  47. #define MModIReg (1l << ModIReg)                /* (Rn) */
  48. #define ModIWReg 5
  49. #define MModIWReg (1l << ModIWReg)              /* (rn) */
  50. #define ModIRReg 6
  51. #define MModIRReg (1l << ModIRReg)              /* (RRn) */
  52. #define ModIWRReg 7
  53. #define MModIWRReg (1l << ModIWRReg)            /* (rrn) */
  54. #define ModIncWReg 8
  55. #define MModIncWReg (1l << ModIncWReg)          /* (rn)+ */
  56. #define ModIncWRReg 9
  57. #define MModIncWRReg (1l << ModIncWRReg)        /* (rrn)+ */
  58. #define ModDecWRReg 10
  59. #define MModDecWRReg (1l << ModDecWRReg)        /* -(rrn) */
  60. #define ModDisp8WReg 11
  61. #define MModDisp8WReg (1l << ModDisp8WReg)      /* d8(rn) */
  62. #define ModDisp8WRReg 12
  63. #define MModDisp8WRReg (1l << ModDisp8WRReg)    /* d8(rrn) */
  64. #define ModDisp16WRReg 13
  65. #define MModDisp16WRReg (1l << ModDisp16WRReg)  /* d16(rrn) */
  66. #define ModDispRWRReg 14
  67. #define MModDispRWRReg (1l << ModDispRWRReg)    /* rrm(rrn */
  68. #define ModAbs 15
  69. #define MModAbs (1l << ModAbs)                  /* NN */
  70. #define ModImm 16
  71. #define MModImm (1l << ModImm)                  /* #N/#NN */
  72. #define ModDisp8RReg 17
  73. #define MModDisp8RReg (1l << ModDisp8RReg)      /* d8(RRn) */
  74. #define ModDisp16RReg 18
  75. #define MModDisp16RReg (1l << ModDisp16RReg)    /* d16(RRn) */
  76.  
  77.  
  78. static CPUVar CPUST9020,CPUST9030,CPUST9040,CPUST9050;
  79.  
  80. static ShortInt AdrMode,AbsSeg;
  81. static Byte AdrPart,OpSize;
  82. static Byte AdrVals[3];
  83.  
  84. static LongInt DPAssume;
  85.  
  86. #define ASSUMEST9Count 1
  87. static ASSUMERec ASSUMEST9s[ASSUMEST9Count] =
  88. {
  89.   {"DP", &DPAssume, 0,  1, 0x0, NULL}
  90. };
  91.  
  92. /*--------------------------------------------------------------------------*/
  93. /* helper functions */
  94.  
  95. static Boolean DecodeReg(char *Asc_O, Byte *Erg, Byte *Size)
  96. {
  97.   Boolean Res;
  98.   char *Asc;
  99.  
  100.   *Size = 0;
  101.   Asc=Asc_O;
  102.  
  103.   if (strlen(Asc) < 2) return False;
  104.   if (*Asc != 'r')
  105.     return False;
  106.   Asc++;
  107.   if (*Asc == 'r')
  108.   {
  109.     if (strlen(Asc) < 2) return False;
  110.     *Size = 1; Asc++;
  111.   }
  112.   else
  113.     *Size = 0;
  114.  
  115.   *Erg = ConstLongInt(Asc, &Res, 10);
  116.   if ((!Res) || (*Erg > 15)) return False;
  117.   if ((*Size == 1) && (Odd(*Erg))) return False;
  118.  
  119.   return True;
  120. }
  121.  
  122. static LargeInt eval_outer_disp(const tStrComp *p_arg, IntType type, Boolean *p_ok)
  123. {
  124.   if (p_arg->str.p_str[0])
  125.     return EvalStrIntExpression(p_arg, type, p_ok);
  126.   else
  127.   {
  128.     *p_ok = True;
  129.     return 0;
  130.   }
  131. }
  132.  
  133. static void DecodeAdr(tStrComp *pArg, LongWord Mask)
  134. {
  135.   Word AdrWord;
  136.   int level;
  137.   Byte flg, Size;
  138.   Boolean OK, IsIndirect;
  139.   tEvalResult EvalResult;
  140.   char *p;
  141.   int l;
  142.  
  143.   AdrMode = ModNone; AdrCnt = 0;
  144.  
  145.   /* immediate */
  146.  
  147.   if (*pArg->str.p_str == '#')
  148.   {
  149.     switch (OpSize)
  150.     {
  151.       case 0:
  152.         AdrVals[0] = EvalStrIntExpressionOffs(pArg, 1, Int8, &OK);
  153.         break;
  154.       case 1:
  155.         AdrWord = EvalStrIntExpressionOffs(pArg, 1, Int16, &OK);
  156.         AdrVals[0] = Hi(AdrWord);
  157.         AdrVals[1] = Lo(AdrWord);
  158.         break;
  159.     }
  160.     if (OK)
  161.     {
  162.       AdrMode = ModImm;
  163.       AdrCnt = OpSize + 1;
  164.     }
  165.     goto func_exit;
  166.   }
  167.  
  168.   /* Arbeitsregister */
  169.  
  170.   if (DecodeReg(pArg->str.p_str, &AdrPart, &Size))
  171.   {
  172.     if (Size == 0)
  173.     {
  174.       if (Mask & MModWReg) AdrMode = ModWReg;
  175.       else
  176.       {
  177.         AdrVals[0] = WorkOfs + AdrPart;
  178.         AdrCnt = 1;
  179.         AdrMode = ModReg;
  180.       }
  181.     }
  182.     else
  183.     {
  184.       if (Mask & MModWRReg) AdrMode = ModWRReg;
  185.       else
  186.       {
  187.         AdrVals[0] = WorkOfs + AdrPart;
  188.         AdrCnt = 1;
  189.         AdrMode = ModRReg;
  190.       }
  191.     }
  192.     goto func_exit;
  193.   }
  194.  
  195.   l = strlen(pArg->str.p_str);
  196.  
  197.   /* Postinkrement */
  198.  
  199.   if ((l > 0) && (pArg->str.p_str[l - 1] == '+'))
  200.   {
  201.     if ((l < 3) || (*pArg->str.p_str != '(') || (pArg->str.p_str[l - 2] != ')')) WrError(ErrNum_InvAddrMode);
  202.     else
  203.     {
  204.       tStrComp RegComp;
  205.  
  206.       pArg->str.p_str[l - 2] = '\0'; pArg->Pos.Len -= 2;
  207.       StrCompRefRight(&RegComp, pArg, 1);
  208.       if (!DecodeReg(RegComp.str.p_str, &AdrPart, &Size)) WrStrErrorPos(ErrNum_InvReg, &RegComp);
  209.       AdrMode = (Size == 0) ? ModIncWReg : ModIncWRReg;
  210.     }
  211.     goto func_exit;
  212.   }
  213.  
  214.   /* Predekrement */
  215.  
  216.   if ((*pArg->str.p_str == '-') && (pArg->str.p_str[1] == '(') && (pArg->str.p_str[l - 1] == ')'))
  217.   {
  218.     tStrComp RegComp;
  219.  
  220.     pArg->str.p_str[l - 1] = '\0';  pArg->Pos.Len--;
  221.     StrCompRefRight(&RegComp, pArg, 2);
  222.     if (DecodeReg(RegComp.str.p_str, &AdrPart, &Size))
  223.     {
  224.       if (Size == 0) WrError(ErrNum_InvAddrMode); else AdrMode = ModDecWRReg;
  225.       goto func_exit;
  226.     }
  227.   }
  228.  
  229.   /* indirekt<->direkt */
  230.  
  231.   if ((l < 3) || (pArg->str.p_str[l - 1] != ')'))
  232.   {
  233.     IsIndirect = False; p = pArg->str.p_str;
  234.   }
  235.   else
  236.   {
  237.     level = 0; p = pArg->str.p_str + l - 2; flg = 0;
  238.     while ((p >= pArg->str.p_str) && (level >= 0))
  239.     {
  240.       switch (*p)
  241.       {
  242.         case '(': if (flg == 0) level--; break;
  243.         case ')': if (flg == 0) level++; break;
  244.         case '\'': if ((!(flg & 2))) flg ^= 1; break;
  245.         case '"': if ((!(flg & 1))) flg ^= 2; break;
  246.       }
  247.       p--;
  248.     }
  249.     IsIndirect = (level == -1) && ((p < pArg->str.p_str) || ((*p == '.') || (*p == '_') || (isdigit(((unsigned int)*p) & 0xff)) || (isalpha(((unsigned int)*p) & 0xff))));
  250.   }
  251.  
  252.   /* indirekt */
  253.  
  254.   if (IsIndirect)
  255.   {
  256.     tStrComp RegComp;
  257.  
  258.     /* discard closing ) at end */
  259.  
  260.     pArg->str.p_str[--l] = '\0'; pArg->Pos.Len--;
  261.  
  262.     /* split off part in () */
  263.  
  264.     StrCompRefRight(&RegComp, pArg, p + 2 - pArg->str.p_str);
  265.  
  266.     /* truncate arg to everything before ( */
  267.  
  268.     p[1] = '\0';
  269.     pArg->Pos.Len = p + 1 - pArg->str.p_str;
  270.     if (DecodeReg(RegComp.str.p_str, &AdrPart, &Size))
  271.     {
  272.       if (Size == 0)   /* d(r) */
  273.       {
  274.         AdrVals[0] = eval_outer_disp(pArg, Int8, &OK);
  275.         if (OK)
  276.         {
  277.           if ((Mask & MModIWReg) && (AdrVals[0] == 0)) AdrMode = ModIWReg;
  278.           else if (((Mask & MModIReg) != 0) && (AdrVals[0] == 0))
  279.           {
  280.             AdrVals[0] = WorkOfs + AdrPart; AdrMode = ModIReg; AdrCnt = 1;
  281.           }
  282.           else
  283.           {
  284.             AdrMode = ModDisp8WReg; AdrCnt = 1;
  285.           }
  286.         }
  287.       }
  288.       else            /* ...(rr) */
  289.       {
  290.         if (DecodeReg(pArg->str.p_str, AdrVals, &Size))
  291.         {             /* rr(rr) */
  292.           if (Size != 1) WrError(ErrNum_InvAddrMode);
  293.           else
  294.           {
  295.             AdrMode = ModDispRWRReg; AdrCnt = 1;
  296.           }
  297.         }
  298.         else
  299.         {             /* d(rr) */
  300.           AdrWord = eval_outer_disp(pArg, Int16, &OK);
  301.           if ((AdrWord == 0) && (Mask & (MModIRReg | MModIWRReg)))
  302.           {
  303.             if (Mask & MModIWRReg) AdrMode = ModIWRReg;
  304.             else
  305.             {
  306.               AdrMode = ModIRReg; AdrVals[0] = AdrPart + WorkOfs; AdrCnt = 1;
  307.             }
  308.           }
  309.           else if ((AdrWord < 0x100) && (Mask & (MModDisp8WRReg | MModDisp8RReg)))
  310.           {
  311.             if (Mask & MModDisp8WRReg)
  312.             {
  313.               AdrVals[0] = Lo(AdrWord); AdrCnt = 1; AdrMode = ModDisp8WRReg;
  314.             }
  315.             else
  316.             {
  317.               AdrVals[0] = AdrPart + WorkOfs;
  318.               AdrVals[1] = Lo(AdrWord);
  319.               AdrCnt = 2;
  320.               AdrMode = ModDisp8RReg;
  321.             }
  322.           }
  323.           else if (Mask & MModDisp16WRReg)
  324.           {
  325.             AdrVals[0] = Hi(AdrWord);
  326.             AdrVals[1] = Lo(AdrWord);
  327.             AdrCnt = 2;
  328.             AdrMode = ModDisp16WRReg;
  329.           }
  330.           else
  331.           {
  332.             AdrVals[0] = AdrPart + WorkOfs;
  333.             AdrVals[2] = Hi(AdrWord);
  334.             AdrVals[1] = Lo(AdrWord);
  335.             AdrCnt = 3;
  336.             AdrMode = ModDisp16RReg;
  337.           }
  338.         }
  339.       }
  340.     }
  341.     else             /* ...(RR) */
  342.     {
  343.       AdrWord = EvalStrIntExpressionWithResult(&RegComp, UInt9, &EvalResult);
  344.       if (!(EvalResult.AddrSpaceMask & (1 << SegReg)))  WrError(ErrNum_InvAddrMode);
  345.       else if (AdrWord < 0xff)
  346.       {
  347.         AdrVals[0] = Lo(AdrWord);
  348.         AdrWord = eval_outer_disp(pArg, Int8, &OK);
  349.         if (AdrWord != 0) WrError(ErrNum_OverRange);
  350.         else
  351.         {
  352.           AdrCnt = 1; AdrMode = ModIReg;
  353.         }
  354.       }
  355.       else if ((AdrWord > 0x1ff) || (Odd(AdrWord))) WrError(ErrNum_InvAddrMode);
  356.       else
  357.       {
  358.         AdrVals[0] = Lo(AdrWord);
  359.         AdrWord = eval_outer_disp(pArg, Int16, &OK);
  360.         if ((AdrWord == 0) && (Mask & MModIRReg))
  361.         {
  362.           AdrCnt = 1; AdrMode = ModIRReg;
  363.         }
  364.         else if ((AdrWord < 0x100) && (Mask & MModDisp8RReg))
  365.         {
  366.           AdrVals[1] = Lo(AdrWord); AdrCnt = 2; AdrMode = ModDisp8RReg;
  367.         }
  368.         else
  369.         {
  370.           AdrVals[2] = Hi(AdrWord);
  371.           AdrVals[1] = Lo(AdrWord);
  372.           AdrCnt = 3;
  373.           AdrMode = ModDisp16RReg;
  374.         }
  375.       }
  376.     }
  377.     goto func_exit;
  378.   }
  379.  
  380.   /* direkt */
  381.  
  382.   AdrWord = EvalStrIntExpressionWithResult(pArg, UInt16, &EvalResult);
  383.   if (EvalResult.OK)
  384.   {
  385.     if (!(EvalResult.AddrSpaceMask & (1 << SegReg)))
  386.     {
  387.       AdrMode = ModAbs;
  388.       AdrVals[0] = Hi(AdrWord);
  389.       AdrVals[1] = Lo(AdrWord);
  390.       AdrCnt = 2;
  391.       ChkSpace(AbsSeg, EvalResult.AddrSpaceMask);
  392.     }
  393.     else if (AdrWord < 0xff)
  394.     {
  395.       AdrMode = ModReg;
  396.       AdrVals[0] = Lo(AdrWord);
  397.       AdrCnt = 1;
  398.     }
  399.     else if ((AdrWord > 0x1ff) || (Odd(AdrWord))) WrError(ErrNum_InvAddrMode);
  400.     else
  401.     {
  402.       AdrMode = ModRReg;
  403.       AdrVals[0] = Lo(AdrWord);
  404.       AdrCnt = 1;
  405.     }
  406.   }
  407.  
  408. func_exit:
  409.   if ((AdrMode != ModNone) && (((1l << AdrMode) & Mask) == 0))
  410.   {
  411.     WrError(ErrNum_InvAddrMode); AdrMode = ModNone; AdrCnt = 0;
  412.   }
  413. }
  414.  
  415. static Boolean SplitBit(tStrComp *pDest, const tStrComp *pSrc, Byte *pErg)
  416. {
  417.   char *p;
  418.   Boolean OK;
  419.   Byte Inv = 0;
  420.  
  421.   StrCompRefRight(pDest, pSrc, 0);
  422.   p = RQuotPos(pDest->str.p_str, '.');
  423.   if ((!p) || (p == pDest->str.p_str + strlen(pDest->str.p_str) + 1))
  424.   {
  425.     Integer val;
  426.  
  427.     if (*pDest->str.p_str == '!')
  428.     {
  429.       Inv = 1;
  430.       pDest->str.p_str++;
  431.       pDest->Pos.StartCol++;
  432.       pDest->Pos.Len--;
  433.     }
  434.     val = EvalStrIntExpression(pDest, UInt8, &OK);
  435.     if (OK)
  436.     {
  437.       *pErg = (val & 15) ^ Inv;
  438.       as_snprintf(pDest->str.p_str, STRINGSIZE, "r%d", (int)(val >> 4));
  439.       return True;
  440.     }
  441.     return False;
  442.   }
  443.  
  444.   Inv = !!(p[1] == '!');
  445.   *pErg = Inv + (EvalStrIntExpressionOffs(pSrc, p + 1 + Inv - pSrc->str.p_str, UInt3, &OK) << 1);
  446.   *p = '\0';
  447.   return OK;
  448. }
  449.  
  450. /*--------------------------------------------------------------------------*/
  451. /* Instruction Decoders */
  452.  
  453. static void DecodeFixed(Word Code)
  454. {
  455.   if (ChkArgCnt(0, 0))
  456.   {
  457.     if (Hi(Code))
  458.       BAsmCode[CodeLen++] = Hi(Code);
  459.     BAsmCode[CodeLen++] = Lo(Code);
  460.   }
  461. }
  462.  
  463. static void DecodeLD(Word IsLDW)
  464. {
  465.   Byte HReg, HPart;
  466.   Word Mask1, Mask2;
  467.  
  468.   if (ChkArgCnt(2, 2))
  469.   {
  470.     if (IsLDW)
  471.     {
  472.       OpSize = 1; Mask1 = MModWRReg; Mask2 = MModRReg;
  473.     }
  474.     else
  475.     {
  476.       Mask1 = MModWReg; Mask2 = MModReg;
  477.     }
  478.     DecodeAdr(&ArgStr[1], Mask1 | Mask2 | MModIWReg | MModDisp8WReg | MModIncWReg |
  479.                          MModIWRReg | MModIncWRReg | MModDecWRReg | MModDisp8WRReg |
  480.                          MModDisp16WRReg | MModDispRWRReg | MModAbs | MModIRReg);
  481.     switch (AdrMode)
  482.     {
  483.       case ModWReg:
  484.       case ModWRReg:
  485.         HReg = AdrPart;
  486.         DecodeAdr(&ArgStr[2], Mask1 | Mask2 | MModIWReg | MModDisp8WReg | MModIWRReg |
  487.                              MModIncWRReg | MModDecWRReg | MModDispRWRReg | MModDisp8WRReg |
  488.                              MModDisp16WRReg | MModAbs | MModImm);
  489.         switch (AdrMode)
  490.         {
  491.           case ModWReg:
  492.             BAsmCode[0] = (HReg << 4) + 8;
  493.             BAsmCode[1] = WorkOfs + AdrPart;
  494.             CodeLen = 2;
  495.             break;
  496.           case ModWRReg:
  497.             BAsmCode[0] = 0xe3;
  498.             BAsmCode[1] = (HReg << 4) + AdrPart;
  499.             CodeLen = 2;
  500.             break;
  501.           case ModReg:
  502.             BAsmCode[0] = (HReg << 4) + 8;
  503.             BAsmCode[1] = AdrVals[0];
  504.             CodeLen = 2;
  505.             break;
  506.           case ModRReg:
  507.             BAsmCode[0] = 0xef;
  508.             BAsmCode[1] = AdrVals[0];
  509.             BAsmCode[2] = HReg + WorkOfs;
  510.             CodeLen = 3;
  511.             break;
  512.           case ModIWReg:
  513.             if (OpSize == 0)
  514.             {
  515.               BAsmCode[0] = 0xe4;
  516.               BAsmCode[1] = (HReg << 4) + AdrPart;
  517.               CodeLen = 2;
  518.             }
  519.             else
  520.             {
  521.               BAsmCode[0] = 0xa6;
  522.               BAsmCode[1] = 0xf0 + AdrPart;
  523.               BAsmCode[2] = WorkOfs + HReg;
  524.               CodeLen = 3;
  525.             }
  526.             break;
  527.           case ModDisp8WReg:
  528.             BAsmCode[0] = 0xb3 + (OpSize * 0x2b);
  529.             BAsmCode[1] = (HReg << 4) + AdrPart;
  530.             BAsmCode[2] = AdrVals[0];
  531.             CodeLen = 3;
  532.             break;
  533.           case ModIWRReg:
  534.             BAsmCode[0] = 0xb5 + (OpSize * 0x2e);
  535.             BAsmCode[1] = (HReg << 4) + AdrPart + OpSize;
  536.             CodeLen = 2;
  537.             break;
  538.           case ModIncWRReg:
  539.             BAsmCode[0] = 0xb4 + (OpSize * 0x21);
  540.             BAsmCode[1] = 0xf1 + AdrPart;
  541.             BAsmCode[2] = WorkOfs + HReg;
  542.             CodeLen = 3;
  543.             break;
  544.           case ModDecWRReg:
  545.             BAsmCode[0] = 0xc2 + OpSize;
  546.             BAsmCode[1] = 0xf1 + AdrPart;
  547.             BAsmCode[2] = WorkOfs + HReg;
  548.             CodeLen = 3;
  549.             break;
  550.           case ModDispRWRReg:
  551.             BAsmCode[0] = 0x60;
  552.             BAsmCode[1] = (0x10 * (1 - OpSize)) + (AdrVals[0] << 4) + AdrPart;
  553.             BAsmCode[2] = 0xf0 + HReg;
  554.             CodeLen = 3;
  555.             break;
  556.           case ModDisp8WRReg:
  557.             BAsmCode[0] = 0x7f + (OpSize * 7);
  558.             BAsmCode[1] = 0xf1 + AdrPart;
  559.             BAsmCode[2] = AdrVals[0];
  560.             BAsmCode[3] = HReg + WorkOfs;
  561.             CodeLen = 4;
  562.             break;
  563.           case ModDisp16WRReg:
  564.             BAsmCode[0] = 0x7f + (OpSize * 7);
  565.             BAsmCode[1] = 0xf0 + AdrPart;
  566.             memcpy(BAsmCode + 2, AdrVals, AdrCnt);
  567.             BAsmCode[2 + AdrCnt] = HReg + WorkOfs;
  568.             CodeLen = 3 + AdrCnt;
  569.             break;
  570.           case ModAbs:
  571.             BAsmCode[0] = 0xc4 + (OpSize * 0x1e);
  572.             BAsmCode[1] = 0xf0 + AdrPart;
  573.             memcpy(BAsmCode + 2, AdrVals, AdrCnt);
  574.             CodeLen = 2 + AdrCnt;
  575.             break;
  576.           case ModImm:
  577.             if (OpSize == 0)
  578.             {
  579.               BAsmCode[0] = (HReg << 4) + 0x0c;
  580.               memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  581.               CodeLen = 1 + AdrCnt;
  582.             }
  583.             else
  584.             {
  585.               BAsmCode[0] = 0xbf;
  586.               BAsmCode[1] = WorkOfs + HReg;
  587.               memcpy(BAsmCode + 2, AdrVals, AdrCnt);
  588.               CodeLen = 2 + AdrCnt;
  589.             }
  590.             break;
  591.         }
  592.         break;
  593.       case ModReg:
  594.       case ModRReg:
  595.         HReg = AdrVals[0];
  596.         DecodeAdr(&ArgStr[2], Mask1 | Mask2 | MModIWReg | MModIWRReg | MModIncWRReg |
  597.                              MModDecWRReg | MModDispRWRReg | MModDisp8WRReg | MModDisp16WRReg |
  598.                              MModImm);
  599.         switch (AdrMode)
  600.         {
  601.           case ModWReg:
  602.             BAsmCode[0] = (AdrPart << 4) + 0x09;
  603.             BAsmCode[1] = HReg;
  604.             CodeLen = 2;
  605.             break;
  606.           case ModWRReg:
  607.             BAsmCode[0] = 0xef;
  608.             BAsmCode[1] = WorkOfs + AdrPart;
  609.             BAsmCode[2] = HReg;
  610.             CodeLen = 3;
  611.             break;
  612.           case ModReg:
  613.           case ModRReg:
  614.             BAsmCode[0] = 0xf4 - (OpSize * 5);
  615.             BAsmCode[1] = AdrVals[0];
  616.             BAsmCode[2] = HReg;
  617.             CodeLen = 3;
  618.             break;
  619.           case ModIWReg:
  620.             BAsmCode[0] = 0xe7 - (0x41 * OpSize);
  621.             BAsmCode[1] = 0xf0 + AdrPart;
  622.             BAsmCode[2] = HReg;
  623.             CodeLen = 3;
  624.             break;
  625.           case ModIWRReg:
  626.             BAsmCode[0] = 0x72 + (OpSize * 12);
  627.             BAsmCode[1] = 0xf1 + AdrPart - OpSize;
  628.             BAsmCode[2] = HReg;
  629.             CodeLen = 3;
  630.             break;
  631.           case ModIncWRReg:
  632.             BAsmCode[0] = 0xb4 + (0x21 * OpSize);
  633.             BAsmCode[1] = 0xf1 + AdrPart;
  634.             BAsmCode[2] = HReg;
  635.             CodeLen = 3;
  636.             break;
  637.           case ModDecWRReg:
  638.             BAsmCode[0] = 0xc2 + OpSize;
  639.             BAsmCode[1] = 0xf1 + AdrPart;
  640.             BAsmCode[2] = HReg;
  641.             CodeLen = 3;
  642.             break;
  643.           case ModDisp8WRReg:
  644.             BAsmCode[0] = 0x7f + (OpSize * 7);
  645.             BAsmCode[1] = 0xf1 + AdrPart;
  646.             BAsmCode[2] = AdrVals[0];
  647.             BAsmCode[3] = HReg;
  648.             CodeLen = 4;
  649.             break;
  650.           case ModDisp16WRReg:
  651.             BAsmCode[0] = 0x7f + (OpSize * 7);
  652.             BAsmCode[1] = 0xf0 + AdrPart;
  653.             memcpy(BAsmCode + 2, AdrVals, AdrCnt);
  654.             BAsmCode[2 + AdrCnt] = HReg;
  655.             CodeLen = 3 + AdrCnt;
  656.             break;
  657.           case ModImm:
  658.             BAsmCode[0] = 0xf5 - (OpSize * 0x36);
  659.             BAsmCode[1] = HReg;
  660.             memcpy(BAsmCode + 2, AdrVals, 2);
  661.             CodeLen = 2 + AdrCnt;
  662.             break;
  663.         }
  664.         break;
  665.       case ModIWReg:
  666.         HReg = AdrPart;
  667.         DecodeAdr(&ArgStr[2], Mask2 | Mask1);
  668.         switch (AdrMode)
  669.         {
  670.           case ModWReg:
  671.             BAsmCode[0] = 0xe5;
  672.             BAsmCode[1] = (HReg << 4) + AdrPart;
  673.             CodeLen = 2;
  674.             break;
  675.           case ModWRReg:
  676.             BAsmCode[0] = 0x96;
  677.             BAsmCode[1] = WorkOfs + AdrPart;
  678.             BAsmCode[2] = 0xf0 + HReg;
  679.             CodeLen = 3;
  680.             break;
  681.           case ModReg:
  682.           case ModRReg:
  683.             BAsmCode[0] = 0xe6 - (0x50 * OpSize);
  684.             BAsmCode[1] = AdrVals[0];
  685.             BAsmCode[2] = 0xf0 + HReg;
  686.             CodeLen = 3;
  687.             break;
  688.         }
  689.         break;
  690.       case ModDisp8WReg:
  691.         BAsmCode[2] = AdrVals[0]; HReg = AdrPart;
  692.         DecodeAdr(&ArgStr[2], Mask1);
  693.         switch (AdrMode)
  694.         {
  695.           case ModWReg:
  696.           case ModWRReg:
  697.             BAsmCode[0] = 0xb2 + (OpSize * 0x2c);
  698.             BAsmCode[1] = (AdrPart << 4) + (OpSize << 4) + HReg;
  699.             CodeLen = 3;
  700.             break;
  701.         }
  702.         break;
  703.       case ModIncWReg:
  704.         HReg = AdrPart;
  705.         DecodeAdr(&ArgStr[2], MModIncWRReg * (1 - OpSize));
  706.         switch (AdrMode)
  707.         {
  708.           case ModIncWRReg:
  709.             BAsmCode[0] = 0xd7;
  710.             BAsmCode[1] = (HReg << 4) + AdrPart + 1;
  711.             CodeLen = 2;
  712.             break;
  713.         }
  714.         break;
  715.       case ModIWRReg:
  716.         HReg = AdrPart;
  717.         DecodeAdr(&ArgStr[2], (MModIWReg * (1 - OpSize)) | Mask1 | Mask2 | MModIWRReg | MModImm);
  718.         switch (AdrMode)
  719.         {
  720.           case ModIWReg:
  721.             BAsmCode[0] = 0xb5;
  722.             BAsmCode[1] = (AdrPart << 4) + HReg + 1;
  723.             CodeLen = 2;
  724.             break;
  725.           case ModWReg:
  726.             BAsmCode[0] = 0x72;
  727.             BAsmCode[1] = 0xf0 + HReg;
  728.             BAsmCode[2] = AdrPart + WorkOfs;
  729.             CodeLen = 3;
  730.             break;
  731.           case ModWRReg:
  732.             BAsmCode[0] = 0xe3;
  733.             BAsmCode[1] = (HReg << 4) + 0x10 + AdrPart;
  734.             CodeLen = 2;
  735.             break;
  736.           case ModReg:
  737.           case ModRReg:
  738.             BAsmCode[0] = 0x72 + (OpSize * 0x4c);
  739.             BAsmCode[1] = 0xf0 + HReg + OpSize;
  740.             BAsmCode[2] = AdrVals[0];
  741.             CodeLen = 3;
  742.             break;
  743.           case ModIWRReg:
  744.             if (OpSize == 0)
  745.             {
  746.               BAsmCode[0] = 0x73;
  747.               BAsmCode[1] = 0xf0 + AdrPart;
  748.               BAsmCode[2] = WorkOfs + HReg;
  749.               CodeLen = 3;
  750.             }
  751.             else
  752.             {
  753.               BAsmCode[0] = 0xe3;
  754.               BAsmCode[1] = 0x11 + (HReg << 4) + AdrPart;
  755.               CodeLen = 2;
  756.             }
  757.             break;
  758.           case ModImm:
  759.             BAsmCode[0] = 0xf3 - (OpSize * 0x35);
  760.             BAsmCode[1] = 0xf0 + HReg;
  761.             memcpy(BAsmCode + 2, AdrVals, AdrCnt);
  762.             CodeLen = 2 + AdrCnt;
  763.             break;
  764.         }
  765.         break;
  766.       case ModIncWRReg:
  767.         HReg = AdrPart;
  768.         DecodeAdr(&ArgStr[2], Mask2 | (MModIncWReg * (1 - OpSize)));
  769.         switch (AdrMode)
  770.         {
  771.           case ModReg:
  772.           case ModRReg:
  773.             BAsmCode[0] = 0xb4 + (OpSize * 0x21);
  774.             BAsmCode[1] = 0xf0 + HReg;
  775.             BAsmCode[2] = AdrVals[0];
  776.             CodeLen = 3;
  777.             break;
  778.           case ModIncWReg:
  779.             BAsmCode[0] = 0xd7;
  780.             BAsmCode[1] = (AdrPart << 4) + HReg;
  781.             CodeLen = 2;
  782.             break;
  783.         }
  784.         break;
  785.       case ModDecWRReg:
  786.          HReg = AdrPart;
  787.          DecodeAdr(&ArgStr[2], Mask2);
  788.          switch (AdrMode)
  789.          {
  790.            case ModReg:
  791.            case ModRReg:
  792.              BAsmCode[0] = 0xc2 + OpSize;
  793.              BAsmCode[1] = 0xf0 + HReg;
  794.              BAsmCode[2] = AdrVals[0];
  795.              CodeLen = 3;
  796.              break;
  797.          }
  798.          break;
  799.       case ModDispRWRReg:
  800.         HReg = AdrPart; HPart = AdrVals[0];
  801.         DecodeAdr(&ArgStr[2], Mask1);
  802.         switch (AdrMode)
  803.         {
  804.           case ModWReg:
  805.           case ModWRReg:
  806.             BAsmCode[0] = 0x60;
  807.             BAsmCode[1] = (0x10 * (1 - OpSize)) + 0x01 + (HPart << 4) + HReg;
  808.             BAsmCode[2] = 0xf0 + AdrPart;
  809.             CodeLen = 3;
  810.             break;
  811.         }
  812.         break;
  813.       case ModDisp8WRReg:
  814.         BAsmCode[2] = AdrVals[0]; HReg = AdrPart;
  815.         DecodeAdr(&ArgStr[2], Mask2 | (OpSize * MModImm));
  816.         switch (AdrMode)
  817.         {
  818.           case ModReg:
  819.           case ModRReg:
  820.             BAsmCode[0] = 0x26 + (OpSize * 0x60);
  821.             BAsmCode[1] = 0xf1 + HReg;
  822.             BAsmCode[3] = AdrVals[0];
  823.             CodeLen = 4;
  824.             break;
  825.           case ModImm:
  826.             BAsmCode[0] = 0x06;
  827.             BAsmCode[1] = 0xf1 + HReg;
  828.             memcpy(BAsmCode + 3, AdrVals, AdrCnt);
  829.             CodeLen = 3 + AdrCnt;
  830.             break;
  831.         }
  832.         break;
  833.       case ModDisp16WRReg:
  834.         memcpy(BAsmCode + 2, AdrVals, 2); HReg = AdrPart;
  835.         DecodeAdr(&ArgStr[2], Mask2 | (OpSize * MModImm));
  836.         switch (AdrMode)
  837.         {
  838.           case ModReg:
  839.           case ModRReg:
  840.             BAsmCode[0] = 0x26 + (OpSize * 0x60);
  841.             BAsmCode[1] = 0xf0 + HReg;
  842.             BAsmCode[4] = AdrVals[0];
  843.             CodeLen = 5;
  844.             break;
  845.           case ModImm:
  846.             BAsmCode[0] = 0x06;
  847.             BAsmCode[1] = 0xf0 + HReg;
  848.             memcpy(BAsmCode + 4, AdrVals, AdrCnt);
  849.             CodeLen =4 + AdrCnt;
  850.             break;
  851.         }
  852.         break;
  853.       case ModAbs:
  854.         memcpy(BAsmCode + 2, AdrVals, 2);
  855.         DecodeAdr(&ArgStr[2], Mask1 | MModImm);
  856.         switch (AdrMode)
  857.         {
  858.           case ModWReg:
  859.           case ModWRReg:
  860.             BAsmCode[0] = 0xc5 + (OpSize * 0x1d);
  861.             BAsmCode[1] = 0xf0 + AdrPart + OpSize;
  862.             CodeLen = 4;
  863.             break;
  864.           case ModImm:
  865.             memmove(BAsmCode + 2 + AdrCnt, BAsmCode + 2, 2);
  866.             BAsmCode[0] = 0x2f + (OpSize * 7);
  867.             BAsmCode[1] = 0xf1;
  868.             memcpy(BAsmCode + 2, AdrVals, AdrCnt);
  869.             CodeLen = 4 + AdrCnt;
  870.             break;
  871.         }
  872.         break;
  873.       case ModIRReg:
  874.         HReg = AdrVals[0];
  875.         DecodeAdr(&ArgStr[2], MModIWRReg * (1 - OpSize));
  876.         switch (AdrMode)
  877.         {
  878.           case ModIWRReg:
  879.             BAsmCode[0] = 0x73;
  880.             BAsmCode[1] = 0xf0 + AdrPart;
  881.             BAsmCode[2] = HReg;
  882.             CodeLen = 3;
  883.             break;
  884.         }
  885.         break;
  886.     }
  887.   }
  888. }
  889.  
  890. static void DecodeLoad(Word Code)
  891. {
  892.   Byte HReg;
  893.  
  894.   if (ChkArgCnt(2, 2))
  895.   {
  896.     DecodeAdr(&ArgStr[1], MModIncWRReg);
  897.     if (AdrMode == ModIncWRReg)
  898.     {
  899.       HReg = AdrPart << 4;
  900.       DecodeAdr(&ArgStr[2], MModIncWRReg);
  901.       if (AdrMode == ModIncWRReg)
  902.       {
  903.         BAsmCode[0] = 0xd6;
  904.         BAsmCode[1] = Code + HReg + AdrPart;
  905.         CodeLen = 2;
  906.       }
  907.     }
  908.   }
  909. }
  910.  
  911. static void DecodePEA_PEAU(Word Code)
  912. {
  913.   if (ChkArgCnt(1, 1))
  914.   {
  915.     DecodeAdr(&ArgStr[1], MModDisp8RReg | MModDisp16RReg);
  916.     if (AdrMode != ModNone)
  917.     {
  918.       BAsmCode[0] = 0x8f;
  919.       BAsmCode[1] = Code;
  920.       memcpy(BAsmCode + 2, AdrVals, AdrCnt);
  921.       BAsmCode[2] += AdrCnt - 2;
  922.       CodeLen =2 + AdrCnt;
  923.     }
  924.   }
  925. }
  926.  
  927. static void DecodePUSH_PUSHU(Word IsU)
  928. {
  929.   if (ChkArgCnt(1, 1))
  930.   {
  931.     DecodeAdr(&ArgStr[1], MModReg | MModIReg | MModImm);
  932.     switch (AdrMode)
  933.     {
  934.       case ModReg:
  935.         BAsmCode[0] = 0x66 - (IsU * 0x36);
  936.         BAsmCode[1] = AdrVals[0];
  937.         CodeLen = 2;
  938.         break;
  939.       case ModIReg:
  940.         BAsmCode[0] = 0xf7 - (IsU * 0xc6);
  941.         BAsmCode[1] = AdrVals[0];
  942.         CodeLen = 2;
  943.         break;
  944.       case ModImm:
  945.         BAsmCode[0] = 0x8f;
  946.         BAsmCode[1] = 0xf1 + (IsU * 2);
  947.         BAsmCode[2] = AdrVals[0];
  948.         CodeLen = 3;
  949.         break;
  950.     }
  951.   }
  952. }
  953.  
  954. static void DecodePUSHW_PUSHUW(Word IsU)
  955. {
  956.   OpSize = 1;
  957.   if (ChkArgCnt(1, 1))
  958.   {
  959.     DecodeAdr(&ArgStr[1], MModRReg | MModImm);
  960.     switch (AdrMode)
  961.     {
  962.       case ModRReg:
  963.         BAsmCode[0] = 0x74 + (IsU * 0x42);
  964.         BAsmCode[1] = AdrVals[0];
  965.         CodeLen = 2;
  966.         break;
  967.       case ModImm:
  968.         BAsmCode[0] = 0x8f;
  969.         BAsmCode[1] = 0xc1 + (IsU * 2);
  970.         memcpy(BAsmCode + 2, AdrVals, AdrCnt);
  971.         CodeLen = 2 + AdrCnt;
  972.         break;
  973.     }
  974.   }
  975. }
  976.  
  977. static void DecodeXCH(Word Code)
  978. {
  979.   UNUSED(Code);
  980.  
  981.   if (ChkArgCnt(2, 2))
  982.   {
  983.     DecodeAdr(&ArgStr[1], MModReg);
  984.     if (AdrMode == ModReg)
  985.     {
  986.       BAsmCode[2] = AdrVals[0];
  987.       DecodeAdr(&ArgStr[2], MModReg);
  988.       if (AdrMode == ModReg)
  989.       {
  990.         BAsmCode[1] = AdrVals[0];
  991.         BAsmCode[0] = 0x16;
  992.         CodeLen = 3;
  993.       }
  994.     }
  995.   }
  996. }
  997.  
  998. static void DecodeALU(Word Code)
  999. {
  1000.   Word Mask1, Mask2;
  1001.   Byte HReg, HPart;
  1002.   Byte CodeMask = Lo(Code) << 4;
  1003.  
  1004.   if (ChkArgCnt(2, 2))
  1005.   {
  1006.     if (Hi(Code))
  1007.     {
  1008.       OpSize = 1; Mask1 = MModWRReg; Mask2 = MModRReg;
  1009.     }
  1010.     else
  1011.     {
  1012.       Mask1 = MModWReg; Mask2 = MModReg;
  1013.     }
  1014.     DecodeAdr(&ArgStr[1], Mask1 | Mask2 | MModIWReg | MModIWRReg | MModIncWRReg |
  1015.                          MModDecWRReg | MModDispRWRReg | MModDisp8WRReg | MModDisp16WRReg |
  1016.                          MModAbs | MModIRReg);
  1017.     switch (AdrMode)
  1018.     {
  1019.       case ModWReg:
  1020.       case ModWRReg:
  1021.         HReg = AdrPart;
  1022.         DecodeAdr(&ArgStr[2], Mask1 | MModIWReg | Mask2 | MModIWRReg | MModIncWRReg |
  1023.                              MModDecWRReg | MModDispRWRReg | MModDisp8WRReg | MModDisp16WRReg |
  1024.                              MModAbs | MModImm);
  1025.         switch (AdrMode)
  1026.         {
  1027.           case ModWReg:
  1028.           case ModWRReg:
  1029.             BAsmCode[0] = CodeMask + 2 + (OpSize * 12);
  1030.             BAsmCode[1] = (HReg << 4) + AdrPart;
  1031.             CodeLen = 2;
  1032.             break;
  1033.           case ModIWReg:
  1034.             if (OpSize == 0)
  1035.             {
  1036.               BAsmCode[0] = CodeMask + 3;
  1037.               BAsmCode[1] = (HReg << 4) + AdrPart;
  1038.               CodeLen = 2;
  1039.             }
  1040.             else
  1041.             {
  1042.               BAsmCode[0] = 0xa6;
  1043.               BAsmCode[1] = CodeMask + AdrPart;
  1044.               BAsmCode[2] = WorkOfs + HReg;
  1045.               CodeLen = 3;
  1046.             }
  1047.             break;
  1048.           case ModReg:
  1049.           case ModRReg:
  1050.             BAsmCode[0] = CodeMask + 4 + (OpSize * 3);
  1051.             BAsmCode[1] = AdrVals[0];
  1052.             BAsmCode[2] = HReg + WorkOfs;
  1053.             CodeLen = 3;
  1054.             break;
  1055.           case ModIWRReg:
  1056.             if (OpSize == 0)
  1057.             {
  1058.               BAsmCode[0] = 0x72;
  1059.               BAsmCode[1] = CodeMask + AdrPart + 1;
  1060.               BAsmCode[2] = HReg + WorkOfs;
  1061.               CodeLen = 3;
  1062.             }
  1063.             else
  1064.             {
  1065.               BAsmCode[0] = CodeMask + 0x0e;
  1066.               BAsmCode[1] = (HReg << 4) + AdrPart + 1;
  1067.               CodeLen = 2;
  1068.             }
  1069.             break;
  1070.           case ModIncWRReg:
  1071.             BAsmCode[0] = 0xb4 + (OpSize * 0x21);
  1072.             BAsmCode[1] = CodeMask + AdrPart + 1;
  1073.             BAsmCode[2] = HReg + WorkOfs;
  1074.             CodeLen = 3;
  1075.             break;
  1076.           case ModDecWRReg:
  1077.             BAsmCode[0] = 0xc2 + OpSize;
  1078.             BAsmCode[1] = CodeMask + AdrPart + 1;
  1079.             BAsmCode[2] = HReg + WorkOfs;
  1080.             CodeLen = 3;
  1081.             break;
  1082.           case ModDispRWRReg:
  1083.             BAsmCode[0] = 0x60;
  1084.             BAsmCode[1] = 0x10 * (1 - OpSize) + (AdrVals[0] << 4) + AdrPart;
  1085.             BAsmCode[2] = CodeMask + HReg;
  1086.             CodeLen = 3;
  1087.             break;
  1088.           case ModDisp8WRReg:
  1089.             BAsmCode[0] = 0x7f + (OpSize * 7);
  1090.             BAsmCode[1] = CodeMask + AdrPart + 1;
  1091.             BAsmCode[2] = AdrVals[0];
  1092.             BAsmCode[3] = WorkOfs + HReg;
  1093.             CodeLen = 4;
  1094.             break;
  1095.           case ModDisp16WRReg:
  1096.             BAsmCode[0]= 0x7f + (OpSize * 7);
  1097.             BAsmCode[1] = CodeMask + AdrPart;
  1098.             memcpy(BAsmCode + 2, AdrVals, AdrCnt);
  1099.             BAsmCode[2 + AdrCnt] = WorkOfs + HReg;
  1100.             CodeLen = 3 + AdrCnt;
  1101.             break;
  1102.           case ModAbs:
  1103.             BAsmCode[0] = 0xc4 + (OpSize * 30);
  1104.             BAsmCode[1] = CodeMask + HReg;
  1105.             memcpy(BAsmCode + 2, AdrVals, AdrCnt);
  1106.             CodeLen = 2 + AdrCnt;
  1107.             break;
  1108.           case ModImm:
  1109.             BAsmCode[0] = CodeMask + 5 + (OpSize * 2);
  1110.             BAsmCode[1] = WorkOfs + HReg + OpSize;
  1111.             memcpy(BAsmCode + 2,AdrVals, AdrCnt);
  1112.             CodeLen = 2 + AdrCnt;
  1113.             break;
  1114.         }
  1115.         break;
  1116.       case ModReg:
  1117.       case ModRReg:
  1118.         HReg = AdrVals[0];
  1119.         DecodeAdr(&ArgStr[2], Mask2 | MModIWReg | MModIWRReg | MModIncWRReg | MModDecWRReg |
  1120.                              MModDisp8WRReg | MModDisp16WRReg | MModImm);
  1121.         switch (AdrMode)
  1122.         {
  1123.           case ModReg:
  1124.           case ModRReg:
  1125.             BAsmCode[0] = CodeMask + 4 + (OpSize * 3);
  1126.             CodeLen = 3;
  1127.             BAsmCode[1] = AdrVals[0];
  1128.             BAsmCode[2] = HReg;
  1129.             break;
  1130.           case ModIWReg:
  1131.             BAsmCode[0] = 0xa6 + 65 * (1 - OpSize);
  1132.             BAsmCode[1] = CodeMask + AdrPart;
  1133.             BAsmCode[2] = HReg;
  1134.             CodeLen=3;
  1135.             break;
  1136.           case ModIWRReg:
  1137.             BAsmCode[0] = 0x72 + (OpSize * 12);
  1138.             BAsmCode[1] = CodeMask + AdrPart + (1 - OpSize);
  1139.             BAsmCode[2] = HReg;
  1140.             CodeLen = 3;
  1141.             break;
  1142.           case ModIncWRReg:
  1143.             BAsmCode[0] = 0xb4 + (OpSize * 0x21);
  1144.             BAsmCode[1] = CodeMask + AdrPart + 1;
  1145.             BAsmCode[2] = HReg;
  1146.             CodeLen = 3;
  1147.             break;
  1148.           case ModDecWRReg:
  1149.             BAsmCode[0] = 0xc2 + OpSize;
  1150.             BAsmCode[1] = CodeMask + AdrPart + 1;
  1151.             BAsmCode[2] = HReg;
  1152.             CodeLen = 3;
  1153.             break;
  1154.           case ModDisp8WRReg:
  1155.             BAsmCode[0] = 0x7f + (OpSize * 7);
  1156.             BAsmCode[1] = CodeMask + AdrPart + 1;
  1157.             BAsmCode[2] = AdrVals[0];
  1158.             BAsmCode[3] = HReg;
  1159.             CodeLen = 4;
  1160.             break;
  1161.           case ModDisp16WRReg:
  1162.             BAsmCode[0] = 0x7f + (OpSize * 7);
  1163.             BAsmCode[1] = CodeMask + AdrPart;
  1164.             memcpy(BAsmCode + 2, AdrVals, AdrCnt);
  1165.             BAsmCode[2 + AdrCnt] = HReg;
  1166.             CodeLen = 3 + AdrCnt;
  1167.             break;
  1168.           case ModImm:
  1169.             BAsmCode[0] = CodeMask + 5 + (OpSize * 2);
  1170.             memcpy(BAsmCode + 2, AdrVals, AdrCnt); BAsmCode[1] = HReg + OpSize;
  1171.             CodeLen = 2 + AdrCnt;
  1172.             break;
  1173.         }
  1174.         break;
  1175.       case ModIWReg:
  1176.         HReg = AdrPart;
  1177.         DecodeAdr(&ArgStr[2], Mask2);
  1178.         switch (AdrMode)
  1179.         {
  1180.           case ModReg:
  1181.           case ModRReg:
  1182.             BAsmCode[0] = 0xe6 - (OpSize * 0x50);
  1183.             BAsmCode[1] = AdrVals[0];
  1184.             BAsmCode[2] = CodeMask + HReg;
  1185.             CodeLen = 3;
  1186.             break;
  1187.         }
  1188.         break;
  1189.       case ModIWRReg:
  1190.         HReg = AdrPart;
  1191.         DecodeAdr(&ArgStr[2], (OpSize * MModWRReg) | Mask2 | MModIWRReg | MModImm);
  1192.         switch (AdrMode)
  1193.         {
  1194.           case ModWRReg:
  1195.             BAsmCode[0] = CodeMask + 0x0e;
  1196.             BAsmCode[1] = (HReg << 4) + 0x10 + AdrPart;
  1197.             CodeLen = 2;
  1198.             break;
  1199.           case ModReg:
  1200.           case ModRReg:
  1201.             BAsmCode[0] = 0x72 + (OpSize * 76);
  1202.             BAsmCode[1] = CodeMask + HReg + OpSize;
  1203.             BAsmCode[2] = AdrVals[0];
  1204.             CodeLen = 3;
  1205.             break;
  1206.           case ModIWRReg:
  1207.             if (OpSize == 0)
  1208.             {
  1209.               BAsmCode[0] = 0x73;
  1210.               BAsmCode[1] = CodeMask + AdrPart;
  1211.               BAsmCode[2] = HReg + WorkOfs;
  1212.               CodeLen = 3;
  1213.             }
  1214.             else
  1215.             {
  1216.               BAsmCode[0] = CodeMask + 0x0e;
  1217.               BAsmCode[1] = 0x11 + (HReg << 4) + AdrPart;
  1218.               CodeLen = 2;
  1219.             }
  1220.             break;
  1221.           case ModImm:
  1222.             BAsmCode[0] = 0xf3 - (OpSize * 0x35);
  1223.             BAsmCode[1] = CodeMask + HReg;
  1224.             memcpy(BAsmCode + 2, AdrVals, AdrCnt);
  1225.             CodeLen = 2 + AdrCnt;
  1226.             break;
  1227.         }
  1228.         break;
  1229.       case ModIncWRReg:
  1230.         HReg = AdrPart;
  1231.         DecodeAdr(&ArgStr[2], Mask2);
  1232.         switch (AdrMode)
  1233.         {
  1234.           case ModReg:
  1235.           case ModRReg:
  1236.             BAsmCode[0] = 0xb4 + (OpSize * 0x21);
  1237.             BAsmCode[1] = CodeMask + HReg;
  1238.             BAsmCode[2] = AdrVals[0];
  1239.             CodeLen = 3;
  1240.             break;
  1241.         }
  1242.         break;
  1243.       case ModDecWRReg:
  1244.         HReg = AdrPart;
  1245.         DecodeAdr(&ArgStr[2], Mask2);
  1246.         switch (AdrMode)
  1247.         {
  1248.           case ModReg:
  1249.           case ModRReg:
  1250.             BAsmCode[0] = 0xc2 + OpSize;
  1251.             BAsmCode[1] = CodeMask + HReg;
  1252.             BAsmCode[2] = AdrVals[0];
  1253.             CodeLen = 3;
  1254.             break;
  1255.         }
  1256.         break;
  1257.       case ModDispRWRReg:
  1258.         HReg = AdrPart; HPart = AdrVals[0];
  1259.         DecodeAdr(&ArgStr[2], Mask1);
  1260.         switch (AdrMode)
  1261.         {
  1262.           case ModWReg:
  1263.           case ModWRReg:
  1264.             BAsmCode[0] = 0x60;
  1265.             BAsmCode[1] = 0x11 - (OpSize * 0x10) + (HPart << 4) + HReg;
  1266.             BAsmCode[2] = CodeMask + AdrPart;
  1267.             CodeLen = 3;
  1268.             break;
  1269.         }
  1270.         break;
  1271.       case ModDisp8WRReg:
  1272.         HReg = AdrPart;
  1273.         BAsmCode[2] = AdrVals[0];
  1274.         DecodeAdr(&ArgStr[2], Mask2 + (OpSize * MModImm));
  1275.         switch (AdrMode)
  1276.         {
  1277.           case ModReg:
  1278.           case ModRReg:
  1279.             BAsmCode[0] = 0x26 + (OpSize * 0x60);
  1280.             BAsmCode[1] = CodeMask + HReg + 1;
  1281.             BAsmCode[3] = AdrVals[0] + OpSize;
  1282.             CodeLen = 4;
  1283.             break;
  1284.           case ModImm:
  1285.             BAsmCode[0] = 0x06;
  1286.             BAsmCode[1] = CodeMask + HReg + 1;
  1287.             memcpy(BAsmCode + 3, AdrVals, AdrCnt);
  1288.             CodeLen = 3 + AdrCnt;
  1289.             break;
  1290.         }
  1291.         break;
  1292.       case ModDisp16WRReg:
  1293.         HReg = AdrPart; memcpy(BAsmCode + 2, AdrVals, 2);
  1294.         DecodeAdr(&ArgStr[2], Mask2 | (OpSize * MModImm));
  1295.         switch (AdrMode)
  1296.         {
  1297.           case ModReg:
  1298.           case ModRReg:
  1299.             BAsmCode[0] = 0x26 + (OpSize * 0x60);
  1300.             BAsmCode[1] = CodeMask + HReg;
  1301.             BAsmCode[4] = AdrVals[0] + OpSize;
  1302.             CodeLen = 5;
  1303.             break;
  1304.           case ModImm:
  1305.             BAsmCode[0] = 0x06;
  1306.             BAsmCode[1] = CodeMask + HReg;
  1307.             memcpy(BAsmCode + 4, AdrVals, AdrCnt);
  1308.             CodeLen = 4 + AdrCnt;
  1309.             break;
  1310.         }
  1311.         break;
  1312.       case ModAbs:
  1313.         memcpy(BAsmCode + 2, AdrVals, 2);
  1314.         DecodeAdr(&ArgStr[2], Mask1 | MModImm);
  1315.         switch (AdrMode)
  1316.         {
  1317.           case ModWReg:
  1318.           case ModWRReg:
  1319.             BAsmCode[0] = 0xc5 + (OpSize * 29);
  1320.             BAsmCode[1] = CodeMask + AdrPart + OpSize;
  1321.             CodeLen = 4;
  1322.             break;
  1323.           case ModImm:
  1324.             memmove(BAsmCode + 2 + AdrCnt, BAsmCode + 2, 2);
  1325.             memcpy(BAsmCode + 2, AdrVals, AdrCnt);
  1326.             BAsmCode[0] = 0x2f + (OpSize * 7);
  1327.             BAsmCode[1] = CodeMask + 1;
  1328.             CodeLen = 4 + AdrCnt;
  1329.             break;
  1330.         }
  1331.         break;
  1332.       case ModIRReg:
  1333.         HReg = AdrVals[0];
  1334.         DecodeAdr(&ArgStr[2], MModIWRReg *(1 - OpSize));
  1335.         switch (AdrMode)
  1336.         {
  1337.           case ModIWRReg:
  1338.             BAsmCode[0] = 0x73;
  1339.             BAsmCode[1] = CodeMask + AdrPart;
  1340.             BAsmCode[2] = HReg;
  1341.             CodeLen = 3;
  1342.             break;
  1343.         }
  1344.         break;
  1345.     }
  1346.   }
  1347. }
  1348.  
  1349. static void DecodeReg8(Word Code)
  1350. {
  1351.   if (ChkArgCnt(1, 1))
  1352.   {
  1353.     DecodeAdr(&ArgStr[1], MModReg | MModIReg);
  1354.     switch (AdrMode)
  1355.     {
  1356.       case ModReg:
  1357.         BAsmCode[0] = Code;
  1358.         BAsmCode[1] = AdrVals[0];
  1359.         CodeLen = 2;
  1360.         break;
  1361.       case ModIReg:
  1362.         BAsmCode[0] = Code + 1;
  1363.         BAsmCode[1] = AdrVals[0];
  1364.         CodeLen = 2;
  1365.         break;
  1366.     }
  1367.   }
  1368. }
  1369.  
  1370. static void DecodeReg16(Word Code)
  1371. {
  1372.   if (ChkArgCnt(1, 1))
  1373.   {
  1374.     DecodeAdr(&ArgStr[1], MModRReg);
  1375.     switch (AdrMode)
  1376.     {
  1377.       case ModRReg:
  1378.         BAsmCode[0] = Lo(Code);
  1379.         BAsmCode[1] = AdrVals[0] + Hi(Code);
  1380.         CodeLen = 2;
  1381.         break;
  1382.     }
  1383.   }
  1384. }
  1385.  
  1386. static void DecodeDIV_MUL(Word Code)
  1387. {
  1388.   Byte HReg;
  1389.  
  1390.   if (ChkArgCnt(2, 2))
  1391.   {
  1392.     DecodeAdr(&ArgStr[1], MModWRReg);
  1393.     if (AdrMode == ModWRReg)
  1394.     {
  1395.       HReg = AdrPart;
  1396.       DecodeAdr(&ArgStr[2], MModWReg);
  1397.       if (AdrMode == ModWReg)
  1398.       {
  1399.         BAsmCode[0] = Code;
  1400.         BAsmCode[1] = (HReg << 4) + AdrPart;
  1401.         CodeLen = 2;
  1402.       }
  1403.     }
  1404.   }
  1405. }
  1406.  
  1407. static void DecodeDIVWS(Word Code)
  1408. {
  1409.   Byte HReg;
  1410.  
  1411.   UNUSED(Code);
  1412.  
  1413.   if (ChkArgCnt(3, 3))
  1414.   {
  1415.     DecodeAdr(&ArgStr[1], MModWRReg);
  1416.     if (AdrMode == ModWRReg)
  1417.     {
  1418.       HReg = AdrPart;
  1419.       DecodeAdr(&ArgStr[2], MModWRReg);
  1420.       if (AdrMode == ModWRReg)
  1421.       {
  1422.         BAsmCode[2] = (HReg << 4) + AdrPart;
  1423.         DecodeAdr(&ArgStr[3], MModRReg);
  1424.         if (AdrMode == ModRReg)
  1425.         {
  1426.           BAsmCode[0] = 0x56;
  1427.           BAsmCode[1] = AdrVals[0];
  1428.           CodeLen = 3;
  1429.         }
  1430.       }
  1431.     }
  1432.   }
  1433. }
  1434.  
  1435. static void DecodeBit2(Word Code)
  1436. {
  1437.   Byte HReg, HPart;
  1438.   tStrComp Comp;
  1439.  
  1440.   if (ChkArgCnt(2, 2) && SplitBit(&Comp, &ArgStr[1], &HReg))
  1441.   {
  1442.     if (Odd(HReg)) WrError(ErrNum_InvAddrMode);
  1443.     else
  1444.     {
  1445.       DecodeAdr(&Comp, MModWReg);
  1446.       if (AdrMode == ModWReg)
  1447.       {
  1448.         HReg = (HReg << 4) + AdrPart;
  1449.         if (SplitBit(&Comp, &ArgStr[2], &HPart))
  1450.         {
  1451.           DecodeAdr(&Comp, MModWReg);
  1452.           if (AdrMode == ModWReg)
  1453.           {
  1454.             HPart = (HPart << 4) + AdrPart;
  1455.             BAsmCode[0] = Code;
  1456.             switch (Code)
  1457.             {
  1458.               case 0xf2: /* BLD */
  1459.                 BAsmCode[1] = HPart | 0x10;
  1460.                 BAsmCode[2] = HReg | (HPart & 0x10);
  1461.                 break;
  1462.               case 0x6f: /* BXOR */
  1463.                 BAsmCode[1] = 0x10 + HReg;
  1464.                 BAsmCode[2] = HPart;
  1465.                 break;
  1466.               default:
  1467.                 BAsmCode[1] = 0x10 + HReg;
  1468.                 BAsmCode[2] = HPart ^ 0x10;
  1469.             }
  1470.             CodeLen = 3;
  1471.           }
  1472.         }
  1473.       }
  1474.     }
  1475.   }
  1476. }
  1477.  
  1478. static void DecodeBit1(Word Code)
  1479. {
  1480.   Byte HReg;
  1481.   tStrComp Comp;
  1482.  
  1483.   if (ChkArgCnt(1, 1) && SplitBit(&Comp, &ArgStr[1], &HReg))
  1484.   {
  1485.     if (Odd(HReg)) WrError(ErrNum_InvAddrMode);
  1486.     else
  1487.     {
  1488.       DecodeAdr(&Comp, MModWReg + (Hi(Code) * MModIWRReg));
  1489.       switch (AdrMode)
  1490.       {
  1491.         case ModWReg:
  1492.           BAsmCode[0] = Lo(Code);
  1493.           BAsmCode[1] = (HReg << 4) + AdrPart;
  1494.           CodeLen = 2;
  1495.           break;
  1496.         case ModIWRReg:
  1497.           BAsmCode[0] = 0xf6;
  1498.           BAsmCode[1] = (HReg << 4) + AdrPart;
  1499.           CodeLen = 2;
  1500.           break;
  1501.       }
  1502.     }
  1503.   }
  1504. }
  1505.  
  1506. static void DecodeBTJF_BTJT(Word Code)
  1507. {
  1508.   Byte HReg;
  1509.   Integer AdrInt;
  1510.   tStrComp Comp;
  1511.  
  1512.   if (ChkArgCnt(2, 2) && SplitBit(&Comp, &ArgStr[1], &HReg))
  1513.   {
  1514.     if (Odd(HReg)) WrError(ErrNum_InvAddrMode);
  1515.     else
  1516.     {
  1517.       DecodeAdr(&Comp, MModWReg);
  1518.       if (AdrMode == ModWReg)
  1519.       {
  1520.         tEvalResult EvalResult;
  1521.  
  1522.         BAsmCode[1] = (HReg << 4) + AdrPart + Code;
  1523.         AdrInt = EvalStrIntExpressionWithResult(&ArgStr[2], UInt16, &EvalResult) - (EProgCounter() + 3);
  1524.         if (EvalResult.OK)
  1525.         {
  1526.           if (!mSymbolQuestionable(EvalResult.Flags) && ((AdrInt < -128) || (AdrInt > 127))) WrError(ErrNum_JmpDistTooBig);
  1527.           else
  1528.           {
  1529.             BAsmCode[0] = 0xaf;
  1530.             BAsmCode[2] = AdrInt & 0xff;
  1531.             CodeLen = 3;
  1532.             ChkSpace(SegCode, EvalResult.AddrSpaceMask);
  1533.           }
  1534.         }
  1535.       }
  1536.     }
  1537.   }
  1538. }
  1539.  
  1540. static void DecodeJP_CALL(Word Code)
  1541. {
  1542.   if (ChkArgCnt(1, 1))
  1543.   {
  1544.     AbsSeg = SegCode;
  1545.     DecodeAdr(&ArgStr[1], MModIRReg | MModAbs);
  1546.     switch (AdrMode)
  1547.     {
  1548.       case ModIRReg:
  1549.         BAsmCode[0] = Hi(Code);
  1550.         BAsmCode[1] = AdrVals[0] | ((Code >> 1) & 1);
  1551.         CodeLen = 2;
  1552.         break;
  1553.       case ModAbs:
  1554.         BAsmCode[0] = Lo(Code);
  1555.         memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  1556.         CodeLen =1 + AdrCnt;
  1557.         break;
  1558.     }
  1559.   }
  1560. }
  1561.  
  1562. static void DecodeCPJFI_CPJTI(Word Code)
  1563. {
  1564.   Byte HReg;
  1565.   Integer AdrInt;
  1566.  
  1567.   if (ChkArgCnt(3, 3))
  1568.   {
  1569.     DecodeAdr(&ArgStr[1], MModWReg);
  1570.     if (AdrMode == ModWReg)
  1571.     {
  1572.       HReg = AdrPart;
  1573.       DecodeAdr(&ArgStr[2], MModIWRReg);
  1574.       if (AdrMode == ModIWRReg)
  1575.       {
  1576.         tEvalResult EvalResult;
  1577.  
  1578.         BAsmCode[1] = (AdrPart << 4) + Code + HReg;
  1579.         AdrInt = EvalStrIntExpressionWithResult(&ArgStr[3], UInt16, &EvalResult) - (EProgCounter() + 3);
  1580.         if (EvalResult.OK)
  1581.         {
  1582.           if (!mSymbolQuestionable(EvalResult.Flags) && ((AdrInt<-128) || (AdrInt>127))) WrError(ErrNum_JmpDistTooBig);
  1583.           else
  1584.           {
  1585.             ChkSpace(SegCode, EvalResult.AddrSpaceMask);
  1586.             BAsmCode[0] = 0x9f;
  1587.             BAsmCode[2] = AdrInt & 0xff;
  1588.             CodeLen = 3;
  1589.           }
  1590.         }
  1591.       }
  1592.     }
  1593.   }
  1594. }
  1595.  
  1596. static void DecodeDJNZ(Word Code)
  1597. {
  1598.   UNUSED(Code);
  1599.  
  1600.   if (ChkArgCnt(2, 2))
  1601.   {
  1602.     DecodeAdr(&ArgStr[1], MModWReg);
  1603.     if (AdrMode == ModWReg)
  1604.     {
  1605.       Integer AdrInt;
  1606.       tEvalResult EvalResult;
  1607.  
  1608.       BAsmCode[0] = (AdrPart << 4) + 0x0a;
  1609.       AdrInt = EvalStrIntExpressionWithResult(&ArgStr[2], UInt16, &EvalResult) - (EProgCounter() + 2);
  1610.       if (EvalResult.OK)
  1611.       {
  1612.         if (!mSymbolQuestionable(EvalResult.Flags) && ((AdrInt < -128) || (AdrInt > 127))) WrError(ErrNum_JmpDistTooBig);
  1613.         else
  1614.         {
  1615.           ChkSpace(SegCode, EvalResult.AddrSpaceMask);
  1616.           BAsmCode[1] = AdrInt & 0xff;
  1617.           CodeLen = 2;
  1618.         }
  1619.       }
  1620.     }
  1621.   }
  1622. }
  1623.  
  1624. static void DecodeDWJNZ(Word Code)
  1625. {
  1626.   UNUSED(Code);
  1627.  
  1628.   if (ChkArgCnt(2, 2))
  1629.   {
  1630.     DecodeAdr(&ArgStr[1], MModRReg);
  1631.     if (AdrMode == ModRReg)
  1632.     {
  1633.       Integer AdrInt;
  1634.       tEvalResult EvalResult;
  1635.  
  1636.       BAsmCode[1] = AdrVals[0];
  1637.       AdrInt = EvalStrIntExpressionWithResult(&ArgStr[2], UInt16, &EvalResult) - (EProgCounter() + 3);
  1638.       if (EvalResult.OK)
  1639.       {
  1640.         if (!mSymbolQuestionable(EvalResult.Flags) && ((AdrInt < -128) || (AdrInt > 127))) WrError(ErrNum_JmpDistTooBig);
  1641.         else
  1642.         {
  1643.           ChkSpace(SegCode, EvalResult.AddrSpaceMask);
  1644.           BAsmCode[0] = 0xc6;
  1645.           BAsmCode[2] = AdrInt & 0xff;
  1646.           CodeLen = 3;
  1647.         }
  1648.       }
  1649.     }
  1650.   }
  1651. }
  1652.  
  1653. static void DecodeCondAbs(Word Code)
  1654. {
  1655.   if (ChkArgCnt(1, 1))
  1656.   {
  1657.     tEvalResult EvalResult;
  1658.     Word AdrWord = EvalStrIntExpressionWithResult(&ArgStr[1], UInt16, &EvalResult);
  1659.  
  1660.     if (EvalResult.OK)
  1661.     {
  1662.       ChkSpace(SegCode, EvalResult.AddrSpaceMask);
  1663.       BAsmCode[0] = 0x0d + Code;
  1664.       BAsmCode[1] = Hi(AdrWord);
  1665.       BAsmCode[2] = Lo(AdrWord);
  1666.       CodeLen = 3;
  1667.     }
  1668.   }
  1669. }
  1670.  
  1671. static void DecodeCondRel(Word Code)
  1672. {
  1673.   if (ChkArgCnt(1, 1))
  1674.   {
  1675.     tEvalResult EvalResult;
  1676.     Integer AdrInt = EvalStrIntExpressionWithResult(&ArgStr[1], UInt16, &EvalResult) - (EProgCounter() + 2);
  1677.  
  1678.     if (EvalResult.OK)
  1679.     {
  1680.       if (!mSymbolQuestionable(EvalResult.Flags) && ((AdrInt < -128) || (AdrInt > 127))) WrError(ErrNum_JmpDistTooBig);
  1681.       else
  1682.       {
  1683.         ChkSpace(SegCode, EvalResult.AddrSpaceMask);
  1684.         BAsmCode[0] = 0x0b + Code;
  1685.         BAsmCode[1] = AdrInt & 0xff;
  1686.         CodeLen = 2;
  1687.       }
  1688.     }
  1689.   }
  1690. }
  1691.  
  1692. static void DecodeSPP(Word Code)
  1693. {
  1694.   Boolean OK;
  1695.  
  1696.   UNUSED(Code);
  1697.  
  1698.   if (!ChkArgCnt(1, 1));
  1699.   else if (*ArgStr[1].str.p_str != '#') WrError(ErrNum_InvAddrMode);
  1700.   else
  1701.   {
  1702.     BAsmCode[1] = (EvalStrIntExpressionOffs(&ArgStr[1], 1, UInt6, &OK) << 2) + 0x02;
  1703.     if (OK)
  1704.     {
  1705.       BAsmCode[0] = 0xc7;
  1706.       CodeLen = 2;
  1707.     }
  1708.   }
  1709. }
  1710.  
  1711. static void DecodeSRP(Word Code)
  1712. {
  1713.   Boolean OK;
  1714.  
  1715.   if (!ChkArgCnt(1, 1));
  1716.   else if (*ArgStr[1].str.p_str != '#') WrError(ErrNum_InvAddrMode);
  1717.   else
  1718.   {
  1719.     BAsmCode[1] = EvalStrIntExpressionOffs(&ArgStr[1], 1, UInt5, &OK) << 3;
  1720.     if (OK)
  1721.     {
  1722.       BAsmCode[0] = 0xc7;
  1723.       BAsmCode[1] += Code;
  1724.       CodeLen=2;
  1725.     }
  1726.   }
  1727. }
  1728.  
  1729. static void DecodeSLA(Word Code)
  1730. {
  1731.   UNUSED(Code);
  1732.  
  1733.   if (ChkArgCnt(1, 1))
  1734.   {
  1735.     DecodeAdr(&ArgStr[1], MModWReg | MModReg | MModIWRReg);
  1736.     switch (AdrMode)
  1737.     {
  1738.       case ModWReg:
  1739.         BAsmCode[0] = 0x42;
  1740.         BAsmCode[1] = (AdrPart << 4) + AdrPart;
  1741.         CodeLen = 2;
  1742.         break;
  1743.       case ModReg:
  1744.         BAsmCode[0] = 0x44;
  1745.         BAsmCode[1] = AdrVals[0];
  1746.         BAsmCode[2] = AdrVals[0];
  1747.         CodeLen = 3;
  1748.         break;
  1749.       case ModIWRReg:
  1750.         BAsmCode[0] = 0x73;
  1751.         BAsmCode[1] = 0x40 + AdrPart;
  1752.         BAsmCode[2] = WorkOfs + AdrPart;
  1753.         CodeLen = 3;
  1754.         break;
  1755.     }
  1756.   }
  1757. }
  1758.  
  1759. static void DecodeSLAW(Word Code)
  1760. {
  1761.   UNUSED(Code);
  1762.  
  1763.   if (ChkArgCnt(1, 1))
  1764.   {
  1765.     DecodeAdr(&ArgStr[1], MModWRReg | MModRReg | MModIWRReg);
  1766.     switch (AdrMode)
  1767.     {
  1768.       case ModWRReg:
  1769.        BAsmCode[0] = 0x4e;
  1770.        BAsmCode[1] = (AdrPart << 4) + AdrPart;
  1771.        CodeLen = 2;
  1772.        break;
  1773.       case ModRReg:
  1774.        BAsmCode[0] = 0x47;
  1775.        BAsmCode[1] = AdrVals[0];
  1776.        BAsmCode[2] = AdrVals[0];
  1777.        CodeLen = 3;
  1778.        break;
  1779.       case ModIWRReg:
  1780.        BAsmCode[0] = 0x4e;
  1781.        BAsmCode[1] = 0x11 + (AdrPart << 4) + AdrPart;
  1782.        CodeLen = 2;
  1783.        break;
  1784.     }
  1785.   }
  1786. }
  1787.  
  1788. static void DecodeREG(Word Code)
  1789. {
  1790.   UNUSED(Code);
  1791.  
  1792.   CodeEquate(SegReg,0,0x1ff);
  1793. }
  1794.  
  1795. static void DecodeBIT(Word Code)
  1796. {
  1797.   Byte Bit;
  1798.   tStrComp Comp;
  1799.  
  1800.   UNUSED(Code);
  1801.  
  1802.   if (ChkArgCnt(1, 1) && SplitBit(&Comp, &ArgStr[1], &Bit))
  1803.   {
  1804.     DecodeAdr(&Comp, MModWReg);
  1805.     if (AdrMode == ModWReg)
  1806.     {
  1807.       PushLocHandle(-1);
  1808.       EnterIntSymbol(&LabPart, (AdrPart << 4) + Bit, SegNone, False);
  1809.       PopLocHandle();
  1810.       as_snprintf(ListLine, STRINGSIZE, "=r%d.%s%c",
  1811.                   (int)AdrPart,
  1812.                   (Odd(Bit)) ? "!" : "", (Bit >> 1) + AscOfs);
  1813.     }
  1814.   }
  1815. }
  1816.  
  1817. /*--------------------------------------------------------------------------*/
  1818. /* Code Table Handling */
  1819.  
  1820. static void AddFixed(const char *NName, Word NCode)
  1821. {
  1822.   AddInstTable(InstTable, NName, NCode, DecodeFixed);
  1823. }
  1824.  
  1825. static void AddALU(const char *NName8, const char *NName16, Word NCode)
  1826. {
  1827.   AddInstTable(InstTable, NName8, NCode, DecodeALU);
  1828.   AddInstTable(InstTable, NName16, NCode | 0x100, DecodeALU);
  1829. }
  1830.  
  1831. static void AddReg(const char *NName, Word NCode)
  1832. {
  1833.   AddInstTable(InstTable, NName, NCode, DecodeReg8);
  1834. }
  1835.  
  1836. static void AddReg16(const char *NName, Word NCode)
  1837. {
  1838.   AddInstTable(InstTable, NName, NCode, DecodeReg16);
  1839. }
  1840.  
  1841. static void AddBit2(const char *NName, Word NCode)
  1842. {
  1843.   AddInstTable(InstTable, NName, NCode, DecodeBit2);
  1844. }
  1845.  
  1846. static void AddBit1(const char *NName, Word NCode)
  1847. {
  1848.   AddInstTable(InstTable, NName, NCode, DecodeBit1);
  1849. }
  1850.  
  1851. static void AddCondition(const char *NameAbs, const char *NameRel, Word NCode)
  1852. {
  1853.   AddInstTable(InstTable, NameAbs, NCode << 4, DecodeCondAbs);
  1854.   AddInstTable(InstTable, NameRel, NCode << 4, DecodeCondRel);
  1855. }
  1856.  
  1857. static void AddLoad(const char *NName, Word NCode)
  1858. {
  1859.   AddInstTable(InstTable, NName, NCode, DecodeLoad);
  1860. }
  1861.  
  1862. static void InitFields(void)
  1863. {
  1864.   InstTable = CreateInstTable(201);
  1865.  
  1866.   add_null_pseudo(InstTable);
  1867.  
  1868.   AddInstTable(InstTable, "LD", 0, DecodeLD);
  1869.   AddInstTable(InstTable, "LDW", 1, DecodeLD);
  1870.   AddInstTable(InstTable, "PEA", 0x01, DecodePEA_PEAU);
  1871.   AddInstTable(InstTable, "PEAU", 0x03, DecodePEA_PEAU);
  1872.   AddInstTable(InstTable, "PUSH", 0, DecodePUSH_PUSHU);
  1873.   AddInstTable(InstTable, "PUSHU", 1, DecodePUSH_PUSHU);
  1874.   AddInstTable(InstTable, "PUSHW", 0, DecodePUSHW_PUSHUW);
  1875.   AddInstTable(InstTable, "PUSHUW", 1, DecodePUSHW_PUSHUW);
  1876.   AddInstTable(InstTable, "XCH", 0, DecodeXCH);
  1877.   AddInstTable(InstTable, "DIV", 0x5f, DecodeDIV_MUL);
  1878.   AddInstTable(InstTable, "MUL", 0x4f, DecodeDIV_MUL);
  1879.   AddInstTable(InstTable, "DIVWS", 0, DecodeDIVWS);
  1880.   AddInstTable(InstTable, "BTJF", 0x10, DecodeBTJF_BTJT);
  1881.   AddInstTable(InstTable, "BTJT", 0, DecodeBTJF_BTJT);
  1882.   AddInstTable(InstTable, "JP", 0xd48d, DecodeJP_CALL);
  1883.   AddInstTable(InstTable, "CALL", 0x74d2, DecodeJP_CALL);
  1884.   AddInstTable(InstTable, "CPJFI", 0, DecodeCPJFI_CPJTI);
  1885.   AddInstTable(InstTable, "CPJTI", 0x10, DecodeCPJFI_CPJTI);
  1886.   AddInstTable(InstTable, "DJNZ", 0, DecodeDJNZ);
  1887.   AddInstTable(InstTable, "DWJNZ", 0, DecodeDWJNZ);
  1888.   AddInstTable(InstTable, "SPP", 0, DecodeSPP);
  1889.   AddInstTable(InstTable, "SRP", 0x00, DecodeSRP);
  1890.   AddInstTable(InstTable, "SRP0", 0x04, DecodeSRP);
  1891.   AddInstTable(InstTable, "SRP1", 0x05, DecodeSRP);
  1892.   AddInstTable(InstTable, "SLA", 0, DecodeSLA);
  1893.   AddInstTable(InstTable, "SLAW", 0, DecodeSLAW);
  1894.   AddInstTable(InstTable, "REG", 0, DecodeREG);
  1895.   AddInstTable(InstTable, "BIT", 0, DecodeBIT);
  1896.  
  1897.   AddFixed("CCF" , 0x0061); AddFixed("DI"  , 0x0010);
  1898.   AddFixed("EI"  , 0x0000); AddFixed("HALT", 0xbf01);
  1899.   AddFixed("IRET", 0x00d3); AddFixed("NOP" , 0x00ff);
  1900.   AddFixed("RCF" , 0x0011); AddFixed("RET" , 0x0046);
  1901.   AddFixed("SCF" , 0x0001); AddFixed("SDM" , 0x00fe);
  1902.   AddFixed("SPM" , 0x00ee); AddFixed("WFI" , 0xef01);
  1903.  
  1904.   AddALU("ADC", "ADCW", 3); AddALU("ADD", "ADDW", 4); AddALU("AND", "ANDW",  1);
  1905.   AddALU("CP" , "CPW" , 9); AddALU("OR" , "ORW" , 0); AddALU("SBC", "SBCW",  2);
  1906.   AddALU("SUB", "SUBW", 5); AddALU("TCM", "TCMW", 8); AddALU("TM" , "TMW" , 10);
  1907.   AddALU("XOR", "XORW", 6);
  1908.  
  1909.   AddReg("CLR" , 0x90); AddReg("CPL" , 0x80); AddReg("DA"  , 0x70);
  1910.   AddReg("DEC" , 0x40); AddReg("INC" , 0x50); AddReg("POP" , 0x76);
  1911.   AddReg("POPU", 0x20); AddReg("RLC" , 0xb0); AddReg("ROL" , 0xa0);
  1912.   AddReg("ROR" , 0xc0); AddReg("RRC" , 0xd0); AddReg("SRA" , 0xe0);
  1913.   AddReg("SWAP", 0xf0);
  1914.  
  1915.   AddReg16("DECW" , 0x00cf); AddReg16("EXT"  , 0x01c6);
  1916.   AddReg16("INCW" , 0x00df); AddReg16("POPUW", 0x00b7);
  1917.   AddReg16("POPW" , 0x0075); AddReg16("RLCW" , 0x008f);
  1918.   AddReg16("RRCW" , 0x0036); AddReg16("SRAW" , 0x002f);
  1919.  
  1920.   AddBit2("BAND", 0x1f); AddBit2("BLD" , 0xf2);
  1921.   AddBit2("BOR" , 0x0f); AddBit2("BXOR", 0x6f);
  1922.  
  1923.   AddBit1("BCPL", 0x006f); AddBit1("BRES" , 0x001f);
  1924.   AddBit1("BSET", 0x000f); AddBit1("BTSET", 0x01f2);
  1925.  
  1926.   AddCondition("JPF"   , "JRF"   , 0x0); AddCondition("JPT"   , "JRT"   , 0x8);
  1927.   AddCondition("JPC"   , "JRC"   , 0x7); AddCondition("JPNC"  , "JRNC"  , 0xf);
  1928.   AddCondition("JPZ"   , "JRZ"   , 0x6); AddCondition("JPNZ"  , "JRNZ"  , 0xe);
  1929.   AddCondition("JPPL"  , "JRPL"  , 0xd); AddCondition("JPMI"  , "JRMI"  , 0x5);
  1930.   AddCondition("JPOV"  , "JROV"  , 0x4); AddCondition("JPNOV" , "JRNOV" , 0xc);
  1931.   AddCondition("JPEQ"  , "JREQ"  , 0x6); AddCondition("JPNE"  , "JRNE"  , 0xe);
  1932.   AddCondition("JPGE"  , "JRGE"  , 0x9); AddCondition("JPLT"  , "JRLT"  , 0x1);
  1933.   AddCondition("JPGT"  , "JRGT"  , 0xa); AddCondition("JPLE"  , "JRLE"  , 0x2);
  1934.   AddCondition("JPUGE" , "JRUGE" , 0xf); AddCondition("JPUL"  , "JRUL"  , 0x7);
  1935.   AddCondition("JPUGT" , "JRUGT" , 0xb); AddCondition("JPULE" , "JRULE" , 0x3);
  1936.  
  1937.   AddLoad("LDPP", 0x00); AddLoad("LDDP", 0x10);
  1938.   AddLoad("LDPD", 0x01); AddLoad("LDDD", 0x11);
  1939.  
  1940.   AddIntelPseudo(InstTable, eIntPseudoFlag_BigEndian);
  1941. }
  1942.  
  1943. static void DeinitFields(void)
  1944. {
  1945.   DestroyInstTable(InstTable);
  1946. }
  1947.  
  1948. /*--------------------------------------------------------------------------*/
  1949.  
  1950.  
  1951. static void MakeCode_ST9(void)
  1952. {
  1953.   OpSize = 0;
  1954.   AbsSeg = (DPAssume == 1) ? SegData : SegCode;
  1955.  
  1956.   if (!LookupInstTable(InstTable, OpPart.str.p_str))
  1957.     WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
  1958. }
  1959.  
  1960. static void InitCode_ST9(void)
  1961. {
  1962.   DPAssume = 0;
  1963. }
  1964.  
  1965. static Boolean IsDef_ST9(void)
  1966. {
  1967.   return (Memo("REG") || Memo("BIT"));
  1968. }
  1969.  
  1970. static void SwitchFrom_ST9(void)
  1971. {
  1972.   DeinitFields();
  1973. }
  1974.  
  1975. static void InternSymbol_ST9(char *Asc, TempResult *Erg)
  1976. {
  1977.   Boolean OK;
  1978.   Boolean Pair;
  1979.   LargeInt Num;
  1980.  
  1981.   as_tempres_set_none(Erg);
  1982.   if ((strlen(Asc) < 2) || (*Asc != 'R'))
  1983.     return;
  1984.   Asc++;
  1985.  
  1986.   if (*Asc == 'R')
  1987.   {
  1988.     if (strlen(Asc) < 2) return;
  1989.     Pair = True; Asc++;
  1990.   }
  1991.   else
  1992.     Pair = False;
  1993.  
  1994.   Num = ConstLongInt(Asc, &OK, 10);
  1995.   if (!OK || (Num < 0) || (Num > 255)) return;
  1996.   if ((Num & 0xf0) == 0xd0) return;
  1997.   if (Pair && Odd(Num)) return;
  1998.  
  1999.   if (Pair) Num += 0x100;
  2000.   as_tempres_set_int(Erg, Num); Erg->AddrSpaceMask |= (1 << SegReg);
  2001. }
  2002.  
  2003. static void SwitchTo_ST9(void)
  2004. {
  2005.   TurnWords = False;
  2006.   SetIntConstMode(eIntConstModeIntel);
  2007.  
  2008.   PCSymbol = "PC"; HeaderID = 0x32; NOPCode = 0xff;
  2009.   DivideChars = ","; HasAttrs = False;
  2010.  
  2011.   ValidSegs = (1 << SegCode) | (1 << SegData) | ( 1 << SegReg);
  2012.   Grans[SegCode] = 1; ListGrans[SegCode] = 1; SegInits[SegCode] = 0;
  2013.   SegLimits[SegCode] = 0xffff;
  2014.   Grans[SegData] = 1; ListGrans[SegData] = 1; SegInits[SegData] = 0;
  2015.   SegLimits[SegData] = 0xffff;
  2016.   Grans[SegReg ] = 1; ListGrans[SegReg ] = 1; SegInits[SegReg ] = 0;
  2017.   SegLimits[SegReg ] = 0xff;
  2018.  
  2019.   MakeCode=MakeCode_ST9; IsDef=IsDef_ST9;
  2020.   SwitchFrom=SwitchFrom_ST9; InternSymbol=InternSymbol_ST9;
  2021.  
  2022.   pASSUMERecs = ASSUMEST9s;
  2023.   ASSUMERecCnt = ASSUMEST9Count;
  2024.  
  2025.   InitFields();
  2026. }
  2027.  
  2028. void codest9_init(void)
  2029. {
  2030.   CPUST9020 = AddCPU("ST9020", SwitchTo_ST9);
  2031.   CPUST9030 = AddCPU("ST9030", SwitchTo_ST9);
  2032.   CPUST9040 = AddCPU("ST9040", SwitchTo_ST9);
  2033.   CPUST9050 = AddCPU("ST9050", SwitchTo_ST9);
  2034.   AddInitPassProc(InitCode_ST9);
  2035. }
  2036.