Subversion Repositories pentevo

Rev

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

  1. /* code6816.c */
  2. /*****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
  4. /*                                                                           */
  5. /* AS-Portierung                                                             */
  6. /*                                                                           */
  7. /* Codegeneratormodul CPU16                                                  */
  8. /*                                                                           */
  9. /*****************************************************************************/
  10.  
  11. #include "stdinc.h"
  12.  
  13. #include <string.h>
  14. #include <ctype.h>
  15.  
  16. #include "nls.h"
  17. #include "nlmessages.h"
  18. #include "as.rsc"
  19. #include "bpemu.h"
  20. #include "strutil.h"
  21. #include "asmdef.h"
  22. #include "asmsub.h"
  23. #include "errmsg.h"
  24. #include "asmpars.h"
  25. #include "asmitree.h"
  26. #include "codepseudo.h"
  27. #include "motpseudo.h"
  28. #include "intpseudo.h"
  29. #include "codevars.h"
  30.  
  31. #include "code6816.h"
  32.  
  33. /*---------------------------------------------------------------------------*/
  34.  
  35. typedef struct
  36. {
  37.   tSymbolSize Size;
  38.   Word Code, ExtCode;
  39.   Byte AdrMask, ExtShift;
  40. } GenOrder;
  41.  
  42. typedef struct
  43. {
  44.   Word Code1, Code2;
  45. } EmuOrder;
  46.  
  47. enum
  48. {
  49.   ModNone = -1,
  50.   ModDisp8 = 0,
  51.   ModDisp16 = 1,
  52.   ModDispE = 2,
  53.   ModAbs = 3,
  54.   ModImm = 4,
  55.   ModImmExt = 5,
  56.   ModDisp20 = ModDisp16,
  57.   ModAbs20 = ModAbs
  58. };
  59.  
  60. #define MModDisp8 (1 << ModDisp8)
  61. #define MModDisp16 (1 << ModDisp16)
  62. #define MModDispE (1 << ModDispE)
  63. #define MModAbs (1 << ModAbs)
  64. #define MModImm (1 << ModImm)
  65. #define MModImmExt (1 << ModImmExt)
  66. #define MModDisp20 MModDisp16
  67. #define MModAbs20 MModAbs
  68.  
  69. static ShortInt AdrMode;
  70. static Byte AdrPart;
  71. static Byte AdrVals[4];
  72.  
  73. static LongInt Reg_EK;
  74.  
  75. static GenOrder *GenOrders;
  76. static EmuOrder *EmuOrders;
  77.  
  78. static CPUVar CPU6816;
  79.  
  80. static const char Regs[][4] =
  81. {
  82.   "D",
  83.   "E",
  84.   "X",
  85.   "Y",
  86.   "Z",
  87.   "K",
  88.   "CCR"
  89. };
  90.  
  91. /*-------------------------------------------------------------------------*/
  92.  
  93. typedef enum
  94. {
  95.   ShortDisp,
  96.   LongDisp,
  97.   NoDisp
  98. } DispType;
  99.  
  100. static unsigned SplitSize(char *Asc, DispType *pErg)
  101. {
  102.   if (strlen(Asc) < 1)
  103.   {
  104.     *pErg = NoDisp;
  105.     return 0;
  106.   }
  107.   else if (*Asc == '>')
  108.   {
  109.     *pErg = LongDisp;
  110.     return 1;
  111.   }
  112.   else if (*Asc == '<')
  113.   {
  114.     *pErg = ShortDisp;
  115.     return 1;
  116.   }
  117.   else
  118.   {
  119.     *pErg = NoDisp;
  120.     return 0;
  121.   }
  122. }
  123.  
  124. static void DecodeAdr(int Start, int Stop, tSymbolSize op_size, Boolean LongAdr, Byte Mask)
  125. {
  126.   Integer V16;
  127.   LongInt V32;
  128.   Boolean OK;
  129.   unsigned Offset;
  130.   DispType Size;
  131.  
  132.   AdrMode = ModNone;
  133.   AdrCnt = 0;
  134.  
  135.   Stop -= Start - 1;
  136.   if (Stop < 1)
  137.   {
  138.     char Str[100];
  139.  
  140.     as_snprintf(Str, sizeof(Str), getmessage(Num_ErrMsgAddrArgCnt), 1, 2, Stop - Start + 1);
  141.     WrXError(ErrNum_WrongArgCnt, Str);
  142.     return;
  143.   }
  144.  
  145.   /* immediate ? */
  146.  
  147.   if (*ArgStr[Start].str.p_str == '#')
  148.   {
  149.     Offset = SplitSize(ArgStr[Start].str.p_str + 1, &Size);
  150.     switch (op_size)
  151.     {
  152.       case eSymbolSizeUnknown:
  153.         WrError(ErrNum_UndefOpSizes);
  154.         break;
  155.       case eSymbolSize8Bit:
  156.         AdrVals[0] = EvalStrIntExpressionOffs(&ArgStr[Start], 1 + Offset, Int8, &OK);
  157.         if (OK)
  158.         {
  159.           AdrCnt = 1;
  160.           AdrMode = ModImm;
  161.         }
  162.         break;
  163.       case eSymbolSize16Bit:
  164.         V16 = EvalStrIntExpressionOffs(&ArgStr[Start], 1 + Offset, (Size == ShortDisp) ? SInt8 : Int16, &OK);
  165.         if ((Size == NoDisp) && (V16 >= -128) && (V16 <= 127) && ((Mask & MModImmExt) != 0))
  166.           Size = ShortDisp;
  167.         if (OK)
  168.         {
  169.           if (Size == ShortDisp)
  170.           {
  171.             AdrVals[0] = Lo(V16);
  172.             AdrCnt = 1;
  173.             AdrMode = ModImmExt;
  174.           }
  175.           else
  176.           {
  177.             AdrVals[0] = Hi(V16);
  178.             AdrVals[1] = Lo(V16);
  179.             AdrCnt = 2;
  180.             AdrMode = ModImm;
  181.           }
  182.         }
  183.         break;
  184.       case eSymbolSize32Bit:
  185.         V32 = EvalStrIntExpressionOffs(&ArgStr[Start], 1 + Offset, Int32, &OK);
  186.         if (OK)
  187.         {
  188.           AdrVals[0] = (V32 >> 24) & 0xff;
  189.           AdrVals[1] = (V32 >> 16) & 0xff;
  190.           AdrVals[2] = (V32 >>  8) & 0xff;
  191.           AdrVals[3] = V32 & 0xff;
  192.           AdrCnt = 4;
  193.           AdrMode = ModImm;
  194.         }
  195.         break;
  196.       default:
  197.         break;
  198.     }
  199.     goto chk;
  200.   }
  201.  
  202.   /* zusammengesetzt ? */
  203.  
  204.   if (Stop == 2)
  205.   {
  206.     AdrPart = 0xff;
  207.     if (!as_strcasecmp(ArgStr[Start + 1].str.p_str, "X"))
  208.       AdrPart = 0x00;
  209.     else if (!as_strcasecmp(ArgStr[Start + 1].str.p_str, "Y"))
  210.       AdrPart = 0x10;
  211.     else if (!as_strcasecmp(ArgStr[Start + 1].str.p_str, "Z"))
  212.       AdrPart = 0x20;
  213.     else
  214.       WrStrErrorPos(ErrNum_InvReg, &ArgStr[Start + 1]);
  215.     if (AdrPart != 0xff)
  216.     {
  217.       if (!as_strcasecmp(ArgStr[Start].str.p_str, "E"))
  218.         AdrMode = ModDispE;
  219.       else
  220.       {
  221.         Offset = SplitSize(ArgStr[Start].str.p_str, &Size);
  222.         if (Size == ShortDisp)
  223.           V32 = EvalStrIntExpressionOffs(&ArgStr[Start], Offset, UInt8, &OK);
  224.         else if (LongAdr)
  225.           V32 = EvalStrIntExpressionOffs(&ArgStr[Start], Offset, SInt20, &OK);
  226.         else
  227.           V32 = EvalStrIntExpressionOffs(&ArgStr[Start], Offset, SInt16, &OK);
  228.         if (OK)
  229.         {
  230.           if (Size == NoDisp)
  231.           {
  232.             if ((V32 >= 0) && (V32 <= 255) && ((Mask & MModDisp8) != 0))
  233.               Size = ShortDisp;
  234.           }
  235.           if (Size == ShortDisp)
  236.           {
  237.             AdrVals[0] = V32 & 0xff;
  238.             AdrCnt = 1;
  239.             AdrMode = ModDisp8;
  240.           }
  241.           else if (LongAdr)
  242.           {
  243.             AdrVals[0] = (V32 >> 16) & 0x0f;
  244.             AdrVals[1] = (V32 >> 8) & 0xff;
  245.             AdrVals[2] = V32 & 0xff;
  246.             AdrCnt = 3;
  247.             AdrMode = ModDisp16;
  248.           }
  249.           else
  250.           {
  251.             AdrVals[0] = (V32 >> 8) & 0xff;
  252.             AdrVals[1] = V32 & 0xff;
  253.             AdrCnt = 2;
  254.             AdrMode = ModDisp16;
  255.           }
  256.         }
  257.       }
  258.     }
  259.     goto chk;
  260.   }
  261.  
  262.    /* absolut ? */
  263.  
  264.   else
  265.   {
  266.     Offset = SplitSize(ArgStr[Start].str.p_str, &Size);
  267.     V32 = EvalStrIntExpressionOffs(&ArgStr[Start], Offset, UInt20, &OK);
  268.     if (OK)
  269.     {
  270.       if (LongAdr)
  271.       {
  272.         AdrVals[0] = (V32 >> 16) & 0xff;
  273.         AdrVals[1] = (V32 >> 8) & 0xff;
  274.         AdrVals[2] = V32 & 0xff;
  275.         AdrMode = ModAbs;
  276.         AdrCnt = 3;
  277.       }
  278.       else
  279.       {
  280.         if ((V32 >> 16) != Reg_EK) WrError(ErrNum_InAccPage);
  281.         AdrVals[0] = (V32 >> 8) & 0xff;
  282.         AdrVals[1] = V32 & 0xff;
  283.         AdrMode = ModAbs;
  284.         AdrCnt = 2;
  285.       }
  286.     }
  287.     goto chk;
  288.   }
  289.  
  290. chk:
  291.   if ((AdrMode != ModNone) && (!(Mask & (1 << AdrMode))))
  292.   {
  293.     WrError(ErrNum_InvAddrMode);
  294.     AdrMode = ModNone;
  295.      AdrCnt = 0;
  296.   }
  297. }
  298.  
  299. /*-------------------------------------------------------------------------*/
  300.  
  301. static void DecodeFixed(Word Code)
  302. {
  303.   if (ChkArgCnt(0, 0))
  304.   {
  305.     BAsmCode[0] = Hi(Code);
  306.     BAsmCode[1] = Lo(Code);
  307.     CodeLen = 2;
  308.   }
  309. }
  310.  
  311. static void DecodeEmu(Word Index)
  312. {
  313.   EmuOrder *pOrder = EmuOrders + Index;
  314.  
  315.   if (ChkArgCnt(0, 0))
  316.   {
  317.     BAsmCode[0] = Hi(pOrder->Code1);
  318.     BAsmCode[1] = Lo(pOrder->Code1);
  319.     BAsmCode[2] = Hi(pOrder->Code2);
  320.     BAsmCode[3] = Lo(pOrder->Code2);
  321.     CodeLen = 4;
  322.   }
  323. }
  324.  
  325. static void DecodeRel(Word Code)
  326. {
  327.   Boolean OK;
  328.   tSymbolFlags Flags;
  329.   LongInt AdrLong;
  330.  
  331.   if (ChkArgCnt(1, 1))
  332.   {
  333.     AdrLong = EvalStrIntExpressionWithFlags(&ArgStr[1], UInt24, &OK, &Flags) - EProgCounter() - 6;
  334.     if (AdrLong & 1) WrError(ErrNum_NotAligned);
  335.     else if (Code & 0x8000)
  336.     {
  337.       if (!mSymbolQuestionable(Flags) && ((AdrLong > 0x7fffl) || (AdrLong < -0x8000l))) WrError(ErrNum_JmpDistTooBig);
  338.       else
  339.       {
  340.         BAsmCode[0] = 0x37;
  341.         BAsmCode[1] = Lo(Code) + 0x80;
  342.         BAsmCode[2] = (AdrLong >> 8) & 0xff;
  343.         BAsmCode[3] = AdrLong & 0xff;
  344.         CodeLen = 4;
  345.       }
  346.     }
  347.     else
  348.     {
  349.       if (!mSymbolQuestionable(Flags) && ((AdrLong > 0x7fl) || (AdrLong < -0x80l))) WrError(ErrNum_JmpDistTooBig);
  350.       else
  351.       {
  352.         BAsmCode[0] = 0xb0 + Lo(Code);
  353.         BAsmCode[1] = AdrLong & 0xff;
  354.         CodeLen = 2;
  355.       }
  356.     }
  357.   }
  358. }
  359.  
  360. static void DecodeLRel(Word Code)
  361. {
  362.   Boolean OK;
  363.   tSymbolFlags Flags;
  364.   LongInt AdrLong;
  365.  
  366.   if (ChkArgCnt(1, 1))
  367.   {
  368.     AdrLong = EvalStrIntExpressionWithFlags(&ArgStr[1], UInt24, &OK, &Flags) - EProgCounter() - 6;
  369.     if (AdrLong & 1) WrError(ErrNum_NotAligned);
  370.     else if (!mSymbolQuestionable(Flags) && ((AdrLong > 0x7fffl) || (AdrLong < -0x8000l))) WrError(ErrNum_JmpDistTooBig);
  371.     else
  372.     {
  373.       BAsmCode[0] = Hi(Code);
  374.       BAsmCode[1] = Lo(Code);
  375.       BAsmCode[2] = (AdrLong >> 8) & 0xff;
  376.       BAsmCode[3] = AdrLong & 0xff;
  377.       CodeLen = 4;
  378.     }
  379.   }
  380. }
  381.  
  382. static void DecodeGen(Word Index)
  383. {
  384.   GenOrder *pOrder = GenOrders + Index;
  385.  
  386.   if (ChkArgCnt(1, 2))
  387.   {
  388.     DecodeAdr(1, ArgCnt, pOrder->Size, False, pOrder->AdrMask);
  389.     switch (AdrMode)
  390.     {
  391.       case ModDisp8:
  392.         BAsmCode[0] = pOrder->Code + AdrPart;
  393.         BAsmCode[1] = AdrVals[0];
  394.         CodeLen = 2;
  395.         break;
  396.       case ModDisp16:
  397.         BAsmCode[0] = 0x17 + pOrder->ExtShift;
  398.         BAsmCode[1] = pOrder->Code + (pOrder->Size << 6) + AdrPart;
  399.         memcpy(BAsmCode + 2, AdrVals, AdrCnt);
  400.         CodeLen = 2 + AdrCnt;
  401.         break;
  402.       case ModDispE:
  403.         BAsmCode[0] = 0x27;
  404.         BAsmCode[1] = pOrder->Code + AdrPart;
  405.         CodeLen = 2;
  406.         break;
  407.       case ModAbs:
  408.         BAsmCode[0] = 0x17 + pOrder->ExtShift;
  409.         BAsmCode[1] = pOrder->Code + (pOrder->Size << 6) + 0x30;
  410.         memcpy(BAsmCode + 2, AdrVals, AdrCnt);
  411.         CodeLen = 2 + AdrCnt;
  412.         break;
  413.       case ModImm:
  414.         if (pOrder->Size == eSymbolSize8Bit)
  415.         {
  416.           BAsmCode[0] = pOrder->Code + 0x30;
  417.           BAsmCode[1] = AdrVals[0];
  418.           CodeLen = 2;
  419.         }
  420.         else
  421.         {
  422.           BAsmCode[0] = 0x37;
  423.           BAsmCode[1] = pOrder->Code + 0x30;
  424.           memcpy(BAsmCode + 2, AdrVals, AdrCnt);
  425.           CodeLen = 2 + AdrCnt;
  426.         }
  427.         break;
  428.       case ModImmExt:
  429.         BAsmCode[0] = pOrder->ExtCode;
  430.         BAsmCode[1] = AdrVals[0];
  431.         CodeLen = 2;
  432.         break;
  433.     }
  434.   }
  435. }
  436.  
  437. static void DecodeAux(Word Code)
  438. {
  439.   if (ChkArgCnt(1, 2))
  440.   {
  441.     DecodeAdr(1, ArgCnt, eSymbolSize16Bit, False, (*OpPart.str.p_str == 'S' ? 0 : MModImm) | MModDisp8 | MModDisp16 | MModAbs);
  442.     switch (AdrMode)
  443.     {
  444.       case ModDisp8:
  445.         BAsmCode[0] = Code + AdrPart;
  446.         BAsmCode[1] = AdrVals[0];
  447.         CodeLen = 2;
  448.         break;
  449.       case ModDisp16:
  450.         BAsmCode[0] = 0x17;
  451.         BAsmCode[1] = Code + AdrPart;
  452.         memcpy(BAsmCode + 2, AdrVals, AdrCnt);
  453.         CodeLen = 2 + AdrCnt;
  454.         break;
  455.       case ModAbs:
  456.         BAsmCode[0] = 0x17;
  457.         BAsmCode[1] = Code + 0x30;
  458.         memcpy(BAsmCode + 2, AdrVals, AdrCnt);
  459.         CodeLen = 2 + AdrCnt;
  460.         break;
  461.       case ModImm:
  462.         BAsmCode[0] = 0x37;
  463.         BAsmCode[1] = Code + 0x30;
  464.         if (*OpPart.str.p_str == 'L') BAsmCode[1] -= 0x40;
  465.         memcpy(BAsmCode + 2, AdrVals, AdrCnt);
  466.         CodeLen = 2 + AdrCnt;
  467.        break;
  468.     }
  469.   }
  470. }
  471.  
  472. static void DecodeImm(Word Code)
  473. {
  474.   if (ChkArgCnt(1, 1))
  475.   {
  476.     DecodeAdr(1, 1, eSymbolSize16Bit, False, MModImm | MModImmExt);
  477.     switch (AdrMode)
  478.     {
  479.       case ModImm:
  480.         BAsmCode[0] = 0x37;
  481.         BAsmCode[1] = Code;
  482.         memcpy(BAsmCode + 2, AdrVals, AdrCnt);
  483.         CodeLen = 2 + AdrCnt;
  484.         break;
  485.       case ModImmExt:
  486.         BAsmCode[0] = Code;
  487.         BAsmCode[1] = AdrVals[0];
  488.         CodeLen = 2;
  489.         break;
  490.     }
  491.   }
  492. }
  493.  
  494. static void DecodeExt(Word Code)
  495. {
  496.   if (ChkArgCnt(1, 1))
  497.   {
  498.     DecodeAdr(1, 1, eSymbolSize16Bit, False, MModAbs);
  499.     switch (AdrMode)
  500.     {
  501.       case ModAbs:
  502.        BAsmCode[0] = Hi(Code);
  503.        BAsmCode[1] = Lo(Code);
  504.        memcpy(BAsmCode + 2, AdrVals, AdrCnt);
  505.        CodeLen = 2 + AdrCnt;
  506.        break;
  507.     }
  508.   }
  509. }
  510.  
  511. static void DecodeStkMult(Word Index)
  512. {
  513.   int z;
  514.   Boolean OK;
  515.  
  516.   if (ChkArgCnt(1, ArgCntMax))
  517.   {
  518.     OK = True;
  519.     BAsmCode[1] = 0;
  520.     for (z = 1; z <= ArgCnt; z++)
  521.       if (OK)
  522.       {
  523.         const size_t RegCnt = as_array_size(Regs);
  524.         size_t z2 = 0;
  525.         NLS_UpString(ArgStr[z].str.p_str);
  526.         while ((z2 < RegCnt) && strcmp(ArgStr[z].str.p_str, Regs[z2]))
  527.           z2++;
  528.         if (z2 >= RegCnt)
  529.         {
  530.           WrStrErrorPos(ErrNum_InvReg, &ArgStr[z]);
  531.           OK = False;
  532.         }
  533.         else
  534.           BAsmCode[1] |= Index ? (1 << z2) : (1 << (RegCnt - 1 - z2));
  535.       }
  536.     if (OK)
  537.     {
  538.       BAsmCode[0] = 0x34 | (Index ^ 1);
  539.       CodeLen = 2;
  540.     }
  541.   }
  542. }
  543.  
  544. static void DecodeMov(Word Index)
  545. {
  546.   Boolean OK;
  547.  
  548.   if (ArgCnt == 2)
  549.   {
  550.     DecodeAdr(1, 1, eSymbolSizeUnknown, False, MModAbs);
  551.     if (AdrMode == ModAbs)
  552.     {
  553.       memcpy(BAsmCode + 2, AdrVals, 2);
  554.       DecodeAdr(2, 2, eSymbolSizeUnknown, False, MModAbs);
  555.       if (AdrMode == ModAbs)
  556.       {
  557.         memcpy(BAsmCode + 4, AdrVals, 2);
  558.         BAsmCode[0] = 0x37;
  559.         BAsmCode[1] = 0xfe | Index;
  560.         CodeLen = 6;
  561.       }
  562.     }
  563.   }
  564.   else if (!ChkArgCnt(3, 3));
  565.   else if (!as_strcasecmp(ArgStr[2].str.p_str, "X"))
  566.   {
  567.     BAsmCode[1] = EvalStrIntExpression(&ArgStr[1], SInt8, &OK);
  568.     if (OK)
  569.     {
  570.       DecodeAdr(3, 3, eSymbolSizeUnknown, False, MModAbs);
  571.       if (AdrMode == ModAbs)
  572.       {
  573.         memcpy(BAsmCode + 2, AdrVals, 2);
  574.         BAsmCode[0] = 0x30 | Index;
  575.         CodeLen = 4;
  576.       }
  577.     }
  578.   }
  579.   else if (!as_strcasecmp(ArgStr[3].str.p_str, "X"))
  580.   {
  581.     BAsmCode[3] = EvalStrIntExpression(&ArgStr[2], SInt8, &OK);
  582.     if (OK)
  583.     {
  584.       DecodeAdr(1, 1, eSymbolSizeUnknown, False, MModAbs);
  585.       if (AdrMode == ModAbs)
  586.       {
  587.         memcpy(BAsmCode + 1, AdrVals, 2);
  588.         BAsmCode[0] = 0x32 | Index;
  589.         CodeLen = 4;
  590.       }
  591.     }
  592.   }
  593.   else WrError(ErrNum_InvAddrMode);
  594. }
  595.  
  596. static void DecodeLogp(Word Index)
  597. {
  598.   if (ChkArgCnt(1, 1))
  599.   {
  600.     DecodeAdr(1, 1, eSymbolSize16Bit, False, MModImm);
  601.     switch (AdrMode)
  602.     {
  603.       case ModImm:
  604.         BAsmCode[0] = 0x37;
  605.         BAsmCode[1] = 0x3a | Index;
  606.         memcpy(BAsmCode + 2, AdrVals, AdrCnt);
  607.         CodeLen = 2 + AdrCnt;
  608.         break;
  609.     }
  610.   }
  611. }
  612.  
  613. static void DecodeMac(Word Index)
  614. {
  615.   Byte Val;
  616.   Boolean OK;
  617.  
  618.   if (ChkArgCnt(2, 2))
  619.   {
  620.     Val = EvalStrIntExpression(&ArgStr[1], UInt4, &OK);
  621.     if (OK)
  622.     {
  623.       BAsmCode[1] = EvalStrIntExpression(&ArgStr[2], UInt4, &OK);
  624.       if (OK)
  625.       {
  626.         BAsmCode[1] |= (Val << 4);
  627.         BAsmCode[0] = 0x7b | Index;
  628.         CodeLen = 2;
  629.       }
  630.     }
  631.   }
  632. }
  633.  
  634. static void DecodeBit8(Word Index)
  635. {
  636.   Byte Mask;
  637.  
  638.   if (ChkArgCnt(2, 3))
  639.   {
  640.     DecodeAdr(ArgCnt, ArgCnt, eSymbolSize8Bit, False, MModImm);
  641.     switch (AdrMode)
  642.     {
  643.       case ModImm:
  644.         Mask = AdrVals[0];
  645.         DecodeAdr(1, ArgCnt - 1, eSymbolSizeUnknown, False, MModDisp8 | MModDisp16 | MModAbs);
  646.         switch (AdrMode)
  647.         {
  648.           case ModDisp8:
  649.             BAsmCode[0] = 0x17;
  650.             BAsmCode[1] = 0x08 | Index | AdrPart;
  651.             BAsmCode[2] = Mask;
  652.             BAsmCode[3] = AdrVals[0];
  653.             CodeLen = 4;
  654.             break;
  655.           case ModDisp16:
  656.             BAsmCode[0] = 0x08 | Index | AdrPart;
  657.             BAsmCode[1] = Mask;
  658.             memcpy(BAsmCode + 2, AdrVals, AdrCnt);
  659.             CodeLen = 2 + AdrCnt;
  660.             break;
  661.           case ModAbs:
  662.             BAsmCode[0] = 0x38 + Index;
  663.             BAsmCode[1] = Mask;
  664.             memcpy(BAsmCode + 2, AdrVals, AdrCnt);
  665.             CodeLen = 2 + AdrCnt;
  666.             break;
  667.         }
  668.         break;
  669.     }
  670.   }
  671. }
  672.  
  673. static void DecodeBit16(Word Index)
  674. {
  675.   if (ChkArgCnt(2, 3))
  676.   {
  677.     DecodeAdr(ArgCnt, ArgCnt, eSymbolSize16Bit, False, MModImm);
  678.     switch (AdrMode)
  679.     {
  680.       case ModImm:
  681.         memcpy(BAsmCode + 2, AdrVals, AdrCnt);
  682.         DecodeAdr(1, ArgCnt - 1, eSymbolSizeUnknown, False, MModDisp16 | MModAbs);
  683.         switch (AdrMode)
  684.         {
  685.           case ModDisp16:
  686.             BAsmCode[0] = 0x27;
  687.             BAsmCode[1] = 0x08 | Index | AdrPart;
  688.             memcpy(BAsmCode + 4, AdrVals, AdrCnt);
  689.             CodeLen = 4 + AdrCnt;
  690.             break;
  691.           case ModAbs:
  692.             BAsmCode[0] = 0x27;
  693.             BAsmCode[1] = 0x38 | Index;
  694.             memcpy(BAsmCode + 4, AdrVals, AdrCnt);
  695.             CodeLen = 4 + AdrCnt;
  696.             break;
  697.         }
  698.     }
  699.   }
  700. }
  701.  
  702. static void DecodeBrBit(Word Index)
  703. {
  704.   Boolean OK;
  705.   tSymbolFlags Flags;
  706.   LongInt AdrLong;
  707.  
  708.   if (ChkArgCnt(3, 4))
  709.   {
  710.     DecodeAdr(ArgCnt - 1, ArgCnt - 1, eSymbolSize8Bit, False, MModImm);
  711.     if (AdrMode == ModImm)
  712.     {
  713.       BAsmCode[1] = AdrVals[0];
  714.       AdrLong = EvalStrIntExpressionWithFlags(&ArgStr[ArgCnt], UInt20, &OK, &Flags) - EProgCounter() - 6;
  715.       if (OK)
  716.       {
  717.         DecodeAdr(1, ArgCnt - 2, eSymbolSizeUnknown, False, MModDisp8 | MModDisp16 | MModAbs);
  718.         switch (AdrMode)
  719.         {
  720.           case ModDisp8:
  721.             if ((AdrLong >= -128) && (AdrLong < 127))
  722.             {
  723.               BAsmCode[0] = 0xcb - (Index << 6) + AdrPart;
  724.               BAsmCode[2] = AdrVals[0];
  725.               BAsmCode[3] = AdrLong & 0xff;
  726.               CodeLen = 4;
  727.             }
  728.             else if (!mSymbolQuestionable(Flags) && ((AdrLong <- 0x8000l) || (AdrLong > 0x7fffl))) WrError(ErrNum_JmpDistTooBig);
  729.             else
  730.             {
  731.               BAsmCode[0] = 0x0a + AdrPart + Index;
  732.               BAsmCode[2] = 0;
  733.               BAsmCode[3] = AdrVals[0];
  734.               BAsmCode[4] = (AdrLong >> 8) & 0xff;
  735.               BAsmCode[5] = AdrLong & 0xff;
  736.               CodeLen = 6;
  737.             }
  738.             break;
  739.           case ModDisp16:
  740.             if (!mSymbolQuestionable(Flags) && ((AdrLong < -0x8000l) || (AdrLong > 0x7fffl))) WrError(ErrNum_JmpDistTooBig);
  741.             else
  742.             {
  743.               BAsmCode[0] = 0x0a + AdrPart + Index;
  744.               memcpy(BAsmCode + 2,AdrVals, 2);
  745.               BAsmCode[4] = (AdrLong >> 8) & 0xff;
  746.               BAsmCode[5] = AdrLong & 0xff;
  747.               CodeLen = 6;
  748.             }
  749.             break;
  750.           case ModAbs:
  751.             if (!mSymbolQuestionable(Flags) && ((AdrLong < -0x8000l) || (AdrLong > 0x7fffl))) WrError(ErrNum_JmpDistTooBig);
  752.             else
  753.             {
  754.               BAsmCode[0] = 0x3a | Index;
  755.               memcpy(BAsmCode + 2, AdrVals, 2);
  756.               BAsmCode[4] = (AdrLong >> 8) & 0xff;
  757.               BAsmCode[5] = AdrLong & 0xff;
  758.               CodeLen = 6;
  759.             }
  760.             break;
  761.         }
  762.       }
  763.     }
  764.   }
  765. }
  766.  
  767. static void DecodeJmpJsr(Word Index)
  768. {
  769.   if (ChkArgCnt(1, 2))
  770.   {
  771.     DecodeAdr(1, ArgCnt, eSymbolSize16Bit, True, MModAbs20 | MModDisp20);
  772.     switch (AdrMode)
  773.     {
  774.       case ModAbs20:
  775.         BAsmCode[0] = 0x7a + (Index << 7);
  776.         memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  777.         CodeLen = 1 + AdrCnt;
  778.         break;
  779.       case ModDisp20:
  780.         BAsmCode[0] = Index ? 0x89 : 0x4b;
  781.         BAsmCode[0] += AdrPart;
  782.         memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  783.         CodeLen = 1 + AdrCnt;
  784.         break;
  785.     }
  786.   }
  787. }
  788.  
  789. static void DecodeBsr(Word Index)
  790. {
  791.   Boolean OK;
  792.   tSymbolFlags Flags;
  793.   LongInt AdrLong;
  794.  
  795.   UNUSED(Index);
  796.  
  797.   if (ChkArgCnt(1, 1))
  798.   {
  799.     AdrLong = EvalStrIntExpressionWithFlags(&ArgStr[1], UInt24, &OK, &Flags) - EProgCounter() - 6;
  800.     if (AdrLong & 1) WrError(ErrNum_NotAligned);
  801.     else if (!mSymbolQuestionable(Flags) & ((AdrLong > 0x7fl) || (AdrLong < -0x80l))) WrError(ErrNum_JmpDistTooBig);
  802.     else
  803.     {
  804.       BAsmCode[0] = 0x36;
  805.       BAsmCode[1] = AdrLong & 0xff;
  806.       CodeLen = 2;
  807.     }
  808.   }
  809. }
  810.  
  811. /*-------------------------------------------------------------------------*/
  812.  
  813. static void AddFixed(const char *NName, Word NCode)
  814. {
  815.   AddInstTable(InstTable, NName, NCode, DecodeFixed);
  816. }
  817.  
  818. static void AddRel(const char *NName, Word NCode)
  819. {
  820.   AddInstTable(InstTable, NName, NCode, DecodeRel);
  821. }
  822.  
  823. static void AddLRel(const char *NName, Word NCode)
  824. {
  825.   AddInstTable(InstTable, NName, NCode, DecodeLRel);
  826. }
  827.  
  828. static void AddGen(const char *NName, tSymbolSize NSize, Word NCode, Word NExtCode, Byte NShift, Byte NMask)
  829. {
  830.   order_array_rsv_end(GenOrders, GenOrder);
  831.   GenOrders[InstrZ].Code = NCode;
  832.   GenOrders[InstrZ].ExtCode = NExtCode;
  833.   GenOrders[InstrZ].Size = NSize;
  834.   GenOrders[InstrZ].AdrMask = NMask;
  835.   GenOrders[InstrZ].ExtShift = NShift;
  836.   AddInstTable(InstTable, NName, InstrZ++, DecodeGen);
  837. }
  838.  
  839. static void AddAux(const char *NName, Word NCode)
  840. {
  841.   AddInstTable(InstTable, NName, NCode, DecodeAux);
  842. }
  843.  
  844. static void AddImm(const char *NName, Word NCode)
  845. {
  846.   AddInstTable(InstTable, NName, NCode, DecodeImm);
  847. }
  848.  
  849. static void AddExt(const char *NName, Word NCode)
  850. {
  851.   AddInstTable(InstTable, NName, NCode, DecodeExt);
  852. }
  853.  
  854. static void AddEmu(const char *NName, Word NCode1, Word NCode2)
  855. {
  856.   order_array_rsv_end(EmuOrders, EmuOrder);
  857.   EmuOrders[InstrZ].Code1 = NCode1;
  858.   EmuOrders[InstrZ].Code2 = NCode2;
  859.   AddInstTable(InstTable, NName, InstrZ++, DecodeEmu);
  860. }
  861.  
  862. static void InitFields(void)
  863. {
  864.   InstTable = CreateInstTable(405);
  865.  
  866.   add_null_pseudo(InstTable);
  867.  
  868.   AddFixed("ABA"   , 0x370b); AddFixed("ABX"   , 0x374f);
  869.   AddFixed("ABY"   , 0x375f); AddFixed("ABZ"   , 0x376f);
  870.   AddFixed("ACE"   , 0x3722); AddFixed("ACED"  , 0x3723);
  871.   AddFixed("ADE"   , 0x2778); AddFixed("ADX"   , 0x37cd);
  872.   AddFixed("ADY"   , 0x37dd); AddFixed("ADZ"   , 0x37ed);
  873.   AddFixed("AEX"   , 0x374d); AddFixed("AEY"   , 0x375d);
  874.   AddFixed("AEZ"   , 0x376d); AddFixed("ASLA"  , 0x3704);
  875.   AddFixed("ASLB"  , 0x3714); AddFixed("ASLD"  , 0x27f4);
  876.   AddFixed("ASLE"  , 0x2774); AddFixed("ASLM"  , 0x27b6);
  877.   AddFixed("LSLB"  , 0x3714); AddFixed("LSLD"  , 0x27f4);
  878.   AddFixed("LSLE"  , 0x2774); AddFixed("LSLA"  , 0x3704);
  879.   AddFixed("ASRA"  , 0x370d); AddFixed("ASRB"  , 0x371d);
  880.   AddFixed("ASRD"  , 0x27fd); AddFixed("ASRE"  , 0x277d);
  881.   AddFixed("ASRM"  , 0x27ba); AddFixed("BGND"  , 0x37a6);
  882.   AddFixed("CBA"   , 0x371b); AddFixed("CLRA"  , 0x3705);
  883.   AddFixed("CLRB"  , 0x3715); AddFixed("CLRD"  , 0x27f5);
  884.   AddFixed("CLRE"  , 0x2775); AddFixed("CLRM"  , 0x27b7);
  885.   AddFixed("COMA"  , 0x3700); AddFixed("COMB"  , 0x3710);
  886.   AddFixed("COMD"  , 0x27f0); AddFixed("COME"  , 0x2770);
  887.   AddFixed("DAA"   , 0x3721); AddFixed("DECA"  , 0x3701);
  888.   AddFixed("DECB"  , 0x3711); AddFixed("EDIV"  , 0x3728);
  889.   AddFixed("EDIVS" , 0x3729); AddFixed("EMUL"  , 0x3725);
  890.   AddFixed("EMULS" , 0x3726); AddFixed("FDIV"  , 0x372b);
  891.   AddFixed("FMULS" , 0x3727); AddFixed("IDIV"  , 0x372a);
  892.   AddFixed("INCA"  , 0x3703); AddFixed("INCB"  , 0x3713);
  893.   AddFixed("LPSTOP", 0x27f1); AddFixed("LSRA"  , 0x370f);
  894.   AddFixed("LSRB"  , 0x371f); AddFixed("LSRD"  , 0x27ff);
  895.   AddFixed("LSRE"  , 0x277f); AddFixed("MUL"   , 0x3724);
  896.   AddFixed("NEGA"  , 0x3702); AddFixed("NEGB"  , 0x3712);
  897.   AddFixed("NEGD"  , 0x27f2); AddFixed("NEGE"  , 0x2772);
  898.   AddFixed("NOP"   , 0x274c); AddFixed("PSHA"  , 0x3708);
  899.   AddFixed("PSHB"  , 0x3718); AddFixed("PSHMAC", 0x27b8);
  900.   AddFixed("PULA"  , 0x3709); AddFixed("PULB"  , 0x3719);
  901.   AddFixed("PULMAC", 0x27b9); AddFixed("ROLA"  , 0x370c);
  902.   AddFixed("ROLB"  , 0x371c); AddFixed("ROLD"  , 0x27fc);
  903.   AddFixed("ROLE"  , 0x277c); AddFixed("RORA"  , 0x370e);
  904.   AddFixed("RORB"  , 0x371e); AddFixed("RORD"  , 0x27fe);
  905.   AddFixed("RORE"  , 0x277e); AddFixed("RTI"   , 0x2777);
  906.   AddFixed("RTS"   , 0x27f7); AddFixed("SBA"   , 0x370a);
  907.   AddFixed("SDE"   , 0x2779); AddFixed("SWI"   , 0x3720);
  908.   AddFixed("SXT"   , 0x27f8); AddFixed("TAB"   , 0x3717);
  909.   AddFixed("TAP"   , 0x37fd); AddFixed("TBA"   , 0x3707);
  910.   AddFixed("TBEK"  , 0x27fa); AddFixed("TBSK"  , 0x379f);
  911.   AddFixed("TBXK"  , 0x379c); AddFixed("TBYK"  , 0x379d);
  912.   AddFixed("TBZK"  , 0x379e); AddFixed("TDE"   , 0x277b);
  913.   AddFixed("TDMSK" , 0x372f); AddFixed("TDP"   , 0x372d);
  914.   AddFixed("TED"   , 0x27fb); AddFixed("TEDM"  , 0x27b1);
  915.   AddFixed("TEKB"  , 0x27bb); AddFixed("TEM"   , 0x27b2);
  916.   AddFixed("TMER"  , 0x27b4); AddFixed("TMET"  , 0x27b5);
  917.   AddFixed("TMXED" , 0x27b3); AddFixed("TPA"   , 0x37fc);
  918.   AddFixed("TPD"   , 0x372c); AddFixed("TSKB"  , 0x37af);
  919.   AddFixed("TSTA"  , 0x3706); AddFixed("TSTB"  , 0x3716);
  920.   AddFixed("TSTD"  , 0x27f6); AddFixed("TSTE"  , 0x2776);
  921.   AddFixed("TSX"   , 0x274f); AddFixed("TSY"   , 0x275f);
  922.   AddFixed("TSZ"   , 0x276f); AddFixed("TXKB"  , 0x37ac);
  923.   AddFixed("TXS"   , 0x374e); AddFixed("TXY"   , 0x275c);
  924.   AddFixed("TXZ"   , 0x276c); AddFixed("TYKB"  , 0x37ad);
  925.   AddFixed("TYS"   , 0x375e); AddFixed("TYX"   , 0x274d);
  926.   AddFixed("TYZ"   , 0x276d); AddFixed("TZKB"  , 0x37ae);
  927.   AddFixed("TZS"   , 0x376e); AddFixed("TZX"   , 0x274e);
  928.   AddFixed("TZY"   , 0x275e); AddFixed("WAI"   , 0x27f3);
  929.   AddFixed("XGAB"  , 0x371a); AddFixed("XGDE"  , 0x277a);
  930.   AddFixed("XGDX"  , 0x37cc); AddFixed("XGDY"  , 0x37dc);
  931.   AddFixed("XGDZ"  , 0x37ec); AddFixed("XGEX"  , 0x374c);
  932.   AddFixed("XGEY"  , 0x375c); AddFixed("XGEZ"  , 0x376c);
  933.   AddFixed("DES"   , 0x3fff); AddFixed("INS"   , 0x3f01);
  934.   AddFixed("DEX"   , 0x3cff); AddFixed("INX"   , 0x3c01);
  935.   AddFixed("DEY"   , 0x3dff); AddFixed("INY"   , 0x3d01);
  936.   AddFixed("PSHX"  , 0x3404); AddFixed("PULX"  , 0x3510);
  937.   AddFixed("PSHY"  , 0x3408); AddFixed("PULY"  , 0x3508);
  938.  
  939.   AddRel("BCC" ,           4); AddRel("BCS",            5); AddRel("BEQ",            7);
  940.   AddRel("BGE" ,          12); AddRel("BGT",           14); AddRel("BHI",            2);
  941.   AddRel("BLE" ,          15); AddRel("BLS",            3); AddRel("BLT",           13);
  942.   AddRel("BMI" ,          11); AddRel("BNE",            6); AddRel("BPL",           10);
  943.   AddRel("BRA" ,           0); AddRel("BRN",            1); AddRel("BVC",            8);
  944.   AddRel("BVS" ,           9); AddRel("BHS",            4); AddRel("BLO",            5);
  945.   AddRel("LBCC", 0x8000 |  4); AddRel("LBCS", 0x8000 |  5); AddRel("LBEQ", 0x8000 |  7);
  946.   AddRel("LBGE", 0x8000 | 12); AddRel("LBGT", 0x8000 | 14); AddRel("LBHI", 0x8000 |  2);
  947.   AddRel("LBLE", 0x8000 | 15); AddRel("LBLS", 0x8000 |  3); AddRel("LBLT", 0x8000 | 13);
  948.   AddRel("LBMI", 0x8000 | 11); AddRel("LBNE", 0x8000 |  6); AddRel("LBPL", 0x8000 | 10);
  949.   AddRel("LBRA", 0x8000 |  0); AddRel("LBRN", 0x8000 |  1); AddRel("LBVC", 0x8000 |  8);
  950.   AddRel("LBVS", 0x8000 |  9); AddRel("LBHS", 0x8000 |  4); AddRel("LBLO", 0x8000 |  5);
  951.  
  952.   AddLRel("LBEV", 0x3791); AddLRel("LBMV", 0x3790); AddLRel("LBSR", 0x27f9);
  953.  
  954.   InstrZ = 0;
  955.   AddGen("ADCA", eSymbolSize8Bit , 0x43, 0xffff, 0x00, MModDisp8 | MModImm |              MModDisp16 | MModAbs | MModDispE);
  956.   AddGen("ADCB", eSymbolSize8Bit , 0xc3, 0xffff, 0x00, MModDisp8 | MModImm |              MModDisp16 | MModAbs | MModDispE);
  957.   AddGen("ADCD", eSymbolSize16Bit, 0x83, 0xffff, 0x20, MModDisp8 | MModImm |              MModDisp16 | MModAbs | MModDispE);
  958.   AddGen("ADCE", eSymbolSize16Bit, 0x03, 0xffff, 0x20,             MModImm |              MModDisp16 | MModAbs            );
  959.   AddGen("ADDA", eSymbolSize8Bit , 0x41, 0xffff, 0x00, MModDisp8 | MModImm |              MModDisp16 | MModAbs | MModDispE);
  960.   AddGen("ADDB", eSymbolSize8Bit , 0xc1, 0xffff, 0x00, MModDisp8 | MModImm |              MModDisp16 | MModAbs | MModDispE);
  961.   AddGen("ADDD", eSymbolSize16Bit, 0x81,   0xfc, 0x20, MModDisp8 | MModImm | MModImmExt | MModDisp16 | MModAbs | MModDispE);
  962.   AddGen("ADDE", eSymbolSize16Bit, 0x01,   0x7c, 0x20,             MModImm | MModImmExt | MModDisp16 | MModAbs            );
  963.   AddGen("ANDA", eSymbolSize8Bit , 0x46, 0xffff, 0x00, MModDisp8 | MModImm |              MModDisp16 | MModAbs | MModDispE);
  964.   AddGen("ANDB", eSymbolSize8Bit , 0xc6, 0xffff, 0x00, MModDisp8 | MModImm |              MModDisp16 | MModAbs | MModDispE);
  965.   AddGen("ANDD", eSymbolSize16Bit, 0x86, 0xffff, 0x20, MModDisp8 | MModImm |              MModDisp16 | MModAbs | MModDispE);
  966.   AddGen("ANDE", eSymbolSize16Bit, 0x06, 0xffff, 0x20,             MModImm |              MModDisp16 | MModAbs            );
  967.   AddGen("ASL" , eSymbolSize8Bit , 0x04, 0xffff, 0x00, MModDisp8 |                        MModDisp16 | MModAbs            );
  968.   AddGen("ASLW", eSymbolSize8Bit , 0x04, 0xffff, 0x10,                                    MModDisp16 | MModAbs            );
  969.   AddGen("LSL" , eSymbolSize8Bit , 0x04, 0xffff, 0x00, MModDisp8 |                        MModDisp16 | MModAbs            );
  970.   AddGen("LSLW", eSymbolSize8Bit , 0x04, 0xffff, 0x10,                                    MModDisp16 | MModAbs            );
  971.   AddGen("ASR" , eSymbolSize8Bit , 0x0d, 0xffff, 0x00, MModDisp8 |                        MModDisp16 | MModAbs            );
  972.   AddGen("ASRW", eSymbolSize8Bit , 0x0d, 0xffff, 0x10,                                    MModDisp16 | MModAbs            );
  973.   AddGen("BITA", eSymbolSize8Bit , 0x49, 0xffff, 0x00, MModDisp8 | MModImm |              MModDisp16 | MModAbs | MModDispE);
  974.   AddGen("BITB", eSymbolSize8Bit , 0xc9, 0xffff, 0x00, MModDisp8 | MModImm |              MModDisp16 | MModAbs | MModDispE);
  975.   AddGen("CLR" , eSymbolSize8Bit , 0x05, 0xffff, 0x00, MModDisp8 |                        MModDisp16 | MModAbs            );
  976.   AddGen("CLRW", eSymbolSize8Bit , 0x05, 0xffff, 0x10,                                    MModDisp16 | MModAbs            );
  977.   AddGen("CMPA", eSymbolSize8Bit , 0x48, 0xffff, 0x00, MModDisp8 | MModImm |              MModDisp16 | MModAbs | MModDispE);
  978.   AddGen("CMPB", eSymbolSize8Bit , 0xc8, 0xffff, 0x00, MModDisp8 | MModImm |              MModDisp16 | MModAbs | MModDispE);
  979.   AddGen("COM" , eSymbolSize8Bit , 0x00, 0xffff, 0x00, MModDisp8 |                        MModDisp16 | MModAbs            );
  980.   AddGen("COMW", eSymbolSize8Bit , 0x00, 0xffff, 0x10,                                    MModDisp16 | MModAbs            );
  981.   AddGen("CPD" , eSymbolSize16Bit, 0x88, 0xffff, 0x20, MModDisp8 | MModImm |              MModDisp16 | MModAbs | MModDispE);
  982.   AddGen("CPE" , eSymbolSize16Bit, 0x08, 0xffff, 0x20,             MModImm |              MModDisp16 | MModAbs            );
  983.   AddGen("DEC" , eSymbolSize8Bit , 0x01, 0xffff, 0x00, MModDisp8 |                        MModDisp16 | MModAbs            );
  984.   AddGen("DECW", eSymbolSize8Bit , 0x01, 0xffff, 0x10,                                    MModDisp16 | MModAbs            );
  985.   AddGen("EORA", eSymbolSize8Bit , 0x44, 0xffff, 0x00, MModDisp8 | MModImm |              MModDisp16 | MModAbs | MModDispE);
  986.   AddGen("EORB", eSymbolSize8Bit , 0xc4, 0xffff, 0x00, MModDisp8 | MModImm |              MModDisp16 | MModAbs | MModDispE);
  987.   AddGen("EORD", eSymbolSize16Bit, 0x84, 0xffff, 0x20, MModDisp8 | MModImm |              MModDisp16 | MModAbs | MModDispE);
  988.   AddGen("EORE", eSymbolSize16Bit, 0x04, 0xffff, 0x20,             MModImm |              MModDisp16 | MModAbs            );
  989.   AddGen("INC" , eSymbolSize8Bit , 0x03, 0xffff, 0x00, MModDisp8 |                        MModDisp16 | MModAbs            );
  990.   AddGen("INCW", eSymbolSize8Bit , 0x03, 0xffff, 0x10,                                    MModDisp16 | MModAbs            );
  991.   AddGen("LDAA", eSymbolSize8Bit , 0x45, 0xffff, 0x00, MModDisp8 | MModImm |              MModDisp16 | MModAbs | MModDispE);
  992.   AddGen("LDAB", eSymbolSize8Bit , 0xc5, 0xffff, 0x00, MModDisp8 | MModImm |              MModDisp16 | MModAbs | MModDispE);
  993.   AddGen("LDD" , eSymbolSize16Bit, 0x85, 0xffff, 0x20, MModDisp8 | MModImm |              MModDisp16 | MModAbs | MModDispE);
  994.   AddGen("LDE" , eSymbolSize16Bit, 0x05, 0xffff, 0x20,             MModImm |              MModDisp16 | MModAbs            );
  995.   AddGen("LSR" , eSymbolSize8Bit , 0x0f, 0xffff, 0x00, MModDisp8 |                        MModDisp16 | MModAbs            );
  996.   AddGen("LSRW", eSymbolSize8Bit , 0x0f, 0xffff, 0x10,                                    MModDisp16 | MModAbs            );
  997.   AddGen("NEG" , eSymbolSize8Bit , 0x02, 0xffff, 0x00, MModDisp8 |                        MModDisp16 | MModAbs            );
  998.   AddGen("NEGW", eSymbolSize8Bit , 0x02, 0xffff, 0x10,                                    MModDisp16 | MModAbs            );
  999.   AddGen("ORAA", eSymbolSize8Bit , 0x47, 0xffff, 0x00, MModDisp8 | MModImm |              MModDisp16 | MModAbs | MModDispE);
  1000.   AddGen("ORAB", eSymbolSize8Bit , 0xc7, 0xffff, 0x00, MModDisp8 | MModImm |              MModDisp16 | MModAbs | MModDispE);
  1001.   AddGen("ORD" , eSymbolSize16Bit, 0x87, 0xffff, 0x20, MModDisp8 | MModImm |              MModDisp16 | MModAbs | MModDispE);
  1002.   AddGen("ORE" , eSymbolSize16Bit, 0x07, 0xffff, 0x20,             MModImm |              MModDisp16 | MModAbs            );
  1003.   AddGen("ROL" , eSymbolSize8Bit , 0x0c, 0xffff, 0x00, MModDisp8 |                        MModDisp16 | MModAbs            );
  1004.   AddGen("ROLW", eSymbolSize8Bit , 0x0c, 0xffff, 0x10,                                    MModDisp16 | MModAbs            );
  1005.   AddGen("ROR" , eSymbolSize8Bit , 0x0e, 0xffff, 0x00, MModDisp8 |                        MModDisp16 | MModAbs            );
  1006.   AddGen("RORW", eSymbolSize8Bit , 0x0e, 0xffff, 0x10,                                    MModDisp16 | MModAbs            );
  1007.   AddGen("SBCA", eSymbolSize8Bit , 0x42, 0xffff, 0x00, MModDisp8 | MModImm |              MModDisp16 | MModAbs | MModDispE);
  1008.   AddGen("SBCB", eSymbolSize8Bit , 0xc2, 0xffff, 0x00, MModDisp8 | MModImm |              MModDisp16 | MModAbs | MModDispE);
  1009.   AddGen("SBCD", eSymbolSize16Bit, 0x82, 0xffff, 0x20, MModDisp8 | MModImm |              MModDisp16 | MModAbs | MModDispE);
  1010.   AddGen("SBCE", eSymbolSize16Bit, 0x02, 0xffff, 0x20,             MModImm |              MModDisp16 | MModAbs            );
  1011.   AddGen("STAA", eSymbolSize8Bit , 0x4a, 0xffff, 0x00, MModDisp8 |                        MModDisp16 | MModAbs | MModDispE);
  1012.   AddGen("STAB", eSymbolSize8Bit , 0xca, 0xffff, 0x00, MModDisp8 |                        MModDisp16 | MModAbs | MModDispE);
  1013.   AddGen("STD" , eSymbolSize16Bit, 0x8a, 0xffff, 0x20, MModDisp8 |                        MModDisp16 | MModAbs | MModDispE);
  1014.   AddGen("STE" , eSymbolSize16Bit, 0x0a, 0xffff, 0x20,                                    MModDisp16 | MModAbs            );
  1015.   AddGen("SUBA", eSymbolSize8Bit , 0x40, 0xffff, 0x00, MModDisp8 | MModImm |              MModDisp16 | MModAbs | MModDispE);
  1016.   AddGen("SUBB", eSymbolSize8Bit , 0xc0, 0xffff, 0x00, MModDisp8 | MModImm |              MModDisp16 | MModAbs | MModDispE);
  1017.   AddGen("SUBD", eSymbolSize16Bit, 0x80, 0xffff, 0x20, MModDisp8 | MModImm |              MModDisp16 | MModAbs | MModDispE);
  1018.   AddGen("SUBE", eSymbolSize16Bit, 0x00, 0xffff, 0x20,             MModImm |              MModDisp16 | MModAbs            );
  1019.   AddGen("TST" , eSymbolSize8Bit , 0x06, 0xffff, 0x00, MModDisp8 |                        MModDisp16 | MModAbs            );
  1020.   AddGen("TSTW", eSymbolSize8Bit , 0x06, 0xffff, 0x10,                                    MModDisp16 | MModAbs            );
  1021.  
  1022.   AddAux("CPS", 0x4f); AddAux("CPX", 0x4c); AddAux("CPY", 0x4d); AddAux("CPZ", 0x4e);
  1023.   AddAux("LDS", 0xcf); AddAux("LDX", 0xcc); AddAux("LDY", 0xcd); AddAux("LDZ", 0xce);
  1024.   AddAux("STS", 0x8f); AddAux("STX", 0x8c); AddAux("STY", 0x8d); AddAux("STZ", 0x8e);
  1025.  
  1026.   AddImm("AIS", 0x3f); AddImm("AIX", 0x3c); AddImm("AIY", 0x3d); AddImm("AIZ", 0x3e);
  1027.  
  1028.   AddExt("LDED", 0x2771); AddExt("LDHI", 0x27b0); AddExt("STED", 0x2773);
  1029.  
  1030.   InstrZ = 0;
  1031.   AddEmu("CLC", 0x373a, 0xfeff); AddEmu("CLI", 0x373a, 0xff1f); AddEmu("CLV", 0x373a, 0xfdff);
  1032.   AddEmu("SEC", 0x373b, 0x0100); AddEmu("SEI", 0x373b, 0x00e0); AddEmu("SEV", 0x373b, 0x0200);
  1033.  
  1034.   AddInstTable(InstTable, "PSHM", 1, DecodeStkMult);
  1035.   AddInstTable(InstTable, "PULM", 0, DecodeStkMult);
  1036.  
  1037.   AddInstTable(InstTable, "MOVB", 0, DecodeMov);
  1038.   AddInstTable(InstTable, "MOVW", 1, DecodeMov);
  1039.  
  1040.   AddInstTable(InstTable, "ANDP", 0, DecodeLogp);
  1041.   AddInstTable(InstTable, "ORP" , 1, DecodeLogp);
  1042.  
  1043.   AddInstTable(InstTable, "MAC" , 0 << 7, DecodeMac);
  1044.   AddInstTable(InstTable, "RMAC", 1 << 7, DecodeMac);
  1045.  
  1046.   AddInstTable(InstTable, "BCLR", 0, DecodeBit8);
  1047.   AddInstTable(InstTable, "BSET", 1, DecodeBit8);
  1048.  
  1049.   AddInstTable(InstTable, "BCLRW", 0, DecodeBit16);
  1050.   AddInstTable(InstTable, "BSETW", 1, DecodeBit16);
  1051.  
  1052.   AddInstTable(InstTable, "BRCLR", 0, DecodeBrBit);
  1053.   AddInstTable(InstTable, "BRSET", 1, DecodeBrBit);
  1054.  
  1055.   AddInstTable(InstTable, "JMP", 0, DecodeJmpJsr);
  1056.   AddInstTable(InstTable, "JSR", 1, DecodeJmpJsr);
  1057.   AddInstTable(InstTable, "BSR", 0, DecodeBsr);
  1058.  
  1059.   add_moto8_pseudo(InstTable, e_moto_pseudo_flags_be);
  1060.   AddMoto16Pseudo(InstTable, e_moto_pseudo_flags_be);
  1061.   AddInstTable(InstTable, "DB", eIntPseudoFlag_BigEndian | eIntPseudoFlag_AllowInt | eIntPseudoFlag_AllowString | eIntPseudoFlag_MotoRep, DecodeIntelDB);
  1062.   AddInstTable(InstTable, "DW", eIntPseudoFlag_BigEndian | eIntPseudoFlag_AllowInt | eIntPseudoFlag_AllowString | eIntPseudoFlag_MotoRep, DecodeIntelDW);
  1063. }
  1064.  
  1065. static void DeinitFields(void)
  1066. {
  1067.   order_array_free(GenOrders);
  1068.   order_array_free(EmuOrders);
  1069.   DestroyInstTable(InstTable); InstTable = NULL;
  1070. }
  1071.  
  1072. /*-------------------------------------------------------------------------*/
  1073.  
  1074. static Boolean DecodeAttrPart_6816(void)
  1075. {
  1076.   if (strlen(AttrPart.str.p_str) > 1)
  1077.   {
  1078.     WrStrErrorPos(ErrNum_UndefAttr, &AttrPart);
  1079.     return False;
  1080.   }
  1081.   return DecodeMoto16AttrSize(*AttrPart.str.p_str, &AttrPartOpSize[0], False);
  1082. }
  1083.  
  1084. static void MakeCode_6816(void)
  1085. {
  1086.   AdrCnt = 0;
  1087.  
  1088.   /* Operandengroesse festlegen. ACHTUNG! Das gilt nur fuer die folgenden
  1089.      Pseudobefehle! Die Maschinenbefehle ueberschreiben diesen Wert! */
  1090.  
  1091.   if (AttrPartOpSize[0] == eSymbolSizeUnknown)
  1092.     AttrPartOpSize[0] = eSymbolSize8Bit;
  1093.  
  1094.   if (!LookupInstTable(InstTable, OpPart.str.p_str))
  1095.     WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
  1096. }
  1097.  
  1098. static void InitCode_6816(void)
  1099. {
  1100.   Reg_EK = 0;
  1101. }
  1102.  
  1103. static Boolean IsDef_6816(void)
  1104. {
  1105.   return False;
  1106. }
  1107.  
  1108. static void SwitchFrom_6816(void)
  1109. {
  1110.   DeinitFields();
  1111. }
  1112.  
  1113. static void SwitchTo_6816(void)
  1114. {
  1115. #define ASSUME6816Count (sizeof(ASSUME6816s) / sizeof(*ASSUME6816s))
  1116.   static ASSUMERec ASSUME6816s[11] =
  1117.   {
  1118.     { "EK" , &Reg_EK , 0 , 0xff , 0x100, NULL }
  1119.   };
  1120.  
  1121.   TurnWords = False;
  1122.   SetIntConstMode(eIntConstModeMoto);
  1123.  
  1124.   PCSymbol = "*";
  1125.   HeaderID = 0x65;
  1126.   NOPCode = 0x274c;
  1127.   DivideChars = ",";
  1128.   HasAttrs = True;
  1129.   AttrChars = ".";
  1130.  
  1131.   ValidSegs = (1 << SegCode);
  1132.   Grans[SegCode] = 1; ListGrans[SegCode] = 1; SegInits[SegCode] = 0;
  1133.   SegLimits[SegCode] = 0xfffffl;
  1134.  
  1135.   DecodeAttrPart = DecodeAttrPart_6816;
  1136.   MakeCode = MakeCode_6816;
  1137.   IsDef = IsDef_6816;
  1138.   SwitchFrom = SwitchFrom_6816;
  1139.   AddMoto16PseudoONOFF(False);
  1140.  
  1141.   pASSUMERecs = ASSUME6816s;
  1142.   ASSUMERecCnt = ASSUME6816Count;
  1143.  
  1144.   InitFields();
  1145. }
  1146.  
  1147. void code6816_init(void)
  1148. {
  1149.   CPU6816 = AddCPU("68HC16", SwitchTo_6816);
  1150.  
  1151.   AddInitPassProc(InitCode_6816);
  1152. }
  1153.