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 "codevars.h"
  26. #include "errmsg.h"
  27.  
  28. #include "code6812.h"
  29.  
  30. typedef struct
  31. {
  32.   Word Code;
  33.   CPUVar MinCPU;
  34. } FixedOrder;
  35.  
  36. typedef struct
  37. {
  38.   Word Code;
  39.   CPUVar MinCPU;
  40.   Boolean MayImm, MayDir, MayExt;
  41.   tSymbolSize ThisOpSize;
  42. } GenOrder;
  43.  
  44. typedef struct
  45. {
  46.   Word Code;
  47.   Boolean MayDir;
  48. } JmpOrder;
  49.  
  50. typedef struct
  51. {
  52.   Word Code;
  53.   Byte OpSize;
  54.   CPUVar MinCPU;
  55. } Reg;
  56.  
  57. enum
  58. {
  59.   eShortModeAuto = 0,
  60.   eShortModeNo = 1,
  61.   eShortModeYes = 2,
  62.   eShortModeExtreme = 3
  63. };
  64.  
  65. enum
  66. {
  67.   ModNone = -1,
  68.   ModImm = 0,
  69.   ModDir = 1,
  70.   ModExt = 2,
  71.   ModIdx = 3,
  72.   ModIdx1 = 4,
  73.   ModIdx2 = 5,
  74.   ModDIdx = 6,
  75.   ModIIdx2 = 7,
  76.   ModExtPg = 8
  77. };
  78.  
  79. #define MModImm (1 << ModImm)
  80. #define MModDir (1 << ModDir)
  81. #define MModExt (1 << ModExt)
  82. #define MModIdx (1 << ModIdx)
  83. #define MModIdx1 (1 << ModIdx1)
  84. #define MModIdx2 (1 << ModIdx2)
  85. #define MModDIdx (1 << ModDIdx)
  86. #define MModIIdx2 (1 << ModIIdx2)
  87. #define MModExtPg (1 << ModExtPg)
  88.  
  89. #define MModAllIdx (MModIdx | MModIdx1 | MModIdx2 | MModDIdx | MModIIdx2)
  90.  
  91. static tSymbolSize OpSize;
  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, 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 (OpSize)
  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.         AdrWord = EvalStrIntExpressionWithFlags(&ArgStr[Start], Int16, &OK, &Flags);
  546.         if (AdrVals[0] == eBaseRegPC)
  547.           AdrWord -= EProgCounter() + ExPos;
  548.         if (OK)
  549.         {
  550.           if ((ShortMode != eShortModeNo) && (ShortMode != eShortModeYes) && ((Mask & MModIdx) != 0) && (DistFits(AdrVals[0], AdrWord, 1, -16, 15, Flags)))
  551.           {
  552.             if (AdrVals[0] == eBaseRegPC)
  553.               AdrWord--;
  554.             AdrVals[0] = (AdrVals[0] << 6) | (AdrWord & 0x1f);
  555.             AdrCnt = 1;
  556.             AdrMode = ModIdx;
  557.           }
  558.           else if ((ShortMode != eShortModeNo) && (ShortMode != eShortModeExtreme) && ((Mask & MModIdx1) != 0) && (DistFits(AdrVals[0], AdrWord, 2, -256, 255, Flags)))
  559.           {
  560.             if (AdrVals[0] == eBaseRegPC)
  561.               AdrWord -= 2;
  562.             AdrVals[0] = 0xe0 | (AdrVals[0] << 3) | (Hi(AdrWord) & 1);
  563.             AdrVals[1] = Lo(AdrWord);
  564.             AdrCnt = 2;
  565.             AdrMode = ModIdx1;
  566.           }
  567.           else
  568.           {
  569.             if (AdrVals[0] == eBaseRegPC)
  570.               AdrWord -= 3;
  571.             AdrVals[0] = 0xe2 | (AdrVals[0] << 3);
  572.             AdrVals[1] = Hi(AdrWord);
  573.             AdrVals[2] = Lo(AdrWord);
  574.             AdrCnt = 3;
  575.             AdrMode = ModIdx2;
  576.           }
  577.         }
  578.       }
  579.       goto chk;
  580.     }
  581.   }
  582.  
  583.   else WrError(ErrNum_InvAddrMode);
  584.  
  585. chk:
  586.   if ((AdrMode != ModNone) && (((1 << AdrMode) & Mask) == 0))
  587.   {
  588.     AdrMode = ModNone;
  589.     AdrCnt = 0;
  590.     WrError(ErrNum_InvAddrMode);
  591.   }
  592. }
  593.  
  594. static void Try2Split(int Src)
  595. {
  596.   char *p;
  597.   int z;
  598.   size_t SrcLen;
  599.  
  600.   KillPrefBlanksStrComp(&ArgStr[Src]);
  601.   KillPostBlanksStrComp(&ArgStr[Src]);
  602.   SrcLen = strlen(ArgStr[Src].str.p_str);
  603.   p = ArgStr[Src].str.p_str + SrcLen - 1;
  604.   while ((p >= ArgStr[Src].str.p_str) && !as_isspace(*p))
  605.     p--;
  606.   if (p >= ArgStr[Src].str.p_str)
  607.   {
  608.     InsertArg(Src + 1, SrcLen);
  609.     for (z = ArgCnt - 1; z >= Src + 1; z--)
  610.       StrCompCopy(&ArgStr[z + 1], &ArgStr[z]);
  611.     StrCompSplitRight(&ArgStr[Src], &ArgStr[Src + 1], p);
  612.     KillPostBlanksStrComp(&ArgStr[Src]);
  613.     KillPrefBlanksStrComp(&ArgStr[Src + 1]);
  614.   }
  615. }
  616.  
  617. /*---------------------------------------------------------------------------*/
  618. /* Instruction Decoders */
  619.  
  620. static void DecodeFixed(Word Index)
  621. {
  622.   FixedOrder *pOrder = FixedOrders + Index;
  623.  
  624.   if (!ChkArgCnt(0, 0));
  625.   else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  626.   else if (!ChkMinCPU(pOrder->MinCPU));
  627.   else
  628.   {
  629.     if (Hi(pOrder->Code))
  630.       BAsmCode[CodeLen++] = Hi(pOrder->Code);
  631.     BAsmCode[CodeLen++] = Lo(pOrder->Code);
  632.   }
  633. }
  634.  
  635. static void DecodeGen(Word Index)
  636. {
  637.   GenOrder *pOrder = GenOrders + Index;
  638.  
  639.   if (!ChkArgCnt(1, 2));
  640.   else if (!ChkMinCPU(pOrder->MinCPU));
  641.   else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  642.   else
  643.   {
  644.     ExPos = 1 + Ord(Hi(pOrder->Code) != 0);
  645.     OpSize = pOrder->ThisOpSize;
  646.     DecodeAdr(1, ArgCnt, MModAllIdx | (pOrder->MayImm ? MModImm : 0) | (pOrder->MayDir ? MModDir : 0) | (pOrder->MayExt ? MModExt : 0));
  647.     if (AdrMode != ModNone)
  648.     {
  649.       if (Hi(pOrder->Code) == 0)
  650.       {
  651.         BAsmCode[0] = pOrder->Code;
  652.         CodeLen = 1;
  653.       }
  654.       else
  655.       {
  656.         BAsmCode[0] = Hi(pOrder->Code);
  657.         BAsmCode[1] = Lo(pOrder->Code);
  658.         CodeLen = 2;
  659.       }
  660.     }
  661.     switch (AdrMode)
  662.     {
  663.       case ModImm:
  664.         break;
  665.       case ModDir:
  666.         BAsmCode[CodeLen - 1] += 0x10;
  667.         break;
  668.       case ModIdx:
  669.       case ModIdx1:
  670.       case ModIdx2:
  671.       case ModDIdx:
  672.       case ModIIdx2:
  673.         BAsmCode[CodeLen - 1] += 0x20;
  674.         break;
  675.       case ModExt:
  676.         BAsmCode[CodeLen - 1] += 0x30;
  677.         break;
  678.     }
  679.     if (AdrMode != ModNone)
  680.     {
  681.       memcpy(BAsmCode + CodeLen, AdrVals, AdrCnt);
  682.       CodeLen += AdrCnt;
  683.     }
  684.   }
  685. }
  686.  
  687. static void DecodeLEA(Word Index)
  688. {
  689.   FixedOrder *pOrder = LEAOrders + Index;
  690.  
  691.   if (!ChkArgCnt(1, 2));
  692.   else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  693.   else
  694.   {
  695.     ExPos = 1;
  696.     DecodeAdr(1, ArgCnt, MModIdx | MModIdx1 | MModIdx2);
  697.     if (AdrMode != ModNone)
  698.     {
  699.       BAsmCode[0] = pOrder->Code;
  700.       memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  701.       CodeLen = 1 + AdrCnt;
  702.     }
  703.   }
  704. }
  705.  
  706. static void DecodeBranch(Word Index)
  707. {
  708.   FixedOrder *pOrder = BranchOrders + Index;
  709.   LongInt Address;
  710.   Boolean OK;
  711.   tSymbolFlags Flags;
  712.  
  713.   if (!ChkArgCnt(1, 1));
  714.   else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  715.   else
  716.   {
  717.     Address = EvalStrIntExpressionWithFlags(&ArgStr[1], AddrInt, &OK, &Flags) - EProgCounter() - 2;
  718.     if (OK)
  719.     {
  720.       if (((Address < -128) || (Address > 127)) && !mSymbolQuestionable(Flags)) WrError(ErrNum_JmpDistTooBig);
  721.       else
  722.       {
  723.         BAsmCode[0] = pOrder->Code;
  724.         BAsmCode[1] = Lo(Address);
  725.         CodeLen = 2;
  726.       }
  727.     }
  728.   }
  729. }
  730.  
  731. static void DecodeLBranch(Word Index)
  732. {
  733.   FixedOrder *pOrder = BranchOrders + Index;
  734.   LongInt Address;
  735.   Boolean OK;
  736.  
  737.   if (!ChkArgCnt(1, 1));
  738.   else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  739.   else
  740.   {
  741.     Address = EvalStrIntExpression(&ArgStr[1], AddrInt, &OK) - EProgCounter() - 4;
  742.     if (OK)
  743.     {
  744.       BAsmCode[0] = 0x18;
  745.       BAsmCode[1] = pOrder->Code;
  746.       BAsmCode[2] = Hi(Address);
  747.       BAsmCode[3] = Lo(Address);
  748.       CodeLen = 4;
  749.     }
  750.   }
  751. }
  752.  
  753. static void DecodeJmp(Word Index)
  754. {
  755.   JmpOrder *pOrder = JmpOrders + Index;
  756.   Word Mask;
  757.  
  758.   if (!ChkArgCnt(1, 2));
  759.   else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  760.   else
  761.   {
  762.     Mask = MModAllIdx | MModExtPg;
  763.     if (pOrder->MayDir)
  764.       Mask |= MModDir;
  765.     ExPos = 1;
  766.     DecodeAdr(1, ArgCnt, Mask);
  767.     if (AdrMode != ModNone)
  768.     {
  769.       switch (AdrMode)
  770.       {
  771.         case ModExt:
  772.           BAsmCode[0] = pOrder->Code;
  773.           break;
  774.         case ModDir:
  775.           BAsmCode[0] = pOrder->Code + 1;
  776.           break;
  777.         case ModIdx:
  778.         case ModIdx1:
  779.         case ModIdx2:
  780.         case ModDIdx:
  781.         case ModIIdx2:
  782.           BAsmCode[0] = pOrder->Code - 1;
  783.           break;
  784.       }
  785.       memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  786.       CodeLen = 1 + AdrCnt;
  787.     }
  788.   }
  789. }
  790.  
  791. static void DecodeLoop(Word Index)
  792. {
  793.   FixedOrder *pOrder = LoopOrders + Index;
  794.   Byte HReg;
  795.   LongInt Address;
  796.   Boolean OK;
  797.   tSymbolFlags Flags;
  798.  
  799.   if (!ChkArgCnt(2, 2));
  800.   else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  801.   else if (!DecodeReg(ArgStr[1].str.p_str, &HReg)) WrStrErrorPos(ErrNum_InvReg, &ArgStr[1]);
  802.   else
  803.   {
  804.     OK = (HReg <= eRegB) || ((HReg >= eRegD) && (HReg <= eRegSP));
  805.     if (!OK) WrStrErrorPos(ErrNum_InvReg, &ArgStr[1]);
  806.     else
  807.     {
  808.       Address = EvalStrIntExpressionWithFlags(&ArgStr[2], AddrInt, &OK, &Flags) - (EProgCounter() + 3);
  809.       if (OK)
  810.       {
  811.         if (((Address < -256) || (Address > 255)) && !mSymbolQuestionable(Flags)) WrError(ErrNum_JmpDistTooBig);
  812.         else
  813.         {
  814.           BAsmCode[0] = 0x04;
  815.           BAsmCode[1] = pOrder->Code | HReg | ((Address >> 4) & 0x10);
  816.           BAsmCode[2] = Address & 0xff;
  817.           CodeLen = 3;
  818.         }
  819.       }
  820.     }
  821.   }
  822. }
  823.  
  824. static void DecodeETBL(Word Index)
  825. {
  826.   if (!ChkArgCnt(1, 2));
  827.   else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  828.   else
  829.   {
  830.     ExPos = 2;
  831.     DecodeAdr(1, ArgCnt, MModIdx);
  832.     if (AdrMode == ModIdx)
  833.     {
  834.       BAsmCode[0] = 0x18;
  835.       BAsmCode[1] = Index;
  836.       memcpy(BAsmCode + 2, AdrVals, AdrCnt);
  837.       CodeLen = 2 + AdrCnt;
  838.     }
  839.   }
  840. }
  841.  
  842. static void DecodeEMACS(Word Index)
  843. {
  844.   LongInt Address;
  845.   Boolean OK;
  846.  
  847.   UNUSED(Index);
  848.  
  849.   if (!ChkArgCnt(1, 1));
  850.   else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  851.   else
  852.   {
  853.     Address = EvalStrIntExpression(&ArgStr[1], UInt16, &OK);
  854.     if (OK)
  855.     {
  856.       BAsmCode[0] = 0x18;
  857.       BAsmCode[1] = 0x12;
  858.       BAsmCode[2] = Hi(Address) & 0xff;
  859.       BAsmCode[3] = Lo(Address);
  860.       CodeLen = 4;
  861.     }
  862.   }
  863. }
  864.  
  865. static void DecodeTransfer(Word Index)
  866. {
  867.   Byte Reg1, Reg2;
  868.   Byte ExtMask;
  869.  
  870.   if (!ChkArgCnt(2, 2));
  871.   else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  872.   else if (!DecodeReg(ArgStr[2].str.p_str, &Reg2)) WrStrErrorPos(ErrNum_InvReg, &ArgStr[2]);
  873.   else if (eRegPC == Reg2) WrStrErrorPos(ErrNum_InvReg, &ArgStr[2]);
  874.   else if (!DecodeReg(ArgStr[1].str.p_str, &Reg1)) WrStrErrorPos(ErrNum_InvReg, &ArgStr[1]);
  875.   else if (eRegPC == Reg1) WrStrErrorPos(ErrNum_InvReg, &ArgStr[1]);
  876.   else if (!ChkRegPair(Reg1, Reg2, &ExtMask)) WrError(ErrNum_InvRegPair);
  877.   else
  878.   {
  879.     BAsmCode[0] = 0xb7;
  880.     Reg1 &= 7;
  881.     Reg2 &= 7;
  882.     BAsmCode[1] = Index | (Reg1 << 4) | Reg2 | ExtMask;
  883.     CodeLen = 2;
  884.   }
  885. }
  886.  
  887. static void DecodeSEX(Word Index)
  888. {
  889.   Byte Reg1, Reg2;
  890.   Byte ExtMask;
  891.  
  892.   if (!ChkArgCnt(2, 2));
  893.   else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  894.   else if (!DecodeReg(ArgStr[2].str.p_str, &Reg2)) WrStrErrorPos(ErrNum_InvReg, &ArgStr[2]);
  895.   else if (ActRegSize != 1) WrStrErrorPos(ErrNum_InvReg, &ArgStr[2]);
  896.   else if (eRegPC == Reg2) WrStrErrorPos(ErrNum_InvReg, &ArgStr[2]);
  897.   else if (!DecodeReg(ArgStr[1].str.p_str, &Reg1)) WrStrErrorPos(ErrNum_InvReg, &ArgStr[1]);
  898.   else if (ActRegSize != 0) WrStrErrorPos(ErrNum_InvReg, &ArgStr[1]);
  899.   else if (eRegPC == Reg1) WrStrErrorPos(ErrNum_InvReg, &ArgStr[1]);
  900.   else if (!ChkRegPair(Reg1, Reg2, &ExtMask)) WrError(ErrNum_InvRegPair);
  901.   else
  902.   {
  903.     BAsmCode[0] = 0xb7;
  904.     BAsmCode[1] = Index | (Reg1 << 4) | Reg2 | ExtMask;
  905.     CodeLen = 2;
  906.   }
  907. }
  908.  
  909. static void DecodeMOV(Word Index)
  910. {
  911.   Byte Arg2Start, HCnt = 0, HAdrVals[4];
  912.   Word Mask;
  913.  
  914.   switch (ArgCnt)
  915.   {
  916.     case 1:
  917.       Try2Split(1);
  918.       break;
  919.     case 2:
  920.       Try2Split(1);
  921.       if (ArgCnt == 2)
  922.         Try2Split(2);
  923.       break;
  924.     case 3:
  925.       Try2Split(2);
  926.       break;
  927.   }
  928.  
  929.   if (!ChkArgCnt(2, 4));
  930.   else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  931.   else
  932.   {
  933.     if (ArgCnt == 2)
  934.       Arg2Start = 2;
  935.     else if (ArgCnt == 4)
  936.       Arg2Start = 3;
  937.     else if (ValidReg(ArgStr[2].str.p_str))
  938.       Arg2Start = 3;
  939.     else
  940.       Arg2Start = 2;
  941.     OpSize = (tSymbolSize)Index;
  942.     ExPos = 2;
  943.     BAsmCode[0] = 0x18;
  944.     BAsmCode[1] = (1 - Index) << 3;
  945.  
  946.     Mask = MModImm | MModExt | MModIdx;
  947.     if (MomCPU >= CPU6812X)
  948.       Mask |= MModIdx1 | MModIdx2 | MModDIdx | MModIIdx2;
  949.  
  950.     /* decode & save source operand */
  951.  
  952.     DecodeAdr(1, Arg2Start - 1, Mask);
  953.     if (AdrMode != ModNone)
  954.     {
  955.       memcpy(HAdrVals, AdrVals, AdrCnt);
  956.       HCnt = AdrCnt;
  957.     }
  958.  
  959.     /* dispatch source address mode */
  960.  
  961.     switch (AdrMode)
  962.     {
  963.       case ModImm:
  964.         ExPos = 4 + 2 * OpSize;
  965.         DecodeAdr(Arg2Start, ArgCnt, MModExt | MModIdx | MModIdx1 | MModIdx2 | MModDIdx | MModIIdx2);
  966.         switch (AdrMode)
  967.         {
  968.           case ModExt:
  969.             BAsmCode[1] |= 3;
  970.             memcpy(BAsmCode + 2 , HAdrVals, HCnt);
  971.             memcpy(BAsmCode + 2 + HCnt, AdrVals, AdrCnt);
  972.             break;
  973.           case ModIdx:
  974.           case ModIdx1:
  975.           case ModIdx2:
  976.           case ModDIdx:
  977.           case ModIIdx2:
  978.             memcpy(BAsmCode + 2 , AdrVals, AdrCnt);
  979.             memcpy(BAsmCode + 2 + AdrCnt, HAdrVals, HCnt);
  980.             break;
  981.         }
  982.         break;
  983.       case ModExt:
  984.         ExPos = 6;
  985.         DecodeAdr(Arg2Start, ArgCnt, MModExt | MModIdx | MModIdx1 | MModIdx2 | MModDIdx | MModIIdx2);
  986.         switch (AdrMode)
  987.         {
  988.           case ModExt:
  989.             BAsmCode[1] |= 4;
  990.             memcpy(BAsmCode + 2, HAdrVals, HCnt);
  991.             memcpy(BAsmCode + 2 + HCnt, AdrVals, AdrCnt);
  992.             break;
  993.           case ModIdx:
  994.           case ModIdx1:
  995.           case ModIdx2:
  996.           case ModDIdx:
  997.           case ModIIdx2:
  998.             BAsmCode[1] |= 1;
  999.             memcpy(BAsmCode + 2, AdrVals, AdrCnt);
  1000.             memcpy(BAsmCode + 2 + AdrCnt, HAdrVals, HCnt);
  1001.             break;
  1002.         }
  1003.         break;
  1004.       case ModIdx:
  1005.       case ModIdx1:
  1006.       case ModIdx2:
  1007.       case ModDIdx:
  1008.       case ModIIdx2:
  1009.         ExPos = 4;
  1010.         DecodeAdr(Arg2Start, ArgCnt, MModExt | MModIdx| MModIdx1 | MModIdx2 | MModDIdx | MModIIdx2);
  1011.         if (AdrMode != ModNone)
  1012.         {
  1013.           BAsmCode[1] |= (AdrMode == ModExt) ? 5 : 2;
  1014.           memcpy(BAsmCode + 2, HAdrVals, HCnt);
  1015.           memcpy(BAsmCode + 2 + HCnt, AdrVals, AdrCnt);
  1016.         }
  1017.         break;
  1018.     }
  1019.     if (AdrMode != ModNone)
  1020.       CodeLen = 2 + AdrCnt + HCnt;
  1021.   }
  1022. }
  1023.  
  1024. static void DecodeLogic(Word Index)
  1025. {
  1026.   if (!ChkArgCnt(1, 1));
  1027.   else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  1028.   else
  1029.   {
  1030.     OpSize = eSymbolSize8Bit; DecodeAdr(1, 1, MModImm);
  1031.     if (AdrMode == ModImm)
  1032.     {
  1033.       BAsmCode[0] = 0x10 | Index;
  1034.       BAsmCode[1] = AdrVals[0];
  1035.       CodeLen = 2;
  1036.     }
  1037.   }
  1038. }
  1039.  
  1040. static void DecodeBit(Word Index)
  1041. {
  1042.   Byte HReg;
  1043.   Boolean OK;
  1044.  
  1045.   if ((ArgCnt == 1) || (ArgCnt == 2))
  1046.     Try2Split(ArgCnt);
  1047.  
  1048.   if (!ChkArgCnt(2, 3));
  1049.   else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  1050.   else
  1051.   {
  1052.     HReg = EvalStrIntExpressionOffs(&ArgStr[ArgCnt], !!(*ArgStr[ArgCnt].str.p_str  == '#'), UInt8, &OK);
  1053.     if (OK)
  1054.     {
  1055.       ExPos = 2; /* wg. Masken-Postbyte */
  1056.       DecodeAdr(1, ArgCnt - 1, MModDir | MModExt | MModIdx | MModIdx1 | MModIdx2);
  1057.       if (AdrMode != ModNone)
  1058.       {
  1059.         BAsmCode[0] = Index;
  1060.         switch (AdrMode)
  1061.         {
  1062.           case ModDir:
  1063.             BAsmCode[0] += 0x40;
  1064.             break;
  1065.           case ModExt:
  1066.             BAsmCode[0] += 0x10;
  1067.             break;
  1068.         }
  1069.         memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  1070.         BAsmCode[1 + AdrCnt] = HReg;
  1071.         CodeLen = 2 + AdrCnt;
  1072.       }
  1073.     }
  1074.   }
  1075. }
  1076.  
  1077. static void DecodeCALL(Word Index)
  1078. {
  1079.   UNUSED(Index);
  1080.  
  1081.   if (!ChkArgCnt(1, 3));
  1082.   else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  1083.   else if (*ArgStr[1].str.p_str == '[')
  1084.   {
  1085.     if (ChkArgCnt(1, 1))
  1086.     {
  1087.       ExPos = 1; DecodeAdr(1, 1, MModDIdx | MModIIdx2);
  1088.       if (AdrMode != ModNone)
  1089.       {
  1090.         BAsmCode[0] = 0x4b;
  1091.         memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  1092.         CodeLen = 1 + AdrCnt;
  1093.       }
  1094.     }
  1095.   }
  1096.   else
  1097.   {
  1098.     if (ChkArgCnt(2, 3))
  1099.     {
  1100.       Boolean OK;
  1101.       Byte Page = EvalStrIntExpression(&ArgStr[ArgCnt], UInt8, &OK);
  1102.  
  1103.       if (OK)
  1104.       {
  1105.         ExPos = 2; /* wg. Seiten-Byte eins mehr */
  1106.         DecodeAdr(1, ArgCnt - 1, MModExt | MModIdx | MModIdx1 | MModIdx2);
  1107.         if (AdrMode != ModNone)
  1108.         {
  1109.           BAsmCode[0] = 0x4a | Ord(AdrMode != ModExt);
  1110.           memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  1111.           BAsmCode[1 + AdrCnt] = Page;
  1112.           CodeLen = 2 + AdrCnt;
  1113.         }
  1114.       }
  1115.     }
  1116.   }
  1117. }
  1118.  
  1119. static void DecodePCALL(Word Index)
  1120. {
  1121.   Boolean OK;
  1122.   LongWord Addr;
  1123.  
  1124.   UNUSED(Index);
  1125.  
  1126.   if (ChkArgCnt(1, 1)
  1127.    && ChkMinCPU(CPU6812X))
  1128.   {
  1129.     Addr = EvalStrIntExpression(&ArgStr[1], UInt24, &OK);
  1130.     if (OK)
  1131.     {
  1132.       BAsmCode[0] = 0x4a;
  1133.       BAsmCode[1] = Hi(Addr);
  1134.       BAsmCode[2] = Lo(Addr);
  1135.       BAsmCode[3] = (Addr >> 16) & 0xff;
  1136.       CodeLen = 4;
  1137.     }
  1138.   }
  1139. }
  1140.  
  1141.  
  1142. static void DecodeBrBit(Word Index)
  1143. {
  1144.   Byte HReg;
  1145.   Boolean OK;
  1146.   tSymbolFlags Flags;
  1147.   LongInt Address;
  1148.  
  1149.   if (ArgCnt == 1)
  1150.   {
  1151.     Try2Split(1);
  1152.     Try2Split(1);
  1153.   }
  1154.   else if (ArgCnt == 2)
  1155.   {
  1156.     Try2Split(ArgCnt);
  1157.     Try2Split(2);
  1158.   }
  1159.  
  1160.   if (!ChkArgCnt(3, 4));
  1161.   else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  1162.   else
  1163.   {
  1164.     HReg = EvalStrIntExpressionOffs(&ArgStr[ArgCnt - 1], !!(*ArgStr[ArgCnt - 1].str.p_str == '#'), UInt8, &OK);
  1165.     if (OK)
  1166.     {
  1167.       Address = EvalStrIntExpressionWithFlags(&ArgStr[ArgCnt], AddrInt, &OK, &Flags) - EProgCounter();
  1168.       if (OK)
  1169.       {
  1170.         ExPos = 3; /* Opcode, Maske+Distanz */
  1171.         DecodeAdr(1, ArgCnt - 2, MModDir | MModExt | MModIdx | MModIdx1 | MModIdx2);
  1172.         if (AdrMode != ModNone)
  1173.         {
  1174.           BAsmCode[0] = 0x0e | Index;
  1175.           memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  1176.           switch (AdrMode)
  1177.           {
  1178.             case ModDir:
  1179.               BAsmCode[0] += 0x40;
  1180.               break;
  1181.             case ModExt:
  1182.               BAsmCode[0] += 0x10;
  1183.               break;
  1184.           }
  1185.           BAsmCode[1 + AdrCnt] = HReg;
  1186.           Address -= 3 + AdrCnt;
  1187.           if (((Address < -128) || (Address > 127)) & !mSymbolQuestionable(Flags)) WrError(ErrNum_JmpDistTooBig);
  1188.           else
  1189.           {
  1190.             BAsmCode[2 + AdrCnt] = Lo(Address);
  1191.             CodeLen = 3 + AdrCnt;
  1192.           }
  1193.         }
  1194.       }
  1195.     }
  1196.   }
  1197. }
  1198.  
  1199. static void DecodeTRAP(Word Index)
  1200. {
  1201.   Boolean OK;
  1202.   tSymbolFlags Flags;
  1203.  
  1204.   UNUSED(Index);
  1205.  
  1206.   if (!ChkArgCnt(1, 1));
  1207.   else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  1208.   else
  1209.   {
  1210.     BAsmCode[1] = EvalStrIntExpressionOffsWithFlags(&ArgStr[1], !!(*ArgStr[1].str.p_str == '#'), UInt8, &OK, &Flags);
  1211.     if (mFirstPassUnknown(Flags))
  1212.       BAsmCode[1] = 0x30;
  1213.     if (OK)
  1214.     {
  1215.       if ((BAsmCode[1] < 0x30) || ((BAsmCode[1] > 0x39) && (BAsmCode[1] < 0x40))) WrError(ErrNum_OverRange);
  1216.       else
  1217.       {
  1218.         BAsmCode[0] = 0x18;
  1219.         CodeLen = 2;
  1220.       }
  1221.     }
  1222.   }
  1223. }
  1224.  
  1225. static void DecodeBTAS(Word Index)
  1226. {
  1227.   UNUSED(Index);
  1228.  
  1229.   if (!ChkArgCnt(2, 3));
  1230.   else if (!ChkMinCPU(CPU6812X));
  1231.   else if (*AttrPart.str.p_str) WrError(ErrNum_UseLessAttr);
  1232.   else
  1233.   {
  1234.     ExPos = 2;
  1235.     OpSize = eSymbolSize8Bit;
  1236.     DecodeAdr(1, ArgCnt - 1, MModDir | MModExt | MModIdx | MModIdx1 | ModIdx2 | ModDIdx);
  1237.     if (AdrMode != ModNone)
  1238.     {
  1239.       BAsmCode[CodeLen++] = 0x18;
  1240.       switch (AdrMode)
  1241.       {
  1242.         case ModImm:
  1243.           break;
  1244.         case ModDir:
  1245.           BAsmCode[CodeLen++] = 0x35;
  1246.           break;
  1247.         case ModIdx:
  1248.         case ModIdx1:
  1249.         case ModIdx2:
  1250.         case ModDIdx:
  1251.           BAsmCode[CodeLen++] = 0x37;
  1252.           break;
  1253.         case ModExt:
  1254.           BAsmCode[CodeLen++] = 0x36;
  1255.           break;
  1256.       }
  1257.       memcpy(BAsmCode + CodeLen, AdrVals, AdrCnt);
  1258.       CodeLen += AdrCnt;
  1259.       DecodeAdr(ArgCnt, ArgCnt, MModImm);
  1260.       if (AdrMode  == ModImm)
  1261.         BAsmCode[CodeLen++] = *AdrVals;
  1262.       else
  1263.         CodeLen = 0;
  1264.     }
  1265.   }
  1266. }
  1267.  
  1268. static void LookupReg(Word Index)
  1269. {
  1270.   Reg *pReg = Regs + Index;
  1271.  
  1272.   ActReg = (MomCPU >= pReg->MinCPU) ? pReg->Code : (Byte)eNoReg;
  1273.   ActRegSize = pReg->OpSize;
  1274. }
  1275.  
  1276. /*---------------------------------------------------------------------------*/
  1277. /* Dynamic Code Table Handling */
  1278.  
  1279. static void AddFixed(const char *NName, Word NCode, CPUVar NMin)
  1280. {
  1281.   order_array_rsv_end(FixedOrders, FixedOrder);
  1282.   FixedOrders[InstrZ].Code = NCode;
  1283.   FixedOrders[InstrZ].MinCPU = NMin;
  1284.   AddInstTable(InstTable, NName, InstrZ++, DecodeFixed);
  1285. }
  1286.  
  1287. static void AddBranch(const char *NName, Word NCode)
  1288. {
  1289.   order_array_rsv_end(BranchOrders, FixedOrder);
  1290.   BranchOrders[InstrZ].Code = NCode;
  1291.   AddInstTable(InstTable, NName + 1, InstrZ  , DecodeBranch);
  1292.   AddInstTable(InstTable, NName    , InstrZ++, DecodeLBranch);
  1293. }
  1294.  
  1295. static void AddGen(const char *NName, Word NCode,
  1296.                    Boolean NMayI, Boolean NMayD, Boolean NMayE,
  1297.                    tSymbolSize NSize, CPUVar NMin)
  1298. {
  1299.   order_array_rsv_end(GenOrders, GenOrder);
  1300.   GenOrders[InstrZ].Code = NCode;
  1301.   GenOrders[InstrZ].MayImm = NMayI;
  1302.   GenOrders[InstrZ].MayDir = NMayD;
  1303.   GenOrders[InstrZ].MayExt = NMayE;
  1304.   GenOrders[InstrZ].ThisOpSize = NSize;
  1305.   GenOrders[InstrZ].MinCPU = NMin;
  1306.   AddInstTable(InstTable, NName, InstrZ++, DecodeGen);
  1307. }
  1308.  
  1309. static void AddLoop(const char *NName, Word NCode)
  1310. {
  1311.   order_array_rsv_end(LoopOrders, FixedOrder);
  1312.   LoopOrders[InstrZ].Code = NCode;
  1313.   AddInstTable(InstTable, NName, InstrZ++, DecodeLoop);
  1314. }
  1315.  
  1316. static void AddLEA(const char *NName, Word NCode)
  1317. {
  1318.   order_array_rsv_end(LEAOrders, FixedOrder);
  1319.   LEAOrders[InstrZ].Code = NCode;
  1320.   AddInstTable(InstTable, NName, InstrZ++, DecodeLEA);
  1321. }
  1322.  
  1323. static void AddJmp(const char *NName, Word NCode, Boolean NDir)
  1324. {
  1325.   order_array_rsv_end(JmpOrders, JmpOrder);
  1326.   JmpOrders[InstrZ].Code = NCode;
  1327.   JmpOrders[InstrZ].MayDir = NDir;
  1328.   AddInstTable(InstTable, NName, InstrZ++, DecodeJmp);
  1329. }
  1330.  
  1331. static void AddReg(const char *NName, Word NCode, Word NSize, CPUVar NMin)
  1332. {
  1333.   order_array_rsv_end(Regs, Reg);
  1334.   Regs[InstrZ].Code = NCode;
  1335.   Regs[InstrZ].OpSize = NSize;
  1336.   Regs[InstrZ].MinCPU = NMin;
  1337.   AddInstTable(RegTable, NName, InstrZ++, LookupReg);
  1338. }
  1339.  
  1340. static void InitFields(void)
  1341. {
  1342.   InstTable = CreateInstTable(405);
  1343.  
  1344.   InstrZ = 0;
  1345.   AddFixed("ABA"  , 0x1806, CPU6812 ); AddFixed("ABX"  , 0x1ae5, CPU6812 );
  1346.   AddFixed("ABY"  , 0x19ed, CPU6812 ); AddFixed("ASLA" , 0x0048, CPU6812 );
  1347.   AddFixed("ASLB" , 0x0058, CPU6812 ); AddFixed("ASLD" , 0x0059, CPU6812 );
  1348.   AddFixed("ASLX" , 0x1848, CPU6812X); AddFixed("ASLY" , 0x1858, CPU6812X);
  1349.   AddFixed("ASRA" , 0x0047, CPU6812 ); AddFixed("ASRB" , 0x0057, CPU6812 );
  1350.   AddFixed("ASRX" , 0x1847, CPU6812X); AddFixed("ASRY" , 0x1857, CPU6812X);
  1351.   AddFixed("BGND" , 0x0000, CPU6812 ); AddFixed("CBA"  , 0x1817, CPU6812 );
  1352.   AddFixed("CLC"  , 0x10fe, CPU6812 ); AddFixed("CLI"  , 0x10ef, CPU6812 );
  1353.   AddFixed("CLRA" , 0x0087, CPU6812 ); AddFixed("CLRB" , 0x00c7, CPU6812 );
  1354.   AddFixed("CLRX" , 0x1887, CPU6812X); AddFixed("CLRY" , 0x18c7, CPU6812X);
  1355.   AddFixed("CLV"  , 0x10fd, CPU6812 ); AddFixed("COMA" , 0x0041, CPU6812 );
  1356.   AddFixed("COMB" , 0x0051, CPU6812 ); AddFixed("COMX" , 0x1841, CPU6812X);
  1357.   AddFixed("COMY" , 0x1851, CPU6812X); AddFixed("DAA"  , 0x1807, CPU6812 );
  1358.   AddFixed("DECA" , 0x0043, CPU6812 ); AddFixed("DECB" , 0x0053, CPU6812 );
  1359.   AddFixed("DECX" , 0x1843, CPU6812X); AddFixed("DECY" , 0x1853, CPU6812X);
  1360.   AddFixed("DES"  , 0x1b9f, CPU6812 ); AddFixed("DEX"  , 0x0009, CPU6812 );
  1361.   AddFixed("DEY"  , 0x0003, CPU6812 ); AddFixed("EDIV" , 0x0011, CPU6812 );
  1362.   AddFixed("EDIVS", 0x1814, CPU6812 ); AddFixed("EMUL" , 0x0013, CPU6812 );
  1363.   AddFixed("EMULS", 0x1813, CPU6812 ); AddFixed("FDIV" , 0x1811, CPU6812 );
  1364.   AddFixed("IDIV" , 0x1810, CPU6812 ); AddFixed("IDIVS", 0x1815, CPU6812 );
  1365.   AddFixed("INCA" , 0x0042, CPU6812 ); AddFixed("INCB" , 0x0052, CPU6812 );
  1366.   AddFixed("INCX" , 0x1842, CPU6812X); AddFixed("INCY" , 0x1852, CPU6812X);
  1367.   AddFixed("INS"  , 0x1b81, CPU6812 ); AddFixed("INX"  , 0x0008, CPU6812 );
  1368.   AddFixed("INY"  , 0x0002, CPU6812 ); AddFixed("LSLA" , 0x0048, CPU6812 );
  1369.   AddFixed("LSLB" , 0x0058, CPU6812 ); AddFixed("LSLX" , 0x1848, CPU6812X);
  1370.   AddFixed("LSLY" , 0x1858, CPU6812X); AddFixed("LSLD" , 0x0059, CPU6812 );
  1371.   AddFixed("LSRA" , 0x0044, CPU6812 ); AddFixed("LSRB" , 0x0054, CPU6812 );
  1372.   AddFixed("LSRX" , 0x1844, CPU6812X); AddFixed("LSRY" , 0x1854, CPU6812X);
  1373.   AddFixed("LSRD" , 0x0049, CPU6812 ); AddFixed("MEM"  , 0x0001, CPU6812 );
  1374.   AddFixed("MUL"  , 0x0012, CPU6812 ); AddFixed("NEGA" , 0x0040, CPU6812 );
  1375.   AddFixed("NEGB" , 0x0050, CPU6812 ); AddFixed("NEGX" , 0x1840, CPU6812X);
  1376.   AddFixed("NEGY" , 0x1850, CPU6812X); AddFixed("NOP"  , 0x00a7, CPU6812 );
  1377.   AddFixed("PSHA" , 0x0036, CPU6812 ); AddFixed("PSHB" , 0x0037, CPU6812 );
  1378.   AddFixed("PSHC" , 0x0039, CPU6812 ); AddFixed("PSHCW", 0x1839, CPU6812X);
  1379.   AddFixed("PSHD" , 0x003b, CPU6812 ); AddFixed("PSHX" , 0x0034, CPU6812 );
  1380.   AddFixed("PSHY" , 0x0035, CPU6812 ); AddFixed("PULA" , 0x0032, CPU6812 );
  1381.   AddFixed("PULB" , 0x0033, CPU6812 ); AddFixed("PULC" , 0x0038, CPU6812 );
  1382.   AddFixed("PULCW", 0x1838, CPU6812X); AddFixed("PULD" , 0x003a, CPU6812 );
  1383.   AddFixed("PULX" , 0x0030, CPU6812 ); AddFixed("PULY" , 0x0031, CPU6812 );
  1384.   AddFixed("REV"  , 0x183a, CPU6812 ); AddFixed("REVW" , 0x183b, CPU6812 );
  1385.   AddFixed("ROLA" , 0x0045, CPU6812 ); AddFixed("ROLB" , 0x0055, CPU6812 );
  1386.   AddFixed("ROLX" , 0x1845, CPU6812X); AddFixed("ROLY" , 0x1855, CPU6812X);
  1387.   AddFixed("RORA" , 0x0046, CPU6812 ); AddFixed("RORB" , 0x0056, CPU6812 );
  1388.   AddFixed("RORX" , 0x1846, CPU6812X); AddFixed("RORY" , 0x1856, CPU6812X);
  1389.   AddFixed("RTC"  , 0x000a, CPU6812 ); AddFixed("RTI"  , 0x000b, CPU6812 );
  1390.   AddFixed("RTS"  , 0x003d, CPU6812 ); AddFixed("SBA"  , 0x1816, CPU6812 );
  1391.   AddFixed("SEC"  , 0x1401, CPU6812 ); AddFixed("SEI"  , 0x1410, CPU6812 );
  1392.   AddFixed("SEV"  , 0x1402, CPU6812 ); AddFixed("STOP" , 0x183e, CPU6812 );
  1393.   AddFixed("SWI"  , 0x003f, CPU6812 ); AddFixed("TAB"  , 0x180e, CPU6812 );
  1394.   AddFixed("TAP"  , 0xb702, CPU6812 ); AddFixed("TBA"  , 0x180f, CPU6812 );
  1395.   AddFixed("TPA"  , 0xb720, CPU6812 ); AddFixed("TSTA" , 0x0097, CPU6812 );
  1396.   AddFixed("TSTB" , 0x00d7, CPU6812 ); AddFixed("TSTX" , 0x1897, CPU6812X);
  1397.   AddFixed("TSTY" , 0x18d7, CPU6812X); AddFixed("TSX"  , 0xb775, CPU6812 );
  1398.   AddFixed("TSY"  , 0xb776, CPU6812 ); AddFixed("TXS"  , 0xb757, CPU6812 );
  1399.   AddFixed("TYS"  , 0xb767, CPU6812 ); AddFixed("WAI"  , 0x003e, CPU6812 );
  1400.   AddFixed("WAV"  , 0x183c, CPU6812 ); AddFixed("XGDX" , 0xb7c5, CPU6812 );
  1401.   AddFixed("XGDY" , 0xb7c6, CPU6812 );
  1402.  
  1403.   InstrZ = 0;
  1404.   AddBranch("LBGT", 0x2e);    AddBranch("LBGE", 0x2c);
  1405.   AddBranch("LBEQ", 0x27);    AddBranch("LBLE", 0x2f);
  1406.   AddBranch("LBLT", 0x2d);    AddBranch("LBHI", 0x22);
  1407.   AddBranch("LBHS", 0x24);    AddBranch("LBCC", 0x24);
  1408.   AddBranch("LBNE", 0x26);    AddBranch("LBLS", 0x23);
  1409.   AddBranch("LBLO", 0x25);    AddBranch("LBCS", 0x25);
  1410.   AddBranch("LBMI", 0x2b);    AddBranch("LBVS", 0x29);
  1411.   AddBranch("LBRA", 0x20);    AddBranch("LBPL", 0x2a);
  1412.   AddBranch("LBRN", 0x21);    AddBranch("LBVC", 0x28);
  1413.   AddBranch("LBSR", 0x07);
  1414.  
  1415.   InstrZ = 0;
  1416.   AddGen("ADCA" , 0x0089, True , True , True , eSymbolSize8Bit   , CPU6812 );
  1417.   AddGen("ADCB" , 0x00c9, True , True , True , eSymbolSize8Bit   , CPU6812 );
  1418.   AddGen("ADDA" , 0x008b, True , True , True , eSymbolSize8Bit   , CPU6812 );
  1419.   AddGen("ADDB" , 0x00cb, True , True , True , eSymbolSize8Bit   , CPU6812 );
  1420.   AddGen("ADDD" , 0x00c3, True , True , True , eSymbolSize16Bit  , CPU6812 );
  1421.   AddGen("ADDX" , 0x188b, True , True , True , eSymbolSize16Bit  , CPU6812X);
  1422.   AddGen("ADDY" , 0x18cb, True , True , True , eSymbolSize16Bit  , CPU6812X);
  1423.   AddGen("ADED" , 0x18c3, True , True , True , eSymbolSize16Bit  , CPU6812X);
  1424.   AddGen("ADEX" , 0x1889, True , True , True , eSymbolSize16Bit  , CPU6812X);
  1425.   AddGen("ADEY" , 0x18c9, True , True , True , eSymbolSize16Bit  , CPU6812X);
  1426.   AddGen("ANDA" , 0x0084, True , True , True , eSymbolSize8Bit   , CPU6812 );
  1427.   AddGen("ANDB" , 0x00c4, True , True , True , eSymbolSize8Bit   , CPU6812 );
  1428.   AddGen("ANDX" , 0x1884, True , True , True , eSymbolSize16Bit  , CPU6812X);
  1429.   AddGen("ANDY" , 0x18c4, True , True , True , eSymbolSize16Bit  , CPU6812X);
  1430.   AddGen("ASL"  , 0x0048, False, False, True , eSymbolSizeUnknown, CPU6812 );
  1431.   AddGen("ASLW" , 0x1848, False, False, True , eSymbolSizeUnknown, CPU6812X);
  1432.   AddGen("ASR"  , 0x0047, False, False, True , eSymbolSizeUnknown, CPU6812 );
  1433.   AddGen("ASRW" , 0x1847, False, False, True , eSymbolSizeUnknown, CPU6812X);
  1434.   AddGen("BITA" , 0x0085, True , True , True , eSymbolSize8Bit   , CPU6812 );
  1435.   AddGen("BITB" , 0x00c5, True , True , True , eSymbolSize8Bit   , CPU6812 );
  1436.   AddGen("BITX" , 0x1885, True , True , True , eSymbolSize16Bit  , CPU6812X);
  1437.   AddGen("BITY" , 0x18c5, True , True , True , eSymbolSize16Bit  , CPU6812X);
  1438.   AddGen("CLR"  , 0x0049, False, False, True , eSymbolSizeUnknown, CPU6812 );
  1439.   AddGen("CLRW" , 0x1849, False, False, True , eSymbolSizeUnknown, CPU6812X);
  1440.   AddGen("CMPA" , 0x0081, True , True , True , eSymbolSize8Bit   , CPU6812 );
  1441.   AddGen("CMPB" , 0x00c1, True , True , True , eSymbolSize8Bit   , CPU6812 );
  1442.   AddGen("COM"  , 0x0041, False, False, True , eSymbolSizeUnknown, CPU6812 );
  1443.   AddGen("COMW" , 0x1841, False, False, True , eSymbolSizeUnknown, CPU6812X);
  1444.   AddGen("CPED" , 0x188c, True , True , True , eSymbolSize16Bit  , CPU6812X);
  1445.   AddGen("CPES" , 0x188f, True , True , True , eSymbolSize16Bit  , CPU6812X);
  1446.   AddGen("CPEX" , 0x188e, True , True , True , eSymbolSize16Bit  , CPU6812X);
  1447.   AddGen("CPEY" , 0x188d, True , True , True , eSymbolSize16Bit  , CPU6812X);
  1448.   AddGen("CPD"  , 0x008c, True , True , True , eSymbolSize16Bit  , CPU6812 );
  1449.   AddGen("CPS"  , 0x008f, True , True , True , eSymbolSize16Bit  , CPU6812 );
  1450.   AddGen("CPX"  , 0x008e, True , True , True , eSymbolSize16Bit  , CPU6812 );
  1451.   AddGen("CPY"  , 0x008d, True , True , True , eSymbolSize16Bit  , CPU6812 );
  1452.   AddGen("DEC"  , 0x0043, False, False, True , eSymbolSizeUnknown, CPU6812 );
  1453.   AddGen("DECW" , 0x1843, False, False, True , eSymbolSizeUnknown, CPU6812X);
  1454.   AddGen("EMAXD", 0x18fa, False, False, False, eSymbolSizeUnknown, CPU6812 );
  1455.   AddGen("EMAXM", 0x18fe, False, False, False, eSymbolSizeUnknown, CPU6812 );
  1456.   AddGen("EMIND", 0x18fb, False, False, False, eSymbolSizeUnknown, CPU6812 );
  1457.   AddGen("EMINM", 0x18ff, False, False, False, eSymbolSizeUnknown, CPU6812 );
  1458.   AddGen("EORA" , 0x0088, True , True , True , eSymbolSize8Bit   , CPU6812 );
  1459.   AddGen("EORB" , 0x00c8, True , True , True , eSymbolSize8Bit   , CPU6812 );
  1460.   AddGen("EORX" , 0x1888, True , True , True , eSymbolSize16Bit  , CPU6812X);
  1461.   AddGen("EORY" , 0x18c8, True , True , True , eSymbolSize16Bit  , CPU6812X);
  1462.   AddGen("GLDAA", 0x1886, False, True , True , eSymbolSizeUnknown, CPU6812X);
  1463.   AddGen("GLDAB", 0x18c6, False, True , True , eSymbolSizeUnknown, CPU6812X);
  1464.   AddGen("GLDD" , 0x18cc, False, True , True , eSymbolSizeUnknown, CPU6812X);
  1465.   AddGen("GLDS" , 0x18cf, False, True , True , eSymbolSizeUnknown, CPU6812X);
  1466.   AddGen("GLDX" , 0x18ce, False, True , True , eSymbolSizeUnknown, CPU6812X);
  1467.   AddGen("GLDY" , 0x18cd, False, True , True , eSymbolSizeUnknown, CPU6812X);
  1468.   AddGen("GSTAA", 0x184a, False, True , True , eSymbolSizeUnknown, CPU6812X);
  1469.   AddGen("GSTAB", 0x184b, False, True , True , eSymbolSizeUnknown, CPU6812X);
  1470.   AddGen("GSTD" , 0x184c, False, True , True , eSymbolSizeUnknown, CPU6812X);
  1471.   AddGen("GSTS" , 0x184f, False, True , True , eSymbolSizeUnknown, CPU6812X);
  1472.   AddGen("GSTX" , 0x184e, False, True , True , eSymbolSizeUnknown, CPU6812X);
  1473.   AddGen("GSTY" , 0x184d, False, True , True , eSymbolSizeUnknown, CPU6812X);
  1474.   AddGen("INC"  , 0x0042, False, False, True , eSymbolSizeUnknown, CPU6812 );
  1475.   AddGen("INCW" , 0x1842, False, False, True , eSymbolSizeUnknown, CPU6812X);
  1476.   AddGen("LDAA" , 0x0086, True , True , True , eSymbolSize8Bit   , CPU6812 );
  1477.   AddGen("LDAB" , 0x00c6, True , True , True , eSymbolSize8Bit   , CPU6812 );
  1478.   AddGen("LDD"  , 0x00cc, True , True , True , eSymbolSize16Bit  , CPU6812 );
  1479.   AddGen("LDS"  , 0x00cf, True , True , True , eSymbolSize16Bit  , CPU6812 );
  1480.   AddGen("LDX"  , 0x00ce, True , True , True , eSymbolSize16Bit  , CPU6812 );
  1481.   AddGen("LDY"  , 0x00cd, True , True , True , eSymbolSize16Bit  , CPU6812 );
  1482.   AddGen("LSL"  , 0x0048, False, False, True , eSymbolSizeUnknown, CPU6812 );
  1483.   AddGen("LSLW" , 0x1848, False, False, True , eSymbolSizeUnknown, CPU6812X);
  1484.   AddGen("LSR"  , 0x0044, False, False, True , eSymbolSizeUnknown, CPU6812 );
  1485.   AddGen("LSRW" , 0x1844, False, False, True , eSymbolSizeUnknown, CPU6812X);
  1486.   AddGen("MAXA" , 0x18f8, False, False, False, eSymbolSizeUnknown, CPU6812 );
  1487.   AddGen("MAXM" , 0x18fc, False, False, False, eSymbolSizeUnknown, CPU6812 );
  1488.   AddGen("MINA" , 0x18f9, False, False, False, eSymbolSizeUnknown, CPU6812 );
  1489.   AddGen("MINM" , 0x18fd, False, False, False, eSymbolSizeUnknown, CPU6812 );
  1490.   AddGen("NEG"  , 0x0040, False, False, True , eSymbolSizeUnknown, CPU6812 );
  1491.   AddGen("NEGW" , 0x1840, False, False, True , eSymbolSizeUnknown, CPU6812X);
  1492.   AddGen("ORAA" , 0x008a, True , True , True , eSymbolSize8Bit   , CPU6812 );
  1493.   AddGen("ORAB" , 0x00ca, True , True , True , eSymbolSize8Bit   , CPU6812 );
  1494.   AddGen("ORX"  , 0x188a, True , True , True , eSymbolSize16Bit  , CPU6812X);
  1495.   AddGen("ORY"  , 0x18ca, True , True , True , eSymbolSize16Bit  , CPU6812X);
  1496.   AddGen("ROL"  , 0x0045, False, False, True , eSymbolSizeUnknown, CPU6812 );
  1497.   AddGen("ROLW" , 0x1845, False, False, True , eSymbolSizeUnknown, CPU6812X);
  1498.   AddGen("ROR"  , 0x0046, False, False, True , eSymbolSizeUnknown, CPU6812 );
  1499.   AddGen("RORW" , 0x1846, False, False, True , eSymbolSizeUnknown, CPU6812X);
  1500.   AddGen("SBCA" , 0x0082, True , True , True , eSymbolSize8Bit   , CPU6812 );
  1501.   AddGen("SBCB" , 0x00c2, True , True , True , eSymbolSize8Bit   , CPU6812 );
  1502.   AddGen("SBED" , 0x1883, True , True , True , eSymbolSize16Bit  , CPU6812X);
  1503.   AddGen("SBEX" , 0x1882, True , True , True , eSymbolSize16Bit  , CPU6812X);
  1504.   AddGen("SBEY" , 0x18c2, True , True , True , eSymbolSize16Bit  , CPU6812X);
  1505.   AddGen("STAA" , 0x004a, False, True , True , eSymbolSize8Bit   , CPU6812 );
  1506.   AddGen("STAB" , 0x004b, False, True , True , eSymbolSize8Bit   , CPU6812 );
  1507.   AddGen("STD"  , 0x004c, False, True , True , eSymbolSizeUnknown, CPU6812 );
  1508.   AddGen("STS"  , 0x004f, False, True , True , eSymbolSizeUnknown, CPU6812 );
  1509.   AddGen("STX"  , 0x004e, False, True , True , eSymbolSizeUnknown, CPU6812 );
  1510.   AddGen("STY"  , 0x004d, False, True , True , eSymbolSizeUnknown, CPU6812 );
  1511.   AddGen("SUBA" , 0x0080, True , True , True , eSymbolSize8Bit   , CPU6812 );
  1512.   AddGen("SUBB" , 0x00c0, True , True , True , eSymbolSize8Bit   , CPU6812 );
  1513.   AddGen("SUBX" , 0x1880, True , True , True , eSymbolSize16Bit  , CPU6812X);
  1514.   AddGen("SUBY" , 0x18c0, True , True , True , eSymbolSize16Bit  , CPU6812X);
  1515.   AddGen("SUBD" , 0x0083, True , True , True , eSymbolSize16Bit  , CPU6812 );
  1516.   AddGen("TST"  , 0x00c7, False, False, True , eSymbolSizeUnknown, CPU6812 );
  1517.   AddGen("TSTW" , 0x18c7, False, False, True , eSymbolSizeUnknown, CPU6812X);
  1518.  
  1519.   InstrZ = 0;
  1520.   AddLoop("DBEQ", 0x00); AddLoop("DBNE", 0x20);
  1521.   AddLoop("IBEQ", 0x80); AddLoop("IBNE", 0xa0);
  1522.   AddLoop("TBEQ", 0x40); AddLoop("TBNE", 0x60);
  1523.  
  1524.   InstrZ = 0;
  1525.   AddLEA("LEAS", 0x1b);
  1526.   AddLEA("LEAX", 0x1a);
  1527.   AddLEA("LEAY", 0x19);
  1528.  
  1529.   InstrZ = 0;
  1530.   AddJmp("JMP", 0x06, False);
  1531.   AddJmp("JSR", 0x16, True );
  1532.  
  1533.   AddInstTable(InstTable, "TBL"   , 0x3d, DecodeETBL);
  1534.   AddInstTable(InstTable, "ETBL"  , 0x3f, DecodeETBL);
  1535.   AddInstTable(InstTable, "EMACS" , 0   , DecodeEMACS);
  1536.   AddInstTable(InstTable, "TFR"   , 0x00, DecodeTransfer);
  1537.   AddInstTable(InstTable, "EXG"   , 0x80, DecodeTransfer);
  1538.   AddInstTable(InstTable, "SEX"   , 0   , DecodeSEX);
  1539.   AddInstTable(InstTable, "MOVB"  , eSymbolSize8Bit, DecodeMOV);
  1540.   AddInstTable(InstTable, "MOVW"  , eSymbolSize16Bit, DecodeMOV);
  1541.   AddInstTable(InstTable, "ANDCC" , 0x00, DecodeLogic);
  1542.   AddInstTable(InstTable, "ORCC"  , 0x04, DecodeLogic);
  1543.   AddInstTable(InstTable, "BSET"  , 0x0c, DecodeBit);
  1544.   AddInstTable(InstTable, "BCLR"  , 0x0d, DecodeBit);
  1545.   AddInstTable(InstTable, "CALL"  , 0   , DecodeCALL);
  1546.   AddInstTable(InstTable, "PCALL" , 0   , DecodePCALL);
  1547.   AddInstTable(InstTable, "BRSET" , 0x00, DecodeBrBit);
  1548.   AddInstTable(InstTable, "BRCLR" , 0x01, DecodeBrBit);
  1549.   AddInstTable(InstTable, "TRAP"  , 0   , DecodeTRAP);
  1550.   AddInstTable(InstTable, "BTAS"  , 0   , DecodeBTAS);
  1551.  
  1552.   RegTable = CreateInstTable(31);
  1553.   InstrZ = 0;
  1554.   AddReg("A"   , eRegA    , 0, CPU6812 );
  1555.   AddReg("B"   , eRegB    , 0, CPU6812 );
  1556.   AddReg("CCR" , eRegCCRL , 0, CPU6812 );
  1557.   AddReg("CCRL", eRegCCRL , 0, CPU6812 );
  1558.   AddReg("D"   , eRegD    , 1, CPU6812 );
  1559.   AddReg("X"   , eRegX    , 1, CPU6812 );
  1560.   AddReg("Y"   , eRegY    , 1, CPU6812 );
  1561.   AddReg("SP"  , eRegSP   , 1, CPU6812 );
  1562.   AddReg("PC"  , eRegPC   , 1, CPU6812 );
  1563.   AddReg("XL"  , eRegXL   , 0, CPU6812 );
  1564.   AddReg("XH"  , eRegXH   , 0, CPU6812X);
  1565.   AddReg("YL"  , eRegYL   , 0, CPU6812 );
  1566.   AddReg("YH"  , eRegYH   , 0, CPU6812X);
  1567.   AddReg("SPL" , eRegSPL  , 0, CPU6812 );
  1568.   AddReg("SPH" , eRegSPH  , 0, CPU6812X);
  1569.   AddReg("CCRH", eRegCCRH , 0, CPU6812X);
  1570.   AddReg("CCRW", eRegCCRW , 1, CPU6812X);
  1571.  
  1572.   init_moto8_pseudo(InstTable, e_moto_8_be | e_moto_8_db | e_moto_8_dw);
  1573. }
  1574.  
  1575. static void DeinitFields(void)
  1576. {
  1577.   DestroyInstTable(InstTable);
  1578.   order_array_free(FixedOrders);
  1579.   order_array_free(BranchOrders);
  1580.   order_array_free(GenOrders);
  1581.   order_array_free(LoopOrders);
  1582.   order_array_free(LEAOrders);
  1583.   order_array_free(JmpOrders);
  1584.  
  1585.   DestroyInstTable(RegTable);
  1586.   order_array_free(Regs);
  1587. }
  1588.  
  1589. /*--------------------------------------------------------------------------*/
  1590. /* Main Functions */
  1591.  
  1592. static Boolean DecodeAttrPart_6812(void)
  1593. {
  1594.   if (strlen(AttrPart.str.p_str) > 1)
  1595.   {
  1596.     WrStrErrorPos(ErrNum_UndefAttr, &AttrPart);
  1597.     return False;
  1598.   }
  1599.  
  1600.   /* Operandengroesse festlegen */
  1601.  
  1602.   return DecodeMoto16AttrSize(*AttrPart.str.p_str, &AttrPartOpSize[0], False);
  1603. }
  1604.  
  1605. static void MakeCode_6812(void)
  1606. {
  1607.   CodeLen = 0;
  1608.   DontPrint = False;
  1609.   OpSize = AttrPartOpSize[0];
  1610.  
  1611.   /* zu ignorierendes */
  1612.  
  1613.   if (Memo(""))
  1614.     return;
  1615.  
  1616.   /* Pseudoanweisungen */
  1617.  
  1618.   if (DecodeMoto16Pseudo(OpSize,True)) return;
  1619.  
  1620.   if (!LookupInstTable(InstTable, OpPart.str.p_str))
  1621.     WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
  1622. }
  1623.  
  1624. static void InitCode_6812(void)
  1625. {
  1626.   Reg_Direct = 0;
  1627.   Reg_GPage = 0;
  1628. }
  1629.  
  1630. static Boolean IsDef_6812(void)
  1631. {
  1632.   return False;
  1633. }
  1634.  
  1635. static Boolean ChkPC_6812X(LargeWord Addr)
  1636. {
  1637.   Byte Page = (Addr >> 16) & 0xff;
  1638.  
  1639.   if (ActPC != SegCode)
  1640.     return False;
  1641.   else if ((Addr & 0xc000) == 0x8000)
  1642.     return ((Page == 0) || ((Page >= 0x30) && (Page <= 0x3f)));
  1643.   else
  1644.     return (Page == 0);
  1645. }
  1646.  
  1647. static void SwitchTo_6812(void)
  1648. {
  1649.   TurnWords = False;
  1650.   SetIntConstMode(eIntConstModeMoto);
  1651.  
  1652.   PCSymbol = "*";
  1653.   HeaderID = 0x66;
  1654.   NOPCode = 0xa7;
  1655.   DivideChars = ",";
  1656.   HasAttrs = True;
  1657.   AttrChars = ".";
  1658.  
  1659.   ValidSegs = (1 << SegCode);
  1660.   Grans[SegCode] = 1; ListGrans[SegCode] = 1; SegInits[SegCode] = 0;
  1661.   if (MomCPU == CPU6812X)
  1662.   {
  1663.     SegLimits[SegCode] = 0x3bfff;
  1664.     ChkPC = ChkPC_6812X;
  1665.     AddrInt = UInt22;
  1666.   }
  1667.   else
  1668.   {
  1669.     SegLimits[SegCode] = 0xffff;
  1670.     AddrInt = UInt16;
  1671.   }
  1672.  
  1673.   DecodeAttrPart = DecodeAttrPart_6812;
  1674.   MakeCode = MakeCode_6812;
  1675.   IsDef = IsDef_6812;
  1676.   SwitchFrom = DeinitFields;
  1677.   InitFields();
  1678.   AddMoto16PseudoONOFF(False);
  1679.  
  1680.   if (MomCPU >= CPU6812X)
  1681.   {
  1682. #define ASSUME6812Count (sizeof(ASSUME6812s) / sizeof(*ASSUME6812s))
  1683.    static const ASSUMERec ASSUME6812s[] =
  1684.    {
  1685.      { "DIRECT" , &Reg_Direct , 0,  0xff,  0x100, NULL },
  1686.      { "GPAGE"  , &Reg_GPage  , 0,  0x7f,   0x80, NULL }
  1687.    };
  1688.  
  1689.    pASSUMERecs = ASSUME6812s;
  1690.    ASSUMERecCnt = ASSUME6812Count;
  1691.   }
  1692. }
  1693.  
  1694. void code6812_init(void)
  1695. {
  1696.   CPU6812  = AddCPU("68HC12", SwitchTo_6812);
  1697.   CPU6812X = AddCPU("68HC12X", SwitchTo_6812);
  1698.  
  1699.   AddInitPassProc(InitCode_6812);
  1700. }
  1701.