Subversion Repositories pentevo

Rev

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

  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 "codevars.h"
  29.  
  30. #include "code6816.h"
  31.  
  32. /*---------------------------------------------------------------------------*/
  33.  
  34. typedef struct
  35. {
  36.   tSymbolSize Size;
  37.   Word Code, ExtCode;
  38.   Byte AdrMask, ExtShift;
  39. } GenOrder;
  40.  
  41. typedef struct
  42. {
  43.   Word Code1, Code2;
  44. } EmuOrder;
  45.  
  46. enum
  47. {
  48.   ModNone = -1,
  49.   ModDisp8 = 0,
  50.   ModDisp16 = 1,
  51.   ModDispE = 2,
  52.   ModAbs = 3,
  53.   ModImm = 4,
  54.   ModImmExt = 5,
  55.   ModDisp20 = ModDisp16,
  56.   ModAbs20 = ModAbs
  57. };
  58.  
  59. #define MModDisp8 (1 << ModDisp8)
  60. #define MModDisp16 (1 << ModDisp16)
  61. #define MModDispE (1 << ModDispE)
  62. #define MModAbs (1 << ModAbs)
  63. #define MModImm (1 << ModImm)
  64. #define MModImmExt (1 << ModImmExt)
  65. #define MModDisp20 MModDisp16
  66. #define MModAbs20 MModAbs
  67.  
  68. static tSymbolSize OpSize;
  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, 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 (OpSize)
  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.     OpSize = pOrder->Size;
  389.     DecodeAdr(1, ArgCnt, False, pOrder->AdrMask);
  390.     switch (AdrMode)
  391.     {
  392.       case ModDisp8:
  393.         BAsmCode[0] = pOrder->Code + AdrPart;
  394.         BAsmCode[1] = AdrVals[0];
  395.         CodeLen = 2;
  396.         break;
  397.       case ModDisp16:
  398.         BAsmCode[0] = 0x17 + pOrder->ExtShift;
  399.         BAsmCode[1] = pOrder->Code + (OpSize << 6) + AdrPart;
  400.         memcpy(BAsmCode + 2, AdrVals, AdrCnt);
  401.         CodeLen = 2 + AdrCnt;
  402.         break;
  403.       case ModDispE:
  404.         BAsmCode[0] = 0x27;
  405.         BAsmCode[1] = pOrder->Code + AdrPart;
  406.         CodeLen = 2;
  407.         break;
  408.       case ModAbs:
  409.         BAsmCode[0] = 0x17 + pOrder->ExtShift;
  410.         BAsmCode[1] = pOrder->Code + (OpSize << 6) + 0x30;
  411.         memcpy(BAsmCode + 2, AdrVals, AdrCnt);
  412.         CodeLen = 2 + AdrCnt;
  413.         break;
  414.       case ModImm:
  415.         if (OpSize == eSymbolSize8Bit)
  416.         {
  417.           BAsmCode[0] = pOrder->Code + 0x30;
  418.           BAsmCode[1] = AdrVals[0];
  419.           CodeLen = 2;
  420.         }
  421.         else
  422.         {
  423.           BAsmCode[0] = 0x37;
  424.           BAsmCode[1] = pOrder->Code + 0x30;
  425.           memcpy(BAsmCode + 2, AdrVals, AdrCnt);
  426.           CodeLen = 2 + AdrCnt;
  427.         }
  428.         break;
  429.       case ModImmExt:
  430.         BAsmCode[0] = pOrder->ExtCode;
  431.         BAsmCode[1] = AdrVals[0];
  432.         CodeLen = 2;
  433.         break;
  434.     }
  435.   }
  436. }
  437.  
  438. static void DecodeAux(Word Code)
  439. {
  440.   if (ChkArgCnt(1, 2))
  441.   {
  442.     OpSize = eSymbolSize16Bit;
  443.     DecodeAdr(1, ArgCnt, False, (*OpPart.str.p_str == 'S' ? 0 : MModImm) | MModDisp8 | MModDisp16 | MModAbs);
  444.     switch (AdrMode)
  445.     {
  446.       case ModDisp8:
  447.         BAsmCode[0] = Code + AdrPart;
  448.         BAsmCode[1] = AdrVals[0];
  449.         CodeLen = 2;
  450.         break;
  451.       case ModDisp16:
  452.         BAsmCode[0] = 0x17;
  453.         BAsmCode[1] = Code + AdrPart;
  454.         memcpy(BAsmCode + 2, AdrVals, AdrCnt);
  455.         CodeLen = 2 + AdrCnt;
  456.         break;
  457.       case ModAbs:
  458.         BAsmCode[0] = 0x17;
  459.         BAsmCode[1] = Code + 0x30;
  460.         memcpy(BAsmCode + 2, AdrVals, AdrCnt);
  461.         CodeLen = 2 + AdrCnt;
  462.         break;
  463.       case ModImm:
  464.         BAsmCode[0] = 0x37;
  465.         BAsmCode[1] = Code + 0x30;
  466.         if (*OpPart.str.p_str == 'L') BAsmCode[1] -= 0x40;
  467.         memcpy(BAsmCode + 2, AdrVals, AdrCnt);
  468.         CodeLen = 2 + AdrCnt;
  469.        break;
  470.     }
  471.   }
  472. }
  473.  
  474. static void DecodeImm(Word Code)
  475. {
  476.   if (ChkArgCnt(1, 1))
  477.   {
  478.     OpSize = eSymbolSize16Bit;
  479.     DecodeAdr(1, 1, False, MModImm | MModImmExt);
  480.     switch (AdrMode)
  481.     {
  482.       case ModImm:
  483.         BAsmCode[0] = 0x37;
  484.         BAsmCode[1] = Code;
  485.         memcpy(BAsmCode + 2, AdrVals, AdrCnt);
  486.         CodeLen = 2 + AdrCnt;
  487.         break;
  488.       case ModImmExt:
  489.         BAsmCode[0] = Code;
  490.         BAsmCode[1] = AdrVals[0];
  491.         CodeLen = 2;
  492.         break;
  493.     }
  494.   }
  495. }
  496.  
  497. static void DecodeExt(Word Code)
  498. {
  499.   if (ChkArgCnt(1, 1))
  500.   {
  501.     OpSize = eSymbolSize16Bit;
  502.     DecodeAdr(1, 1, False, MModAbs);
  503.     switch (AdrMode)
  504.     {
  505.       case ModAbs:
  506.        BAsmCode[0] = Hi(Code);
  507.        BAsmCode[1] = Lo(Code);
  508.        memcpy(BAsmCode + 2, AdrVals, AdrCnt);
  509.        CodeLen = 2 + AdrCnt;
  510.        break;
  511.     }
  512.   }
  513. }
  514.  
  515. static void DecodeStkMult(Word Index)
  516. {
  517.   int z;
  518.   Boolean OK;
  519.  
  520.   if (ChkArgCnt(1, ArgCntMax))
  521.   {
  522.     OK = True;
  523.     BAsmCode[1] = 0;
  524.     for (z = 1; z <= ArgCnt; z++)
  525.       if (OK)
  526.       {
  527.         const size_t RegCnt = as_array_size(Regs);
  528.         size_t z2 = 0;
  529.         NLS_UpString(ArgStr[z].str.p_str);
  530.         while ((z2 < RegCnt) && strcmp(ArgStr[z].str.p_str, Regs[z2]))
  531.           z2++;
  532.         if (z2 >= RegCnt)
  533.         {
  534.           WrStrErrorPos(ErrNum_InvReg, &ArgStr[z]);
  535.           OK = False;
  536.         }
  537.         else
  538.           BAsmCode[1] |= Index ? (1 << z2) : (1 << (RegCnt - 1 - z2));
  539.       }
  540.     if (OK)
  541.     {
  542.       BAsmCode[0] = 0x34 | (Index ^ 1);
  543.       CodeLen = 2;
  544.     }
  545.   }
  546. }
  547.  
  548. static void DecodeMov(Word Index)
  549. {
  550.   Boolean OK;
  551.  
  552.   if (ArgCnt == 2)
  553.   {
  554.     DecodeAdr(1, 1, False, MModAbs);
  555.     if (AdrMode == ModAbs)
  556.     {
  557.       memcpy(BAsmCode + 2, AdrVals, 2);
  558.       DecodeAdr(2, 2, False, MModAbs);
  559.       if (AdrMode == ModAbs)
  560.       {
  561.         memcpy(BAsmCode + 4, AdrVals, 2);
  562.         BAsmCode[0] = 0x37;
  563.         BAsmCode[1] = 0xfe | Index;
  564.         CodeLen = 6;
  565.       }
  566.     }
  567.   }
  568.   else if (!ChkArgCnt(3, 3));
  569.   else if (!as_strcasecmp(ArgStr[2].str.p_str, "X"))
  570.   {
  571.     BAsmCode[1] = EvalStrIntExpression(&ArgStr[1], SInt8, &OK);
  572.     if (OK)
  573.     {
  574.       DecodeAdr(3, 3, False, MModAbs);
  575.       if (AdrMode == ModAbs)
  576.       {
  577.         memcpy(BAsmCode + 2, AdrVals, 2);
  578.         BAsmCode[0] = 0x30 | Index;
  579.         CodeLen = 4;
  580.       }
  581.     }
  582.   }
  583.   else if (!as_strcasecmp(ArgStr[3].str.p_str, "X"))
  584.   {
  585.     BAsmCode[3] = EvalStrIntExpression(&ArgStr[2], SInt8, &OK);
  586.     if (OK)
  587.     {
  588.       DecodeAdr(1, 1, False, MModAbs);
  589.       if (AdrMode == ModAbs)
  590.       {
  591.         memcpy(BAsmCode + 1, AdrVals, 2);
  592.         BAsmCode[0] = 0x32 | Index;
  593.         CodeLen = 4;
  594.       }
  595.     }
  596.   }
  597.   else WrError(ErrNum_InvAddrMode);
  598. }
  599.  
  600. static void DecodeLogp(Word Index)
  601. {
  602.   if (ChkArgCnt(1, 1))
  603.   {
  604.     OpSize = eSymbolSize16Bit; DecodeAdr(1, 1, False, MModImm);
  605.     switch (AdrMode)
  606.     {
  607.       case ModImm:
  608.         BAsmCode[0] = 0x37;
  609.         BAsmCode[1] = 0x3a | Index;
  610.         memcpy(BAsmCode + 2, AdrVals, AdrCnt);
  611.         CodeLen = 2 + AdrCnt;
  612.         break;
  613.     }
  614.   }
  615. }
  616.  
  617. static void DecodeMac(Word Index)
  618. {
  619.   Byte Val;
  620.   Boolean OK;
  621.  
  622.   if (ChkArgCnt(2, 2))
  623.   {
  624.     Val = EvalStrIntExpression(&ArgStr[1], UInt4, &OK);
  625.     if (OK)
  626.     {
  627.       BAsmCode[1] = EvalStrIntExpression(&ArgStr[2], UInt4, &OK);
  628.       if (OK)
  629.       {
  630.         BAsmCode[1] |= (Val << 4);
  631.         BAsmCode[0] = 0x7b | Index;
  632.         CodeLen = 2;
  633.       }
  634.     }
  635.   }
  636. }
  637.  
  638. static void DecodeBit8(Word Index)
  639. {
  640.   Byte Mask;
  641.  
  642.   if (ChkArgCnt(2, 3))
  643.   {
  644.     OpSize = eSymbolSize8Bit;
  645.     DecodeAdr(ArgCnt, ArgCnt, False, MModImm);
  646.     switch (AdrMode)
  647.     {
  648.       case ModImm:
  649.         Mask = AdrVals[0];
  650.         DecodeAdr(1, ArgCnt - 1, False, MModDisp8 | MModDisp16 | MModAbs);
  651.         switch (AdrMode)
  652.         {
  653.           case ModDisp8:
  654.             BAsmCode[0] = 0x17;
  655.             BAsmCode[1] = 0x08 | Index | AdrPart;
  656.             BAsmCode[2] = Mask;
  657.             BAsmCode[3] = AdrVals[0];
  658.             CodeLen = 4;
  659.             break;
  660.           case ModDisp16:
  661.             BAsmCode[0] = 0x08 | Index | AdrPart;
  662.             BAsmCode[1] = Mask;
  663.             memcpy(BAsmCode + 2, AdrVals, AdrCnt);
  664.             CodeLen = 2 + AdrCnt;
  665.             break;
  666.           case ModAbs:
  667.             BAsmCode[0] = 0x38 + Index;
  668.             BAsmCode[1] = Mask;
  669.             memcpy(BAsmCode + 2, AdrVals, AdrCnt);
  670.             CodeLen = 2 + AdrCnt;
  671.             break;
  672.         }
  673.         break;
  674.     }
  675.   }
  676. }
  677.  
  678. static void DecodeBit16(Word Index)
  679. {
  680.   if (ChkArgCnt(2, 3))
  681.   {
  682.     OpSize = eSymbolSize16Bit;
  683.     DecodeAdr(ArgCnt, ArgCnt, False, MModImm);
  684.     switch (AdrMode)
  685.     {
  686.       case ModImm:
  687.         memcpy(BAsmCode + 2, AdrVals, AdrCnt);
  688.         DecodeAdr(1, ArgCnt - 1, False, MModDisp16 | MModAbs);
  689.         switch (AdrMode)
  690.         {
  691.           case ModDisp16:
  692.             BAsmCode[0] = 0x27;
  693.             BAsmCode[1] = 0x08 | Index | AdrPart;
  694.             memcpy(BAsmCode + 4, AdrVals, AdrCnt);
  695.             CodeLen = 4 + AdrCnt;
  696.             break;
  697.           case ModAbs:
  698.             BAsmCode[0] = 0x27;
  699.             BAsmCode[1] = 0x38 | Index;
  700.             memcpy(BAsmCode + 4, AdrVals, AdrCnt);
  701.             CodeLen = 4 + AdrCnt;
  702.             break;
  703.         }
  704.     }
  705.   }
  706. }
  707.  
  708. static void DecodeBrBit(Word Index)
  709. {
  710.   Boolean OK;
  711.   tSymbolFlags Flags;
  712.   LongInt AdrLong;
  713.  
  714.   if (ChkArgCnt(3, 4))
  715.   {
  716.     OpSize = eSymbolSize8Bit; DecodeAdr(ArgCnt - 1, ArgCnt - 1, False, MModImm);
  717.     if (AdrMode == ModImm)
  718.     {
  719.       BAsmCode[1] = AdrVals[0];
  720.       AdrLong = EvalStrIntExpressionWithFlags(&ArgStr[ArgCnt], UInt20, &OK, &Flags) - EProgCounter() - 6;
  721.       if (OK)
  722.       {
  723.         DecodeAdr(1, ArgCnt - 2, False, MModDisp8 | MModDisp16 | MModAbs);
  724.         switch (AdrMode)
  725.         {
  726.           case ModDisp8:
  727.             if ((AdrLong >= -128) && (AdrLong < 127))
  728.             {
  729.               BAsmCode[0] = 0xcb - (Index << 6) + AdrPart;
  730.               BAsmCode[2] = AdrVals[0];
  731.               BAsmCode[3] = AdrLong & 0xff;
  732.               CodeLen = 4;
  733.             }
  734.             else if (!mSymbolQuestionable(Flags) && ((AdrLong <- 0x8000l) || (AdrLong > 0x7fffl))) WrError(ErrNum_JmpDistTooBig);
  735.             else
  736.             {
  737.               BAsmCode[0] = 0x0a + AdrPart + Index;
  738.               BAsmCode[2] = 0;
  739.               BAsmCode[3] = AdrVals[0];
  740.               BAsmCode[4] = (AdrLong >> 8) & 0xff;
  741.               BAsmCode[5] = AdrLong & 0xff;
  742.               CodeLen = 6;
  743.             }
  744.             break;
  745.           case ModDisp16:
  746.             if (!mSymbolQuestionable(Flags) && ((AdrLong < -0x8000l) || (AdrLong > 0x7fffl))) WrError(ErrNum_JmpDistTooBig);
  747.             else
  748.             {
  749.               BAsmCode[0] = 0x0a + AdrPart + Index;
  750.               memcpy(BAsmCode + 2,AdrVals, 2);
  751.               BAsmCode[4] = (AdrLong >> 8) & 0xff;
  752.               BAsmCode[5] = AdrLong & 0xff;
  753.               CodeLen = 6;
  754.             }
  755.             break;
  756.           case ModAbs:
  757.             if (!mSymbolQuestionable(Flags) && ((AdrLong < -0x8000l) || (AdrLong > 0x7fffl))) WrError(ErrNum_JmpDistTooBig);
  758.             else
  759.             {
  760.               BAsmCode[0] = 0x3a | Index;
  761.               memcpy(BAsmCode + 2, AdrVals, 2);
  762.               BAsmCode[4] = (AdrLong >> 8) & 0xff;
  763.               BAsmCode[5] = AdrLong & 0xff;
  764.               CodeLen = 6;
  765.             }
  766.             break;
  767.         }
  768.       }
  769.     }
  770.   }
  771. }
  772.  
  773. static void DecodeJmpJsr(Word Index)
  774. {
  775.   if (ChkArgCnt(1, 2))
  776.   {
  777.     OpSize = eSymbolSize16Bit;
  778.     DecodeAdr(1, ArgCnt, True, MModAbs20 | MModDisp20);
  779.     switch (AdrMode)
  780.     {
  781.       case ModAbs20:
  782.         BAsmCode[0] = 0x7a + (Index << 7);
  783.         memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  784.         CodeLen = 1 + AdrCnt;
  785.         break;
  786.       case ModDisp20:
  787.         BAsmCode[0] = Index ? 0x89 : 0x4b;
  788.         BAsmCode[0] += AdrPart;
  789.         memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  790.         CodeLen = 1 + AdrCnt;
  791.         break;
  792.     }
  793.   }
  794. }
  795.  
  796. static void DecodeBsr(Word Index)
  797. {
  798.   Boolean OK;
  799.   tSymbolFlags Flags;
  800.   LongInt AdrLong;
  801.  
  802.   UNUSED(Index);
  803.  
  804.   if (ChkArgCnt(1, 1))
  805.   {
  806.     AdrLong = EvalStrIntExpressionWithFlags(&ArgStr[1], UInt24, &OK, &Flags) - EProgCounter() - 6;
  807.     if (AdrLong & 1) WrError(ErrNum_NotAligned);
  808.     else if (!mSymbolQuestionable(Flags) & ((AdrLong > 0x7fl) || (AdrLong < -0x80l))) WrError(ErrNum_JmpDistTooBig);
  809.     else
  810.     {
  811.       BAsmCode[0] = 0x36;
  812.       BAsmCode[1] = AdrLong & 0xff;
  813.       CodeLen = 2;
  814.     }
  815.   }
  816. }
  817.  
  818. /*-------------------------------------------------------------------------*/
  819.  
  820. static void AddFixed(const char *NName, Word NCode)
  821. {
  822.   AddInstTable(InstTable, NName, NCode, DecodeFixed);
  823. }
  824.  
  825. static void AddRel(const char *NName, Word NCode)
  826. {
  827.   AddInstTable(InstTable, NName, NCode, DecodeRel);
  828. }
  829.  
  830. static void AddLRel(const char *NName, Word NCode)
  831. {
  832.   AddInstTable(InstTable, NName, NCode, DecodeLRel);
  833. }
  834.  
  835. static void AddGen(const char *NName, tSymbolSize NSize, Word NCode, Word NExtCode, Byte NShift, Byte NMask)
  836. {
  837.   order_array_rsv_end(GenOrders, GenOrder);
  838.   GenOrders[InstrZ].Code = NCode;
  839.   GenOrders[InstrZ].ExtCode = NExtCode;
  840.   GenOrders[InstrZ].Size = NSize;
  841.   GenOrders[InstrZ].AdrMask = NMask;
  842.   GenOrders[InstrZ].ExtShift = NShift;
  843.   AddInstTable(InstTable, NName, InstrZ++, DecodeGen);
  844. }
  845.  
  846. static void AddAux(const char *NName, Word NCode)
  847. {
  848.   AddInstTable(InstTable, NName, NCode, DecodeAux);
  849. }
  850.  
  851. static void AddImm(const char *NName, Word NCode)
  852. {
  853.   AddInstTable(InstTable, NName, NCode, DecodeImm);
  854. }
  855.  
  856. static void AddExt(const char *NName, Word NCode)
  857. {
  858.   AddInstTable(InstTable, NName, NCode, DecodeExt);
  859. }
  860.  
  861. static void AddEmu(const char *NName, Word NCode1, Word NCode2)
  862. {
  863.   order_array_rsv_end(EmuOrders, EmuOrder);
  864.   EmuOrders[InstrZ].Code1 = NCode1;
  865.   EmuOrders[InstrZ].Code2 = NCode2;
  866.   AddInstTable(InstTable, NName, InstrZ++, DecodeEmu);
  867. }
  868.  
  869. static void InitFields(void)
  870. {
  871.   InstTable = CreateInstTable(405);
  872.  
  873.   AddFixed("ABA"   , 0x370b); AddFixed("ABX"   , 0x374f);
  874.   AddFixed("ABY"   , 0x375f); AddFixed("ABZ"   , 0x376f);
  875.   AddFixed("ACE"   , 0x3722); AddFixed("ACED"  , 0x3723);
  876.   AddFixed("ADE"   , 0x2778); AddFixed("ADX"   , 0x37cd);
  877.   AddFixed("ADY"   , 0x37dd); AddFixed("ADZ"   , 0x37ed);
  878.   AddFixed("AEX"   , 0x374d); AddFixed("AEY"   , 0x375d);
  879.   AddFixed("AEZ"   , 0x376d); AddFixed("ASLA"  , 0x3704);
  880.   AddFixed("ASLB"  , 0x3714); AddFixed("ASLD"  , 0x27f4);
  881.   AddFixed("ASLE"  , 0x2774); AddFixed("ASLM"  , 0x27b6);
  882.   AddFixed("LSLB"  , 0x3714); AddFixed("LSLD"  , 0x27f4);
  883.   AddFixed("LSLE"  , 0x2774); AddFixed("LSLA"  , 0x3704);
  884.   AddFixed("ASRA"  , 0x370d); AddFixed("ASRB"  , 0x371d);
  885.   AddFixed("ASRD"  , 0x27fd); AddFixed("ASRE"  , 0x277d);
  886.   AddFixed("ASRM"  , 0x27ba); AddFixed("BGND"  , 0x37a6);
  887.   AddFixed("CBA"   , 0x371b); AddFixed("CLRA"  , 0x3705);
  888.   AddFixed("CLRB"  , 0x3715); AddFixed("CLRD"  , 0x27f5);
  889.   AddFixed("CLRE"  , 0x2775); AddFixed("CLRM"  , 0x27b7);
  890.   AddFixed("COMA"  , 0x3700); AddFixed("COMB"  , 0x3710);
  891.   AddFixed("COMD"  , 0x27f0); AddFixed("COME"  , 0x2770);
  892.   AddFixed("DAA"   , 0x3721); AddFixed("DECA"  , 0x3701);
  893.   AddFixed("DECB"  , 0x3711); AddFixed("EDIV"  , 0x3728);
  894.   AddFixed("EDIVS" , 0x3729); AddFixed("EMUL"  , 0x3725);
  895.   AddFixed("EMULS" , 0x3726); AddFixed("FDIV"  , 0x372b);
  896.   AddFixed("FMULS" , 0x3727); AddFixed("IDIV"  , 0x372a);
  897.   AddFixed("INCA"  , 0x3703); AddFixed("INCB"  , 0x3713);
  898.   AddFixed("LPSTOP", 0x27f1); AddFixed("LSRA"  , 0x370f);
  899.   AddFixed("LSRB"  , 0x371f); AddFixed("LSRD"  , 0x27ff);
  900.   AddFixed("LSRE"  , 0x277f); AddFixed("MUL"   , 0x3724);
  901.   AddFixed("NEGA"  , 0x3702); AddFixed("NEGB"  , 0x3712);
  902.   AddFixed("NEGD"  , 0x27f2); AddFixed("NEGE"  , 0x2772);
  903.   AddFixed("NOP"   , 0x274c); AddFixed("PSHA"  , 0x3708);
  904.   AddFixed("PSHB"  , 0x3718); AddFixed("PSHMAC", 0x27b8);
  905.   AddFixed("PULA"  , 0x3709); AddFixed("PULB"  , 0x3719);
  906.   AddFixed("PULMAC", 0x27b9); AddFixed("ROLA"  , 0x370c);
  907.   AddFixed("ROLB"  , 0x371c); AddFixed("ROLD"  , 0x27fc);
  908.   AddFixed("ROLE"  , 0x277c); AddFixed("RORA"  , 0x370e);
  909.   AddFixed("RORB"  , 0x371e); AddFixed("RORD"  , 0x27fe);
  910.   AddFixed("RORE"  , 0x277e); AddFixed("RTI"   , 0x2777);
  911.   AddFixed("RTS"   , 0x27f7); AddFixed("SBA"   , 0x370a);
  912.   AddFixed("SDE"   , 0x2779); AddFixed("SWI"   , 0x3720);
  913.   AddFixed("SXT"   , 0x27f8); AddFixed("TAB"   , 0x3717);
  914.   AddFixed("TAP"   , 0x37fd); AddFixed("TBA"   , 0x3707);
  915.   AddFixed("TBEK"  , 0x27fa); AddFixed("TBSK"  , 0x379f);
  916.   AddFixed("TBXK"  , 0x379c); AddFixed("TBYK"  , 0x379d);
  917.   AddFixed("TBZK"  , 0x379e); AddFixed("TDE"   , 0x277b);
  918.   AddFixed("TDMSK" , 0x372f); AddFixed("TDP"   , 0x372d);
  919.   AddFixed("TED"   , 0x27fb); AddFixed("TEDM"  , 0x27b1);
  920.   AddFixed("TEKB"  , 0x27bb); AddFixed("TEM"   , 0x27b2);
  921.   AddFixed("TMER"  , 0x27b4); AddFixed("TMET"  , 0x27b5);
  922.   AddFixed("TMXED" , 0x27b3); AddFixed("TPA"   , 0x37fc);
  923.   AddFixed("TPD"   , 0x372c); AddFixed("TSKB"  , 0x37af);
  924.   AddFixed("TSTA"  , 0x3706); AddFixed("TSTB"  , 0x3716);
  925.   AddFixed("TSTD"  , 0x27f6); AddFixed("TSTE"  , 0x2776);
  926.   AddFixed("TSX"   , 0x274f); AddFixed("TSY"   , 0x275f);
  927.   AddFixed("TSZ"   , 0x276f); AddFixed("TXKB"  , 0x37ac);
  928.   AddFixed("TXS"   , 0x374e); AddFixed("TXY"   , 0x275c);
  929.   AddFixed("TXZ"   , 0x276c); AddFixed("TYKB"  , 0x37ad);
  930.   AddFixed("TYS"   , 0x375e); AddFixed("TYX"   , 0x274d);
  931.   AddFixed("TYZ"   , 0x276d); AddFixed("TZKB"  , 0x37ae);
  932.   AddFixed("TZS"   , 0x376e); AddFixed("TZX"   , 0x274e);
  933.   AddFixed("TZY"   , 0x275e); AddFixed("WAI"   , 0x27f3);
  934.   AddFixed("XGAB"  , 0x371a); AddFixed("XGDE"  , 0x277a);
  935.   AddFixed("XGDX"  , 0x37cc); AddFixed("XGDY"  , 0x37dc);
  936.   AddFixed("XGDZ"  , 0x37ec); AddFixed("XGEX"  , 0x374c);
  937.   AddFixed("XGEY"  , 0x375c); AddFixed("XGEZ"  , 0x376c);
  938.   AddFixed("DES"   , 0x3fff); AddFixed("INS"   , 0x3f01);
  939.   AddFixed("DEX"   , 0x3cff); AddFixed("INX"   , 0x3c01);
  940.   AddFixed("DEY"   , 0x3dff); AddFixed("INY"   , 0x3d01);
  941.   AddFixed("PSHX"  , 0x3404); AddFixed("PULX"  , 0x3510);
  942.   AddFixed("PSHY"  , 0x3408); AddFixed("PULY"  , 0x3508);
  943.  
  944.   AddRel("BCC" ,           4); AddRel("BCS",            5); AddRel("BEQ",            7);
  945.   AddRel("BGE" ,          12); AddRel("BGT",           14); AddRel("BHI",            2);
  946.   AddRel("BLE" ,          15); AddRel("BLS",            3); AddRel("BLT",           13);
  947.   AddRel("BMI" ,          11); AddRel("BNE",            6); AddRel("BPL",           10);
  948.   AddRel("BRA" ,           0); AddRel("BRN",            1); AddRel("BVC",            8);
  949.   AddRel("BVS" ,           9); AddRel("BHS",            4); AddRel("BLO",            5);
  950.   AddRel("LBCC", 0x8000 |  4); AddRel("LBCS", 0x8000 |  5); AddRel("LBEQ", 0x8000 |  7);
  951.   AddRel("LBGE", 0x8000 | 12); AddRel("LBGT", 0x8000 | 14); AddRel("LBHI", 0x8000 |  2);
  952.   AddRel("LBLE", 0x8000 | 15); AddRel("LBLS", 0x8000 |  3); AddRel("LBLT", 0x8000 | 13);
  953.   AddRel("LBMI", 0x8000 | 11); AddRel("LBNE", 0x8000 |  6); AddRel("LBPL", 0x8000 | 10);
  954.   AddRel("LBRA", 0x8000 |  0); AddRel("LBRN", 0x8000 |  1); AddRel("LBVC", 0x8000 |  8);
  955.   AddRel("LBVS", 0x8000 |  9); AddRel("LBHS", 0x8000 |  4); AddRel("LBLO", 0x8000 |  5);
  956.  
  957.   AddLRel("LBEV", 0x3791); AddLRel("LBMV", 0x3790); AddLRel("LBSR", 0x27f9);
  958.  
  959.   InstrZ = 0;
  960.   AddGen("ADCA", eSymbolSize8Bit , 0x43, 0xffff, 0x00, MModDisp8 | MModImm |              MModDisp16 | MModAbs | MModDispE);
  961.   AddGen("ADCB", eSymbolSize8Bit , 0xc3, 0xffff, 0x00, MModDisp8 | MModImm |              MModDisp16 | MModAbs | MModDispE);
  962.   AddGen("ADCD", eSymbolSize16Bit, 0x83, 0xffff, 0x20, MModDisp8 | MModImm |              MModDisp16 | MModAbs | MModDispE);
  963.   AddGen("ADCE", eSymbolSize16Bit, 0x03, 0xffff, 0x20,             MModImm |              MModDisp16 | MModAbs            );
  964.   AddGen("ADDA", eSymbolSize8Bit , 0x41, 0xffff, 0x00, MModDisp8 | MModImm |              MModDisp16 | MModAbs | MModDispE);
  965.   AddGen("ADDB", eSymbolSize8Bit , 0xc1, 0xffff, 0x00, MModDisp8 | MModImm |              MModDisp16 | MModAbs | MModDispE);
  966.   AddGen("ADDD", eSymbolSize16Bit, 0x81,   0xfc, 0x20, MModDisp8 | MModImm | MModImmExt | MModDisp16 | MModAbs | MModDispE);
  967.   AddGen("ADDE", eSymbolSize16Bit, 0x01,   0x7c, 0x20,             MModImm | MModImmExt | MModDisp16 | MModAbs            );
  968.   AddGen("ANDA", eSymbolSize8Bit , 0x46, 0xffff, 0x00, MModDisp8 | MModImm |              MModDisp16 | MModAbs | MModDispE);
  969.   AddGen("ANDB", eSymbolSize8Bit , 0xc6, 0xffff, 0x00, MModDisp8 | MModImm |              MModDisp16 | MModAbs | MModDispE);
  970.   AddGen("ANDD", eSymbolSize16Bit, 0x86, 0xffff, 0x20, MModDisp8 | MModImm |              MModDisp16 | MModAbs | MModDispE);
  971.   AddGen("ANDE", eSymbolSize16Bit, 0x06, 0xffff, 0x20,             MModImm |              MModDisp16 | MModAbs            );
  972.   AddGen("ASL" , eSymbolSize8Bit , 0x04, 0xffff, 0x00, MModDisp8 |                        MModDisp16 | MModAbs            );
  973.   AddGen("ASLW", eSymbolSize8Bit , 0x04, 0xffff, 0x10,                                    MModDisp16 | MModAbs            );
  974.   AddGen("LSL" , eSymbolSize8Bit , 0x04, 0xffff, 0x00, MModDisp8 |                        MModDisp16 | MModAbs            );
  975.   AddGen("LSLW", eSymbolSize8Bit , 0x04, 0xffff, 0x10,                                    MModDisp16 | MModAbs            );
  976.   AddGen("ASR" , eSymbolSize8Bit , 0x0d, 0xffff, 0x00, MModDisp8 |                        MModDisp16 | MModAbs            );
  977.   AddGen("ASRW", eSymbolSize8Bit , 0x0d, 0xffff, 0x10,                                    MModDisp16 | MModAbs            );
  978.   AddGen("BITA", eSymbolSize8Bit , 0x49, 0xffff, 0x00, MModDisp8 | MModImm |              MModDisp16 | MModAbs | MModDispE);
  979.   AddGen("BITB", eSymbolSize8Bit , 0xc9, 0xffff, 0x00, MModDisp8 | MModImm |              MModDisp16 | MModAbs | MModDispE);
  980.   AddGen("CLR" , eSymbolSize8Bit , 0x05, 0xffff, 0x00, MModDisp8 |                        MModDisp16 | MModAbs            );
  981.   AddGen("CLRW", eSymbolSize8Bit , 0x05, 0xffff, 0x10,                                    MModDisp16 | MModAbs            );
  982.   AddGen("CMPA", eSymbolSize8Bit , 0x48, 0xffff, 0x00, MModDisp8 | MModImm |              MModDisp16 | MModAbs | MModDispE);
  983.   AddGen("CMPB", eSymbolSize8Bit , 0xc8, 0xffff, 0x00, MModDisp8 | MModImm |              MModDisp16 | MModAbs | MModDispE);
  984.   AddGen("COM" , eSymbolSize8Bit , 0x00, 0xffff, 0x00, MModDisp8 |                        MModDisp16 | MModAbs            );
  985.   AddGen("COMW", eSymbolSize8Bit , 0x00, 0xffff, 0x10,                                    MModDisp16 | MModAbs            );
  986.   AddGen("CPD" , eSymbolSize16Bit, 0x88, 0xffff, 0x20, MModDisp8 | MModImm |              MModDisp16 | MModAbs | MModDispE);
  987.   AddGen("CPE" , eSymbolSize16Bit, 0x08, 0xffff, 0x20,             MModImm |              MModDisp16 | MModAbs            );
  988.   AddGen("DEC" , eSymbolSize8Bit , 0x01, 0xffff, 0x00, MModDisp8 |                        MModDisp16 | MModAbs            );
  989.   AddGen("DECW", eSymbolSize8Bit , 0x01, 0xffff, 0x10,                                    MModDisp16 | MModAbs            );
  990.   AddGen("EORA", eSymbolSize8Bit , 0x44, 0xffff, 0x00, MModDisp8 | MModImm |              MModDisp16 | MModAbs | MModDispE);
  991.   AddGen("EORB", eSymbolSize8Bit , 0xc4, 0xffff, 0x00, MModDisp8 | MModImm |              MModDisp16 | MModAbs | MModDispE);
  992.   AddGen("EORD", eSymbolSize16Bit, 0x84, 0xffff, 0x20, MModDisp8 | MModImm |              MModDisp16 | MModAbs | MModDispE);
  993.   AddGen("EORE", eSymbolSize16Bit, 0x04, 0xffff, 0x20,             MModImm |              MModDisp16 | MModAbs            );
  994.   AddGen("INC" , eSymbolSize8Bit , 0x03, 0xffff, 0x00, MModDisp8 |                        MModDisp16 | MModAbs            );
  995.   AddGen("INCW", eSymbolSize8Bit , 0x03, 0xffff, 0x10,                                    MModDisp16 | MModAbs            );
  996.   AddGen("LDAA", eSymbolSize8Bit , 0x45, 0xffff, 0x00, MModDisp8 | MModImm |              MModDisp16 | MModAbs | MModDispE);
  997.   AddGen("LDAB", eSymbolSize8Bit , 0xc5, 0xffff, 0x00, MModDisp8 | MModImm |              MModDisp16 | MModAbs | MModDispE);
  998.   AddGen("LDD" , eSymbolSize16Bit, 0x85, 0xffff, 0x20, MModDisp8 | MModImm |              MModDisp16 | MModAbs | MModDispE);
  999.   AddGen("LDE" , eSymbolSize16Bit, 0x05, 0xffff, 0x20,             MModImm |              MModDisp16 | MModAbs            );
  1000.   AddGen("LSR" , eSymbolSize8Bit , 0x0f, 0xffff, 0x00, MModDisp8 |                        MModDisp16 | MModAbs            );
  1001.   AddGen("LSRW", eSymbolSize8Bit , 0x0f, 0xffff, 0x10,                                    MModDisp16 | MModAbs            );
  1002.   AddGen("NEG" , eSymbolSize8Bit , 0x02, 0xffff, 0x00, MModDisp8 |                        MModDisp16 | MModAbs            );
  1003.   AddGen("NEGW", eSymbolSize8Bit , 0x02, 0xffff, 0x10,                                    MModDisp16 | MModAbs            );
  1004.   AddGen("ORAA", eSymbolSize8Bit , 0x47, 0xffff, 0x00, MModDisp8 | MModImm |              MModDisp16 | MModAbs | MModDispE);
  1005.   AddGen("ORAB", eSymbolSize8Bit , 0xc7, 0xffff, 0x00, MModDisp8 | MModImm |              MModDisp16 | MModAbs | MModDispE);
  1006.   AddGen("ORD" , eSymbolSize16Bit, 0x87, 0xffff, 0x20, MModDisp8 | MModImm |              MModDisp16 | MModAbs | MModDispE);
  1007.   AddGen("ORE" , eSymbolSize16Bit, 0x07, 0xffff, 0x20,             MModImm |              MModDisp16 | MModAbs            );
  1008.   AddGen("ROL" , eSymbolSize8Bit , 0x0c, 0xffff, 0x00, MModDisp8 |                        MModDisp16 | MModAbs            );
  1009.   AddGen("ROLW", eSymbolSize8Bit , 0x0c, 0xffff, 0x10,                                    MModDisp16 | MModAbs            );
  1010.   AddGen("ROR" , eSymbolSize8Bit , 0x0e, 0xffff, 0x00, MModDisp8 |                        MModDisp16 | MModAbs            );
  1011.   AddGen("RORW", eSymbolSize8Bit , 0x0e, 0xffff, 0x10,                                    MModDisp16 | MModAbs            );
  1012.   AddGen("SBCA", eSymbolSize8Bit , 0x42, 0xffff, 0x00, MModDisp8 | MModImm |              MModDisp16 | MModAbs | MModDispE);
  1013.   AddGen("SBCB", eSymbolSize8Bit , 0xc2, 0xffff, 0x00, MModDisp8 | MModImm |              MModDisp16 | MModAbs | MModDispE);
  1014.   AddGen("SBCD", eSymbolSize16Bit, 0x82, 0xffff, 0x20, MModDisp8 | MModImm |              MModDisp16 | MModAbs | MModDispE);
  1015.   AddGen("SBCE", eSymbolSize16Bit, 0x02, 0xffff, 0x20,             MModImm |              MModDisp16 | MModAbs            );
  1016.   AddGen("STAA", eSymbolSize8Bit , 0x4a, 0xffff, 0x00, MModDisp8 |                        MModDisp16 | MModAbs | MModDispE);
  1017.   AddGen("STAB", eSymbolSize8Bit , 0xca, 0xffff, 0x00, MModDisp8 |                        MModDisp16 | MModAbs | MModDispE);
  1018.   AddGen("STD" , eSymbolSize16Bit, 0x8a, 0xffff, 0x20, MModDisp8 |                        MModDisp16 | MModAbs | MModDispE);
  1019.   AddGen("STE" , eSymbolSize16Bit, 0x0a, 0xffff, 0x20,                                    MModDisp16 | MModAbs            );
  1020.   AddGen("SUBA", eSymbolSize8Bit , 0x40, 0xffff, 0x00, MModDisp8 | MModImm |              MModDisp16 | MModAbs | MModDispE);
  1021.   AddGen("SUBB", eSymbolSize8Bit , 0xc0, 0xffff, 0x00, MModDisp8 | MModImm |              MModDisp16 | MModAbs | MModDispE);
  1022.   AddGen("SUBD", eSymbolSize16Bit, 0x80, 0xffff, 0x20, MModDisp8 | MModImm |              MModDisp16 | MModAbs | MModDispE);
  1023.   AddGen("SUBE", eSymbolSize16Bit, 0x00, 0xffff, 0x20,             MModImm |              MModDisp16 | MModAbs            );
  1024.   AddGen("TST" , eSymbolSize8Bit , 0x06, 0xffff, 0x00, MModDisp8 |                        MModDisp16 | MModAbs            );
  1025.   AddGen("TSTW", eSymbolSize8Bit , 0x06, 0xffff, 0x10,                                    MModDisp16 | MModAbs            );
  1026.  
  1027.   AddAux("CPS", 0x4f); AddAux("CPX", 0x4c); AddAux("CPY", 0x4d); AddAux("CPZ", 0x4e);
  1028.   AddAux("LDS", 0xcf); AddAux("LDX", 0xcc); AddAux("LDY", 0xcd); AddAux("LDZ", 0xce);
  1029.   AddAux("STS", 0x8f); AddAux("STX", 0x8c); AddAux("STY", 0x8d); AddAux("STZ", 0x8e);
  1030.  
  1031.   AddImm("AIS", 0x3f); AddImm("AIX", 0x3c); AddImm("AIY", 0x3d); AddImm("AIZ", 0x3e);
  1032.  
  1033.   AddExt("LDED", 0x2771); AddExt("LDHI", 0x27b0); AddExt("STED", 0x2773);
  1034.  
  1035.   InstrZ = 0;
  1036.   AddEmu("CLC", 0x373a, 0xfeff); AddEmu("CLI", 0x373a, 0xff1f); AddEmu("CLV", 0x373a, 0xfdff);
  1037.   AddEmu("SEC", 0x373b, 0x0100); AddEmu("SEI", 0x373b, 0x00e0); AddEmu("SEV", 0x373b, 0x0200);
  1038.  
  1039.   AddInstTable(InstTable, "PSHM", 1, DecodeStkMult);
  1040.   AddInstTable(InstTable, "PULM", 0, DecodeStkMult);
  1041.  
  1042.   AddInstTable(InstTable, "MOVB", 0, DecodeMov);
  1043.   AddInstTable(InstTable, "MOVW", 1, DecodeMov);
  1044.  
  1045.   AddInstTable(InstTable, "ANDP", 0, DecodeLogp);
  1046.   AddInstTable(InstTable, "ORP" , 1, DecodeLogp);
  1047.  
  1048.   AddInstTable(InstTable, "MAC" , 0 << 7, DecodeMac);
  1049.   AddInstTable(InstTable, "RMAC", 1 << 7, DecodeMac);
  1050.  
  1051.   AddInstTable(InstTable, "BCLR", 0, DecodeBit8);
  1052.   AddInstTable(InstTable, "BSET", 1, DecodeBit8);
  1053.  
  1054.   AddInstTable(InstTable, "BCLRW", 0, DecodeBit16);
  1055.   AddInstTable(InstTable, "BSETW", 1, DecodeBit16);
  1056.  
  1057.   AddInstTable(InstTable, "BRCLR", 0, DecodeBrBit);
  1058.   AddInstTable(InstTable, "BRSET", 1, DecodeBrBit);
  1059.  
  1060.   AddInstTable(InstTable, "JMP", 0, DecodeJmpJsr);
  1061.   AddInstTable(InstTable, "JSR", 1, DecodeJmpJsr);
  1062.   AddInstTable(InstTable, "BSR", 0, DecodeBsr);
  1063.  
  1064.   AddInstTable(InstTable, "DB", 0, DecodeMotoBYT);
  1065.   AddInstTable(InstTable, "DW", 0, DecodeMotoADR);
  1066.  
  1067.   init_moto8_pseudo(InstTable, e_moto_8_be);
  1068. }
  1069.  
  1070. static void DeinitFields(void)
  1071. {
  1072.   order_array_free(GenOrders);
  1073.   order_array_free(EmuOrders);
  1074.   DestroyInstTable(InstTable); InstTable = NULL;
  1075. }
  1076.  
  1077. /*-------------------------------------------------------------------------*/
  1078.  
  1079. static Boolean DecodeAttrPart_6816(void)
  1080. {
  1081.   if (strlen(AttrPart.str.p_str) > 1)
  1082.   {
  1083.     WrStrErrorPos(ErrNum_UndefAttr, &AttrPart);
  1084.     return False;
  1085.   }
  1086.   return DecodeMoto16AttrSize(*AttrPart.str.p_str, &AttrPartOpSize[0], False);
  1087. }
  1088.  
  1089. static void MakeCode_6816(void)
  1090. {
  1091.   CodeLen = 0;
  1092.   DontPrint = False;
  1093.   AdrCnt = 0;
  1094.  
  1095.   /* Operandengroesse festlegen. ACHTUNG! Das gilt nur fuer die folgenden
  1096.      Pseudobefehle! Die Maschinenbefehle ueberschreiben diesen Wert! */
  1097.  
  1098.   OpSize = AttrPartOpSize[0];
  1099.  
  1100.   /* zu ignorierendes */
  1101.  
  1102.   if (Memo(""))
  1103.     return;
  1104.  
  1105.   /* Pseudoanweisungen */
  1106.  
  1107.   if (DecodeMoto16Pseudo(OpSize, True))
  1108.     return;
  1109.  
  1110.   if (!LookupInstTable(InstTable, OpPart.str.p_str))
  1111.     WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
  1112. }
  1113.  
  1114. static void InitCode_6816(void)
  1115. {
  1116.   Reg_EK = 0;
  1117. }
  1118.  
  1119. static Boolean IsDef_6816(void)
  1120. {
  1121.   return False;
  1122. }
  1123.  
  1124. static void SwitchFrom_6816(void)
  1125. {
  1126.   DeinitFields();
  1127. }
  1128.  
  1129. static void SwitchTo_6816(void)
  1130. {
  1131. #define ASSUME6816Count (sizeof(ASSUME6816s) / sizeof(*ASSUME6816s))
  1132.   static ASSUMERec ASSUME6816s[11] =
  1133.   {
  1134.     { "EK" , &Reg_EK , 0 , 0xff , 0x100, NULL }
  1135.   };
  1136.  
  1137.   TurnWords = False;
  1138.   SetIntConstMode(eIntConstModeMoto);
  1139.  
  1140.   PCSymbol = "*";
  1141.   HeaderID = 0x65;
  1142.   NOPCode = 0x274c;
  1143.   DivideChars = ",";
  1144.   HasAttrs = True;
  1145.   AttrChars = ".";
  1146.  
  1147.   ValidSegs = (1 << SegCode);
  1148.   Grans[SegCode] = 1; ListGrans[SegCode] = 1; SegInits[SegCode] = 0;
  1149.   SegLimits[SegCode] = 0xfffffl;
  1150.  
  1151.   DecodeAttrPart = DecodeAttrPart_6816;
  1152.   MakeCode = MakeCode_6816;
  1153.   IsDef = IsDef_6816;
  1154.   SwitchFrom = SwitchFrom_6816;
  1155.   AddMoto16PseudoONOFF(False);
  1156.  
  1157.   pASSUMERecs = ASSUME6816s;
  1158.   ASSUMERecCnt = ASSUME6816Count;
  1159.  
  1160.   InitFields();
  1161. }
  1162.  
  1163. void code6816_init(void)
  1164. {
  1165.   CPU6816 = AddCPU("68HC16", SwitchTo_6816);
  1166.  
  1167.   AddInitPassProc(InitCode_6816);
  1168. }
  1169.