Subversion Repositories pentevo

Rev

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

  1. /* code7700.c */
  2. /*****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
  4. /*                                                                           */
  5. /* AS-Portierung                                                             */
  6. /*                                                                           */
  7. /* AS-Codegeneratormodul MELPS-7700                                          */
  8. /*                                                                           */
  9. /*****************************************************************************/
  10.  
  11. #include "stdinc.h"
  12. #include <string.h>
  13.  
  14. #include "bpemu.h"
  15. #include "strutil.h"
  16. #include "asmdef.h"
  17. #include "asmsub.h"
  18. #include "asmpars.h"
  19. #include "asmitree.h"
  20. #include "codepseudo.h"
  21. #include "intpseudo.h"
  22. #include "motpseudo.h"
  23. #include "codevars.h"
  24. #include "errmsg.h"
  25.  
  26. #include "code7700.h"
  27.  
  28. typedef struct
  29. {
  30.   Word Code;
  31.   ShortInt Disp8, Disp16;
  32. } RelOrder;
  33.  
  34. typedef struct
  35. {
  36.   Byte CodeImm, CodeAbs8, CodeAbs16, CodeIdxX8, CodeIdxX16,
  37.        CodeIdxY8, CodeIdxY16;
  38. } XYOrder;
  39.  
  40. enum
  41. {
  42.   ModNone =   (-1),
  43.   ModImm =     0,
  44.   ModAbs8 =    1,
  45.   ModAbs16 =   2,
  46.   ModAbs24 =   3,
  47.   ModIdxX8 =   4,
  48.   ModIdxX16 =  5,
  49.   ModIdxX24 =  6,
  50.   ModIdxY8 =   7,
  51.   ModIdxY16 =  8,
  52.   ModIdxY24 =  9,
  53.   ModInd8 =   10,
  54.   ModInd16 =  11,
  55.   ModInd24 =  12,
  56.   ModIndX8 =  13,
  57.   ModIndX16 = 14,
  58.   ModIndX24 = 15,
  59.   ModIndY8 =  16,
  60.   ModIndY16 = 17,
  61.   ModIndY24 = 18,
  62.   ModIdxS8 =  19,
  63.   ModIndS8 =  20
  64. };
  65.  
  66. #define MModImm      (1l << ModImm)
  67. #define MModAbs8     (1l << ModAbs8)
  68. #define MModAbs16    (1l << ModAbs16)
  69. #define MModAbs24    (1l << ModAbs24)
  70. #define MModIdxX8    (1l << ModIdxX8)
  71. #define MModIdxX16   (1l << ModIdxX16)
  72. #define MModIdxX24   (1l << ModIdxX24)
  73. #define MModIdxY8    (1l << ModIdxY8)
  74. #define MModIdxY16   (1l << ModIdxY16)
  75. #define MModIdxY24   (1l << ModIdxY24)
  76. #define MModInd8     (1l << ModInd8)
  77. #define MModInd16    (1l << ModInd16)
  78. #define MModInd24    (1l << ModInd24)
  79. #define MModIndX8    (1l << ModIndX8)
  80. #define MModIndX16   (1l << ModIndX16)
  81. #define MModIndX24   (1l << ModIndX24)
  82. #define MModIndY8    (1l << ModIndY8)
  83. #define MModIndY16   (1l << ModIndY16)
  84. #define MModIndY24   (1l << ModIndY24)
  85. #define MModIdxS8    (1l << ModIdxS8)
  86. #define MModIndS8    (1l << ModIndS8)
  87.  
  88. #define PushRegCnt 10
  89. static const char PushRegNames[PushRegCnt][4] =
  90. {
  91.   "A", "B", "X", "Y", "DPR", "DT", "DBR", "PG", "PBR", "PS"
  92. };
  93. static const Byte PushRegCodes[PushRegCnt] =
  94. {
  95.   0  ,1  ,2  ,3  ,4    ,5   ,5    ,6   ,6    ,7
  96. };
  97.  
  98. #define PrefAccB 0x42
  99.  
  100. static LongInt Reg_PG, Reg_DT, Reg_X, Reg_M, Reg_DPR, BankReg;
  101.  
  102. static Boolean WordSize;
  103. static Byte AdrVals[3];
  104. static ShortInt AdrType;
  105.  
  106. static RelOrder *RelOrders;
  107. static XYOrder *XYOrders;
  108.  
  109. static CPUVar CPU65816, CPUM7700, CPUM7750, CPUM7751;
  110.  
  111. static ASSUMERec ASSUME7700s[] =
  112. {
  113.   { "PG" , &Reg_PG , 0,   0xff,   0x100, NULL },
  114.   { "DT" , &Reg_DT , 0,   0xff,   0x100, NULL },
  115.   { "PBR", &Reg_PG , 0,   0xff,   0x100, NULL },
  116.   { "DBR", &Reg_DT , 0,   0xff,   0x100, NULL },
  117.   { "X"  , &Reg_X  , 0,      1,      -1, NULL },
  118.   { "M"  , &Reg_M  , 0,      1,      -1, NULL },
  119.   { "DPR", &Reg_DPR, 0, 0xffff, 0x10000, NULL }
  120. };
  121.  
  122. /*---------------------------------------------------------------------------*/
  123. /* Address Parsing */
  124.  
  125. static void CodeDisp(const tStrComp *pArg, LongInt Start, LongWord Mask)
  126. {
  127.   Boolean OK;
  128.   tSymbolFlags Flags;
  129.   LongInt Adr;
  130.   ShortInt DType;
  131.   int ArgLen = strlen(pArg->str.p_str);
  132.   unsigned Offset = 0;
  133.  
  134.   if ((ArgLen > 1) && (pArg->str.p_str[Offset] == '<'))
  135.   {
  136.     Offset = 1;
  137.     DType = 0;
  138.   }
  139.   else if ((ArgLen > 1) && (pArg->str.p_str[Offset] == '>'))
  140.   {
  141.     if ((ArgLen > 2) && (pArg->str.p_str[Offset + 1] == '>'))
  142.     {
  143.       Offset = 2;
  144.       DType = 2;
  145.     }
  146.     else
  147.     {
  148.       Offset = 1;
  149.       DType = 1;
  150.     }
  151.   }
  152.   else
  153.     DType = -1;
  154.  
  155.   Adr = EvalStrIntExpressionOffsWithFlags(pArg, Offset, UInt24, &OK, &Flags);
  156.  
  157.   if (!OK)
  158.     return;
  159.  
  160.   if (DType == -1)
  161.   {
  162.     if ((Mask & (1l << Start))
  163.      && (Adr >= Reg_DPR)
  164.      && (Adr < Reg_DPR + 0x100))
  165.       DType = 0;
  166.     else if ((Mask & (2l << Start))
  167.           && ((Adr >> 16) == BankReg))
  168.       DType = 1;
  169.     else
  170.       DType = 2;
  171.   }
  172.  
  173.   if (!(Mask & (1l << (Start + DType)))) WrError(ErrNum_InvAddrMode);
  174.   else
  175.   {
  176.     switch (DType)
  177.     {
  178.       case 0:
  179.         if (mFirstPassUnknown(Flags) || (ChkRange(Adr, Reg_DPR, Reg_DPR + 0xff)))
  180.         {
  181.           AdrCnt = 1;
  182.           AdrType = Start;
  183.           AdrVals[0] = Lo(Adr - Reg_DPR);
  184.         }
  185.         break;
  186.       case 1:
  187.         if (!mFirstPassUnknown(Flags) && ((Adr >> 16) != BankReg)) WrError(ErrNum_OverRange);
  188.         else
  189.         {
  190.           AdrCnt = 2;
  191.           AdrType = Start + 1;
  192.           AdrVals[0] = Lo(Adr);
  193.           AdrVals[1] = Hi(Adr);
  194.         }
  195.         break;
  196.       case 2:
  197.         AdrCnt = 3;
  198.         AdrType = Start + 2;
  199.         AdrVals[0] = Lo(Adr);
  200.         AdrVals[1] = Hi(Adr);
  201.         AdrVals[2] = Adr >> 16;
  202.         break;
  203.     }
  204.   }
  205. }
  206.  
  207. static Integer SplitArg(const tStrComp *pSrc, tStrComp *pDest)
  208. {
  209.   tStrComp IArg;
  210.   char *p;
  211.  
  212.   StrCompRefRight(&IArg, pSrc, 1);
  213.   StrCompShorten(&IArg, 1);
  214.   p = QuotPos(IArg.str.p_str, ',');
  215.   if (!p)
  216.   {
  217.     StrCompCopy(&pDest[0], &IArg);
  218.     return 1;
  219.   }
  220.   else
  221.   {
  222.     StrCompSplitCopy(&pDest[0], &pDest[1], &IArg, p);
  223.     return 2;
  224.   }
  225. }
  226.  
  227. static void DecodeAdr(Integer Start, LongWord Mask)
  228. {
  229.   Word AdrWord;
  230.   Boolean OK;
  231.   Integer HCnt;
  232.   String HStr[2];
  233.   tStrComp HArg[2];
  234.  
  235.   StrCompMkTemp(&HArg[0], HStr[0], sizeof(HStr[0]));
  236.   StrCompMkTemp(&HArg[1], HStr[1], sizeof(HStr[1]));
  237.   AdrType = ModNone;
  238.   AdrCnt = 0;
  239.  
  240.   /* I. 1 Parameter */
  241.  
  242.   if (Start == ArgCnt)
  243.   {
  244.     /* I.1. immediate */
  245.  
  246.     if (*ArgStr[Start].str.p_str == '#')
  247.     {
  248.       if (WordSize)
  249.       {
  250.         AdrWord = EvalStrIntExpressionOffs(&ArgStr[Start], 1, Int16, &OK);
  251.         AdrVals[0] = Lo(AdrWord);
  252.         AdrVals[1] = Hi(AdrWord);
  253.       }
  254.       else
  255.         AdrVals[0] = EvalStrIntExpressionOffs(&ArgStr[Start], 1, Int8, &OK);
  256.       if (OK)
  257.       {
  258.         AdrCnt = 1 + Ord(WordSize);
  259.         AdrType = ModImm;
  260.       }
  261.       goto chk;
  262.     }
  263.  
  264.     /* I.2. indirekt */
  265.  
  266.     if (IsIndirect(ArgStr[Start].str.p_str))
  267.     {
  268.       HCnt = SplitArg(&ArgStr[Start], HArg);
  269.  
  270.       /* I.2.i. einfach indirekt */
  271.  
  272.       if (HCnt == 1)
  273.       {
  274.         CodeDisp(&HArg[0], ModInd8, Mask);
  275.         goto chk;
  276.       }
  277.  
  278.       /* I.2.ii indirekt mit Vorindizierung */
  279.  
  280.       else if (!as_strcasecmp(HArg[1].str.p_str, "X"))
  281.       {
  282.         CodeDisp(&HArg[0], ModIndX8, Mask);
  283.         goto chk;
  284.       }
  285.  
  286.       else
  287.       {
  288.         WrError(ErrNum_InvAddrMode);
  289.         goto chk;
  290.       }
  291.     }
  292.  
  293.     /* I.3. absolut */
  294.  
  295.     else
  296.     {
  297.       CodeDisp(&ArgStr[Start], ModAbs8, Mask);
  298.       goto chk;
  299.     }
  300.   }
  301.  
  302.   /* II. 2 Parameter */
  303.  
  304.   else if (Start + 1 == ArgCnt)
  305.   {
  306.     /* II.1 indirekt mit Nachindizierung */
  307.  
  308.     if (IsIndirect(ArgStr[Start].str.p_str))
  309.     {
  310.       if (as_strcasecmp(ArgStr[Start + 1].str.p_str, "Y")) WrError(ErrNum_InvAddrMode);
  311.       else
  312.       {
  313.         HCnt = SplitArg(&ArgStr[Start], HArg);
  314.  
  315.         /* II.1.i. (d),Y */
  316.  
  317.         if (HCnt == 1)
  318.         {
  319.           CodeDisp(&HArg[0], ModIndY8, Mask);
  320.           goto chk;
  321.         }
  322.  
  323.         /* II.1.ii. (d,S),Y */
  324.  
  325.         else if (!as_strcasecmp(HArg[1].str.p_str, "S"))
  326.         {
  327.           AdrVals[0] = EvalStrIntExpression(&HArg[0], Int8, &OK);
  328.           if (OK)
  329.           {
  330.             AdrType = ModIndS8;
  331.             AdrCnt = 1;
  332.           }
  333.           goto chk;
  334.         }
  335.  
  336.         else WrError(ErrNum_InvAddrMode);
  337.       }
  338.       goto chk;
  339.     }
  340.  
  341.     /* II.2. einfach indiziert */
  342.  
  343.     else
  344.     {
  345.       /* II.2.i. d,X */
  346.  
  347.       if (!as_strcasecmp(ArgStr[Start + 1].str.p_str, "X"))
  348.       {
  349.         CodeDisp(&ArgStr[Start], ModIdxX8, Mask);
  350.         goto chk;
  351.       }
  352.  
  353.       /* II.2.ii. d,Y */
  354.  
  355.       else if (!as_strcasecmp(ArgStr[Start + 1].str.p_str, "Y"))
  356.       {
  357.         CodeDisp(&ArgStr[Start], ModIdxY8, Mask);
  358.         goto chk;
  359.       }
  360.  
  361.       /* II.2.iii. d,S */
  362.  
  363.       else if (!as_strcasecmp(ArgStr[Start + 1].str.p_str, "S"))
  364.       {
  365.         AdrVals[0] = EvalStrIntExpression(&ArgStr[Start], Int8, &OK);
  366.         if (OK)
  367.         {
  368.           AdrType = ModIdxS8;
  369.           AdrCnt = 1;
  370.         }
  371.         goto chk;
  372.       }
  373.  
  374.       else WrError(ErrNum_InvAddrMode);
  375.     }
  376.   }
  377.  
  378.   else
  379.     (void)ChkArgCnt(Start, Start + 1);
  380.  
  381. chk:
  382.   if ((AdrType != ModNone)
  383.    && (!(Mask & (1l << ((LongWord)AdrType)))))
  384.    {
  385.      AdrType = ModNone;
  386.      AdrCnt = 0;
  387.      WrError(ErrNum_InvAddrMode);
  388.    }
  389. }
  390.  
  391. static Boolean CPUMatch(Byte Mask)
  392. {
  393.   return ((Mask >> (MomCPU - CPU65816)) & 1);
  394. }
  395.  
  396. /*---------------------------------------------------------------------------*/
  397.  
  398. /* see my rant about BRK in code65.c */
  399.  
  400. static void DecodeBRK(Word Code)
  401. {
  402.   UNUSED(Code);
  403.  
  404.   if (ChkArgCnt(0, 1))
  405.   {
  406.     BAsmCode[0] = 0x00;
  407.     if (ArgCnt > 0)
  408.     {
  409.       Boolean OK;
  410.  
  411.       BAsmCode[1] = EvalStrIntExpressionOffs(&ArgStr[1], !!(*ArgStr[1].str.p_str == '#'), Int8, &OK);
  412.       if (OK)
  413.         CodeLen = 2;
  414.     }
  415.     else
  416.       CodeLen = 1;
  417.   }
  418. }
  419.  
  420. static void DecodeFixed(Word Code)
  421. {
  422.   if (ChkArgCnt(0, 0))
  423.   {
  424.     CodeLen = 1 + Ord(Hi(Code) != 0);
  425.     if (CodeLen == 2)
  426.       BAsmCode[0] = Hi(Code);
  427.     BAsmCode[CodeLen - 1] = Lo(Code);
  428.   }
  429. }
  430.  
  431. static void DecodePHB_PLB(Word Code)
  432. {
  433.   if (ChkArgCnt(0, 0))
  434.   {
  435.     if (MomCPU >= CPUM7700)
  436.     {
  437.       CodeLen = 2;
  438.       BAsmCode[0] = PrefAccB;
  439.       BAsmCode[1] = 0x48;
  440.     }
  441.     else
  442.     {
  443.       CodeLen = 1;
  444.       BAsmCode[0] = 0x8b;
  445.     }
  446.     BAsmCode[CodeLen - 1] += Code;
  447.   }
  448. }
  449.  
  450. static void DecodeRel(Word Index)
  451. {
  452.   const RelOrder *pOrder = RelOrders + Index;
  453.   LongInt AdrLong;
  454.   Boolean OK;
  455.   tSymbolFlags Flags;
  456.  
  457.   if (ChkArgCnt(1, 1))
  458.   {
  459.     AdrLong = EvalStrIntExpressionOffsWithFlags(&ArgStr[1], !!(*ArgStr[1].str.p_str == '#'), Int32, &OK, &Flags);
  460.     if (OK)
  461.     {
  462.       OK = pOrder->Disp8 == -1;
  463.       if (OK)
  464.         AdrLong -= EProgCounter() + pOrder->Disp16;
  465.       else
  466.       {
  467.         AdrLong -= EProgCounter() + pOrder->Disp8;
  468.         if (((AdrLong > 127) || (AdrLong < -128)) && !mSymbolQuestionable(Flags) && (pOrder->Disp16 != -1))
  469.         {
  470.           OK = True;
  471.           AdrLong -= pOrder->Disp16 - pOrder->Disp8;
  472.         }
  473.       }
  474.       if (OK)            /* d16 */
  475.       {
  476.         if (((AdrLong < -32768) || (AdrLong > 32767)) && !mSymbolQuestionable(Flags)) WrError(ErrNum_DistTooBig);
  477.         else
  478.         {
  479.           CodeLen = 3;
  480.           BAsmCode[0] = Hi(pOrder->Code);
  481.           BAsmCode[1] = Lo(AdrLong);
  482.           BAsmCode[2] = Hi(AdrLong);
  483.         }
  484.       }
  485.       else               /* d8 */
  486.       {
  487.         if (((AdrLong < -128) || (AdrLong > 127)) && !mSymbolQuestionable(Flags)) WrError(ErrNum_JmpDistTooBig);
  488.         else
  489.         {
  490.           CodeLen = 2;
  491.           BAsmCode[0] = Lo(pOrder->Code);
  492.           BAsmCode[1] = Lo(AdrLong);
  493.         }
  494.       }
  495.     }
  496.   }
  497. }
  498.  
  499. static void DecodeAcc(Word Code)
  500. {
  501.   int Start;
  502.   Boolean LFlag = Hi(Code);
  503.   Code = Lo(Code);
  504.  
  505.   if (ChkArgCnt(1, 3))
  506.   {
  507.     WordSize = (Reg_M == 0);
  508.     if (!as_strcasecmp(ArgStr[1].str.p_str, "A"))
  509.       Start = 2;
  510.     else if (!as_strcasecmp(ArgStr[1].str.p_str, "B"))
  511.     {
  512.       Start = 2;
  513.       BAsmCode[0] = PrefAccB;
  514.       CodeLen++;
  515.       if (!ChkExcludeCPUExt(CPU65816, ErrNum_AddrModeNotSupported))
  516.         return;
  517.     }
  518.     else
  519.       Start = 1;
  520.     DecodeAdr(Start,
  521.               MModAbs8 | MModAbs16 | MModAbs24
  522.             | MModIdxX8 | MModIdxX16 | MModIdxX24
  523.             | MModIdxY16
  524.             | MModInd8 | MModIndX8 | MModIndY8
  525.             | MModIdxS8 | MModIndS8
  526.             | ((Code == 0x80) ? 0 : MModImm)); /* STA */
  527.     if (AdrType != ModNone)
  528.     {
  529.       if ((LFlag) && (AdrType != ModInd8) && (AdrType != ModIndY8)) WrError(ErrNum_InvAddrMode);
  530.       else
  531.       {
  532.         switch (AdrType)
  533.         {
  534.           case ModImm:
  535.             BAsmCode[CodeLen] = Code + 0x09;
  536.             break;
  537.           case ModAbs8:
  538.             BAsmCode[CodeLen] = Code + 0x05;
  539.             break;
  540.           case ModAbs16:
  541.             BAsmCode[CodeLen] = Code + 0x0d;
  542.             break;
  543.           case ModAbs24:
  544.             BAsmCode[CodeLen] = Code + 0x0f;
  545.             break;
  546.           case ModIdxX8:
  547.             BAsmCode[CodeLen] = Code + 0x15;
  548.             break;
  549.           case ModIdxX16:
  550.             BAsmCode[CodeLen] = Code + 0x1d;
  551.             break;
  552.           case ModIdxX24:
  553.             BAsmCode[CodeLen] = Code + 0x1f;
  554.             break;
  555.           case ModIdxY16:
  556.             BAsmCode[CodeLen] = Code + 0x19;
  557.             break;
  558.           case ModInd8:
  559.             BAsmCode[CodeLen] = LFlag ? Code + 0x07 : Code + 0x12;
  560.             break;
  561.           case ModIndX8:
  562.             BAsmCode[CodeLen] = Code + 0x01;
  563.             break;
  564.           case ModIndY8:
  565.             BAsmCode[CodeLen] = (LFlag) ? Code + 0x17 : Code + 0x11;
  566.             break;
  567.           case ModIdxS8:
  568.             BAsmCode[CodeLen] = Code + 0x03;
  569.             break;
  570.           case ModIndS8:
  571.             BAsmCode[CodeLen] = Code + 0x13;
  572.             break;
  573.         }
  574.         memcpy(BAsmCode + CodeLen + 1, AdrVals, AdrCnt);
  575.         CodeLen += 1 + AdrCnt;
  576.       }
  577.     }
  578.   }
  579. }
  580.  
  581. static void DecodeEXTS_EXTZ(Word Code)
  582. {
  583.   if (ArgCnt == 0)
  584.   {
  585.     const char AccArg[] = "A";
  586.  
  587.     AppendArg(strlen(AccArg));
  588.     strmaxcpy(ArgStr[ArgCnt].str.p_str, AccArg, STRINGSIZE);
  589.   }
  590.  
  591.   if (ChkArgCnt(1, 1)
  592.    && ChkMinCPU(CPUM7750))
  593.   {
  594.     BAsmCode[1] = Code;
  595.     BAsmCode[0] = 0;
  596.     if (!as_strcasecmp(ArgStr[1].str.p_str, "A"))
  597.       BAsmCode[0] = 0x89;
  598.     else if (!as_strcasecmp(ArgStr[1].str.p_str, "B"))
  599.       BAsmCode[0] = 0x42;
  600.     else WrError(ErrNum_InvAddrMode);
  601.     if (BAsmCode[0] != 0)
  602.       CodeLen = 2;
  603.   }
  604. }
  605.  
  606. static void DecodeRMW(Word Code)
  607. {
  608.   if ((ArgCnt == 0) || ((ArgCnt == 1) && (!as_strcasecmp(ArgStr[1].str.p_str, "A"))))
  609.   {
  610.     CodeLen = 1;
  611.     BAsmCode[0] = Hi(Code);
  612.   }
  613.   else if ((ArgCnt == 1) && (!as_strcasecmp(ArgStr[1].str.p_str, "B")))
  614.   {
  615.     CodeLen = 2;
  616.     BAsmCode[0] = PrefAccB;
  617.     BAsmCode[1] = Hi(Code);
  618.     if (!ChkExcludeCPUExt(CPU65816, ErrNum_AddrModeNotSupported))
  619.       return;
  620.   }
  621.   else if (!ChkArgCnt(0, 2));
  622.   else
  623.   {
  624.     DecodeAdr(1, MModAbs8 | MModAbs16 | MModIdxX8 | MModIdxX16);
  625.     if (AdrType != ModNone)
  626.     {
  627.       switch (AdrType)
  628.       {
  629.         case ModAbs8:
  630.           BAsmCode[0] = Lo(Code);
  631.           break;
  632.         case ModAbs16:
  633.           BAsmCode[0] = Lo(Code) + 8;
  634.           break;
  635.         case ModIdxX8:
  636.           BAsmCode[0] = Lo(Code) + 16;
  637.           break;
  638.         case ModIdxX16:
  639.           BAsmCode[0] = Lo(Code) + 24;
  640.           break;
  641.       }
  642.       memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  643.       CodeLen = 1 + AdrCnt;
  644.     }
  645.   }
  646. }
  647.  
  648. static void DecodeASR(Word Code)
  649. {
  650.   UNUSED(Code);
  651.  
  652.   if (!ChkMinCPU(CPUM7750));
  653.   else if ((ArgCnt == 0) || ((ArgCnt == 1) && (!as_strcasecmp(ArgStr[1].str.p_str, "A"))))
  654.   {
  655.     BAsmCode[0] = 0x89;
  656.     BAsmCode[1] = 0x08;
  657.     CodeLen = 2;
  658.   }
  659.   else if ((ArgCnt == 1) && (!as_strcasecmp(ArgStr[1].str.p_str, "B")))
  660.   {
  661.     BAsmCode[0] = 0x42;
  662.     BAsmCode[1] = 0x08;
  663.     CodeLen = 2;
  664.   }
  665.   else if (ChkArgCnt(1, 2))
  666.   {
  667.     DecodeAdr(1, MModAbs8 | MModIdxX8 | MModAbs16 | MModIdxX16);
  668.     if (AdrType != ModNone)
  669.     {
  670.       BAsmCode[0] = 0x89;
  671.       switch (AdrType)
  672.       {
  673.         case ModAbs8:
  674.           BAsmCode[1] = 0x06;
  675.           break;
  676.         case ModIdxX8:
  677.           BAsmCode[1] = 0x16;
  678.           break;
  679.         case ModAbs16:
  680.           BAsmCode[1] = 0x0e;
  681.           break;
  682.         case ModIdxX16:
  683.           BAsmCode[1] = 0x1e;
  684.           break;
  685.       }
  686.       memcpy(BAsmCode + 2, AdrVals, AdrCnt);
  687.       CodeLen = 2 + AdrCnt;
  688.     }
  689.   }
  690. }
  691.  
  692. static void DecodeBBC_BBS(Word Code)
  693. {
  694.   if (ChkArgCnt(3, 3)
  695.    && ChkMinCPU(CPUM7700))
  696.   {
  697.     WordSize = (Reg_M == 0);
  698.     ArgCnt = 2;
  699.     DecodeAdr(2, MModAbs8 + MModAbs16);
  700.     if (AdrType != ModNone)
  701.     {
  702.       BAsmCode[0] = Code + ((AdrType == ModAbs16) ? 8 : 0);
  703.       memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  704.       CodeLen = 1 + AdrCnt;
  705.       ArgCnt = 1;
  706.       DecodeAdr(1, MModImm);
  707.       if (AdrType == ModNone)
  708.         CodeLen = 0;
  709.       else
  710.       {
  711.         LongInt AdrLong;
  712.         Boolean OK;
  713.         tSymbolFlags Flags;
  714.  
  715.         memcpy(BAsmCode + CodeLen, AdrVals, AdrCnt);
  716.         CodeLen += AdrCnt;
  717.         AdrLong = EvalStrIntExpressionWithFlags(&ArgStr[3], UInt24, &OK, &Flags) - (EProgCounter() + CodeLen + 1);
  718.         if (!OK)
  719.           CodeLen = 0;
  720.         else if (!mSymbolQuestionable(Flags) && ((AdrLong < -128) || (AdrLong > 127)))
  721.         {
  722.           WrError(ErrNum_JmpDistTooBig);
  723.           CodeLen = 0;
  724.         }
  725.         else
  726.         {
  727.           BAsmCode[CodeLen] = Lo(AdrLong);
  728.           CodeLen++;
  729.         }
  730.       }
  731.     }
  732.   }
  733. }
  734.  
  735. static void DecodeBIT(Word Code)
  736. {
  737.   UNUSED(Code);
  738.  
  739.   if (ChkArgCnt(1, 2)
  740.    && ChkExactCPU(CPU65816))
  741.   {
  742.     WordSize = (Reg_M == 0);
  743.     DecodeAdr(1, MModAbs8 | MModAbs16 | MModIdxX8 | MModIdxX16 | MModImm);
  744.     if (AdrType != ModNone)
  745.     {
  746.       switch (AdrType)
  747.       {
  748.         case ModAbs8:
  749.           BAsmCode[0] = 0x24;
  750.           break;
  751.         case ModAbs16:
  752.           BAsmCode[0] = 0x2c;
  753.           break;
  754.         case ModIdxX8:
  755.           BAsmCode[0] = 0x34;
  756.           break;
  757.         case ModIdxX16:
  758.           BAsmCode[0] = 0x3c;
  759.           break;
  760.         case ModImm:
  761.           BAsmCode[0] = 0x89;
  762.           break;
  763.       }
  764.       memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  765.       CodeLen = 1 + AdrCnt;
  766.     }
  767.   }
  768. }
  769.  
  770. static void DecodeCLB_SEB(Word Code)
  771. {
  772.   if (ChkArgCnt(2, 2)
  773.    && ChkMinCPU(CPUM7700))
  774.   {
  775.     WordSize = (Reg_M == 0);
  776.     DecodeAdr(2, MModAbs8 | MModAbs16);
  777.     if (AdrType != ModNone)
  778.     {
  779.       BAsmCode[0] = Code + ((AdrType == ModAbs16) ? 8 : 0);
  780.       memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  781.       CodeLen = 1 + AdrCnt;
  782.       ArgCnt = 1;
  783.       DecodeAdr(1, MModImm);
  784.       if (AdrType == ModNone)
  785.         CodeLen = 0;
  786.       else
  787.       {
  788.         memcpy(BAsmCode + CodeLen, AdrVals, AdrCnt);
  789.         CodeLen += AdrCnt;
  790.       }
  791.     }
  792.   }
  793. }
  794.  
  795. static void DecodeTSB_TRB(Word Code)
  796. {
  797.   if (MomCPU == CPU65816)
  798.   {
  799.     if (ChkArgCnt(1, 1))
  800.     {
  801.       DecodeAdr(1, MModAbs8 + MModAbs16);
  802.       if (AdrType != ModNone)
  803.       {
  804.         BAsmCode[0] = Code + ((AdrType == ModAbs16) ? 8 : 0);
  805.         memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  806.         CodeLen = 1 + AdrCnt;
  807.       }
  808.     }
  809.   }
  810.   else if (Code == 0x14) (void)ChkExactCPU(CPU65816); /* TRB */
  811.   else if (ChkArgCnt(0, 0))
  812.   {
  813.     CodeLen = 2;
  814.     BAsmCode[0] = 0x42;
  815.     BAsmCode[1] = 0x3b;
  816.   }
  817. }
  818.  
  819. static void DecodeImm8(Word Code)
  820. {
  821.   if (ChkArgCnt(1, 1))
  822.   {
  823.     WordSize = False;
  824.     DecodeAdr(1, MModImm);
  825.     if (AdrType == ModImm)
  826.     {
  827.       CodeLen = 1 + Ord(Hi(Code) != 0);
  828.       if (CodeLen == 2)
  829.         BAsmCode[0] = Hi(Code);
  830.       BAsmCode[CodeLen-1] = Lo(Code);
  831.       memcpy(BAsmCode + CodeLen, AdrVals, AdrCnt);
  832.       CodeLen += AdrCnt;
  833.     }
  834.   }
  835. }
  836.  
  837. static void DecodeRLA(Word Code)
  838. {
  839.   UNUSED(Code);
  840.  
  841.   if (ChkArgCnt(1, 1))
  842.   {
  843.     WordSize = (Reg_M == 0);
  844.     DecodeAdr(1, MModImm);
  845.     if (AdrType != ModNone)
  846.     {
  847.       CodeLen = 2 + AdrCnt;
  848.       BAsmCode[0] = 0x89;
  849.       BAsmCode[1] = 0x49;
  850.       memcpy(BAsmCode + 2, AdrVals, AdrCnt);
  851.     }
  852.   }
  853. }
  854.  
  855. static void DecodeXY(Word Index)
  856. {
  857.   const XYOrder *pOrder = XYOrders + Index;
  858.  
  859.   if (ChkArgCnt(1, 2))
  860.   {
  861.     WordSize = (Reg_X == 0);
  862.     DecodeAdr(1, ((pOrder->CodeImm    != 0xff) ? MModImm : 0)
  863.                | ((pOrder->CodeAbs8   != 0xff) ? MModAbs8 : 0)
  864.                | ((pOrder->CodeAbs16  != 0xff) ? MModAbs16 : 0)
  865.                | ((pOrder->CodeIdxX8  != 0xff) ? MModIdxX8 : 0)
  866.                | ((pOrder->CodeIdxX16 != 0xff) ? MModIdxX16 : 0)
  867.                | ((pOrder->CodeIdxY8  != 0xff) ? MModIdxY8 : 0)
  868.                | ((pOrder->CodeIdxY16 != 0xff) ? MModIdxY16 : 0));
  869.     if (AdrType != ModNone)
  870.     {
  871.       switch (AdrType)
  872.       {
  873.         case ModImm:
  874.           BAsmCode[0] = pOrder->CodeImm;
  875.           break;
  876.         case ModAbs8:
  877.           BAsmCode[0] = pOrder->CodeAbs8;
  878.           break;
  879.         case ModAbs16:
  880.           BAsmCode[0] = pOrder->CodeAbs16;
  881.           break;
  882.         case ModIdxX8:
  883.           BAsmCode[0] = pOrder->CodeIdxX8;
  884.           break;
  885.         case ModIdxY8:
  886.           BAsmCode[0] = pOrder->CodeIdxY8;
  887.           break;
  888.         case ModIdxX16:
  889.           BAsmCode[0] = pOrder->CodeIdxX16;
  890.           break;
  891.         case ModIdxY16:
  892.           BAsmCode[0] = pOrder->CodeIdxY16;
  893.           break;
  894.       }
  895.       memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  896.       CodeLen = 1 + AdrCnt;
  897.     }
  898.   }
  899. }
  900.  
  901. static void DecodeMulDiv(Word Code)
  902. {
  903.   Byte LFlag = Hi(Code);
  904.   Code = Lo(Code);
  905.  
  906.   if (ChkArgCnt(1, 2))
  907.   {
  908.     WordSize = (Reg_M == 0);
  909.     DecodeAdr(1, MModImm | MModAbs8 | MModAbs16 | MModAbs24 | MModIdxX8 | MModIdxX16
  910.                | MModIdxX24 | MModIdxY16 | MModInd8 | MModIndX8 | MModIndY8
  911.                | MModIdxS8 | MModIndS8);
  912.     if (AdrType != ModNone)
  913.     {
  914.       if ((LFlag) && (AdrType != ModInd8) && (AdrType != ModIndY8)) WrError(ErrNum_InvAddrMode);
  915.       else
  916.       {
  917.         BAsmCode[0] = 0x89;
  918.         switch (AdrType)
  919.         {
  920.           case ModImm:
  921.             BAsmCode[1] = 0x09;
  922.             break;
  923.           case ModAbs8:
  924.             BAsmCode[1] = 0x05;
  925.             break;
  926.           case ModAbs16:
  927.             BAsmCode[1] = 0x0d;
  928.             break;
  929.           case ModAbs24:
  930.             BAsmCode[1] = 0x0f;
  931.             break;
  932.           case ModIdxX8:
  933.             BAsmCode[1] = 0x15;
  934.             break;
  935.           case ModIdxX16:
  936.             BAsmCode[1] = 0x1d;
  937.             break;
  938.           case ModIdxX24:
  939.             BAsmCode[1] = 0x1f;
  940.             break;
  941.           case ModIdxY16:
  942.             BAsmCode[1] = 0x19;
  943.             break;
  944.           case ModInd8:
  945.             BAsmCode[1] = (LFlag) ? 0x07 : 0x12;
  946.             break;
  947.           case ModIndX8:
  948.             BAsmCode[1] = 0x01;
  949.             break;
  950.           case ModIndY8:
  951.             BAsmCode[1] = (LFlag) ? 0x17 : 0x11;
  952.             break;
  953.           case ModIdxS8:
  954.             BAsmCode[1] = 0x03;
  955.             break;
  956.           case ModIndS8:
  957.             BAsmCode[1] = 0x13;
  958.             break;
  959.         }
  960.         BAsmCode[1] += Code;
  961.         memcpy(BAsmCode + 2, AdrVals, AdrCnt);
  962.         CodeLen = 2 + AdrCnt;
  963.       }
  964.     }
  965.   }
  966. }
  967.  
  968. static void DecodeJML_JSL(Word Code)
  969. {
  970.   if (ChkArgCnt(1, 1))
  971.   {
  972.     Boolean OK;
  973.     LongInt AdrLong = EvalStrIntExpression(&ArgStr[1], UInt24, &OK);
  974.  
  975.     if (OK)
  976.     {
  977.       CodeLen = 4;
  978.       BAsmCode[0] = Code;
  979.       BAsmCode[3] = AdrLong >> 16;
  980.       BAsmCode[2] = Hi(AdrLong);
  981.       BAsmCode[1] = Lo(AdrLong);
  982.     }
  983.   }
  984. }
  985.  
  986. static void DecodeJMP_JSR(Word IsJSR)
  987. {
  988.   Byte LFlag = Hi(IsJSR);
  989.   IsJSR = Lo(IsJSR);
  990.  
  991.   if (ChkArgCnt(1, 1))
  992.   {
  993.     BankReg = Reg_PG;
  994.     DecodeAdr(1, MModAbs24 | MModIndX16
  995.                | (LFlag ? 0: MModAbs16)
  996.                | (IsJSR ? 0 : MModInd16));
  997.     if (AdrType != ModNone)
  998.     {
  999.       switch (AdrType)
  1000.       {
  1001.         case ModAbs16:
  1002.           BAsmCode[0] = IsJSR ? 0x20 : 0x4c;
  1003.           break;
  1004.         case ModAbs24:
  1005.           BAsmCode[0] = IsJSR ? 0x22 : 0x5c;
  1006.           break;
  1007.         case ModIndX16:
  1008.           BAsmCode[0] = IsJSR ? 0xfc : 0x7c;
  1009.           break;
  1010.         case ModInd16:
  1011.           BAsmCode[0] = LFlag ? 0xdc : 0x6c;
  1012.           break;
  1013.       }
  1014.       memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  1015.       CodeLen = 1 + AdrCnt;
  1016.     }
  1017.   }
  1018. }
  1019.  
  1020. static void DecodeLDM(Word Code)
  1021. {
  1022.   UNUSED(Code);
  1023.  
  1024.   if (ChkArgCnt(2, 3)
  1025.    && ChkMinCPU(CPUM7700))
  1026.   {
  1027.     DecodeAdr(2, MModAbs8 | MModAbs16 | MModIdxX8 | MModIdxX16);
  1028.     if (AdrType != ModNone)
  1029.     {
  1030.       switch (AdrType)
  1031.       {
  1032.         case ModAbs8:
  1033.           BAsmCode[0] = 0x64;
  1034.           break;
  1035.         case ModAbs16:
  1036.           BAsmCode[0] = 0x9c;
  1037.           break;
  1038.         case ModIdxX8:
  1039.           BAsmCode[0] = 0x74;
  1040.           break;
  1041.         case ModIdxX16:
  1042.           BAsmCode[0] = 0x9e;
  1043.           break;
  1044.       }
  1045.       memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  1046.       CodeLen = 1 + AdrCnt;
  1047.       WordSize = (Reg_M == 0);
  1048.       ArgCnt = 1;
  1049.       DecodeAdr(1, MModImm);
  1050.       if (AdrType == ModNone)
  1051.         CodeLen = 0;
  1052.       else
  1053.       {
  1054.         memcpy(BAsmCode + CodeLen, AdrVals, AdrCnt);
  1055.         CodeLen += AdrCnt;
  1056.       }
  1057.     }
  1058.   }
  1059. }
  1060.  
  1061. static void DecodeSTZ(Word Code)
  1062. {
  1063.   UNUSED(Code);
  1064.  
  1065.   if (ChkArgCnt(1, 2)
  1066.    && ChkMinCPU(CPU65816))
  1067.   {
  1068.     DecodeAdr(1, MModAbs8 | MModAbs16 | MModIdxX8 | MModIdxX16);
  1069.     if (AdrType != ModNone)
  1070.     {
  1071.       switch (AdrType)
  1072.       {
  1073.         case ModAbs8:
  1074.           BAsmCode[0] = 0x64;
  1075.           break;
  1076.         case ModAbs16:
  1077.           BAsmCode[0] = 0x9c;
  1078.           break;
  1079.         case ModIdxX8:
  1080.           BAsmCode[0] = 0x74;
  1081.           break;
  1082.         case ModIdxX16:
  1083.           BAsmCode[0] = 0x9e;
  1084.           break;
  1085.       }
  1086.       memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  1087.       CodeLen = 1 + AdrCnt;
  1088.     }
  1089.   }
  1090. }
  1091.  
  1092. static void DecodeMVN_MVP(Word Code)
  1093. {
  1094.   if (ChkArgCnt(2, 2))
  1095.   {
  1096.     Boolean OK;
  1097.     LongInt Src = EvalStrIntExpression(&ArgStr[1], UInt24, &OK);
  1098.  
  1099.     if (OK)
  1100.     {
  1101.       LongInt Dest = EvalStrIntExpression(&ArgStr[2], UInt24, &OK);
  1102.  
  1103.       if (OK)
  1104.       {
  1105.         BAsmCode[0] = Code;
  1106.         BAsmCode[1] = Dest >> 16;
  1107.         BAsmCode[2] = Src >> 16;
  1108.         CodeLen = 3;
  1109.       }
  1110.     }
  1111.   }
  1112. }
  1113.  
  1114. static void DecodePSH_PUL(Word Code)
  1115. {
  1116.   if (ChkArgCnt(0, 0)
  1117.    && ChkMinCPU(CPUM7700))
  1118.   {
  1119.     Boolean OK;
  1120.     int z, Start;
  1121.  
  1122.     BAsmCode[0] = Code;
  1123.     BAsmCode[1] = 0;
  1124.     OK = True;
  1125.     z = 1;
  1126.     while ((z <= ArgCnt) && (OK))
  1127.     {
  1128.       Boolean OK;
  1129.  
  1130.       if (*ArgStr[z].str.p_str == '#')
  1131.         BAsmCode[1] |= EvalStrIntExpressionOffs(&ArgStr[z], 1, Int8, &OK);
  1132.       else
  1133.       {
  1134.         Start = 0;
  1135.         while ((Start < PushRegCnt) && (as_strcasecmp(PushRegNames[Start], ArgStr[z].str.p_str)))
  1136.           Start++;
  1137.         OK = (Start < PushRegCnt);
  1138.         if (OK)
  1139.           BAsmCode[1] |= 1l << PushRegCodes[Start];
  1140.         else
  1141.           WrStrErrorPos(ErrNum_InvRegName, &ArgStr[z]);
  1142.       }
  1143.       z++;
  1144.     }
  1145.     if (OK)
  1146.       CodeLen = 2;
  1147.   }
  1148. }
  1149.  
  1150. static void DecodePEA(Word Code)
  1151. {
  1152.   UNUSED(Code);
  1153.  
  1154.   WordSize = True;
  1155.   if (ChkArgCnt(1, 1))
  1156.   {
  1157.     DecodeAdr(1, MModAbs16);
  1158.     if (AdrType != ModNone)
  1159.     {
  1160.       CodeLen = 1 + AdrCnt;
  1161.       BAsmCode[0] = 0xf4;
  1162.       memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  1163.     }
  1164.   }
  1165. }
  1166.  
  1167. static void DecodePEI(Word Code)
  1168. {
  1169.   UNUSED(Code);
  1170.  
  1171.   if (ChkArgCnt(1, 1))
  1172.   {
  1173.     DecodeAdr(1, MModInd8);
  1174.     if (AdrType != ModNone)
  1175.     {
  1176.       CodeLen = 1 + AdrCnt; BAsmCode[0] = 0xd4;
  1177.       memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  1178.     }
  1179.   }
  1180. }
  1181.  
  1182. static void DecodePER(Word Code)
  1183. {
  1184.   UNUSED(Code);
  1185.  
  1186.   if (ChkArgCnt(1, 1))
  1187.   {
  1188.     Boolean OK, Rel = !(*ArgStr[1].str.p_str == '#');
  1189.     tSymbolFlags Flags;
  1190.  
  1191.     BAsmCode[0] = 0x62;
  1192.     if (Rel)
  1193.     {
  1194.       LongInt AdrLong = EvalStrIntExpressionWithFlags(&ArgStr[1], UInt24, &OK, &Flags) - (EProgCounter() + 3);
  1195.  
  1196.       if (OK)
  1197.       {
  1198.         if (((AdrLong < -32768) || (AdrLong > 32767)) && !mSymbolQuestionable(Flags)) WrError(ErrNum_JmpDistTooBig);
  1199.         else
  1200.         {
  1201.           CodeLen = 3;
  1202.           BAsmCode[1] = AdrLong & 0xff;
  1203.           BAsmCode[2] = (AdrLong >> 8) & 0xff;
  1204.         }
  1205.       }
  1206.     }
  1207.     else
  1208.     {
  1209.       Word AdrWord = EvalStrIntExpressionOffs(&ArgStr[1], 1, Int16, &OK);
  1210.  
  1211.       if (OK)
  1212.       {
  1213.         CodeLen = 3;
  1214.         BAsmCode[1] = Lo(AdrWord);
  1215.         BAsmCode[2] = Hi(AdrWord);
  1216.       }
  1217.     }
  1218.   }
  1219. }
  1220.  
  1221. /*---------------------------------------------------------------------------*/
  1222.  
  1223. static void AddFixed(const char *NName, Word NCode, Byte NAllowed)
  1224. {
  1225.   if (CPUMatch(NAllowed))
  1226.     AddInstTable(InstTable, NName, NCode, DecodeFixed);
  1227. }
  1228.  
  1229. static void AddRel(const char *NName, Word NCode, ShortInt NDisp8, ShortInt NDisp16)
  1230. {
  1231.   order_array_rsv_end(RelOrders, RelOrder);
  1232.   RelOrders[InstrZ].Code = NCode;
  1233.   RelOrders[InstrZ].Disp8 = NDisp8;
  1234.   RelOrders[InstrZ].Disp16 = NDisp16;
  1235.   AddInstTable(InstTable, NName, InstrZ++, DecodeRel);
  1236. }
  1237.  
  1238. static void AddAcc(const char *NName, Byte NCode)
  1239. {
  1240.   char Tmp[30];
  1241.  
  1242.   AddInstTable(InstTable, NName, NCode, DecodeAcc);
  1243.   as_snprintf(Tmp, sizeof(Tmp), "%sL", NName);
  1244.   AddInstTable(InstTable, Tmp, 0x0100 | NCode, DecodeAcc);
  1245. }
  1246.  
  1247. static void AddRMW(const char *NName, Word NACode, Word NMCode)
  1248. {
  1249.   AddInstTable(InstTable, NName, NACode << 8 | NMCode, DecodeRMW);
  1250. }
  1251.  
  1252. static void AddImm8(const char *NName, Word NCode, Byte NAllowed)
  1253. {
  1254.   if (CPUMatch(NAllowed))
  1255.     AddInstTable(InstTable, NName, NCode, DecodeImm8);
  1256. }
  1257.  
  1258. static void AddXY(const char *NName, Byte NCodeImm, Byte NCodeAbs8, Byte NCodeAbs16,
  1259.                   Byte NCodeIdxX8, Byte NCodeIdxX16, Byte NCodeIdxY8,
  1260.                   Byte NCodeIdxY16)
  1261. {
  1262.   order_array_rsv_end(XYOrders, XYOrder);
  1263.   XYOrders[InstrZ].CodeImm = NCodeImm;
  1264.   XYOrders[InstrZ].CodeAbs8 = NCodeAbs8;
  1265.   XYOrders[InstrZ].CodeAbs16 = NCodeAbs16;
  1266.   XYOrders[InstrZ].CodeIdxX8 = NCodeIdxX8;
  1267.   XYOrders[InstrZ].CodeIdxX16 = NCodeIdxX16;
  1268.   XYOrders[InstrZ].CodeIdxY8 = NCodeIdxY8;
  1269.   XYOrders[InstrZ].CodeIdxY16 = NCodeIdxY16;
  1270.   AddInstTable(InstTable, NName, InstrZ++, DecodeXY);
  1271. }
  1272.  
  1273. static void AddMulDiv(const char *NName, Word NCode, Byte NAllowed)
  1274. {
  1275.   if (CPUMatch(NAllowed))
  1276.   {
  1277.     char Tmp[30];
  1278.  
  1279.     AddInstTable(InstTable, NName, NCode, DecodeMulDiv);
  1280.     as_snprintf(Tmp, sizeof(Tmp), "%sL", NName);
  1281.     AddInstTable(InstTable, Tmp, 0x0100 | NCode, DecodeMulDiv);
  1282.   }
  1283. }
  1284.  
  1285. static void InitFields(void)
  1286. {
  1287.   InstTable = CreateInstTable(403);
  1288.   SetDynamicInstTable(InstTable);
  1289.  
  1290.   AddInstTable(InstTable, "BRK", 0, DecodeBRK);
  1291.   AddInstTable(InstTable, "PHB", 0, DecodePHB_PLB);
  1292.   AddInstTable(InstTable, "PLB", 0x20, DecodePHB_PLB);
  1293.   AddInstTable(InstTable, "EXTS", 0x8b, DecodeEXTS_EXTZ);
  1294.   AddInstTable(InstTable, "EXTZ", 0xab, DecodeEXTS_EXTZ);
  1295.   AddInstTable(InstTable, "ASR", 0, DecodeASR);
  1296.   AddInstTable(InstTable, "BBC", 0x34, DecodeBBC_BBS);
  1297.   AddInstTable(InstTable, "BBS", 0x24, DecodeBBC_BBS);
  1298.   AddInstTable(InstTable, "BIT", 0, DecodeBIT);
  1299.   AddInstTable(InstTable, "CLB", 0x14, DecodeCLB_SEB);
  1300.   AddInstTable(InstTable, "SEB", 0x04, DecodeCLB_SEB);
  1301.   AddInstTable(InstTable, "TSB", 0x04, DecodeTSB_TRB);
  1302.   AddInstTable(InstTable, "TRB", 0x14, DecodeTSB_TRB);
  1303.   AddInstTable(InstTable, "RLA", 0, DecodeRLA);
  1304.   AddInstTable(InstTable, "JML", 0x5c, DecodeJML_JSL);
  1305.   AddInstTable(InstTable, "JSL", 0x22, DecodeJML_JSL);
  1306.   AddInstTable(InstTable, "JMP", 0x0000, DecodeJMP_JSR);
  1307.   AddInstTable(InstTable, "JSR", 0x0001, DecodeJMP_JSR);
  1308.   AddInstTable(InstTable, "JMPL", 0x0100, DecodeJMP_JSR);
  1309.   AddInstTable(InstTable, "JSRL", 0x0101, DecodeJMP_JSR);
  1310.   AddInstTable(InstTable, "LDM", 0, DecodeLDM);
  1311.   AddInstTable(InstTable, "STZ", 0, DecodeSTZ);
  1312.   AddInstTable(InstTable, "MVN", 0x54, DecodeMVN_MVP);
  1313.   AddInstTable(InstTable, "MVP", 0x44, DecodeMVN_MVP);
  1314.   AddInstTable(InstTable, "PSH", 0xeb, DecodePSH_PUL);
  1315.   AddInstTable(InstTable, "PUL", 0xfb, DecodePSH_PUL);
  1316.   AddInstTable(InstTable, "PEA", 0, DecodePEA);
  1317.   AddInstTable(InstTable, "PEI", 0, DecodePEI);
  1318.   AddInstTable(InstTable, "PER", 0, DecodePER);
  1319.  
  1320.   AddFixed("CLC", 0x0018, 15); AddFixed("CLI", 0x0058, 15);
  1321.   AddFixed("CLM", 0x00d8, 14); AddFixed("CLV", 0x00b8, 15);
  1322.   AddFixed("DEX", 0x00ca, 15); AddFixed("DEY", 0x0088, 15);
  1323.   AddFixed("INX", 0x00e8, 15); AddFixed("INY", 0x00c8, 15);
  1324.   AddFixed("NOP", 0x00ea, 15); AddFixed("PHA", 0x0048, 15);
  1325.   AddFixed("PHD", 0x000b, 15); AddFixed("PHG", 0x004b, 14);
  1326.   AddFixed("PHP", 0x0008, 15); AddFixed("PHT", 0x008b, 14);
  1327.   AddFixed("PHX", 0x00da, 15); AddFixed("PHY", 0x005a, 15);
  1328.   AddFixed("PLA", 0x0068, 15); AddFixed("PLD", 0x002b, 15);
  1329.   AddFixed("PLP", 0x0028, 15); AddFixed("PLT", 0x00ab, 14);
  1330.   AddFixed("PLX", 0x00fa, 15); AddFixed("PLY", 0x007a, 15);
  1331.   AddFixed("RTI", 0x0040, 15); AddFixed("RTL", 0x006b, 15);
  1332.   AddFixed("RTS", 0x0060, 15); AddFixed("SEC", 0x0038, 15);
  1333.   AddFixed("SEI", 0x0078, 15); AddFixed("SEM", 0x00f8, 14);
  1334.   AddFixed("STP", 0x00db, 15); AddFixed("TAD", 0x005b, 15);
  1335.   AddFixed("TAS", 0x001b, 15); AddFixed("TAX", 0x00aa, 15);
  1336.   AddFixed("TAY", 0x00a8, 15); AddFixed("TBD", 0x425b, 14);
  1337.   AddFixed("TBS", 0x421b, 14); AddFixed("TBX", 0x42aa, 14);
  1338.   AddFixed("TBY", 0x42a8, 14); AddFixed("TDA", 0x007b, 15);
  1339.   AddFixed("TDB", 0x427b, 14); AddFixed("TSA", 0x003b, 15);
  1340.   AddFixed("TSX", 0x00ba, 15); AddFixed("TXA", 0x008a, 15);
  1341.   AddFixed("TXB", 0x428a, 14); AddFixed("TXS", 0x009a, 15);
  1342.   AddFixed("TXY", 0x009b, 15); AddFixed("TYA", 0x0098, 15);
  1343.   AddFixed("TYB", 0x4298, 15); AddFixed("TYX", 0x00bb, 15);
  1344.   AddFixed("WIT", 0x00cb, 14); AddFixed("XAB", 0x8928, 14);
  1345.   AddFixed("CLD", 0x00d8,  1); AddFixed("SED", 0x00f8,  1);
  1346.   AddFixed("TCS", 0x001b, 15); AddFixed("TSC", 0x003b, 15);
  1347.   AddFixed("TCD", 0x005b, 15); AddFixed("TDC", 0x007b, 15);
  1348.   AddFixed("PHK", 0x004b,  1); AddFixed("WAI", 0x00cb,  1);
  1349.   AddFixed("XBA", 0x00eb,  1); AddFixed("SWA", 0x00eb,  1);
  1350.   AddFixed("XCE", 0x00fb,  1);
  1351.   AddFixed("DEA", (MomCPU >= CPUM7700) ? 0x001a : 0x003a, 15);
  1352.   AddFixed("INA", (MomCPU >= CPUM7700) ? 0x003a : 0x001a, 15);
  1353.  
  1354.   InstrZ = 0;
  1355.   AddRel("BCC" , 0x0090,  2, -1);
  1356.   AddRel("BLT" , 0x0090,  2, -1);
  1357.   AddRel("BCS" , 0x00b0,  2, -1);
  1358.   AddRel("BGE" , 0x00b0,  2, -1);
  1359.   AddRel("BEQ" , 0x00f0,  2, -1);
  1360.   AddRel("BMI" , 0x0030,  2, -1);
  1361.   AddRel("BNE" , 0x00d0,  2, -1);
  1362.   AddRel("BPL" , 0x0010,  2, -1);
  1363.   AddRel("BRA" , 0x8280,  2,  3);
  1364.   AddRel("BVC" , 0x0050,  2, -1);
  1365.   AddRel("BVS" , 0x0070,  2, -1);
  1366.   AddRel("BRL" , 0x8200, -1,  3);
  1367.   AddRel("BRAL", 0x8200, -1,  3);
  1368.  
  1369.   AddAcc("ADC", 0x60);
  1370.   AddAcc("AND", 0x20);
  1371.   AddAcc("CMP", 0xc0);
  1372.   AddAcc("CPA", 0xc0);
  1373.   AddAcc("EOR", 0x40);
  1374.   AddAcc("LDA", 0xa0);
  1375.   AddAcc("ORA", 0x00);
  1376.   AddAcc("SBC", 0xe0);
  1377.   AddAcc("STA", 0x80);
  1378.  
  1379.   AddRMW("ASL", 0x0a, 0x06);
  1380.   AddRMW("DEC", (MomCPU >= CPUM7700) ? 0x1a : 0x3a, 0xc6);
  1381.   AddRMW("ROL", 0x2a, 0x26);
  1382.   AddRMW("INC", (MomCPU >= CPUM7700) ? 0x3a : 0x1a, 0xe6);
  1383.   AddRMW("LSR", 0x4a, 0x46);
  1384.   AddRMW("ROR", 0x6a, 0x66);
  1385.  
  1386.   AddImm8("CLP", 0x00c2, 15);
  1387.   AddImm8("REP", 0x00c2, 15);
  1388.   AddImm8("LDT", 0x89c2, 14);
  1389.   AddImm8("SEP", 0x00e2, 15);
  1390.   AddImm8("RMPA", 0x89e2, 8);
  1391.   AddImm8("COP", 0x0002, 1);
  1392.  
  1393.   InstrZ = 0;
  1394.   AddXY("CPX", 0xe0, 0xe4, 0xec, 0xff, 0xff, 0xff, 0xff);
  1395.   AddXY("CPY", 0xc0, 0xc4, 0xcc, 0xff, 0xff, 0xff, 0xff);
  1396.   AddXY("LDX", 0xa2, 0xa6, 0xae, 0xff, 0xff, 0xb6, 0xbe);
  1397.   AddXY("LDY", 0xa0, 0xa4, 0xac, 0xb4, 0xbc, 0xff, 0xff);
  1398.   AddXY("STX", 0xff, 0x86, 0x8e, 0xff, 0xff, 0x96, 0xff);
  1399.   AddXY("STY", 0xff, 0x84, 0x8c, 0x94, 0xff, 0xff, 0xff);
  1400.  
  1401.   AddMulDiv("MPY", 0x0000, 14); AddMulDiv("MPYS", 0x0080, 12);
  1402.   AddMulDiv("DIV", 0x0020, 14); AddMulDiv("DIVS", 0x00a0, 12); /*???*/
  1403.  
  1404.   init_moto8_pseudo(InstTable, e_moto_8_le | e_moto_8_ddb);
  1405. }
  1406.  
  1407. static void DeinitFields(void)
  1408. {
  1409.   DestroyInstTable(InstTable);
  1410.  
  1411.   order_array_free(RelOrders);
  1412.   order_array_free(XYOrders);
  1413. }
  1414.  
  1415. static void MakeCode_7700(void)
  1416. {
  1417.   CodeLen = 0;
  1418.   DontPrint = False;
  1419.   BankReg = Reg_DT;
  1420.  
  1421.   /* zu ignorierendes */
  1422.  
  1423.   if (Memo("")) return;
  1424.  
  1425.   /* Pseudoanweisungen */
  1426.  
  1427.   if (DecodeIntelPseudo(False))
  1428.     return;
  1429.  
  1430.   if (!LookupInstTable(InstTable, OpPart.str.p_str))
  1431.     WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
  1432. }
  1433.  
  1434. static void InitCode_7700(void)
  1435. {
  1436.   Reg_PG = 0;
  1437.   Reg_DT = 0;
  1438.   Reg_X = 0;
  1439.   Reg_M = 0;
  1440.   Reg_DPR = 0;
  1441. }
  1442.  
  1443. static Boolean IsDef_7700(void)
  1444. {
  1445.   return False;
  1446. }
  1447.  
  1448. static void SwitchFrom_7700(void)
  1449. {
  1450.   DeinitFields();
  1451. }
  1452.  
  1453. static void SwitchTo_7700(void)
  1454. {
  1455.   TurnWords = False;
  1456.   SetIntConstMode(eIntConstModeMoto);
  1457.  
  1458.   PCSymbol = "*"; HeaderID = 0x19; NOPCode = 0xea;
  1459.   DivideChars = ","; HasAttrs = False;
  1460.  
  1461.   ValidSegs = 1 << SegCode;
  1462.   Grans[SegCode] = 1; ListGrans[SegCode] = 1; SegInits[SegCode] = 0;
  1463.   SegLimits[SegCode] = 0xffffffl;
  1464.  
  1465.   pASSUMERecs = ASSUME7700s;
  1466.   ASSUMERecCnt = sizeof(ASSUME7700s) / sizeof(*ASSUME7700s);
  1467.  
  1468.   MakeCode = MakeCode_7700; IsDef = IsDef_7700;
  1469.   SwitchFrom = SwitchFrom_7700; InitFields();
  1470. }
  1471.  
  1472. void code7700_init(void)
  1473. {
  1474.   CPU65816 = AddCPU("65816"    , SwitchTo_7700);
  1475.   CPUM7700 = AddCPU("MELPS7700", SwitchTo_7700);
  1476.   CPUM7750 = AddCPU("MELPS7750", SwitchTo_7700);
  1477.   CPUM7751 = AddCPU("MELPS7751", SwitchTo_7700);
  1478.  
  1479.   AddInitPassProc(InitCode_7700);
  1480. }
  1481.