Subversion Repositories pentevo

Rev

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

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