Subversion Repositories pentevo

Rev

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

  1. /* code96.c */
  2. /*****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
  4. /*                                                                           */
  5. /* AS-Portierung                                                             */
  6. /*                                                                           */
  7. /* Codegenerator MCS/96-Familie                                              */
  8. /*                                                                           */
  9. /*****************************************************************************/
  10.  
  11. #include "stdinc.h"
  12. #include <string.h>
  13.  
  14. #include "bpemu.h"
  15. #include "asmdef.h"
  16. #include "asmsub.h"
  17. #include "asmpars.h"
  18. #include "asmitree.h"
  19. #include "codepseudo.h"
  20. #include "intpseudo.h"
  21. #include "codevars.h"
  22. #include "errmsg.h"
  23. #include "strutil.h"
  24.  
  25. #include "code96.h"
  26.  
  27. typedef enum
  28. {
  29.   ModNone = -1,
  30.   ModDir = 0,
  31.   ModInd = 1,
  32.   ModPost = 2,
  33.   ModIdx = 3,
  34.   ModImm = 4
  35. } tAdrMode;
  36.  
  37. #define ModNone (-1)
  38. #define MModDir (1 << ModDir)
  39. #define MModInd (1 << ModInd)
  40. #define MModPost (1 << ModPost)
  41. #define MModIdx (1 << ModIdx)
  42. #define MModMem (MModInd | MModPost | MModIdx)
  43. #define MModImm (1 << ModImm)
  44.  
  45. #define SFRStart 2
  46. #define SFRStop 0x17
  47.  
  48. typedef enum
  49. {
  50.   eForceNone = 0,
  51.   eForceShort = 1,
  52.   eForceLong = 2
  53. } tForceSize;
  54.  
  55. static CPUVar CPU8096, CPU80196, CPU80196N, CPU80296;
  56.  
  57. static Byte AdrMode;
  58. static ShortInt AdrType;
  59. static Byte AdrVals[4];
  60. static ShortInt OpSize;
  61.  
  62. static LongInt WSRVal, WSR1Val;
  63. static Word WinStart, WinStop, WinEnd, WinBegin;
  64. static Word Win1Start, Win1Stop, Win1Begin, Win1End;
  65.  
  66. static IntType MemInt;
  67.  
  68. /*---------------------------------------------------------------------------*/
  69.  
  70. static void ChkSFR(Word Adr, const tStrComp *pArg)
  71. {
  72.   if ((Adr >= SFRStart) && (Adr <= SFRStop))
  73.     WrStrErrorPos(ErrNum_IOAddrNotAllowed, pArg);
  74. }
  75.  
  76. static void Chk296(Word Adr, const tStrComp *pArg)
  77. {
  78.   if ((MomCPU == CPU80296) && (Adr <= 1))
  79.     WrStrErrorPos(ErrNum_IOAddrNotAllowed, pArg);
  80. }
  81.  
  82. static Boolean ChkWork(Word *Adr)
  83. {
  84.   /* Registeradresse, die von Fenstern ueberdeckt wird ? */
  85.  
  86.   if ((*Adr >= WinBegin) && (*Adr <= WinEnd))
  87.     return False;
  88.  
  89.   else if ((*Adr >= Win1Begin) && (*Adr <= Win1End))
  90.     return False;
  91.  
  92.   /* Speicheradresse in Fenster ? */
  93.  
  94.   else if ((*Adr >= WinStart) && (*Adr <= WinStop))
  95.   {
  96.     *Adr = (*Adr) - WinStart + WinBegin;
  97.     return True;
  98.   }
  99.  
  100.   else if ((*Adr >= Win1Start) && (*Adr <= Win1Stop))
  101.   {
  102.     *Adr = (*Adr) - Win1Start + Win1Begin;
  103.     return True;
  104.   }
  105.  
  106.   /* Default */
  107.  
  108.   else
  109.     return (*Adr <= 0xff);
  110. }
  111.  
  112. static void ChkAdr(Byte Mask, const tStrComp *pArg)
  113. {
  114.   if ((AdrType == ModDir) && (!(Mask & MModDir)))
  115.   {
  116.     AdrType = ModInd; /* not exactly right, but AdrMode counts */
  117.     AdrMode = 0;
  118.   }
  119.  
  120.   if ((AdrType != ModNone) && (!(Mask & (1 << AdrType))))
  121.   {
  122.     WrStrErrorPos(ErrNum_InvAddrMode, pArg);
  123.     AdrType = ModNone;
  124.     AdrCnt = 0;
  125.   }
  126. }
  127.  
  128. static int SplitForceSize(const char *pArg, tForceSize *pForceSize)
  129. {
  130.   switch (*pArg)
  131.   {
  132.     case '>': *pForceSize = eForceLong; return 1;
  133.     case '<': *pForceSize = eForceShort; return 1;
  134.     default: return 0;
  135.   }
  136. }
  137.  
  138. static void DecodeAdr(const tStrComp *pArg, Byte Mask, Boolean AddrWide)
  139. {
  140.   LongInt AdrInt;
  141.   LongWord AdrWord;
  142.   Word BReg;
  143.   Boolean OK;
  144.   tSymbolFlags Flags;
  145.   char *p, *p2;
  146.   int ArgLen;
  147.   Byte Reg;
  148.   LongWord OMask;
  149.  
  150.   AdrType = ModNone;
  151.   AdrCnt = 0;
  152.   OMask = (1 << OpSize) - 1;
  153.  
  154.   if (*pArg->str.p_str == '#')
  155.   {
  156.     switch (OpSize)
  157.     {
  158.       case -1:
  159.         WrStrErrorPos(ErrNum_UndefOpSizes, pArg);
  160.         break;
  161.       case 0:
  162.         AdrVals[0] = EvalStrIntExpressionOffs(pArg, 1, Int8, &OK);
  163.         if (OK)
  164.         {
  165.           AdrType = ModImm;
  166.           AdrCnt = 1;
  167.           AdrMode = 1;
  168.         }
  169.         break;
  170.       case 1:
  171.         AdrWord = EvalStrIntExpressionOffs(pArg, 1, Int16, &OK);
  172.         if (OK)
  173.         {
  174.           AdrType = ModImm;
  175.           AdrCnt = 2;
  176.           AdrMode = 1;
  177.           AdrVals[0] = Lo(AdrWord);
  178.           AdrVals[1] = Hi(AdrWord);
  179.         }
  180.         break;
  181.     }
  182.     goto chk;
  183.   }
  184.  
  185.   p = QuotPos(pArg->str.p_str, '[');
  186.   if (p)
  187.   {
  188.     tStrComp Left, Mid, Right;
  189.  
  190.     StrCompSplitRef(&Left, &Mid, pArg, p);
  191.     p2 = RQuotPos(Mid.str.p_str, ']');
  192.     ArgLen = strlen(Mid.str.p_str);
  193.     if (!p2 || (p2 > Mid.str.p_str + ArgLen - 1) || (p2 < Mid.str.p_str + ArgLen - 2)) WrStrErrorPos(ErrNum_InvAddrMode, pArg);
  194.     else
  195.     {
  196.       StrCompSplitRef(&Mid, &Right, &Mid, p2);
  197.       BReg = EvalStrIntExpressionWithFlags(&Mid, Int16, &OK, &Flags);
  198.       if (mFirstPassUnknown(Flags))
  199.         BReg = 0;
  200.       if (OK)
  201.       {
  202.         if (!ChkWork(&BReg)) WrStrErrorPos(ErrNum_OverRange, &Mid);
  203.         else
  204.         {
  205.           Reg = Lo(BReg);
  206.           ChkSFR(Reg, &Mid);
  207.           if (Reg & 1) WrStrErrorPos(ErrNum_AddrMustBeEven, &Mid);
  208.           else if ((strlen(Left.str.p_str) == 0) && !strcmp(Right.str.p_str, "+"))
  209.           {
  210.             AdrType = ModPost;
  211.             AdrMode = 2;
  212.             AdrCnt = 1;
  213.             AdrVals[0] = Reg + 1;
  214.           }
  215.           else if (strlen(Right.str.p_str) != 0) WrStrErrorPos(ErrNum_InvAddrMode, pArg);
  216.           else if (strlen(Left.str.p_str) == 0)
  217.           {
  218.             AdrVals[0] = Reg;
  219.             AdrCnt = 1;
  220.             if (Mask & MModInd)
  221.             {
  222.               AdrType = ModInd;
  223.               AdrMode = 2;
  224.               AdrCnt = 1;
  225.             }
  226.             else
  227.             {
  228.               WrStrErrorPos(ErrNum_IndexedForIndirect, pArg);
  229.               AdrType = ModIdx;
  230.               AdrMode = 3;
  231.               AdrVals[AdrCnt++] = 0;
  232.             }
  233.           }
  234.           else
  235.           {
  236.             tForceSize ForceSize = eForceNone;
  237.             int Offset = SplitForceSize(Left.str.p_str, &ForceSize);
  238.  
  239.             AdrInt = EvalStrIntExpressionOffsWithFlags(&Left, Offset, AddrWide ? Int24 : Int16, &OK, &Flags);
  240.             if (OK)
  241.             {
  242.               if ((AdrInt == 0) && (Mask & MModInd) && !ForceSize)
  243.               {
  244.                 AdrType = ModInd;
  245.                 AdrMode = 2;
  246.                 AdrCnt = 1;
  247.                 AdrVals[0] = Reg;
  248.               }
  249.               else if (AddrWide)
  250.               {
  251.                 AdrType = ModIdx;
  252.                 AdrMode= 3;
  253.                 AdrCnt = 4;
  254.                 AdrVals[0] = Reg;
  255.                 AdrVals[1] = AdrInt & 0xff;
  256.                 AdrVals[2] = (AdrInt >> 8) & 0xff;
  257.                 AdrVals[3] = (AdrInt >> 16) & 0xff;
  258.               }
  259.               else
  260.               {
  261.                 Boolean IsShort = (AdrInt >= -128) && (AdrInt <= 127);
  262.  
  263.                 if (!ForceSize)
  264.                   ForceSize = IsShort ? eForceShort : eForceLong;
  265.                 if (ForceSize == eForceShort)
  266.                 {
  267.                   if ((AdrInt > 127) && !mSymbolQuestionable(Flags)) WrStrErrorPos(ErrNum_OverRange, &Left);
  268.                   else if ((AdrInt < -128) && !mSymbolQuestionable(Flags)) WrStrErrorPos(ErrNum_UnderRange, &Left);
  269.                   else
  270.                   {
  271.                     AdrType = ModIdx;
  272.                     AdrMode = 3;
  273.                     AdrCnt = 2;
  274.                     AdrVals[0] = Reg;
  275.                     AdrVals[1] = Lo(AdrInt);
  276.                   }
  277.                 }
  278.                 else
  279.                 {
  280.                   AdrType = ModIdx;
  281.                   AdrMode = 3;
  282.                   AdrCnt = 3;
  283.                   AdrVals[0] = Reg + 1;
  284.                   AdrVals[1] = Lo(AdrInt);
  285.                   AdrVals[2] = Hi(AdrInt);
  286.                 }
  287.               }
  288.             }
  289.           }
  290.         }
  291.       }
  292.     }
  293.   }
  294.   else
  295.   {
  296.     tForceSize ForceSize = eForceNone;
  297.     int Offset = SplitForceSize(pArg->str.p_str, &ForceSize);
  298.  
  299.     AdrWord = EvalStrIntExpressionOffsWithFlags(pArg, Offset, MemInt, &OK, &Flags);
  300.     if (mFirstPassUnknown(Flags))
  301.       AdrWord &= (0xffffffff - OMask);
  302.     if (OK)
  303.     {
  304.       if (AdrWord & OMask) WrStrErrorPos(ErrNum_NotAligned, pArg);
  305.       else
  306.       {
  307.         BReg = AdrWord & 0xffff;
  308.         if ((!(BReg & 0xffff0000)) && ChkWork(&BReg) && !ForceSize)
  309.         {
  310.           AdrType = ModDir;
  311.           AdrCnt = 1;
  312.           AdrVals[0] = Lo(BReg);
  313.         }
  314.         else if (AddrWide)
  315.         {
  316.           AdrType = ModIdx;
  317.           AdrMode = 3;
  318.           AdrCnt = 4;
  319.           AdrVals[0] = 0;
  320.           AdrVals[1] = AdrWord & 0xff;
  321.           AdrVals[2] = (AdrWord >> 8) & 0xff;
  322.           AdrVals[3] = (AdrWord >> 16) & 0xff;
  323.         }
  324.         else
  325.         {
  326.           Boolean IsShort = AdrWord >= 0xff80;
  327.  
  328.           if (!ForceSize)
  329.             ForceSize = IsShort ? eForceShort : eForceLong;
  330.           if (ForceSize == eForceShort)
  331.           {
  332.             if (!IsShort) WrStrErrorPos(ErrNum_UnderRange, pArg);
  333.             else
  334.             {
  335.               AdrType = ModIdx;
  336.               AdrMode = 3;
  337.               AdrCnt = 2;
  338.               AdrVals[0] = 0;
  339.               AdrVals[1] = Lo(AdrWord);
  340.             }
  341.           }
  342.           else
  343.           {
  344.             AdrType = ModIdx;
  345.             AdrMode = 3;
  346.             AdrCnt = 3;
  347.             AdrVals[0] = 1;
  348.             AdrVals[1] = Lo(AdrWord);
  349.             AdrVals[2] = Hi(AdrWord);
  350.           }
  351.         }
  352.       }
  353.     }
  354.   }
  355.  
  356. chk:
  357.   ChkAdr(Mask, pArg);
  358. }
  359.  
  360. static void CalcWSRWindow(void)
  361. {
  362.   WSRVal &= 0x7f;
  363.   if (WSRVal <= 0x0f)
  364.   {
  365.     WinStart = 0xffff;
  366.     WinStop = 0;
  367.     WinBegin = 0xff;
  368.     WinEnd = 0;
  369.   }
  370.   else if (WSRVal <= 0x1f)
  371.   {
  372.     WinBegin = 0x80;
  373.     WinEnd = 0xff;
  374.     WinStart = (WSRVal < 0x18) ? ((WSRVal - 0x10) << 7) : ((WSRVal + 0x20) << 7);
  375.     WinStop = WinStart + 0x7f;
  376.   }
  377.   else if (WSRVal <= 0x3f)
  378.   {
  379.     WinBegin = 0xc0;
  380.     WinEnd = 0xff;
  381.     WinStart = (WSRVal < 0x30) ? ((WSRVal - 0x20) << 6) : ((WSRVal + 0x40) << 6);
  382.     WinStop = WinStart + 0x3f;
  383.   }
  384.   else if (WSRVal <= 0x7f)
  385.   {
  386.     WinBegin = 0xe0;
  387.     WinEnd = 0xff;
  388.     WinStart = (WSRVal < 0x60) ? ((WSRVal - 0x40) << 5) : ((WSRVal + 0x80) << 5);
  389.     WinStop = WinStart + 0x1f;
  390.   }
  391.   if ((WinStop > 0x1fdf) && (MomCPU < CPU80296))
  392.     WinStop = 0x1fdf;
  393. }
  394.  
  395. static void CalcWSR1Window(void)
  396. {
  397.   if (WSR1Val <= 0x1f)
  398.   {
  399.     Win1Start = 0xffff;
  400.     Win1Stop = 0;
  401.     Win1Begin = 0xff;
  402.     Win1End = 0;
  403.   }
  404.   else if (WSR1Val <= 0x3f)
  405.   {
  406.     Win1Begin = 0x40;
  407.     Win1End = 0x7f;
  408.     Win1Start = (WSR1Val < 0x30) ? ((WSR1Val - 0x20) << 6) : ((WSR1Val + 0x40) << 6);
  409.     Win1Stop = Win1Start + 0x3f;
  410.   }
  411.   else if (WSR1Val <= 0x7f)
  412.   {
  413.     Win1Begin = 0x60;
  414.     Win1End = 0x7f;
  415.     Win1Start = (WSR1Val < 0x60) ? ((WSR1Val - 0x40) << 5) : ((WSR1Val + 0x80) << 5);
  416.     Win1Stop = Win1Start + 0x1f;
  417.   }
  418.   else
  419.   {
  420.     Win1Begin = 0x40;
  421.     Win1End = 0x7f;
  422.     Win1Start = (WSR1Val + 0x340) << 6;
  423.     Win1Stop = Win1Start + 0x3f;
  424.   }
  425. }
  426.  
  427. static Boolean IsShortBranch(LongInt Dist)
  428. {
  429.   return (Dist >= -1024) && (Dist <= 1023);
  430. }
  431.  
  432. static Boolean IsByteBranch(LongInt Dist)
  433. {
  434.   return (Dist >= -128) && (Dist <= 127);
  435. }
  436.  
  437. static Boolean GetShort(Word Code, LongInt Dist)
  438. {
  439.   switch (Code)
  440.   {
  441.     case 0: return True;
  442.     case 1: return False;
  443.     default: return IsShortBranch(Dist);
  444.   }
  445. }
  446.  
  447. /*---------------------------------------------------------------------------*/
  448.  
  449. static void DecodeFixed(Word Code)
  450. {
  451.   if (ChkArgCnt(0, 0))
  452.     BAsmCode[(CodeLen = 1) - 1] = Code;
  453. }
  454.  
  455. static void DecodeALU3(Word Code)
  456. {
  457.   if (ChkArgCnt(2, 3))
  458.   {
  459.     int Start = 0;
  460.     Boolean Special = (Hi(Code) & 0x40) || False,
  461.             DoubleDest = (Hi(Code) & 0x08) || False;
  462.  
  463.     OpSize = Hi(Code) & 3;
  464.     if (Hi(Code) & 0x80)
  465.       BAsmCode[Start++] = 0xfe;
  466.     BAsmCode[Start++] = 0x40 + (Ord(ArgCnt==2) << 5)
  467.                       + ((1 - OpSize) << 4)
  468.                       + (Lo(Code) << 2);
  469.     DecodeAdr(&ArgStr[ArgCnt], MModImm | MModMem, False);
  470.     if (AdrType != ModNone)
  471.     {
  472.       Boolean OK;
  473.  
  474.       BAsmCode[Start - 1] += AdrMode;
  475.       memcpy(BAsmCode + Start, AdrVals, AdrCnt);
  476.       Start += AdrCnt;
  477.       if ((Special) && (AdrMode == 0))
  478.         ChkSFR(AdrVals[0], &ArgStr[ArgCnt]);
  479.       if (ArgCnt == 3)
  480.       {
  481.         DecodeAdr(&ArgStr[2], MModDir, False);
  482.         OK = (AdrType != ModNone);
  483.         if (OK)
  484.         {
  485.           BAsmCode[Start++] = AdrVals[0];
  486.           if (Special)
  487.             ChkSFR(AdrVals[0], &ArgStr[2]);
  488.         }
  489.       }
  490.       else
  491.         OK = True;
  492.       if (OK)
  493.       {
  494.         OpSize += DoubleDest;
  495.         DecodeAdr(&ArgStr[1], MModDir, False);
  496.         if (AdrType != ModNone)
  497.         {
  498.           BAsmCode[Start] = AdrVals[0];
  499.           CodeLen = Start + 1;
  500.           if (Special)
  501.           {
  502.             ChkSFR(AdrVals[0], &ArgStr[1]);
  503.             Chk296(AdrVals[0], &ArgStr[1]);
  504.           }
  505.         }
  506.       }
  507.     }
  508.   }
  509. }
  510.  
  511. static void DecodeALU2(Word Code)
  512. {
  513.   if (ChkArgCnt(2, 2))
  514.   {
  515.     int Start = 0;
  516.     Boolean Special = (Hi(Code) & 0x40) || False,
  517.             DoubleDest = (Hi(Code) & 0x08) || False;
  518.     Byte HReg, Mask;
  519.  
  520.     OpSize = Hi(Code) & 3;
  521.  
  522.     if (Hi(Code) & 0x80)
  523.       BAsmCode[Start++] = 0xfe;
  524.     HReg = ((Hi(Code) & 0x20) ? 2 : 1) << 1;
  525.     BAsmCode[Start++] = Lo(Code) + ((1 - OpSize) << HReg);
  526.     Mask = MModMem | ((Hi(Code) & 0x20) ? MModImm : 0);
  527.     DecodeAdr(&ArgStr[2], Mask, False);
  528.     if (AdrType != ModNone)
  529.     {
  530.       BAsmCode[Start - 1] += AdrMode;
  531.       memcpy(BAsmCode + Start, AdrVals, AdrCnt);
  532.       Start += AdrCnt;
  533.       if ((Special) && (AdrMode == 0))
  534.         ChkSFR(AdrVals[0], &ArgStr[2]);
  535.       OpSize += DoubleDest;
  536.       DecodeAdr(&ArgStr[1], MModDir, False);
  537.       if (AdrType != ModNone)
  538.       {
  539.         BAsmCode[Start] = AdrVals[0];
  540.         CodeLen = 1 + Start;
  541.         if (Special)
  542.         {
  543.           ChkSFR(AdrVals[0], &ArgStr[1]);
  544.         }
  545.       }
  546.     }
  547.   }
  548. }
  549.  
  550. static void DecodeCMPL(Word Code)
  551. {
  552.   UNUSED(Code);
  553.  
  554.   if (ChkArgCnt(2, 2)
  555.    && ChkMinCPU(CPU80196))
  556.   {
  557.     OpSize = 2;
  558.     DecodeAdr(&ArgStr[1], MModDir, False);
  559.     if (AdrType != ModNone)
  560.     {
  561.       BAsmCode[2] = AdrVals[0];
  562.       DecodeAdr(&ArgStr[2], MModDir, False);
  563.       if (AdrType != ModNone)
  564.       {
  565.         BAsmCode[1] = AdrVals[0];
  566.         BAsmCode[0] = 0xc5;
  567.         CodeLen = 3;
  568.       }
  569.     }
  570.   }
  571. }
  572.  
  573. static void DecodePUSH_POP(Word IsPOP)
  574. {
  575.   OpSize = 1;
  576.  
  577.   if (ChkArgCnt(1, 1))
  578.   {
  579.     DecodeAdr(&ArgStr[1], MModMem | (IsPOP ? 0 : MModImm), False);
  580.     if (AdrType != ModNone)
  581.     {
  582.       CodeLen = 1 + AdrCnt;
  583.       BAsmCode[0] = 0xc8 + AdrMode + (IsPOP << 2);
  584.       memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  585.     }
  586.   }
  587. }
  588.  
  589. static void DecodeBMOV(Word Code)
  590. {
  591.   if (ChkArgCnt(2, 2))
  592.   {
  593.     OpSize = 2;
  594.     DecodeAdr(&ArgStr[1], MModDir, False);
  595.     if (AdrType != ModNone)
  596.     {
  597.       BAsmCode[2] = AdrVals[0];
  598.       OpSize = 1;
  599.       DecodeAdr(&ArgStr[2], MModDir, False);
  600.       if (AdrType != ModNone)
  601.       {
  602.         BAsmCode[1] = AdrVals[0];
  603.         BAsmCode[0] = Code;
  604.         CodeLen = 3;
  605.       }
  606.     }
  607.   }
  608. }
  609.  
  610. static void DecodeALU1(Word Code)
  611. {
  612.   if (ChkArgCnt(1, 1))
  613.   {
  614.     Boolean DoubleDest = (Hi(Code) & 0x08) || False;
  615.     OpSize = (Hi(Code) & 3) + DoubleDest;
  616.     DecodeAdr(&ArgStr[1], MModDir, False);
  617.     if (AdrType != ModNone)
  618.     {
  619.       CodeLen = 1 + AdrCnt;
  620.       OpSize -= DoubleDest;
  621.       BAsmCode[0] = Code + ((1 - OpSize) << 4);
  622.       memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  623.     }
  624.   }
  625. }
  626.  
  627. static void DecodeXCH(Word Code)
  628. {
  629.   Byte HReg;
  630.  
  631.   OpSize = Hi(Code) & 3;
  632.  
  633.   if (ChkArgCnt(2, 2)
  634.    && ChkMinCPU(CPU80196))
  635.   {
  636.     DecodeAdr(&ArgStr[1], MModIdx | MModDir, False);
  637.     switch (AdrType)
  638.     {
  639.       case ModIdx:
  640.         memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  641.         HReg = AdrCnt;
  642.         BAsmCode[0] = (AdrMode ? 0x0b : 0x04) + ((1 - OpSize) << 4);
  643.         DecodeAdr(&ArgStr[2], MModDir, False);
  644.         if (AdrType != ModNone)
  645.         {
  646.           BAsmCode[1 + HReg] = AdrVals[0];
  647.           CodeLen = 2 + HReg;
  648.         }
  649.         break;
  650.       case ModDir:
  651.         HReg = AdrVals[0];
  652.         DecodeAdr(&ArgStr[2], MModDir | MModIdx, False);
  653.         if (AdrType != ModNone)
  654.         {
  655.           BAsmCode[0] = ((AdrType == ModIdx) ? 0x0b : 0x04) + ((1 - OpSize) << 4);
  656.           memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  657.           BAsmCode[1 + AdrCnt] = HReg;
  658.           CodeLen = 2 + AdrCnt;
  659.         }
  660.         break;
  661.     }
  662.   }
  663. }
  664.  
  665. static void DecodeLDBZE_LDBSE(Word Code)
  666. {
  667.   if (ChkArgCnt(2, 2))
  668.   {
  669.     OpSize = 0;
  670.     DecodeAdr(&ArgStr[2], MModMem | MModImm, False);
  671.     if (AdrType != ModNone)
  672.     {
  673.       int Start;
  674.  
  675.       BAsmCode[0] = Code + AdrMode;
  676.       memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  677.       Start = 1 + AdrCnt;
  678.       OpSize = 1;
  679.       DecodeAdr(&ArgStr[1], MModDir, False);
  680.       if (AdrType != ModNone)
  681.       {
  682.         BAsmCode[Start] = AdrVals[0];
  683.         CodeLen = 1 + Start;
  684.       }
  685.     }
  686.   }
  687. }
  688.  
  689. static void DecodeNORML(Word Code)
  690. {
  691.   UNUSED(Code);
  692.  
  693.   if (ChkArgCnt(2, 2))
  694.   {
  695.     OpSize = eSymbolSize8Bit;
  696.     DecodeAdr(&ArgStr[2], MModDir, False);
  697.     if (AdrType != ModNone)
  698.     {
  699.       BAsmCode[1] = AdrVals[0];
  700.       OpSize = eSymbolSize32Bit;
  701.       DecodeAdr(&ArgStr[1], MModDir, False);
  702.       if (AdrType != ModNone)
  703.       {
  704.         CodeLen = 3;
  705.         BAsmCode[0] = 0x0f;
  706.         BAsmCode[2] = AdrVals[0];
  707.       }
  708.     }
  709.   }
  710. }
  711.  
  712. static void DecodeIDLPD(Word Code)
  713. {
  714.   UNUSED(Code);
  715.  
  716.   if (ChkArgCnt(1, 1)
  717.    && ChkMinCPU(CPU80196))
  718.   {
  719.     OpSize = 0;
  720.     DecodeAdr(&ArgStr[1], MModImm, False);
  721.     if (AdrType != ModNone)
  722.     {
  723.       CodeLen = 2;
  724.       BAsmCode[0] = 0xf6;
  725.       BAsmCode[1] = AdrVals[0];
  726.     }
  727.   }
  728. }
  729.  
  730. static void DecodeShift(Word Code)
  731. {
  732.   OpSize = Hi(Code) & 3;
  733.  
  734.   if (ChkArgCnt(2, 2))
  735.   {
  736.     DecodeAdr(&ArgStr[1], MModDir, False);
  737.     if (AdrType != ModNone)
  738.     {
  739.       BAsmCode[0] = 0x08 + Lo(Code) + (Ord(OpSize == 0) << 4) + (Ord(OpSize == 2) << 2);
  740.       BAsmCode[2] = AdrVals[0];
  741.       OpSize = 0;
  742.       DecodeAdr(&ArgStr[2], MModDir | MModImm, False);
  743.       if (AdrType != ModNone)
  744.       {
  745.         if ((AdrType == ModImm) && (AdrVals[0] > 15)) WrStrErrorPos(ErrNum_OverRange, &ArgStr[2]);
  746.         else if ((AdrType == ModDir) && (AdrVals[0] < 16)) WrStrErrorPos(ErrNum_UnderRange, &ArgStr[2]);
  747.         else
  748.         {
  749.           BAsmCode[1] = AdrVals[0];
  750.           CodeLen = 3;
  751.         }
  752.       }
  753.     }
  754.   }
  755. }
  756.  
  757. static void DecodeSKIP(Word Code)
  758. {
  759.   UNUSED(Code);
  760.  
  761.   if (ChkArgCnt(1, 1))
  762.   {
  763.     OpSize = 0;
  764.     DecodeAdr(&ArgStr[1], MModDir, False);
  765.     if (AdrType != ModNone)
  766.     {
  767.       CodeLen = 2;
  768.       BAsmCode[0] = 0;
  769.       BAsmCode[1] = AdrVals[0];
  770.     }
  771.   }
  772. }
  773.  
  774. static void DecodeELD_EST(Word Code)
  775. {
  776.   OpSize = Hi(Code) & 3;
  777.  
  778.   if (ChkArgCnt(2, 2)
  779.    && ChkMinCPU(CPU80196N))
  780.   {
  781.     DecodeAdr(&ArgStr[2], MModInd | MModIdx, True);
  782.     if (AdrType != ModNone)
  783.     {
  784.       Byte HReg;
  785.  
  786.       BAsmCode[0] = Code + (AdrMode & 1) + ((1 - OpSize) << 1);
  787.       memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  788.       HReg = 1 + AdrCnt;
  789.       DecodeAdr(&ArgStr[1], MModDir, False);
  790.       if (AdrType == ModDir)
  791.       {
  792.         BAsmCode[HReg] = AdrVals[0];
  793.         CodeLen = HReg + 1;
  794.       }
  795.     }
  796.   }
  797. }
  798.  
  799. static void DecodeMac(Word Code)
  800. {
  801.   if (ChkArgCnt(1, 2)
  802.    && ChkMinCPU(CPU80296))
  803.   {
  804.     OpSize = 1;
  805.     BAsmCode[0] = 0x4c + (Ord(ArgCnt == 1) << 5);
  806.     DecodeAdr(&ArgStr[ArgCnt], MModMem | (Hi(Code) ? 0 : MModImm), False);
  807.     if (AdrType != ModNone)
  808.     {
  809.       int HReg;
  810.  
  811.       BAsmCode[0] += AdrMode;
  812.       memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  813.       HReg = 1 + AdrCnt;
  814.       if (ArgCnt == 2)
  815.       {
  816.         DecodeAdr(&ArgStr[1], MModDir, False);
  817.         if (AdrType == ModDir)
  818.         {
  819.           BAsmCode[HReg] = AdrVals[0];
  820.           HReg++;
  821.         }
  822.       }
  823.       if (AdrType != ModNone)
  824.       {
  825.         BAsmCode[HReg] = Lo(Code);
  826.         CodeLen = 1 + HReg;
  827.       }
  828.     }
  829.   }
  830. }
  831.  
  832. static void DecodeMVAC_MSAC(Word Code)
  833. {
  834.   if (ChkArgCnt(2, 2)
  835.    && ChkMinCPU(CPU80296))
  836.   {
  837.     OpSize = 2;
  838.     DecodeAdr(&ArgStr[1], MModDir, False);
  839.     if (AdrType == ModDir)
  840.     {
  841.       BAsmCode[0] = 0x0d;
  842.       BAsmCode[2] = AdrVals[0] + Code;
  843.       OpSize = 0;
  844.       DecodeAdr(&ArgStr[2], MModImm | MModDir, False);
  845.       BAsmCode[1] = AdrVals[0];
  846.       switch (AdrType)
  847.       {
  848.         case ModImm:
  849.           if (AdrVals[0] > 31) WrStrErrorPos(ErrNum_OverRange, &ArgStr[2]);
  850.           else CodeLen = 3;
  851.           break;
  852.         case ModDir:
  853.           if (AdrVals[0] < 32) WrStrErrorPos(ErrNum_UnderRange, &ArgStr[2]);
  854.           else CodeLen = 3;
  855.       }
  856.     }
  857.   }
  858. }
  859.  
  860. static void DecodeRpt(Word Code)
  861. {
  862.   if (ChkArgCnt(1, 1)
  863.    && ChkMinCPU(CPU80296))
  864.   {
  865.     OpSize = 1;
  866.     DecodeAdr(&ArgStr[1], MModImm | MModPost | MModInd, False);
  867.     if (AdrType != ModNone)
  868.     {
  869.       BAsmCode[0] = 0x40 + AdrMode;
  870.       memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  871.       BAsmCode[1 + AdrCnt] = Code;
  872.       BAsmCode[2 + AdrCnt] = 4;
  873.       CodeLen = 3 + AdrCnt;
  874.     }
  875.   }
  876. }
  877.  
  878. static void DecodeRel(Word Code)
  879. {
  880.   if (ChkArgCnt(1, 1))
  881.   {
  882.     Boolean OK;
  883.     tSymbolFlags Flags;
  884.     LongInt AdrInt = EvalStrIntExpressionWithFlags(&ArgStr[1], MemInt, &OK, &Flags) - (EProgCounter() + 2);
  885.  
  886.     if (OK)
  887.     {
  888.       if (!mSymbolQuestionable(Flags) && !IsByteBranch(AdrInt)) WrStrErrorPos(ErrNum_JmpDistTooBig, &ArgStr[1]);
  889.       else
  890.       {
  891.         CodeLen = 2;
  892.         BAsmCode[0] = Code;
  893.         BAsmCode[1] = AdrInt & 0xff;
  894.       }
  895.     }
  896.   }
  897. }
  898.  
  899. static void DecodeSCALL_LCALL_CALL(Word Code)
  900. {
  901.   if (ChkArgCnt(1, 1))
  902.   {
  903.     Boolean OK;
  904.     tSymbolFlags Flags;
  905.     LongWord AdrWord = EvalStrIntExpressionWithFlags(&ArgStr[1], MemInt, &OK, &Flags);
  906.  
  907.     if (OK)
  908.     {
  909.       LongInt AdrInt = AdrWord - (EProgCounter() + 2);
  910.       Boolean IsShort = GetShort(Code, AdrInt);
  911.  
  912.       if (IsShort)
  913.       {
  914.         if (!mSymbolQuestionable(Flags) && !IsShortBranch(AdrInt)) WrStrErrorPos(ErrNum_JmpDistTooBig, &ArgStr[1]);
  915.         else
  916.         {
  917.           CodeLen = 2;
  918.           BAsmCode[1] = AdrInt & 0xff;
  919.           BAsmCode[0] = 0x28 + ((AdrInt & 0x700) >> 8);
  920.         }
  921.       }
  922.       else
  923.       {
  924.         CodeLen = 3;
  925.         BAsmCode[0] = 0xef;
  926.         AdrInt--;
  927.         BAsmCode[1] = Lo(AdrInt);
  928.         BAsmCode[2] = Hi(AdrInt);
  929.         if (!mSymbolQuestionable(Flags) && IsShortBranch(AdrInt))
  930.           WrStrErrorPos(ErrNum_ShortJumpPossible, &ArgStr[1]);
  931.       }
  932.     }
  933.   }
  934. }
  935.  
  936. static void DecodeBR_LJMP_SJMP(Word Code)
  937. {
  938.   OpSize = 1;
  939.   if (!ChkArgCnt(1, 1));
  940.   else if ((Code == 0xff) && (QuotPos(ArgStr[1].str.p_str, '[')))
  941.   {
  942.     DecodeAdr(&ArgStr[1], MModInd, False);
  943.     if (AdrType != ModNone)
  944.     {
  945.       CodeLen = 2;
  946.       BAsmCode[0] = 0xe3;
  947.       BAsmCode[1] = AdrVals[0];
  948.     }
  949.   }
  950.   else
  951.   {
  952.     Boolean OK;
  953.     tSymbolFlags Flags;
  954.     LongWord AdrWord = EvalStrIntExpressionWithFlags(&ArgStr[1], MemInt, &OK, &Flags);
  955.  
  956.     if (OK)
  957.     {
  958.       LongInt AdrInt = AdrWord - (EProgCounter() + 2);
  959.       Boolean IsShort = GetShort(Code, AdrInt);
  960.  
  961.       if (IsShort)
  962.       {
  963.         if (!mSymbolQuestionable(Flags) && !IsShortBranch(AdrInt)) WrStrErrorPos(ErrNum_JmpDistTooBig, &ArgStr[1]);
  964.         else
  965.         {
  966.           CodeLen = 2;
  967.           BAsmCode[1] = AdrInt & 0xff;
  968.           BAsmCode[0] = 0x20 + ((AdrInt & 0x700) >> 8);
  969.         }
  970.       }
  971.       else
  972.       {
  973.         CodeLen = 3;
  974.         BAsmCode[0] = 0xe7;
  975.         AdrInt--;
  976.         BAsmCode[1] = Lo(AdrInt);
  977.         BAsmCode[2] = Hi(AdrInt);
  978.         if (!mSymbolQuestionable(Flags) && IsShortBranch(AdrInt))
  979.           WrStrErrorPos(ErrNum_ShortJumpPossible, &ArgStr[1]);
  980.       }
  981.     }
  982.   }
  983. }
  984.  
  985. static void DecodeTIJMP(Word Code)
  986. {
  987.   UNUSED(Code);
  988.  
  989.   if (ChkArgCnt(3, 3)
  990.    && ChkMinCPU(CPU80196))
  991.   {
  992.     OpSize = 1;
  993.     DecodeAdr(&ArgStr[1], MModDir, False);
  994.     if (AdrType != ModNone)
  995.     {
  996.       BAsmCode[3] = AdrVals[0];
  997.       DecodeAdr(&ArgStr[2], MModDir, False);
  998.       if (AdrType != ModNone)
  999.       {
  1000.         BAsmCode[1] = AdrVals[0];
  1001.         OpSize = 0;
  1002.         DecodeAdr(&ArgStr[3], MModImm, False);
  1003.         if (AdrType != ModNone)
  1004.         {
  1005.           BAsmCode[2] = AdrVals[0];
  1006.           BAsmCode[0] = 0xe2;
  1007.           CodeLen = 4;
  1008.         }
  1009.       }
  1010.     }
  1011.   }
  1012. }
  1013.  
  1014. static void DecodeDJNZ_DJNZW(Word Size)
  1015. {
  1016.   if (ChkArgCnt(2, 2)
  1017.    && (!Size || ChkMinCPU(CPU80196)))
  1018.   {
  1019.     OpSize = Size;
  1020.     DecodeAdr(&ArgStr[1], MModDir, False);
  1021.     if (AdrType != ModNone)
  1022.     {
  1023.       Boolean OK;
  1024.       tSymbolFlags Flags;
  1025.       LongInt AdrInt;
  1026.  
  1027.       BAsmCode[0] = 0xe0 + OpSize;
  1028.       BAsmCode[1] = AdrVals[0];
  1029.       AdrInt = EvalStrIntExpressionWithFlags(&ArgStr[2], MemInt, &OK, &Flags) - (EProgCounter() + 3);
  1030.       if (OK)
  1031.       {
  1032.         if (!mSymbolQuestionable(Flags) && !IsByteBranch(AdrInt)) WrStrErrorPos(ErrNum_JmpDistTooBig, &ArgStr[2]);
  1033.         else
  1034.         {
  1035.           CodeLen = 3;
  1036.           BAsmCode[2] = AdrInt & 0xff;
  1037.         }
  1038.       }
  1039.     }
  1040.   }
  1041. }
  1042.  
  1043. static void DecodeJBC_JBS(Word Code)
  1044. {
  1045.   if (ChkArgCnt(3, 3))
  1046.   {
  1047.     Boolean OK;
  1048.  
  1049.     BAsmCode[0] = Code + EvalStrIntExpression(&ArgStr[2], UInt3, &OK);
  1050.     if (OK)
  1051.     {
  1052.       OpSize = 0;
  1053.       DecodeAdr(&ArgStr[1], MModDir, False);
  1054.       if (AdrType != ModNone)
  1055.       {
  1056.         LongInt AdrInt;
  1057.         tSymbolFlags Flags;
  1058.  
  1059.         BAsmCode[1] = AdrVals[0];
  1060.         AdrInt = EvalStrIntExpressionWithFlags(&ArgStr[3], MemInt, &OK, &Flags) - (EProgCounter() + 3);
  1061.         if (OK)
  1062.         {
  1063.           if (!mSymbolQuestionable(Flags) && !IsByteBranch(AdrInt)) WrStrErrorPos(ErrNum_JmpDistTooBig, &ArgStr[3]);
  1064.           else
  1065.           {
  1066.             CodeLen = 3;
  1067.             BAsmCode[2] = AdrInt & 0xff;
  1068.           }
  1069.         }
  1070.       }
  1071.     }
  1072.   }
  1073. }
  1074.  
  1075. static void DecodeECALL(Word Code)
  1076. {
  1077.   UNUSED(Code);
  1078.  
  1079.   if (ChkArgCnt(1, 1)
  1080.    && ChkMinCPU(CPU80196N))
  1081.   {
  1082.     Boolean OK;
  1083.     LongInt AdrInt = EvalStrIntExpression(&ArgStr[1], MemInt, &OK) - (EProgCounter() + 4);
  1084.     if (OK)
  1085.     {
  1086.       BAsmCode[0] = 0xf1;
  1087.       BAsmCode[1] = AdrInt & 0xff;
  1088.       BAsmCode[2] = (AdrInt >> 8) & 0xff;
  1089.       BAsmCode[3] = (AdrInt >> 16) & 0xff;
  1090.       CodeLen = 4;
  1091.     }
  1092.   }
  1093. }
  1094.  
  1095. static void DecodeEJMP_EBR(Word Code)
  1096. {
  1097.   UNUSED(Code);
  1098.  
  1099.   OpSize = 1;
  1100.   if (!ChkArgCnt(1, 1));
  1101.   else if (!ChkMinCPU(CPU80196N));
  1102.   else if (*ArgStr[1].str.p_str == '[')
  1103.   {
  1104.     DecodeAdr(&ArgStr[1], MModInd, False);
  1105.     if (AdrType != ModNone)
  1106.     {
  1107.       BAsmCode[0] = 0xe3;
  1108.       BAsmCode[1] = AdrVals[0] + 1;
  1109.       CodeLen = 2;
  1110.     }
  1111.   }
  1112.   else
  1113.   {
  1114.     Boolean OK;
  1115.     LongInt AdrInt = EvalStrIntExpression(&ArgStr[1], MemInt, &OK) - (EProgCounter() + 4);
  1116.     if (OK)
  1117.     {
  1118.       BAsmCode[0] = 0xe6;
  1119.       BAsmCode[1] = AdrInt & 0xff;
  1120.       BAsmCode[2] = (AdrInt >> 8) & 0xff;
  1121.       BAsmCode[3] = (AdrInt >> 16) & 0xff;
  1122.       CodeLen = 4;
  1123.     }
  1124.   }
  1125. }
  1126.  
  1127. /*---------------------------------------------------------------------------*/
  1128.  
  1129. static void AddSize(const char *NName, Word NCode, InstProc Proc, Word SizeMask)
  1130. {
  1131.   int l;
  1132.   char SizeName[20];
  1133.  
  1134.   if (SizeMask & 2)
  1135.     AddInstTable(InstTable, NName, 0x0100 | NCode, Proc);
  1136.  
  1137.   l = as_snprintf(SizeName, sizeof(SizeName), "%sB", NName);
  1138.   if (SizeMask & 1)
  1139.     AddInstTable(InstTable, SizeName, 0x0000 | NCode, Proc);
  1140.  
  1141.   if (SizeMask & 4)
  1142.   {
  1143.     SizeName[l - 1] = 'L';
  1144.     AddInstTable(InstTable, SizeName, 0x0200 | NCode, Proc);
  1145.   }
  1146. }
  1147.  
  1148. static void AddFixed(const char *NName, Byte NCode, CPUVar NMin, CPUVar NMax)
  1149. {
  1150.   if ((MomCPU >= NMin) && (MomCPU <= NMax))
  1151.     AddInstTable(InstTable, NName, NCode, DecodeFixed);
  1152. }
  1153.  
  1154. static void AddALU3(const char *NName, Word NCode)
  1155. {
  1156.   AddSize(NName, NCode, DecodeALU3, 3);
  1157. }
  1158.  
  1159. static void AddALU2(const char *NName, Word NCode)
  1160. {
  1161.   AddSize(NName, NCode, DecodeALU2, 3);
  1162. }
  1163.  
  1164. static void AddALU1(const char *NName, Word NCode)
  1165. {
  1166.   AddSize(NName, NCode, DecodeALU1, 3);
  1167. }
  1168.  
  1169. static void AddRel(const char *NName, Byte NCode)
  1170. {
  1171.   AddInstTable(InstTable, NName, NCode, DecodeRel);
  1172. }
  1173.  
  1174. static void AddMac(const char *NName, Word NCode, Boolean NRel)
  1175. {
  1176.   AddInstTable(InstTable, NName, NCode | (NRel ? 0x100 : 0), DecodeMac);
  1177. }
  1178.  
  1179. static void AddRpt(const char *NName, Byte NCode)
  1180. {
  1181.   AddInstTable(InstTable, NName, NCode, DecodeRpt);
  1182. }
  1183.  
  1184. static void InitFields(void)
  1185. {
  1186.   InstTable = CreateInstTable(207);
  1187.   SetDynamicInstTable(InstTable);
  1188.   AddInstTable(InstTable, "CMPL", 0, DecodeCMPL);
  1189.   AddInstTable(InstTable, "PUSH", 0, DecodePUSH_POP);
  1190.   AddInstTable(InstTable, "POP" , 1, DecodePUSH_POP);
  1191.   if (MomCPU >= CPU80196)
  1192.   {
  1193.     AddInstTable(InstTable, "BMOV", 0xc1, DecodeBMOV);
  1194.     AddInstTable(InstTable, "BMOVI", 0xcd, DecodeBMOV);
  1195.   }
  1196.   if (MomCPU >= CPU80196N)
  1197.     AddInstTable(InstTable, "EBMOVI", 0xe4, DecodeBMOV);
  1198.   AddSize("XCH", 0, DecodeXCH, 3);
  1199.   AddInstTable(InstTable, "LDBZE", 0xac, DecodeLDBZE_LDBSE);
  1200.   AddInstTable(InstTable, "LDBSE", 0xbc, DecodeLDBZE_LDBSE);
  1201.   AddInstTable(InstTable, "NORML", 0, DecodeNORML);
  1202.   AddInstTable(InstTable, "IDLPD", 0, DecodeIDLPD);
  1203.   AddSize("SHR", 0, DecodeShift, 7);
  1204.   AddSize("SHL", 1, DecodeShift, 7);
  1205.   AddSize("SHRA", 2, DecodeShift, 7);
  1206.   AddInstTable(InstTable, "SKIP", 0, DecodeSKIP);
  1207.   AddSize("ELD", 0xe8, DecodeELD_EST, 3);
  1208.   AddSize("EST", 0x1c, DecodeELD_EST, 3);
  1209.   AddInstTable(InstTable, "MVAC", 1, DecodeMVAC_MSAC);
  1210.   AddInstTable(InstTable, "MSAC", 3, DecodeMVAC_MSAC);
  1211.   AddInstTable(InstTable, "CALL", 0xff, DecodeSCALL_LCALL_CALL);
  1212.   AddInstTable(InstTable, "LCALL", 1, DecodeSCALL_LCALL_CALL);
  1213.   AddInstTable(InstTable, "SCALL", 0, DecodeSCALL_LCALL_CALL);
  1214.   AddInstTable(InstTable, "BR", 0xff, DecodeBR_LJMP_SJMP);
  1215.   AddInstTable(InstTable, "LJMP", 1, DecodeBR_LJMP_SJMP);
  1216.   AddInstTable(InstTable, "SJMP", 0, DecodeBR_LJMP_SJMP);
  1217.   AddInstTable(InstTable, "TIJMP", 0, DecodeTIJMP);
  1218.   AddInstTable(InstTable, "DJNZ", 0, DecodeDJNZ_DJNZW);
  1219.   AddInstTable(InstTable, "DJNZW", 1, DecodeDJNZ_DJNZW);
  1220.   AddInstTable(InstTable, "JBC", 0x30, DecodeJBC_JBS);
  1221.   AddInstTable(InstTable, "JBS", 0x38, DecodeJBC_JBS);
  1222.   AddInstTable(InstTable, "ECALL", 0, DecodeECALL);
  1223.   AddInstTable(InstTable, "EJMP", 0, DecodeEJMP_EBR);
  1224.   AddInstTable(InstTable, "EBR", 0, DecodeEJMP_EBR);
  1225.  
  1226.   AddFixed("CLRC" , 0xf8, CPU8096  , CPU80296 );
  1227.   AddFixed("CLRVT", 0xfc, CPU8096  , CPU80296 );
  1228.   AddFixed("DI"   , 0xfa, CPU8096  , CPU80296 );
  1229.   AddFixed("DPTS" , 0xec, CPU80196 , CPU80196N);
  1230.   AddFixed("EI"   , 0xfb, CPU8096  , CPU80296 );
  1231.   AddFixed("EPTS" , 0xed, CPU80196 , CPU80196N);
  1232.   AddFixed("NOP"  , 0xfd, CPU8096  , CPU80296 );
  1233.   AddFixed("POPA" , 0xf5, CPU80196 , CPU80296 );
  1234.   AddFixed("POPF" , 0xf3, CPU8096  , CPU80296 );
  1235.   AddFixed("PUSHA", 0xf4, CPU80196 , CPU80296 );
  1236.   AddFixed("PUSHF", 0xf2, CPU8096  , CPU80296 );
  1237.   AddFixed("RET"  , 0xf0, CPU8096  , CPU80296 );
  1238.   AddFixed("RST"  , 0xff, CPU8096  , CPU80296 );
  1239.   AddFixed("SETC" , 0xf9, CPU8096  , CPU80296 );
  1240.   AddFixed("TRAP" , 0xf7, CPU8096  , CPU80296 );
  1241.   AddFixed("RETI" , 0xe5, CPU80196N, CPU80296 );
  1242.  
  1243.   AddALU3("ADD" , 0x0001);
  1244.   AddALU3("AND" , 0x0000);
  1245.   AddALU3("MUL" , 0xc803);
  1246.   AddALU3("MULU", 0x4803);
  1247.   AddALU3("SUB" , 0x0002);
  1248.  
  1249.   AddALU2("ADDC", 0x20a4);
  1250.   AddALU2("CMP" , 0x2088);
  1251.   AddALU2("DIV" , 0xe88c);
  1252.   AddALU2("DIVU", 0x688c);
  1253.   AddALU2("LD"  , 0x20a0);
  1254.   AddALU2("OR"  , 0x2080);
  1255.   AddALU2("ST"  , 0x00c0);
  1256.   AddALU2("SUBC", 0x20a8);
  1257.   AddALU2("XOR" , 0x2084);
  1258.  
  1259.   AddALU1("CLR", 0x0001);
  1260.   AddALU1("DEC", 0x0005);
  1261.   AddALU1("EXT", 0x8806);
  1262.   AddALU1("INC", 0x0007);
  1263.   AddALU1("NEG", 0x0003);
  1264.   AddALU1("NOT", 0x0002);
  1265.  
  1266.   AddRel("JC"   , 0xdb);
  1267.   AddRel("JE"   , 0xdf);
  1268.   AddRel("JGE"  , 0xd6);
  1269.   AddRel("JGT"  , 0xd2);
  1270.   AddRel("JH"   , 0xd9);
  1271.   AddRel("JLE"  , 0xda);
  1272.   AddRel("JLT"  , 0xde);
  1273.   AddRel("JNC"  , 0xd3);
  1274.   AddRel("JNE"  , 0xd7);
  1275.   AddRel("JNH"  , 0xd1);
  1276.   AddRel("JNST" , 0xd0);
  1277.   AddRel("JNV"  , 0xd5);
  1278.   AddRel("JNVT" , 0xd4);
  1279.   AddRel("JST"  , 0xd8);
  1280.   AddRel("JV"   , 0xdd);
  1281.   AddRel("JVT"  , 0xdc);
  1282.  
  1283.   AddMac("MAC"   , 0x00, False); AddMac("SMAC"  , 0x01, False);
  1284.   AddMac("MACR"  , 0x04, True ); AddMac("SMACR" , 0x05, True );
  1285.   AddMac("MACZ"  , 0x08, False); AddMac("SMACZ" , 0x09, False);
  1286.   AddMac("MACRZ" , 0x0c, True ); AddMac("SMACRZ", 0x0d, True );
  1287.  
  1288.   AddRpt("RPT"    , 0x00); AddRpt("RPTNST" , 0x10); AddRpt("RPTNH"  , 0x11);
  1289.   AddRpt("RPTGT"  , 0x12); AddRpt("RPTNC"  , 0x13); AddRpt("RPTNVT" , 0x14);
  1290.   AddRpt("RPTNV"  , 0x15); AddRpt("RPTGE"  , 0x16); AddRpt("RPTNE"  , 0x17);
  1291.   AddRpt("RPTST"  , 0x18); AddRpt("RPTH"   , 0x19); AddRpt("RPTLE"  , 0x1a);
  1292.   AddRpt("RPTC"   , 0x1b); AddRpt("RPTVT"  , 0x1c); AddRpt("RPTV"   , 0x1d);
  1293.   AddRpt("RPTLT"  , 0x1e); AddRpt("RPTE"   , 0x1f); AddRpt("RPTI"   , 0x20);
  1294.   AddRpt("RPTINST", 0x30); AddRpt("RPTINH" , 0x31); AddRpt("RPTIGT" , 0x32);
  1295.   AddRpt("RPTINC" , 0x33); AddRpt("RPTINVT", 0x34); AddRpt("RPTINV" , 0x35);
  1296.   AddRpt("RPTIGE" , 0x36); AddRpt("RPTINE" , 0x37); AddRpt("RPTIST" , 0x38);
  1297.   AddRpt("RPTIH"  , 0x39); AddRpt("RPTILE" , 0x3a); AddRpt("RPTIC"  , 0x3b);
  1298.   AddRpt("RPTIVT" , 0x3c); AddRpt("RPTIV"  , 0x3d); AddRpt("RPTILT" , 0x3e);
  1299.   AddRpt("RPTIE"  , 0x3f);
  1300. }
  1301.  
  1302. static void DeinitFields(void)
  1303. {
  1304.   DestroyInstTable(InstTable);
  1305. }
  1306.  
  1307. /*-------------------------------------------------------------------------*/
  1308.  
  1309. static void MakeCode_96(void)
  1310. {
  1311.   CodeLen = 0;
  1312.   DontPrint = False;
  1313.   OpSize = -1;
  1314.  
  1315.   /* zu ignorierendes */
  1316.  
  1317.   if (Memo(""))
  1318.     return;
  1319.  
  1320.   /* Pseudoanweisungen */
  1321.  
  1322.   if (DecodeIntelPseudo(False))
  1323.     return;
  1324.  
  1325.   if (!LookupInstTable(InstTable, OpPart.str.p_str))
  1326.     WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
  1327. }
  1328.  
  1329. static void InitCode_96(void)
  1330. {
  1331.   WSRVal  = 0; CalcWSRWindow();
  1332.   WSR1Val = 0; CalcWSR1Window();
  1333. }
  1334.  
  1335. static Boolean IsDef_96(void)
  1336. {
  1337.   return False;
  1338. }
  1339.  
  1340. static void SwitchFrom_96(void)
  1341. {
  1342.   DeinitFields();
  1343. }
  1344.  
  1345. static ASSUMERec ASSUME96s[] =
  1346. {
  1347.   {"WSR" , &WSRVal , 0, 0xff, 0x00, CalcWSRWindow  },
  1348.   {"WSR1", &WSR1Val, 0, 0xbf, 0x00, CalcWSR1Window },
  1349. };
  1350.  
  1351. static void SwitchTo_96(void)
  1352. {
  1353.   TurnWords = False;
  1354.   SetIntConstMode(eIntConstModeIntel);
  1355.  
  1356.   PCSymbol = "$";
  1357.   HeaderID = 0x39;
  1358.   NOPCode = 0xfd;
  1359.   DivideChars = ",";
  1360.   HasAttrs = False;
  1361.  
  1362.   ValidSegs = 1 << SegCode;
  1363.   Grans[SegCode ] = 1;
  1364.   ListGrans[SegCode ] = 1;
  1365.   SegInits[SegCode ] = 0;
  1366.   SegLimits[SegCode] = (MomCPU >= CPU80196N) ? 0xffffffl : 0xffff;
  1367.  
  1368.   MakeCode = MakeCode_96;
  1369.   IsDef = IsDef_96;
  1370.   SwitchFrom = SwitchFrom_96;
  1371.  
  1372.   MemInt = (MomCPU >= CPU80196N) ? UInt24 : UInt16;
  1373.  
  1374.   if (MomCPU >= CPU80196)
  1375.   {
  1376.     pASSUMERecs = ASSUME96s;
  1377.     ASSUMERecCnt = (MomCPU >= CPU80296) ? (sizeof(ASSUME96s) / sizeof(*ASSUME96s)) : 1;
  1378.   }
  1379.  
  1380.   InitFields();
  1381. }
  1382.  
  1383. void code96_init(void)
  1384. {
  1385.   CPU8096   = AddCPU("8096"  , SwitchTo_96);
  1386.   CPU80196  = AddCPU("80196" , SwitchTo_96);
  1387.   CPU80196N = AddCPU("80196N", SwitchTo_96);
  1388.   CPU80296  = AddCPU("80296" , SwitchTo_96);
  1389.  
  1390.   AddInitPassProc(InitCode_96);
  1391. }
  1392.