Subversion Repositories pentevo

Rev

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

  1. /* code6812.c */
  2. /*****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
  4. /*                                                                           */
  5. /* AS-Portierung                                                             */
  6. /*                                                                           */
  7. /* Codegeneratormodul CPU12                                                  */
  8. /*                                                                           */
  9. /*****************************************************************************/
  10.  
  11. #include "stdinc.h"
  12.  
  13. #include <ctype.h>
  14. #include <string.h>
  15.  
  16. #include "strutil.h"
  17. #include "bpemu.h"
  18. #include "asmdef.h"
  19. #include "asmpars.h"
  20. #include "asmsub.h"
  21. #include "asmallg.h"
  22. #include "asmitree.h"
  23. #include "codepseudo.h"
  24. #include "motpseudo.h"
  25. #include "intpseudo.h"
  26. #include "codevars.h"
  27. #include "errmsg.h"
  28.  
  29. #include "code6812.h"
  30.  
  31. typedef struct
  32. {
  33.   Word Code;
  34.   CPUVar MinCPU;
  35. } FixedOrder;
  36.  
  37. typedef struct
  38. {
  39.   Word Code;
  40.   CPUVar MinCPU;
  41.   Boolean MayImm, MayDir, MayExt;
  42.   tSymbolSize ThisOpSize;
  43. } GenOrder;
  44.  
  45. typedef struct
  46. {
  47.   Word Code;
  48.   Boolean MayDir;
  49. } JmpOrder;
  50.  
  51. typedef struct
  52. {
  53.   Word Code;
  54.   Byte OpSize;
  55.   CPUVar MinCPU;
  56. } Reg;
  57.  
  58. enum
  59. {
  60.   eShortModeAuto = 0,
  61.   eShortModeNo = 1,
  62.   eShortModeYes = 2,
  63.   eShortModeExtreme = 3
  64. };
  65.  
  66. enum
  67. {
  68.   ModNone = -1,
  69.   ModImm = 0,
  70.   ModDir = 1,
  71.   ModExt = 2,
  72.   ModIdx = 3,
  73.   ModIdx1 = 4,
  74.   ModIdx2 = 5,
  75.   ModDIdx = 6,
  76.   ModIIdx2 = 7,
  77.   ModExtPg = 8
  78. };
  79.  
  80. #define MModImm (1 << ModImm)
  81. #define MModDir (1 << ModDir)
  82. #define MModExt (1 << ModExt)
  83. #define MModIdx (1 << ModIdx)
  84. #define MModIdx1 (1 << ModIdx1)
  85. #define MModIdx2 (1 << ModIdx2)
  86. #define MModDIdx (1 << ModDIdx)
  87. #define MModIIdx2 (1 << ModIIdx2)
  88. #define MModExtPg (1 << ModExtPg)
  89.  
  90. #define MModAllIdx (MModIdx | MModIdx1 | MModIdx2 | MModDIdx | MModIIdx2)
  91.  
  92. static ShortInt AdrMode;
  93. static ShortInt ExPos;
  94. static Byte AdrVals[4];
  95. static Byte ActReg, ActRegSize;
  96. static CPUVar CPU6812, CPU6812X;
  97. static IntType AddrInt;
  98.  
  99. static LongInt Reg_Direct, Reg_GPage;
  100.  
  101. static FixedOrder *FixedOrders;
  102. static FixedOrder *BranchOrders;
  103. static GenOrder *GenOrders;
  104. static FixedOrder *LoopOrders;
  105. static FixedOrder *LEAOrders;
  106. static JmpOrder *JmpOrders;
  107. static Reg *Regs;
  108.  
  109. static PInstTable RegTable;
  110.  
  111. /*---------------------------------------------------------------------------*/
  112. /* Address Expression Decoder */
  113.  
  114. enum
  115. {
  116.   eRegA = 0,
  117.   eRegB = 1,
  118.   eRegCCRL = 2,
  119.   eRegD = 4,
  120.   eRegX = 5,
  121.   eRegY = 6,
  122.   eRegSP = 7,
  123.   eRegPC = 8,
  124.   eRegHalf = 0x40,
  125.   eRegUpper = 0x80,
  126.   eRegWord = 0xc0,
  127.   eRegXL = eRegHalf | eRegX,
  128.   eRegXH = eRegHalf | eRegUpper | eRegX,
  129.   eRegYL = eRegHalf | eRegY,
  130.   eRegYH = eRegHalf | eRegUpper | eRegY,
  131.   eRegSPL = eRegHalf | eRegSP,
  132.   eRegSPH = eRegHalf | eRegUpper | eRegSP,
  133.   eRegCCRH = eRegCCRL | eRegUpper,
  134.   eRegCCRW = eRegCCRL | eRegWord,
  135.   eNoReg = 0xff
  136. };
  137.  
  138. static Boolean DecodeReg(const char *pAsc, Byte *pErg)
  139. {
  140.   Boolean Result;
  141.   String Reg;
  142.  
  143.   strmaxcpy(Reg, pAsc, STRINGSIZE);
  144.   UpString(Reg);
  145.   Result = LookupInstTable(RegTable, Reg) && (ActReg != eNoReg);
  146.  
  147.   if (Result)
  148.     *pErg = ActReg;
  149.  
  150.   return Result;
  151. }
  152.  
  153. enum
  154. {
  155.   eBaseRegX = 0,
  156.   eBaseRegY = 1,
  157.   eBaseRegSP = 2,
  158.   eBaseRegPC = 3
  159. };
  160.  
  161. static Boolean DecodeBaseReg(const char *pAsc, Byte *pErg)
  162. {
  163.   Boolean Result = DecodeReg(pAsc, pErg);
  164.  
  165.   if (Result)
  166.   {
  167.     switch (*pErg)
  168.     {
  169.       case eRegX:
  170.         *pErg = eBaseRegX;
  171.         break;
  172.       case eRegY:
  173.         *pErg = eBaseRegY;
  174.         break;
  175.       case eRegSP:
  176.         *pErg = eBaseRegSP;
  177.         break;
  178.       case eRegPC:
  179.         *pErg = eBaseRegPC;
  180.         break;
  181.       default:
  182.         Result = FALSE;
  183.     }
  184.   }
  185.  
  186.   return Result;
  187. }
  188.  
  189. static Boolean ValidReg(const char *Asc_o)
  190. {
  191.   Byte Dummy;
  192.   String Asc;
  193.   int l = strlen(Asc_o);
  194.  
  195.   if ((*Asc_o == '-') || (*Asc_o == '+'))
  196.     strcpy(Asc, Asc_o + 1);
  197.   else
  198.   {
  199.     strcpy(Asc, Asc_o);
  200.     if ((l > 0) && ((Asc_o[l - 1] == '-') || (Asc_o[l - 1] == '+')))
  201.       Asc[l - 1] = '\0';
  202.   }
  203.   return DecodeBaseReg(Asc, &Dummy);
  204. }
  205.  
  206. enum
  207. {
  208.   eIdxRegA = 0,
  209.   eIdxRegB = 1,
  210.   eIdxRegD = 2
  211. };
  212.  
  213. static Boolean DecodeIdxReg(const char *pAsc, Byte *pErg)
  214. {
  215.   Boolean Result = DecodeReg(pAsc, pErg);
  216.  
  217.   if (Result)
  218.   {
  219.     switch (*pErg)
  220.     {
  221.       case eRegA:
  222.         *pErg = eIdxRegA;
  223.         break;
  224.       case eRegB:
  225.         *pErg = eIdxRegB;
  226.         break;
  227.       case eRegD:
  228.         *pErg = eIdxRegD;
  229.         break;
  230.       default:
  231.         Result = FALSE;
  232.     }
  233.   }
  234.  
  235.   return Result;
  236. }
  237.  
  238. static Boolean ChkRegPair(Byte SrcReg, Byte DestReg, Byte *pExtMask)
  239. {
  240.   Boolean Result = TRUE;
  241.  
  242.   switch (SrcReg)
  243.   {
  244.     case eRegA:
  245.       if ((DestReg <= eRegCCRL) || ((DestReg >= eRegD) && (DestReg <= eRegSP)))
  246.         *pExtMask = 0;
  247.       else if ((DestReg == eRegCCRH) || (DestReg == eRegXH) || (DestReg == eRegYH) || (DestReg == eRegSPH))
  248.         *pExtMask = 8;
  249.       else
  250.         Result = False;
  251.       break;
  252.  
  253.     case eRegB:
  254.       if ((DestReg <= eRegCCRL) || ((DestReg >= eRegD) && (DestReg <= eRegSP)))
  255.         *pExtMask = 0;
  256.       else if ((DestReg == eRegXL) || (DestReg == eRegYL) || (DestReg == eRegSPL))
  257.         *pExtMask = 8;
  258.       else
  259.         Result = False;
  260.       break;
  261.  
  262.     case eRegCCRL:
  263.       if ((DestReg <= eRegCCRL) || ((DestReg >= eRegD) && (DestReg <= eRegSP)))
  264.         *pExtMask = 0;
  265.       else
  266.         Result = False;
  267.       break;
  268.  
  269.     case eRegD:
  270.     case eRegX:
  271.     case eRegY:
  272.     case eRegSP:
  273.       if ((DestReg <= eRegCCRL) || ((DestReg >= eRegD) && (DestReg <= eRegSP)))
  274.         *pExtMask = 0;
  275.       else if (DestReg == eRegCCRW)
  276.         *pExtMask = 8;
  277.       else
  278.         Result = False;
  279.       break;
  280.  
  281.     case eRegXL:
  282.     case eRegYL:
  283.     case eRegSPL:
  284.       if (DestReg <= eRegCCRL)
  285.         *pExtMask = 0;
  286.       else
  287.         Result = False;
  288.       break;
  289.  
  290.     case eRegXH:
  291.     case eRegYH:
  292.     case eRegSPH:
  293.     case eRegCCRH:
  294.       if (DestReg == eRegA)
  295.         *pExtMask = 8;
  296.       else
  297.         Result = False;
  298.       break;
  299.  
  300.     case eRegCCRW:
  301.       if ((DestReg == eRegCCRW) || ((DestReg >= eRegD) && (DestReg <= eRegSP)))
  302.         *pExtMask = 8;
  303.       else
  304.         Result = False;
  305.       break;
  306.  
  307.     default:
  308.       Result = False;
  309.   }
  310.  
  311.   if ((Result) && (*pExtMask) && (MomCPU < CPU6812X))
  312.     Result = FALSE;
  313.  
  314.   return Result;
  315. }
  316.  
  317. static void CutShort(char *Asc, Integer *ShortMode)
  318. {
  319.   if (*Asc == '>')
  320.   {
  321.     *ShortMode = eShortModeNo;
  322.     strmov(Asc, Asc + 1);
  323.   }
  324.   else if (*Asc == '<')
  325.   {
  326.     if (Asc[1] == '<')
  327.     {
  328.       *ShortMode = eShortModeExtreme;
  329.       strmov(Asc, Asc + 2);
  330.     }
  331.     else
  332.     {
  333.       *ShortMode = eShortModeYes;
  334.       strmov(Asc,Asc + 1);
  335.     }
  336.   }
  337.   else
  338.     *ShortMode = eShortModeAuto;
  339. }
  340.  
  341. static Boolean DistFits(Byte Reg, Integer Dist, Integer Offs, LongInt Min, LongInt Max, tSymbolFlags Flags)
  342. {
  343.   if (Reg == eBaseRegPC)
  344.     Dist -= Offs;
  345.   return (((Dist >= Min) && (Dist <= Max)) || ((Reg == eBaseRegPC) && mSymbolQuestionable(Flags)));
  346. }
  347.  
  348. static void DecodeAdr(int Start, int Stop, tSymbolSize op_size, Word Mask)
  349. {
  350.   Integer ShortMode;
  351.   LongInt AdrWord;
  352.   int l;
  353.   char *p;
  354.   Boolean OK;
  355.   tSymbolFlags Flags;
  356.   Boolean DecFlag, AutoFlag, PostFlag;
  357.  
  358.   AdrMode = ModNone;
  359.   AdrCnt = 0;
  360.  
  361.   /* one argument? */
  362.  
  363.   if (Stop - Start == 0)
  364.   {
  365.     /* immediate */
  366.  
  367.     if (*ArgStr[Start].str.p_str == '#')
  368.     {
  369.       switch (op_size)
  370.       {
  371.         case eSymbolSizeUnknown:
  372.           WrError(ErrNum_UndefOpSizes);
  373.           break;
  374.         case eSymbolSize8Bit:
  375.           AdrVals[0] = EvalStrIntExpressionOffs(&ArgStr[Start], 1, Int8, &OK);
  376.           if (OK)
  377.           {
  378.             AdrCnt = 1;
  379.             AdrMode = ModImm;
  380.           }
  381.           break;
  382.         case eSymbolSize16Bit:
  383.           AdrWord = EvalStrIntExpressionOffs(&ArgStr[Start], 1, Int16, &OK);
  384.           if (OK)
  385.           {
  386.             AdrVals[0] = AdrWord >> 8;
  387.             AdrVals[1] = AdrWord & 0xff;
  388.             AdrCnt = 2;
  389.             AdrMode = ModImm;
  390.           }
  391.           break;
  392.         default:
  393.           break;
  394.       }
  395.       goto chk;
  396.     }
  397.  
  398.     /* indirekt */
  399.  
  400.     if ((*ArgStr[Start].str.p_str == '[') && (ArgStr[Start].str.p_str[strlen(ArgStr[Start].str.p_str) - 1] == ']'))
  401.     {
  402.       strmov(ArgStr[Start].str.p_str, ArgStr[Start].str.p_str + 1);
  403.       ArgStr[Start].str.p_str[strlen(ArgStr[Start].str.p_str) - 1] = '\0';
  404.       p = QuotPos(ArgStr[Start].str.p_str, ',');
  405.       if (p)
  406.         *p = '\0';
  407.       if (!p) WrError(ErrNum_InvAddrMode);
  408.       else if (!DecodeBaseReg(p + 1, AdrVals))
  409.         WrXError(ErrNum_InvReg, p + 1);
  410.       else if (!as_strcasecmp(ArgStr[Start].str.p_str, "D"))
  411.       {
  412.         AdrVals[0] = (AdrVals[0] << 3) | 0xe7;
  413.         AdrCnt = 1;
  414.         AdrMode = ModDIdx;
  415.       }
  416.       else
  417.       {
  418.         AdrWord = EvalStrIntExpression(&ArgStr[Start], Int16, &OK);
  419.         if (OK)
  420.         {
  421.           if (AdrVals[0] == eBaseRegPC)
  422.             AdrWord -= EProgCounter() + ExPos + 3;
  423.           AdrVals[0] = (AdrVals[0] << 3) | 0xe3;
  424.           AdrVals[1] = AdrWord >> 8;
  425.           AdrVals[2] = AdrWord & 0xff;
  426.           AdrCnt = 3;
  427.           AdrMode = ModIIdx2;
  428.         }
  429.       }
  430.       goto chk;
  431.     }
  432.  
  433.     /* dann absolut */
  434.  
  435.     CutShort(ArgStr[Start].str.p_str, &ShortMode);
  436.     AdrWord = EvalStrIntExpressionWithFlags(&ArgStr[Start], AddrInt, &OK, &Flags);
  437.     if (mFirstPassUnknown(Flags))
  438.     {
  439.       if ((!(Mask & (MModExt | MModExtPg))) || (ShortMode == eShortModeYes))
  440.         AdrWord = (Reg_Direct << 8) | Lo(AdrWord);
  441.     }
  442.  
  443.     if (OK)
  444.     {
  445.       if ((ShortMode != eShortModeNo)
  446.        && (Hi(AdrWord) == Reg_Direct)
  447.        && ((Mask & MModDir) != 0))
  448.       {
  449.         AdrMode = ModDir;
  450.         AdrVals[0] = AdrWord & 0xff;
  451.         AdrCnt = 1;
  452.       }
  453.       else
  454.       {
  455.         AdrMode = ModExt;
  456.         AdrVals[0] = Hi(AdrWord);
  457.         AdrVals[1] = Lo(AdrWord);
  458.         if (Mask & MModExtPg)
  459.         {
  460.           Mask |= MModExt;
  461.           if ((HiWord(EProgCounter()) != HiWord(AdrWord))
  462.            && ((AdrWord & 0xc000) == 0x8000)
  463.            && ((EProgCounter() & 0xc000) == 0x8000)
  464.            && !mFirstPassUnknown(Flags))
  465.             WrError(ErrNum_PageCrossing);
  466.         }
  467.         AdrCnt = 2;
  468.       }
  469.     }
  470.     goto chk;
  471.   }
  472.  
  473.   /* two arguments? */
  474.  
  475.   else if (Stop - Start == 1)
  476.   {
  477.     /* Autoin/-dekrement abspalten */
  478.  
  479.     l = strlen(ArgStr[Stop].str.p_str);
  480.     if ((*ArgStr[Stop].str.p_str == '-') || (*ArgStr[Stop].str.p_str == '+'))
  481.     {
  482.       DecFlag = (*ArgStr[Stop].str.p_str == '-');
  483.       AutoFlag = True;
  484.       PostFlag = False;
  485.       strmov(ArgStr[Stop].str.p_str, ArgStr[Stop].str.p_str + 1);
  486.     }
  487.     else if ((ArgStr[Stop].str.p_str[l - 1] == '-') || (ArgStr[Stop].str.p_str[l - 1] == '+'))
  488.     {
  489.       DecFlag = (ArgStr[Stop].str.p_str[l - 1] == '-');
  490.       AutoFlag = True;
  491.       PostFlag = True;
  492.       ArgStr[Stop].str.p_str[l - 1] = '\0';
  493.     }
  494.     else
  495.       AutoFlag = DecFlag = PostFlag = False;
  496.  
  497.     if (AutoFlag)
  498.     {
  499.       if (!DecodeBaseReg(ArgStr[Stop].str.p_str, AdrVals)) WrStrErrorPos(ErrNum_InvReg, &ArgStr[Stop]);
  500.       else if (AdrVals[0] == eBaseRegPC) WrStrErrorPos(ErrNum_InvReg, &ArgStr[Stop]);
  501.       else
  502.       {
  503.         AdrWord = EvalStrIntExpressionWithFlags(&ArgStr[Start], SInt8, &OK, &Flags);
  504.         if (mFirstPassUnknown(Flags))
  505.           AdrWord = 1;
  506.  
  507.         /* no increment/decrement degenerates to register indirect with zero displacement! */
  508.  
  509.         if (AdrWord == 0)
  510.         {
  511.           AdrVals[0] = (AdrVals[0] << 6);
  512.           AdrCnt = 1;
  513.           AdrMode = ModIdx;
  514.         }
  515.         else if (AdrWord > 8) WrError(ErrNum_OverRange);
  516.         else if (AdrWord < -8) WrError(ErrNum_UnderRange);
  517.         else
  518.         {
  519.           if (AdrWord < 0)
  520.           {
  521.             DecFlag = !DecFlag;
  522.             AdrWord = (-AdrWord);
  523.           }
  524.           AdrWord = DecFlag ? 8 - AdrWord : AdrWord - 1;
  525.           AdrVals[0] = (AdrVals[0] << 6) | 0x20 | (Ord(PostFlag) << 4) | (Ord(DecFlag) << 3) | (AdrWord & 7);
  526.           AdrCnt = 1;
  527.           AdrMode = ModIdx;
  528.         }
  529.       }
  530.       goto chk;
  531.     }
  532.  
  533.     else
  534.     {
  535.       if (!DecodeBaseReg(ArgStr[Stop].str.p_str, AdrVals)) WrStrErrorPos(ErrNum_InvReg, &ArgStr[Stop]);
  536.       else if (DecodeIdxReg(ArgStr[Start].str.p_str, AdrVals + 1))
  537.       {
  538.         AdrVals[0] = (AdrVals[0] << 3) | AdrVals[1] | 0xe4;
  539.         AdrCnt = 1;
  540.         AdrMode = ModIdx;
  541.       }
  542.       else
  543.       {
  544.         CutShort(ArgStr[Start].str.p_str, &ShortMode);
  545.         if (ArgStr[Start].str.p_str[0])
  546.           AdrWord = EvalStrIntExpressionWithFlags(&ArgStr[Start], Int16, &OK, &Flags);
  547.         else
  548.         {
  549.           AdrWord = 0;
  550.           OK = True;
  551.         }
  552.         if (AdrVals[0] == eBaseRegPC)
  553.           AdrWord -= EProgCounter() + ExPos;
  554.         if (OK)
  555.         {
  556.           if ((ShortMode != eShortModeNo) && (ShortMode != eShortModeYes) && ((Mask & MModIdx) != 0) && (DistFits(AdrVals[0], AdrWord, 1, -16, 15, Flags)))
  557.           {
  558.             if (AdrVals[0] == eBaseRegPC)
  559.               AdrWord--;
  560.             AdrVals[0] = (AdrVals[0] << 6) | (AdrWord & 0x1f);
  561.             AdrCnt = 1;
  562.             AdrMode = ModIdx;
  563.           }
  564.           else if ((ShortMode != eShortModeNo) && (ShortMode != eShortModeExtreme) && ((Mask & MModIdx1) != 0) && (DistFits(AdrVals[0], AdrWord, 2, -256, 255, Flags)))
  565.           {
  566.             if (AdrVals[0] == eBaseRegPC)
  567.               AdrWord -= 2;
  568.             AdrVals[0] = 0xe0 | (AdrVals[0] << 3) | (Hi(AdrWord) & 1);
  569.             AdrVals[1] = Lo(AdrWord);
  570.             AdrCnt = 2;
  571.             AdrMode = ModIdx1;
  572.           }
  573.           else
  574.           {
  575.             if (AdrVals[0] == eBaseRegPC)
  576.               AdrWord -= 3;
  577.             AdrVals[0] = 0xe2 | (AdrVals[0] << 3);
  578.             AdrVals[1] = Hi(AdrWord);
  579.             AdrVals[2] = Lo(AdrWord);
  580.             AdrCnt = 3;
  581.             AdrMode = ModIdx2;
  582.           }
  583.         }
  584.       }
  585.       goto chk;
  586.     }
  587.   }
  588.  
  589.   else WrError(ErrNum_InvAddrMode);
  590.  
  591. chk:
  592.   if ((AdrMode != ModNone) && (((1 << AdrMode) & Mask) == 0))
  593.   {
  594.     AdrMode = ModNone;
  595.     AdrCnt = 0;
  596.     WrError(ErrNum_InvAddrMode);
  597.   }
  598. }
  599.  
  600. static void Try2Split(int Src)
  601. {
  602.   char *p;
  603.   int z;
  604.   size_t SrcLen;
  605.  
  606.   KillPrefBlanksStrComp(&ArgStr[Src]);
  607.   KillPostBlanksStrComp(&ArgStr[Src]);
  608.   SrcLen = strlen(ArgStr[Src].str.p_str);
  609.   p = ArgStr[Src].str.p_str + SrcLen - 1;
  610.   while ((p >= ArgStr[Src].str.p_str) && !as_isspace(*p))
  611.     p--;
  612.   if (p >= ArgStr[Src].str.p_str)
  613.   {
  614.     InsertArg(Src + 1, SrcLen);
  615.     for (z = ArgCnt - 1; z >= Src + 1; z--)
  616.       StrCompCopy(&ArgStr[z + 1], &ArgStr[z]);
  617.     StrCompSplitRight(&ArgStr[Src], &ArgStr[Src + 1], p);
  618.     KillPostBlanksStrComp(&ArgStr[Src]);
  619.     KillPrefBlanksStrComp(&ArgStr[Src + 1]);
  620.   }
  621. }
  622.  
  623. /*---------------------------------------------------------------------------*/
  624. /* Instruction Decoders */
  625.  
  626. static void DecodeFixed(Word Index)
  627. {
  628.   FixedOrder *pOrder = FixedOrders + Index;
  629.  
  630.   if (!ChkArgCnt(0, 0));
  631.   else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  632.   else if (!ChkMinCPU(pOrder->MinCPU));
  633.   else
  634.   {
  635.     if (Hi(pOrder->Code))
  636.       BAsmCode[CodeLen++] = Hi(pOrder->Code);
  637.     BAsmCode[CodeLen++] = Lo(pOrder->Code);
  638.   }
  639. }
  640.  
  641. static void DecodeGen(Word Index)
  642. {
  643.   GenOrder *pOrder = GenOrders + Index;
  644.  
  645.   if (!ChkArgCnt(1, 2));
  646.   else if (!ChkMinCPU(pOrder->MinCPU));
  647.   else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  648.   else
  649.   {
  650.     ExPos = 1 + Ord(Hi(pOrder->Code) != 0);
  651.     DecodeAdr(1, ArgCnt, pOrder->ThisOpSize, MModAllIdx | (pOrder->MayImm ? MModImm : 0) | (pOrder->MayDir ? MModDir : 0) | (pOrder->MayExt ? MModExt : 0));
  652.     if (AdrMode != ModNone)
  653.     {
  654.       if (Hi(pOrder->Code) == 0)
  655.       {
  656.         BAsmCode[0] = pOrder->Code;
  657.         CodeLen = 1;
  658.       }
  659.       else
  660.       {
  661.         BAsmCode[0] = Hi(pOrder->Code);
  662.         BAsmCode[1] = Lo(pOrder->Code);
  663.         CodeLen = 2;
  664.       }
  665.     }
  666.     switch (AdrMode)
  667.     {
  668.       case ModImm:
  669.         break;
  670.       case ModDir:
  671.         BAsmCode[CodeLen - 1] += 0x10;
  672.         break;
  673.       case ModIdx:
  674.       case ModIdx1:
  675.       case ModIdx2:
  676.       case ModDIdx:
  677.       case ModIIdx2:
  678.         BAsmCode[CodeLen - 1] += 0x20;
  679.         break;
  680.       case ModExt:
  681.         BAsmCode[CodeLen - 1] += 0x30;
  682.         break;
  683.     }
  684.     if (AdrMode != ModNone)
  685.     {
  686.       memcpy(BAsmCode + CodeLen, AdrVals, AdrCnt);
  687.       CodeLen += AdrCnt;
  688.     }
  689.   }
  690. }
  691.  
  692. static void DecodeLEA(Word Index)
  693. {
  694.   FixedOrder *pOrder = LEAOrders + Index;
  695.  
  696.   if (!ChkArgCnt(1, 2));
  697.   else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  698.   else
  699.   {
  700.     ExPos = 1;
  701.     DecodeAdr(1, ArgCnt, eSymbolSizeUnknown, MModIdx | MModIdx1 | MModIdx2);
  702.     if (AdrMode != ModNone)
  703.     {
  704.       BAsmCode[0] = pOrder->Code;
  705.       memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  706.       CodeLen = 1 + AdrCnt;
  707.     }
  708.   }
  709. }
  710.  
  711. static void DecodeBranch(Word Index)
  712. {
  713.   FixedOrder *pOrder = BranchOrders + Index;
  714.   LongInt Address;
  715.   Boolean OK;
  716.   tSymbolFlags Flags;
  717.  
  718.   if (!ChkArgCnt(1, 1));
  719.   else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  720.   else
  721.   {
  722.     Address = EvalStrIntExpressionWithFlags(&ArgStr[1], AddrInt, &OK, &Flags) - EProgCounter() - 2;
  723.     if (OK)
  724.     {
  725.       if (((Address < -128) || (Address > 127)) && !mSymbolQuestionable(Flags)) WrError(ErrNum_JmpDistTooBig);
  726.       else
  727.       {
  728.         BAsmCode[0] = pOrder->Code;
  729.         BAsmCode[1] = Lo(Address);
  730.         CodeLen = 2;
  731.       }
  732.     }
  733.   }
  734. }
  735.  
  736. static void DecodeLBranch(Word Index)
  737. {
  738.   FixedOrder *pOrder = BranchOrders + Index;
  739.   LongInt Address;
  740.   Boolean OK;
  741.  
  742.   if (!ChkArgCnt(1, 1));
  743.   else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  744.   else
  745.   {
  746.     Address = EvalStrIntExpression(&ArgStr[1], AddrInt, &OK) - EProgCounter() - 4;
  747.     if (OK)
  748.     {
  749.       BAsmCode[0] = 0x18;
  750.       BAsmCode[1] = pOrder->Code;
  751.       BAsmCode[2] = Hi(Address);
  752.       BAsmCode[3] = Lo(Address);
  753.       CodeLen = 4;
  754.     }
  755.   }
  756. }
  757.  
  758. static void DecodeJmp(Word Index)
  759. {
  760.   JmpOrder *pOrder = JmpOrders + Index;
  761.   Word Mask;
  762.  
  763.   if (!ChkArgCnt(1, 2));
  764.   else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  765.   else
  766.   {
  767.     Mask = MModAllIdx | MModExtPg;
  768.     if (pOrder->MayDir)
  769.       Mask |= MModDir;
  770.     ExPos = 1;
  771.     DecodeAdr(1, ArgCnt, eSymbolSizeUnknown, Mask);
  772.     if (AdrMode != ModNone)
  773.     {
  774.       switch (AdrMode)
  775.       {
  776.         case ModExt:
  777.           BAsmCode[0] = pOrder->Code;
  778.           break;
  779.         case ModDir:
  780.           BAsmCode[0] = pOrder->Code + 1;
  781.           break;
  782.         case ModIdx:
  783.         case ModIdx1:
  784.         case ModIdx2:
  785.         case ModDIdx:
  786.         case ModIIdx2:
  787.           BAsmCode[0] = pOrder->Code - 1;
  788.           break;
  789.       }
  790.       memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  791.       CodeLen = 1 + AdrCnt;
  792.     }
  793.   }
  794. }
  795.  
  796. static void DecodeLoop(Word Index)
  797. {
  798.   FixedOrder *pOrder = LoopOrders + Index;
  799.   Byte HReg;
  800.   LongInt Address;
  801.   Boolean OK;
  802.   tSymbolFlags Flags;
  803.  
  804.   if (!ChkArgCnt(2, 2));
  805.   else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  806.   else if (!DecodeReg(ArgStr[1].str.p_str, &HReg)) WrStrErrorPos(ErrNum_InvReg, &ArgStr[1]);
  807.   else
  808.   {
  809.     OK = (HReg <= eRegB) || ((HReg >= eRegD) && (HReg <= eRegSP));
  810.     if (!OK) WrStrErrorPos(ErrNum_InvReg, &ArgStr[1]);
  811.     else
  812.     {
  813.       Address = EvalStrIntExpressionWithFlags(&ArgStr[2], AddrInt, &OK, &Flags) - (EProgCounter() + 3);
  814.       if (OK)
  815.       {
  816.         if (((Address < -256) || (Address > 255)) && !mSymbolQuestionable(Flags)) WrError(ErrNum_JmpDistTooBig);
  817.         else
  818.         {
  819.           BAsmCode[0] = 0x04;
  820.           BAsmCode[1] = pOrder->Code | HReg | ((Address >> 4) & 0x10);
  821.           BAsmCode[2] = Address & 0xff;
  822.           CodeLen = 3;
  823.         }
  824.       }
  825.     }
  826.   }
  827. }
  828.  
  829. static void DecodeETBL(Word Index)
  830. {
  831.   if (!ChkArgCnt(1, 2));
  832.   else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  833.   else
  834.   {
  835.     ExPos = 2;
  836.     DecodeAdr(1, ArgCnt, eSymbolSizeUnknown, MModIdx);
  837.     if (AdrMode == ModIdx)
  838.     {
  839.       BAsmCode[0] = 0x18;
  840.       BAsmCode[1] = Index;
  841.       memcpy(BAsmCode + 2, AdrVals, AdrCnt);
  842.       CodeLen = 2 + AdrCnt;
  843.     }
  844.   }
  845. }
  846.  
  847. static void DecodeEMACS(Word Index)
  848. {
  849.   LongInt Address;
  850.   Boolean OK;
  851.  
  852.   UNUSED(Index);
  853.  
  854.   if (!ChkArgCnt(1, 1));
  855.   else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  856.   else
  857.   {
  858.     Address = EvalStrIntExpression(&ArgStr[1], UInt16, &OK);
  859.     if (OK)
  860.     {
  861.       BAsmCode[0] = 0x18;
  862.       BAsmCode[1] = 0x12;
  863.       BAsmCode[2] = Hi(Address) & 0xff;
  864.       BAsmCode[3] = Lo(Address);
  865.       CodeLen = 4;
  866.     }
  867.   }
  868. }
  869.  
  870. static void DecodeTransfer(Word Index)
  871. {
  872.   Byte Reg1, Reg2;
  873.   Byte ExtMask;
  874.  
  875.   if (!ChkArgCnt(2, 2));
  876.   else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  877.   else if (!DecodeReg(ArgStr[2].str.p_str, &Reg2)) WrStrErrorPos(ErrNum_InvReg, &ArgStr[2]);
  878.   else if (eRegPC == Reg2) WrStrErrorPos(ErrNum_InvReg, &ArgStr[2]);
  879.   else if (!DecodeReg(ArgStr[1].str.p_str, &Reg1)) WrStrErrorPos(ErrNum_InvReg, &ArgStr[1]);
  880.   else if (eRegPC == Reg1) WrStrErrorPos(ErrNum_InvReg, &ArgStr[1]);
  881.   else if (!ChkRegPair(Reg1, Reg2, &ExtMask)) WrError(ErrNum_InvRegPair);
  882.   else
  883.   {
  884.     BAsmCode[0] = 0xb7;
  885.     Reg1 &= 7;
  886.     Reg2 &= 7;
  887.     BAsmCode[1] = Index | (Reg1 << 4) | Reg2 | ExtMask;
  888.     CodeLen = 2;
  889.   }
  890. }
  891.  
  892. static void DecodeSEX(Word Index)
  893. {
  894.   Byte Reg1, Reg2;
  895.   Byte ExtMask;
  896.  
  897.   if (!ChkArgCnt(2, 2));
  898.   else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  899.   else if (!DecodeReg(ArgStr[2].str.p_str, &Reg2)) WrStrErrorPos(ErrNum_InvReg, &ArgStr[2]);
  900.   else if (ActRegSize != 1) WrStrErrorPos(ErrNum_InvReg, &ArgStr[2]);
  901.   else if (eRegPC == Reg2) WrStrErrorPos(ErrNum_InvReg, &ArgStr[2]);
  902.   else if (!DecodeReg(ArgStr[1].str.p_str, &Reg1)) WrStrErrorPos(ErrNum_InvReg, &ArgStr[1]);
  903.   else if (ActRegSize != 0) WrStrErrorPos(ErrNum_InvReg, &ArgStr[1]);
  904.   else if (eRegPC == Reg1) WrStrErrorPos(ErrNum_InvReg, &ArgStr[1]);
  905.   else if (!ChkRegPair(Reg1, Reg2, &ExtMask)) WrError(ErrNum_InvRegPair);
  906.   else
  907.   {
  908.     BAsmCode[0] = 0xb7;
  909.     BAsmCode[1] = Index | (Reg1 << 4) | Reg2 | ExtMask;
  910.     CodeLen = 2;
  911.   }
  912. }
  913.  
  914. static void DecodeMOV(Word Index)
  915. {
  916.   Byte Arg2Start, HCnt = 0, HAdrVals[4];
  917.   Word Mask;
  918.  
  919.   switch (ArgCnt)
  920.   {
  921.     case 1:
  922.       Try2Split(1);
  923.       break;
  924.     case 2:
  925.       Try2Split(1);
  926.       if (ArgCnt == 2)
  927.         Try2Split(2);
  928.       break;
  929.     case 3:
  930.       Try2Split(2);
  931.       break;
  932.   }
  933.  
  934.   if (!ChkArgCnt(2, 4));
  935.   else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  936.   else
  937.   {
  938.     tSymbolSize op_size = (tSymbolSize)Index;
  939.  
  940.     if (ArgCnt == 2)
  941.       Arg2Start = 2;
  942.     else if (ArgCnt == 4)
  943.       Arg2Start = 3;
  944.     else if (ValidReg(ArgStr[2].str.p_str))
  945.       Arg2Start = 3;
  946.     else
  947.       Arg2Start = 2;
  948.     ExPos = 2;
  949.     BAsmCode[0] = 0x18;
  950.     BAsmCode[1] = (1 - Index) << 3;
  951.  
  952.     Mask = MModImm | MModExt | MModIdx;
  953.     if (MomCPU >= CPU6812X)
  954.       Mask |= MModIdx1 | MModIdx2 | MModDIdx | MModIIdx2;
  955.  
  956.     /* decode & save source operand */
  957.  
  958.     DecodeAdr(1, Arg2Start - 1, op_size, Mask);
  959.     if (AdrMode != ModNone)
  960.     {
  961.       memcpy(HAdrVals, AdrVals, AdrCnt);
  962.       HCnt = AdrCnt;
  963.     }
  964.  
  965.     /* dispatch source address mode */
  966.  
  967.     switch (AdrMode)
  968.     {
  969.       case ModImm:
  970.         ExPos = 4 + 2 * op_size;
  971.         DecodeAdr(Arg2Start, ArgCnt, eSymbolSizeUnknown, MModExt | MModIdx | MModIdx1 | MModIdx2 | MModDIdx | MModIIdx2);
  972.         switch (AdrMode)
  973.         {
  974.           case ModExt:
  975.             BAsmCode[1] |= 3;
  976.             memcpy(BAsmCode + 2, HAdrVals, HCnt);
  977.             memcpy(BAsmCode + 2 + HCnt, AdrVals, AdrCnt);
  978.             break;
  979.           case ModIdx:
  980.           case ModIdx1:
  981.           case ModIdx2:
  982.           case ModDIdx:
  983.           case ModIIdx2:
  984.             memcpy(BAsmCode + 2, AdrVals, AdrCnt);
  985.             memcpy(BAsmCode + 2 + AdrCnt, HAdrVals, HCnt);
  986.             break;
  987.         }
  988.         break;
  989.       case ModExt:
  990.         ExPos = 6;
  991.         DecodeAdr(Arg2Start, ArgCnt, eSymbolSizeUnknown, MModExt | MModIdx | MModIdx1 | MModIdx2 | MModDIdx | MModIIdx2);
  992.         switch (AdrMode)
  993.         {
  994.           case ModExt:
  995.             BAsmCode[1] |= 4;
  996.             memcpy(BAsmCode + 2, HAdrVals, HCnt);
  997.             memcpy(BAsmCode + 2 + HCnt, AdrVals, AdrCnt);
  998.             break;
  999.           case ModIdx:
  1000.           case ModIdx1:
  1001.           case ModIdx2:
  1002.           case ModDIdx:
  1003.           case ModIIdx2:
  1004.             BAsmCode[1] |= 1;
  1005.             memcpy(BAsmCode + 2, AdrVals, AdrCnt);
  1006.             memcpy(BAsmCode + 2 + AdrCnt, HAdrVals, HCnt);
  1007.             break;
  1008.         }
  1009.         break;
  1010.       case ModIdx:
  1011.       case ModIdx1:
  1012.       case ModIdx2:
  1013.       case ModDIdx:
  1014.       case ModIIdx2:
  1015.         ExPos = 4;
  1016.         DecodeAdr(Arg2Start, ArgCnt, eSymbolSizeUnknown, MModExt | MModIdx| MModIdx1 | MModIdx2 | MModDIdx | MModIIdx2);
  1017.         if (AdrMode != ModNone)
  1018.         {
  1019.           BAsmCode[1] |= (AdrMode == ModExt) ? 5 : 2;
  1020.           memcpy(BAsmCode + 2, HAdrVals, HCnt);
  1021.           memcpy(BAsmCode + 2 + HCnt, AdrVals, AdrCnt);
  1022.         }
  1023.         break;
  1024.     }
  1025.     if (AdrMode != ModNone)
  1026.       CodeLen = 2 + AdrCnt + HCnt;
  1027.   }
  1028. }
  1029.  
  1030. static void DecodeLogic(Word Index)
  1031. {
  1032.   if (!ChkArgCnt(1, 1));
  1033.   else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  1034.   else
  1035.   {
  1036.     DecodeAdr(1, 1, eSymbolSize8Bit, MModImm);
  1037.     if (AdrMode == ModImm)
  1038.     {
  1039.       BAsmCode[0] = 0x10 | Index;
  1040.       BAsmCode[1] = AdrVals[0];
  1041.       CodeLen = 2;
  1042.     }
  1043.   }
  1044. }
  1045.  
  1046. static void DecodeBit(Word Index)
  1047. {
  1048.   Byte HReg;
  1049.   Boolean OK;
  1050.  
  1051.   if ((ArgCnt == 1) || (ArgCnt == 2))
  1052.     Try2Split(ArgCnt);
  1053.  
  1054.   if (!ChkArgCnt(2, 3));
  1055.   else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  1056.   else
  1057.   {
  1058.     HReg = EvalStrIntExpressionOffs(&ArgStr[ArgCnt], !!(*ArgStr[ArgCnt].str.p_str  == '#'), UInt8, &OK);
  1059.     if (OK)
  1060.     {
  1061.       ExPos = 2; /* wg. Masken-Postbyte */
  1062.       DecodeAdr(1, ArgCnt - 1, eSymbolSizeUnknown, MModDir | MModExt | MModIdx | MModIdx1 | MModIdx2);
  1063.       if (AdrMode != ModNone)
  1064.       {
  1065.         BAsmCode[0] = Index;
  1066.         switch (AdrMode)
  1067.         {
  1068.           case ModDir:
  1069.             BAsmCode[0] += 0x40;
  1070.             break;
  1071.           case ModExt:
  1072.             BAsmCode[0] += 0x10;
  1073.             break;
  1074.         }
  1075.         memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  1076.         BAsmCode[1 + AdrCnt] = HReg;
  1077.         CodeLen = 2 + AdrCnt;
  1078.       }
  1079.     }
  1080.   }
  1081. }
  1082.  
  1083. static void DecodeCALL(Word Index)
  1084. {
  1085.   UNUSED(Index);
  1086.  
  1087.   if (!ChkArgCnt(1, 3));
  1088.   else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  1089.   else if (*ArgStr[1].str.p_str == '[')
  1090.   {
  1091.     if (ChkArgCnt(1, 1))
  1092.     {
  1093.       ExPos = 1; DecodeAdr(1, 1, eSymbolSizeUnknown, MModDIdx | MModIIdx2);
  1094.       if (AdrMode != ModNone)
  1095.       {
  1096.         BAsmCode[0] = 0x4b;
  1097.         memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  1098.         CodeLen = 1 + AdrCnt;
  1099.       }
  1100.     }
  1101.   }
  1102.   else
  1103.   {
  1104.     if (ChkArgCnt(2, 3))
  1105.     {
  1106.       Boolean OK;
  1107.       Byte Page = EvalStrIntExpression(&ArgStr[ArgCnt], UInt8, &OK);
  1108.  
  1109.       if (OK)
  1110.       {
  1111.         ExPos = 2; /* wg. Seiten-Byte eins mehr */
  1112.         DecodeAdr(1, ArgCnt - 1, eSymbolSizeUnknown, MModExt | MModIdx | MModIdx1 | MModIdx2);
  1113.         if (AdrMode != ModNone)
  1114.         {
  1115.           BAsmCode[0] = 0x4a | Ord(AdrMode != ModExt);
  1116.           memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  1117.           BAsmCode[1 + AdrCnt] = Page;
  1118.           CodeLen = 2 + AdrCnt;
  1119.         }
  1120.       }
  1121.     }
  1122.   }
  1123. }
  1124.  
  1125. static void DecodePCALL(Word Index)
  1126. {
  1127.   Boolean OK;
  1128.   LongWord Addr;
  1129.  
  1130.   UNUSED(Index);
  1131.  
  1132.   if (ChkArgCnt(1, 1)
  1133.    && ChkMinCPU(CPU6812X))
  1134.   {
  1135.     Addr = EvalStrIntExpression(&ArgStr[1], UInt24, &OK);
  1136.     if (OK)
  1137.     {
  1138.       BAsmCode[0] = 0x4a;
  1139.       BAsmCode[1] = Hi(Addr);
  1140.       BAsmCode[2] = Lo(Addr);
  1141.       BAsmCode[3] = (Addr >> 16) & 0xff;
  1142.       CodeLen = 4;
  1143.     }
  1144.   }
  1145. }
  1146.  
  1147.  
  1148. static void DecodeBrBit(Word Index)
  1149. {
  1150.   Byte HReg;
  1151.   Boolean OK;
  1152.   tSymbolFlags Flags;
  1153.   LongInt Address;
  1154.  
  1155.   if (ArgCnt == 1)
  1156.   {
  1157.     Try2Split(1);
  1158.     Try2Split(1);
  1159.   }
  1160.   else if (ArgCnt == 2)
  1161.   {
  1162.     Try2Split(ArgCnt);
  1163.     Try2Split(2);
  1164.   }
  1165.  
  1166.   if (!ChkArgCnt(3, 4));
  1167.   else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  1168.   else
  1169.   {
  1170.     HReg = EvalStrIntExpressionOffs(&ArgStr[ArgCnt - 1], !!(*ArgStr[ArgCnt - 1].str.p_str == '#'), UInt8, &OK);
  1171.     if (OK)
  1172.     {
  1173.       Address = EvalStrIntExpressionWithFlags(&ArgStr[ArgCnt], AddrInt, &OK, &Flags) - EProgCounter();
  1174.       if (OK)
  1175.       {
  1176.         ExPos = 3; /* Opcode, Maske+Distanz */
  1177.         DecodeAdr(1, ArgCnt - 2, eSymbolSizeUnknown, MModDir | MModExt | MModIdx | MModIdx1 | MModIdx2);
  1178.         if (AdrMode != ModNone)
  1179.         {
  1180.           BAsmCode[0] = 0x0e | Index;
  1181.           memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  1182.           switch (AdrMode)
  1183.           {
  1184.             case ModDir:
  1185.               BAsmCode[0] += 0x40;
  1186.               break;
  1187.             case ModExt:
  1188.               BAsmCode[0] += 0x10;
  1189.               break;
  1190.           }
  1191.           BAsmCode[1 + AdrCnt] = HReg;
  1192.           Address -= 3 + AdrCnt;
  1193.           if (((Address < -128) || (Address > 127)) & !mSymbolQuestionable(Flags)) WrError(ErrNum_JmpDistTooBig);
  1194.           else
  1195.           {
  1196.             BAsmCode[2 + AdrCnt] = Lo(Address);
  1197.             CodeLen = 3 + AdrCnt;
  1198.           }
  1199.         }
  1200.       }
  1201.     }
  1202.   }
  1203. }
  1204.  
  1205. static void DecodeTRAP(Word Index)
  1206. {
  1207.   Boolean OK;
  1208.   tSymbolFlags Flags;
  1209.  
  1210.   UNUSED(Index);
  1211.  
  1212.   if (!ChkArgCnt(1, 1));
  1213.   else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  1214.   else
  1215.   {
  1216.     BAsmCode[1] = EvalStrIntExpressionOffsWithFlags(&ArgStr[1], !!(*ArgStr[1].str.p_str == '#'), UInt8, &OK, &Flags);
  1217.     if (mFirstPassUnknown(Flags))
  1218.       BAsmCode[1] = 0x30;
  1219.     if (OK)
  1220.     {
  1221.       if ((BAsmCode[1] < 0x30) || ((BAsmCode[1] > 0x39) && (BAsmCode[1] < 0x40))) WrError(ErrNum_OverRange);
  1222.       else
  1223.       {
  1224.         BAsmCode[0] = 0x18;
  1225.         CodeLen = 2;
  1226.       }
  1227.     }
  1228.   }
  1229. }
  1230.  
  1231. static void DecodeBTAS(Word Index)
  1232. {
  1233.   UNUSED(Index);
  1234.  
  1235.   if (!ChkArgCnt(2, 3));
  1236.   else if (!ChkMinCPU(CPU6812X));
  1237.   else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  1238.   else
  1239.   {
  1240.     ExPos = 2;
  1241.     DecodeAdr(1, ArgCnt - 1, eSymbolSize8Bit, MModDir | MModExt | MModIdx | MModIdx1 | ModIdx2 | ModDIdx);
  1242.     if (AdrMode != ModNone)
  1243.     {
  1244.       BAsmCode[CodeLen++] = 0x18;
  1245.       switch (AdrMode)
  1246.       {
  1247.         case ModImm:
  1248.           break;
  1249.         case ModDir:
  1250.           BAsmCode[CodeLen++] = 0x35;
  1251.           break;
  1252.         case ModIdx:
  1253.         case ModIdx1:
  1254.         case ModIdx2:
  1255.         case ModDIdx:
  1256.           BAsmCode[CodeLen++] = 0x37;
  1257.           break;
  1258.         case ModExt:
  1259.           BAsmCode[CodeLen++] = 0x36;
  1260.           break;
  1261.       }
  1262.       memcpy(BAsmCode + CodeLen, AdrVals, AdrCnt);
  1263.       CodeLen += AdrCnt;
  1264.       DecodeAdr(ArgCnt, ArgCnt, eSymbolSize8Bit, MModImm);
  1265.       if (AdrMode  == ModImm)
  1266.         BAsmCode[CodeLen++] = *AdrVals;
  1267.       else
  1268.         CodeLen = 0;
  1269.     }
  1270.   }
  1271. }
  1272.  
  1273. static void LookupReg(Word Index)
  1274. {
  1275.   Reg *pReg = Regs + Index;
  1276.  
  1277.   ActReg = (MomCPU >= pReg->MinCPU) ? pReg->Code : (Byte)eNoReg;
  1278.   ActRegSize = pReg->OpSize;
  1279. }
  1280.  
  1281. /*---------------------------------------------------------------------------*/
  1282. /* Dynamic Code Table Handling */
  1283.  
  1284. static void AddFixed(const char *NName, Word NCode, CPUVar NMin)
  1285. {
  1286.   order_array_rsv_end(FixedOrders, FixedOrder);
  1287.   FixedOrders[InstrZ].Code = NCode;
  1288.   FixedOrders[InstrZ].MinCPU = NMin;
  1289.   AddInstTable(InstTable, NName, InstrZ++, DecodeFixed);
  1290. }
  1291.  
  1292. static void AddBranch(const char *NName, Word NCode)
  1293. {
  1294.   order_array_rsv_end(BranchOrders, FixedOrder);
  1295.   BranchOrders[InstrZ].Code = NCode;
  1296.   AddInstTable(InstTable, NName + 1, InstrZ  , DecodeBranch);
  1297.   AddInstTable(InstTable, NName    , InstrZ++, DecodeLBranch);
  1298. }
  1299.  
  1300. static void AddGen(const char *NName, Word NCode,
  1301.                    Boolean NMayI, Boolean NMayD, Boolean NMayE,
  1302.                    tSymbolSize NSize, CPUVar NMin)
  1303. {
  1304.   order_array_rsv_end(GenOrders, GenOrder);
  1305.   GenOrders[InstrZ].Code = NCode;
  1306.   GenOrders[InstrZ].MayImm = NMayI;
  1307.   GenOrders[InstrZ].MayDir = NMayD;
  1308.   GenOrders[InstrZ].MayExt = NMayE;
  1309.   GenOrders[InstrZ].ThisOpSize = NSize;
  1310.   GenOrders[InstrZ].MinCPU = NMin;
  1311.   AddInstTable(InstTable, NName, InstrZ++, DecodeGen);
  1312. }
  1313.  
  1314. static void AddLoop(const char *NName, Word NCode)
  1315. {
  1316.   order_array_rsv_end(LoopOrders, FixedOrder);
  1317.   LoopOrders[InstrZ].Code = NCode;
  1318.   AddInstTable(InstTable, NName, InstrZ++, DecodeLoop);
  1319. }
  1320.  
  1321. static void AddLEA(const char *NName, Word NCode)
  1322. {
  1323.   order_array_rsv_end(LEAOrders, FixedOrder);
  1324.   LEAOrders[InstrZ].Code = NCode;
  1325.   AddInstTable(InstTable, NName, InstrZ++, DecodeLEA);
  1326. }
  1327.  
  1328. static void AddJmp(const char *NName, Word NCode, Boolean NDir)
  1329. {
  1330.   order_array_rsv_end(JmpOrders, JmpOrder);
  1331.   JmpOrders[InstrZ].Code = NCode;
  1332.   JmpOrders[InstrZ].MayDir = NDir;
  1333.   AddInstTable(InstTable, NName, InstrZ++, DecodeJmp);
  1334. }
  1335.  
  1336. static void AddReg(const char *NName, Word NCode, Word NSize, CPUVar NMin)
  1337. {
  1338.   order_array_rsv_end(Regs, Reg);
  1339.   Regs[InstrZ].Code = NCode;
  1340.   Regs[InstrZ].OpSize = NSize;
  1341.   Regs[InstrZ].MinCPU = NMin;
  1342.   AddInstTable(RegTable, NName, InstrZ++, LookupReg);
  1343. }
  1344.  
  1345. static void InitFields(void)
  1346. {
  1347.   InstTable = CreateInstTable(405);
  1348.  
  1349.   add_null_pseudo(InstTable);
  1350.  
  1351.   InstrZ = 0;
  1352.   AddFixed("ABA"  , 0x1806, CPU6812 ); AddFixed("ABX"  , 0x1ae5, CPU6812 );
  1353.   AddFixed("ABY"  , 0x19ed, CPU6812 ); AddFixed("ASLA" , 0x0048, CPU6812 );
  1354.   AddFixed("ASLB" , 0x0058, CPU6812 ); AddFixed("ASLD" , 0x0059, CPU6812 );
  1355.   AddFixed("ASLX" , 0x1848, CPU6812X); AddFixed("ASLY" , 0x1858, CPU6812X);
  1356.   AddFixed("ASRA" , 0x0047, CPU6812 ); AddFixed("ASRB" , 0x0057, CPU6812 );
  1357.   AddFixed("ASRX" , 0x1847, CPU6812X); AddFixed("ASRY" , 0x1857, CPU6812X);
  1358.   AddFixed("BGND" , 0x0000, CPU6812 ); AddFixed("CBA"  , 0x1817, CPU6812 );
  1359.   AddFixed("CLC"  , 0x10fe, CPU6812 ); AddFixed("CLI"  , 0x10ef, CPU6812 );
  1360.   AddFixed("CLRA" , 0x0087, CPU6812 ); AddFixed("CLRB" , 0x00c7, CPU6812 );
  1361.   AddFixed("CLRX" , 0x1887, CPU6812X); AddFixed("CLRY" , 0x18c7, CPU6812X);
  1362.   AddFixed("CLV"  , 0x10fd, CPU6812 ); AddFixed("COMA" , 0x0041, CPU6812 );
  1363.   AddFixed("COMB" , 0x0051, CPU6812 ); AddFixed("COMX" , 0x1841, CPU6812X);
  1364.   AddFixed("COMY" , 0x1851, CPU6812X); AddFixed("DAA"  , 0x1807, CPU6812 );
  1365.   AddFixed("DECA" , 0x0043, CPU6812 ); AddFixed("DECB" , 0x0053, CPU6812 );
  1366.   AddFixed("DECX" , 0x1843, CPU6812X); AddFixed("DECY" , 0x1853, CPU6812X);
  1367.   AddFixed("DES"  , 0x1b9f, CPU6812 ); AddFixed("DEX"  , 0x0009, CPU6812 );
  1368.   AddFixed("DEY"  , 0x0003, CPU6812 ); AddFixed("EDIV" , 0x0011, CPU6812 );
  1369.   AddFixed("EDIVS", 0x1814, CPU6812 ); AddFixed("EMUL" , 0x0013, CPU6812 );
  1370.   AddFixed("EMULS", 0x1813, CPU6812 ); AddFixed("FDIV" , 0x1811, CPU6812 );
  1371.   AddFixed("IDIV" , 0x1810, CPU6812 ); AddFixed("IDIVS", 0x1815, CPU6812 );
  1372.   AddFixed("INCA" , 0x0042, CPU6812 ); AddFixed("INCB" , 0x0052, CPU6812 );
  1373.   AddFixed("INCX" , 0x1842, CPU6812X); AddFixed("INCY" , 0x1852, CPU6812X);
  1374.   AddFixed("INS"  , 0x1b81, CPU6812 ); AddFixed("INX"  , 0x0008, CPU6812 );
  1375.   AddFixed("INY"  , 0x0002, CPU6812 ); AddFixed("LSLA" , 0x0048, CPU6812 );
  1376.   AddFixed("LSLB" , 0x0058, CPU6812 ); AddFixed("LSLX" , 0x1848, CPU6812X);
  1377.   AddFixed("LSLY" , 0x1858, CPU6812X); AddFixed("LSLD" , 0x0059, CPU6812 );
  1378.   AddFixed("LSRA" , 0x0044, CPU6812 ); AddFixed("LSRB" , 0x0054, CPU6812 );
  1379.   AddFixed("LSRX" , 0x1844, CPU6812X); AddFixed("LSRY" , 0x1854, CPU6812X);
  1380.   AddFixed("LSRD" , 0x0049, CPU6812 ); AddFixed("MEM"  , 0x0001, CPU6812 );
  1381.   AddFixed("MUL"  , 0x0012, CPU6812 ); AddFixed("NEGA" , 0x0040, CPU6812 );
  1382.   AddFixed("NEGB" , 0x0050, CPU6812 ); AddFixed("NEGX" , 0x1840, CPU6812X);
  1383.   AddFixed("NEGY" , 0x1850, CPU6812X); AddFixed("NOP"  , 0x00a7, CPU6812 );
  1384.   AddFixed("PSHA" , 0x0036, CPU6812 ); AddFixed("PSHB" , 0x0037, CPU6812 );
  1385.   AddFixed("PSHC" , 0x0039, CPU6812 ); AddFixed("PSHCW", 0x1839, CPU6812X);
  1386.   AddFixed("PSHD" , 0x003b, CPU6812 ); AddFixed("PSHX" , 0x0034, CPU6812 );
  1387.   AddFixed("PSHY" , 0x0035, CPU6812 ); AddFixed("PULA" , 0x0032, CPU6812 );
  1388.   AddFixed("PULB" , 0x0033, CPU6812 ); AddFixed("PULC" , 0x0038, CPU6812 );
  1389.   AddFixed("PULCW", 0x1838, CPU6812X); AddFixed("PULD" , 0x003a, CPU6812 );
  1390.   AddFixed("PULX" , 0x0030, CPU6812 ); AddFixed("PULY" , 0x0031, CPU6812 );
  1391.   AddFixed("REV"  , 0x183a, CPU6812 ); AddFixed("REVW" , 0x183b, CPU6812 );
  1392.   AddFixed("ROLA" , 0x0045, CPU6812 ); AddFixed("ROLB" , 0x0055, CPU6812 );
  1393.   AddFixed("ROLX" , 0x1845, CPU6812X); AddFixed("ROLY" , 0x1855, CPU6812X);
  1394.   AddFixed("RORA" , 0x0046, CPU6812 ); AddFixed("RORB" , 0x0056, CPU6812 );
  1395.   AddFixed("RORX" , 0x1846, CPU6812X); AddFixed("RORY" , 0x1856, CPU6812X);
  1396.   AddFixed("RTC"  , 0x000a, CPU6812 ); AddFixed("RTI"  , 0x000b, CPU6812 );
  1397.   AddFixed("RTS"  , 0x003d, CPU6812 ); AddFixed("SBA"  , 0x1816, CPU6812 );
  1398.   AddFixed("SEC"  , 0x1401, CPU6812 ); AddFixed("SEI"  , 0x1410, CPU6812 );
  1399.   AddFixed("SEV"  , 0x1402, CPU6812 ); AddFixed("STOP" , 0x183e, CPU6812 );
  1400.   AddFixed("SWI"  , 0x003f, CPU6812 ); AddFixed("TAB"  , 0x180e, CPU6812 );
  1401.   AddFixed("TAP"  , 0xb702, CPU6812 ); AddFixed("TBA"  , 0x180f, CPU6812 );
  1402.   AddFixed("TPA"  , 0xb720, CPU6812 ); AddFixed("TSTA" , 0x0097, CPU6812 );
  1403.   AddFixed("TSTB" , 0x00d7, CPU6812 ); AddFixed("TSTX" , 0x1897, CPU6812X);
  1404.   AddFixed("TSTY" , 0x18d7, CPU6812X); AddFixed("TSX"  , 0xb775, CPU6812 );
  1405.   AddFixed("TSY"  , 0xb776, CPU6812 ); AddFixed("TXS"  , 0xb757, CPU6812 );
  1406.   AddFixed("TYS"  , 0xb767, CPU6812 ); AddFixed("WAI"  , 0x003e, CPU6812 );
  1407.   AddFixed("WAV"  , 0x183c, CPU6812 ); AddFixed("XGDX" , 0xb7c5, CPU6812 );
  1408.   AddFixed("XGDY" , 0xb7c6, CPU6812 );
  1409.  
  1410.   InstrZ = 0;
  1411.   AddBranch("LBGT", 0x2e);    AddBranch("LBGE", 0x2c);
  1412.   AddBranch("LBEQ", 0x27);    AddBranch("LBLE", 0x2f);
  1413.   AddBranch("LBLT", 0x2d);    AddBranch("LBHI", 0x22);
  1414.   AddBranch("LBHS", 0x24);    AddBranch("LBCC", 0x24);
  1415.   AddBranch("LBNE", 0x26);    AddBranch("LBLS", 0x23);
  1416.   AddBranch("LBLO", 0x25);    AddBranch("LBCS", 0x25);
  1417.   AddBranch("LBMI", 0x2b);    AddBranch("LBVS", 0x29);
  1418.   AddBranch("LBRA", 0x20);    AddBranch("LBPL", 0x2a);
  1419.   AddBranch("LBRN", 0x21);    AddBranch("LBVC", 0x28);
  1420.   AddBranch("LBSR", 0x07);
  1421.  
  1422.   InstrZ = 0;
  1423.   AddGen("ADCA" , 0x0089, True , True , True , eSymbolSize8Bit   , CPU6812 );
  1424.   AddGen("ADCB" , 0x00c9, True , True , True , eSymbolSize8Bit   , CPU6812 );
  1425.   AddGen("ADDA" , 0x008b, True , True , True , eSymbolSize8Bit   , CPU6812 );
  1426.   AddGen("ADDB" , 0x00cb, True , True , True , eSymbolSize8Bit   , CPU6812 );
  1427.   AddGen("ADDD" , 0x00c3, True , True , True , eSymbolSize16Bit  , CPU6812 );
  1428.   AddGen("ADDX" , 0x188b, True , True , True , eSymbolSize16Bit  , CPU6812X);
  1429.   AddGen("ADDY" , 0x18cb, True , True , True , eSymbolSize16Bit  , CPU6812X);
  1430.   AddGen("ADED" , 0x18c3, True , True , True , eSymbolSize16Bit  , CPU6812X);
  1431.   AddGen("ADEX" , 0x1889, True , True , True , eSymbolSize16Bit  , CPU6812X);
  1432.   AddGen("ADEY" , 0x18c9, True , True , True , eSymbolSize16Bit  , CPU6812X);
  1433.   AddGen("ANDA" , 0x0084, True , True , True , eSymbolSize8Bit   , CPU6812 );
  1434.   AddGen("ANDB" , 0x00c4, True , True , True , eSymbolSize8Bit   , CPU6812 );
  1435.   AddGen("ANDX" , 0x1884, True , True , True , eSymbolSize16Bit  , CPU6812X);
  1436.   AddGen("ANDY" , 0x18c4, True , True , True , eSymbolSize16Bit  , CPU6812X);
  1437.   AddGen("ASL"  , 0x0048, False, False, True , eSymbolSizeUnknown, CPU6812 );
  1438.   AddGen("ASLW" , 0x1848, False, False, True , eSymbolSizeUnknown, CPU6812X);
  1439.   AddGen("ASR"  , 0x0047, False, False, True , eSymbolSizeUnknown, CPU6812 );
  1440.   AddGen("ASRW" , 0x1847, False, False, True , eSymbolSizeUnknown, CPU6812X);
  1441.   AddGen("BITA" , 0x0085, True , True , True , eSymbolSize8Bit   , CPU6812 );
  1442.   AddGen("BITB" , 0x00c5, True , True , True , eSymbolSize8Bit   , CPU6812 );
  1443.   AddGen("BITX" , 0x1885, True , True , True , eSymbolSize16Bit  , CPU6812X);
  1444.   AddGen("BITY" , 0x18c5, True , True , True , eSymbolSize16Bit  , CPU6812X);
  1445.   AddGen("CLR"  , 0x0049, False, False, True , eSymbolSizeUnknown, CPU6812 );
  1446.   AddGen("CLRW" , 0x1849, False, False, True , eSymbolSizeUnknown, CPU6812X);
  1447.   AddGen("CMPA" , 0x0081, True , True , True , eSymbolSize8Bit   , CPU6812 );
  1448.   AddGen("CMPB" , 0x00c1, True , True , True , eSymbolSize8Bit   , CPU6812 );
  1449.   AddGen("COM"  , 0x0041, False, False, True , eSymbolSizeUnknown, CPU6812 );
  1450.   AddGen("COMW" , 0x1841, False, False, True , eSymbolSizeUnknown, CPU6812X);
  1451.   AddGen("CPED" , 0x188c, True , True , True , eSymbolSize16Bit  , CPU6812X);
  1452.   AddGen("CPES" , 0x188f, True , True , True , eSymbolSize16Bit  , CPU6812X);
  1453.   AddGen("CPEX" , 0x188e, True , True , True , eSymbolSize16Bit  , CPU6812X);
  1454.   AddGen("CPEY" , 0x188d, True , True , True , eSymbolSize16Bit  , CPU6812X);
  1455.   AddGen("CPD"  , 0x008c, True , True , True , eSymbolSize16Bit  , CPU6812 );
  1456.   AddGen("CPS"  , 0x008f, True , True , True , eSymbolSize16Bit  , CPU6812 );
  1457.   AddGen("CPX"  , 0x008e, True , True , True , eSymbolSize16Bit  , CPU6812 );
  1458.   AddGen("CPY"  , 0x008d, True , True , True , eSymbolSize16Bit  , CPU6812 );
  1459.   AddGen("DEC"  , 0x0043, False, False, True , eSymbolSizeUnknown, CPU6812 );
  1460.   AddGen("DECW" , 0x1843, False, False, True , eSymbolSizeUnknown, CPU6812X);
  1461.   AddGen("EMAXD", 0x18fa, False, False, False, eSymbolSizeUnknown, CPU6812 );
  1462.   AddGen("EMAXM", 0x18fe, False, False, False, eSymbolSizeUnknown, CPU6812 );
  1463.   AddGen("EMIND", 0x18fb, False, False, False, eSymbolSizeUnknown, CPU6812 );
  1464.   AddGen("EMINM", 0x18ff, False, False, False, eSymbolSizeUnknown, CPU6812 );
  1465.   AddGen("EORA" , 0x0088, True , True , True , eSymbolSize8Bit   , CPU6812 );
  1466.   AddGen("EORB" , 0x00c8, True , True , True , eSymbolSize8Bit   , CPU6812 );
  1467.   AddGen("EORX" , 0x1888, True , True , True , eSymbolSize16Bit  , CPU6812X);
  1468.   AddGen("EORY" , 0x18c8, True , True , True , eSymbolSize16Bit  , CPU6812X);
  1469.   AddGen("GLDAA", 0x1886, False, True , True , eSymbolSizeUnknown, CPU6812X);
  1470.   AddGen("GLDAB", 0x18c6, False, True , True , eSymbolSizeUnknown, CPU6812X);
  1471.   AddGen("GLDD" , 0x18cc, False, True , True , eSymbolSizeUnknown, CPU6812X);
  1472.   AddGen("GLDS" , 0x18cf, False, True , True , eSymbolSizeUnknown, CPU6812X);
  1473.   AddGen("GLDX" , 0x18ce, False, True , True , eSymbolSizeUnknown, CPU6812X);
  1474.   AddGen("GLDY" , 0x18cd, False, True , True , eSymbolSizeUnknown, CPU6812X);
  1475.   AddGen("GSTAA", 0x184a, False, True , True , eSymbolSizeUnknown, CPU6812X);
  1476.   AddGen("GSTAB", 0x184b, False, True , True , eSymbolSizeUnknown, CPU6812X);
  1477.   AddGen("GSTD" , 0x184c, False, True , True , eSymbolSizeUnknown, CPU6812X);
  1478.   AddGen("GSTS" , 0x184f, False, True , True , eSymbolSizeUnknown, CPU6812X);
  1479.   AddGen("GSTX" , 0x184e, False, True , True , eSymbolSizeUnknown, CPU6812X);
  1480.   AddGen("GSTY" , 0x184d, False, True , True , eSymbolSizeUnknown, CPU6812X);
  1481.   AddGen("INC"  , 0x0042, False, False, True , eSymbolSizeUnknown, CPU6812 );
  1482.   AddGen("INCW" , 0x1842, False, False, True , eSymbolSizeUnknown, CPU6812X);
  1483.   AddGen("LDAA" , 0x0086, True , True , True , eSymbolSize8Bit   , CPU6812 );
  1484.   AddGen("LDAB" , 0x00c6, True , True , True , eSymbolSize8Bit   , CPU6812 );
  1485.   AddGen("LDD"  , 0x00cc, True , True , True , eSymbolSize16Bit  , CPU6812 );
  1486.   AddGen("LDS"  , 0x00cf, True , True , True , eSymbolSize16Bit  , CPU6812 );
  1487.   AddGen("LDX"  , 0x00ce, True , True , True , eSymbolSize16Bit  , CPU6812 );
  1488.   AddGen("LDY"  , 0x00cd, True , True , True , eSymbolSize16Bit  , CPU6812 );
  1489.   AddGen("LSL"  , 0x0048, False, False, True , eSymbolSizeUnknown, CPU6812 );
  1490.   AddGen("LSLW" , 0x1848, False, False, True , eSymbolSizeUnknown, CPU6812X);
  1491.   AddGen("LSR"  , 0x0044, False, False, True , eSymbolSizeUnknown, CPU6812 );
  1492.   AddGen("LSRW" , 0x1844, False, False, True , eSymbolSizeUnknown, CPU6812X);
  1493.   AddGen("MAXA" , 0x18f8, False, False, False, eSymbolSizeUnknown, CPU6812 );
  1494.   AddGen("MAXM" , 0x18fc, False, False, False, eSymbolSizeUnknown, CPU6812 );
  1495.   AddGen("MINA" , 0x18f9, False, False, False, eSymbolSizeUnknown, CPU6812 );
  1496.   AddGen("MINM" , 0x18fd, False, False, False, eSymbolSizeUnknown, CPU6812 );
  1497.   AddGen("NEG"  , 0x0040, False, False, True , eSymbolSizeUnknown, CPU6812 );
  1498.   AddGen("NEGW" , 0x1840, False, False, True , eSymbolSizeUnknown, CPU6812X);
  1499.   AddGen("ORAA" , 0x008a, True , True , True , eSymbolSize8Bit   , CPU6812 );
  1500.   AddGen("ORAB" , 0x00ca, True , True , True , eSymbolSize8Bit   , CPU6812 );
  1501.   AddGen("ORX"  , 0x188a, True , True , True , eSymbolSize16Bit  , CPU6812X);
  1502.   AddGen("ORY"  , 0x18ca, True , True , True , eSymbolSize16Bit  , CPU6812X);
  1503.   AddGen("ROL"  , 0x0045, False, False, True , eSymbolSizeUnknown, CPU6812 );
  1504.   AddGen("ROLW" , 0x1845, False, False, True , eSymbolSizeUnknown, CPU6812X);
  1505.   AddGen("ROR"  , 0x0046, False, False, True , eSymbolSizeUnknown, CPU6812 );
  1506.   AddGen("RORW" , 0x1846, False, False, True , eSymbolSizeUnknown, CPU6812X);
  1507.   AddGen("SBCA" , 0x0082, True , True , True , eSymbolSize8Bit   , CPU6812 );
  1508.   AddGen("SBCB" , 0x00c2, True , True , True , eSymbolSize8Bit   , CPU6812 );
  1509.   AddGen("SBED" , 0x1883, True , True , True , eSymbolSize16Bit  , CPU6812X);
  1510.   AddGen("SBEX" , 0x1882, True , True , True , eSymbolSize16Bit  , CPU6812X);
  1511.   AddGen("SBEY" , 0x18c2, True , True , True , eSymbolSize16Bit  , CPU6812X);
  1512.   AddGen("STAA" , 0x004a, False, True , True , eSymbolSize8Bit   , CPU6812 );
  1513.   AddGen("STAB" , 0x004b, False, True , True , eSymbolSize8Bit   , CPU6812 );
  1514.   AddGen("STD"  , 0x004c, False, True , True , eSymbolSizeUnknown, CPU6812 );
  1515.   AddGen("STS"  , 0x004f, False, True , True , eSymbolSizeUnknown, CPU6812 );
  1516.   AddGen("STX"  , 0x004e, False, True , True , eSymbolSizeUnknown, CPU6812 );
  1517.   AddGen("STY"  , 0x004d, False, True , True , eSymbolSizeUnknown, CPU6812 );
  1518.   AddGen("SUBA" , 0x0080, True , True , True , eSymbolSize8Bit   , CPU6812 );
  1519.   AddGen("SUBB" , 0x00c0, True , True , True , eSymbolSize8Bit   , CPU6812 );
  1520.   AddGen("SUBX" , 0x1880, True , True , True , eSymbolSize16Bit  , CPU6812X);
  1521.   AddGen("SUBY" , 0x18c0, True , True , True , eSymbolSize16Bit  , CPU6812X);
  1522.   AddGen("SUBD" , 0x0083, True , True , True , eSymbolSize16Bit  , CPU6812 );
  1523.   AddGen("TST"  , 0x00c7, False, False, True , eSymbolSizeUnknown, CPU6812 );
  1524.   AddGen("TSTW" , 0x18c7, False, False, True , eSymbolSizeUnknown, CPU6812X);
  1525.  
  1526.   InstrZ = 0;
  1527.   AddLoop("DBEQ", 0x00); AddLoop("DBNE", 0x20);
  1528.   AddLoop("IBEQ", 0x80); AddLoop("IBNE", 0xa0);
  1529.   AddLoop("TBEQ", 0x40); AddLoop("TBNE", 0x60);
  1530.  
  1531.   InstrZ = 0;
  1532.   AddLEA("LEAS", 0x1b);
  1533.   AddLEA("LEAX", 0x1a);
  1534.   AddLEA("LEAY", 0x19);
  1535.  
  1536.   InstrZ = 0;
  1537.   AddJmp("JMP", 0x06, False);
  1538.   AddJmp("JSR", 0x16, True );
  1539.  
  1540.   AddInstTable(InstTable, "TBL"   , 0x3d, DecodeETBL);
  1541.   AddInstTable(InstTable, "ETBL"  , 0x3f, DecodeETBL);
  1542.   AddInstTable(InstTable, "EMACS" , 0   , DecodeEMACS);
  1543.   AddInstTable(InstTable, "TFR"   , 0x00, DecodeTransfer);
  1544.   AddInstTable(InstTable, "EXG"   , 0x80, DecodeTransfer);
  1545.   AddInstTable(InstTable, "SEX"   , 0   , DecodeSEX);
  1546.   AddInstTable(InstTable, "MOVB"  , eSymbolSize8Bit, DecodeMOV);
  1547.   AddInstTable(InstTable, "MOVW"  , eSymbolSize16Bit, DecodeMOV);
  1548.   AddInstTable(InstTable, "ANDCC" , 0x00, DecodeLogic);
  1549.   AddInstTable(InstTable, "ORCC"  , 0x04, DecodeLogic);
  1550.   AddInstTable(InstTable, "BSET"  , 0x0c, DecodeBit);
  1551.   AddInstTable(InstTable, "BCLR"  , 0x0d, DecodeBit);
  1552.   AddInstTable(InstTable, "CALL"  , 0   , DecodeCALL);
  1553.   AddInstTable(InstTable, "PCALL" , 0   , DecodePCALL);
  1554.   AddInstTable(InstTable, "BRSET" , 0x00, DecodeBrBit);
  1555.   AddInstTable(InstTable, "BRCLR" , 0x01, DecodeBrBit);
  1556.   AddInstTable(InstTable, "TRAP"  , 0   , DecodeTRAP);
  1557.   AddInstTable(InstTable, "BTAS"  , 0   , DecodeBTAS);
  1558.  
  1559.   RegTable = CreateInstTable(31);
  1560.   InstrZ = 0;
  1561.   AddReg("A"   , eRegA    , 0, CPU6812 );
  1562.   AddReg("B"   , eRegB    , 0, CPU6812 );
  1563.   AddReg("CCR" , eRegCCRL , 0, CPU6812 );
  1564.   AddReg("CCRL", eRegCCRL , 0, CPU6812 );
  1565.   AddReg("D"   , eRegD    , 1, CPU6812 );
  1566.   AddReg("X"   , eRegX    , 1, CPU6812 );
  1567.   AddReg("Y"   , eRegY    , 1, CPU6812 );
  1568.   AddReg("SP"  , eRegSP   , 1, CPU6812 );
  1569.   AddReg("PC"  , eRegPC   , 1, CPU6812 );
  1570.   AddReg("XL"  , eRegXL   , 0, CPU6812 );
  1571.   AddReg("XH"  , eRegXH   , 0, CPU6812X);
  1572.   AddReg("YL"  , eRegYL   , 0, CPU6812 );
  1573.   AddReg("YH"  , eRegYH   , 0, CPU6812X);
  1574.   AddReg("SPL" , eRegSPL  , 0, CPU6812 );
  1575.   AddReg("SPH" , eRegSPH  , 0, CPU6812X);
  1576.   AddReg("CCRH", eRegCCRH , 0, CPU6812X);
  1577.   AddReg("CCRW", eRegCCRW , 1, CPU6812X);
  1578.  
  1579.   add_moto8_pseudo(InstTable, e_moto_pseudo_flags_be);
  1580.   AddMoto16Pseudo(InstTable, e_moto_pseudo_flags_be);
  1581.   AddInstTable(InstTable, "DB", eIntPseudoFlag_BigEndian | eIntPseudoFlag_AllowInt | eIntPseudoFlag_AllowString | eIntPseudoFlag_MotoRep, DecodeIntelDB);
  1582.   AddInstTable(InstTable, "DW", eIntPseudoFlag_BigEndian | eIntPseudoFlag_AllowInt | eIntPseudoFlag_AllowString | eIntPseudoFlag_MotoRep, DecodeIntelDW);
  1583. }
  1584.  
  1585. static void DeinitFields(void)
  1586. {
  1587.   DestroyInstTable(InstTable);
  1588.   order_array_free(FixedOrders);
  1589.   order_array_free(BranchOrders);
  1590.   order_array_free(GenOrders);
  1591.   order_array_free(LoopOrders);
  1592.   order_array_free(LEAOrders);
  1593.   order_array_free(JmpOrders);
  1594.  
  1595.   DestroyInstTable(RegTable);
  1596.   order_array_free(Regs);
  1597. }
  1598.  
  1599. /*--------------------------------------------------------------------------*/
  1600. /* Main Functions */
  1601.  
  1602. static Boolean DecodeAttrPart_6812(void)
  1603. {
  1604.   if (strlen(AttrPart.str.p_str) > 1)
  1605.   {
  1606.     WrStrErrorPos(ErrNum_UndefAttr, &AttrPart);
  1607.     return False;
  1608.   }
  1609.  
  1610.   /* Operandengroesse festlegen */
  1611.  
  1612.   return DecodeMoto16AttrSize(*AttrPart.str.p_str, &AttrPartOpSize[0], False);
  1613. }
  1614.  
  1615. static void MakeCode_6812(void)
  1616. {
  1617.   if (!LookupInstTable(InstTable, OpPart.str.p_str))
  1618.     WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
  1619. }
  1620.  
  1621. static void InitCode_6812(void)
  1622. {
  1623.   Reg_Direct = 0;
  1624.   Reg_GPage = 0;
  1625. }
  1626.  
  1627. static Boolean IsDef_6812(void)
  1628. {
  1629.   return False;
  1630. }
  1631.  
  1632. static Boolean ChkPC_6812X(LargeWord Addr)
  1633. {
  1634.   Byte Page = (Addr >> 16) & 0xff;
  1635.  
  1636.   if (ActPC != SegCode)
  1637.     return False;
  1638.   else if ((Addr & 0xc000) == 0x8000)
  1639.     return ((Page == 0) || ((Page >= 0x30) && (Page <= 0x3f)));
  1640.   else
  1641.     return (Page == 0);
  1642. }
  1643.  
  1644. static void SwitchTo_6812(void)
  1645. {
  1646.   TurnWords = False;
  1647.   SetIntConstMode(eIntConstModeMoto);
  1648.  
  1649.   PCSymbol = "*";
  1650.   HeaderID = 0x66;
  1651.   NOPCode = 0xa7;
  1652.   DivideChars = ",";
  1653.   HasAttrs = True;
  1654.   AttrChars = ".";
  1655.  
  1656.   ValidSegs = (1 << SegCode);
  1657.   Grans[SegCode] = 1; ListGrans[SegCode] = 1; SegInits[SegCode] = 0;
  1658.   if (MomCPU == CPU6812X)
  1659.   {
  1660.     SegLimits[SegCode] = 0x3bfff;
  1661.     ChkPC = ChkPC_6812X;
  1662.     AddrInt = UInt22;
  1663.   }
  1664.   else
  1665.   {
  1666.     SegLimits[SegCode] = 0xffff;
  1667.     AddrInt = UInt16;
  1668.   }
  1669.  
  1670.   DecodeAttrPart = DecodeAttrPart_6812;
  1671.   MakeCode = MakeCode_6812;
  1672.   IsDef = IsDef_6812;
  1673.   SwitchFrom = DeinitFields;
  1674.   InitFields();
  1675.   AddMoto16PseudoONOFF(False);
  1676.  
  1677.   if (MomCPU >= CPU6812X)
  1678.   {
  1679. #define ASSUME6812Count (sizeof(ASSUME6812s) / sizeof(*ASSUME6812s))
  1680.    static const ASSUMERec ASSUME6812s[] =
  1681.    {
  1682.      { "DIRECT" , &Reg_Direct , 0,  0xff,  0x100, NULL },
  1683.      { "GPAGE"  , &Reg_GPage  , 0,  0x7f,   0x80, NULL }
  1684.    };
  1685.  
  1686.    pASSUMERecs = ASSUME6812s;
  1687.    ASSUMERecCnt = ASSUME6812Count;
  1688.   }
  1689. }
  1690.  
  1691. void code6812_init(void)
  1692. {
  1693.   CPU6812  = AddCPU("68HC12", SwitchTo_6812);
  1694.   CPU6812X = AddCPU("68HC12X", SwitchTo_6812);
  1695.  
  1696.   AddInitPassProc(InitCode_6812);
  1697. }
  1698.