Subversion Repositories pentevo

Rev

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

  1. /* codemn2610.c */
  2. /****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                    */
  4. /*                                                                          */
  5. /* AS, C-Version                                                            */
  6. /*                                                                          */
  7. /* Code Generator for MN161x Processor - alternate version                  */
  8. /*                                                                          */
  9. /****************************************************************************/
  10.  
  11. #include "stdinc.h"
  12. #include <string.h>
  13. #include <ctype.h>
  14.  
  15. #include "bpemu.h"
  16. #include "be_le.h"
  17. #include "strutil.h"
  18. #include "asmdef.h"
  19. #include "asmpars.h"
  20. #include "asmsub.h"
  21. #include "motpseudo.h"
  22. #include "asmitree.h"
  23. #include "codevars.h"
  24. #include "headids.h"
  25. #include "errmsg.h"
  26. #include "codepseudo.h"
  27. #include "ibmfloat.h"
  28. #include "onoff_common.h"
  29. #include "chartrans.h"
  30.  
  31. #include "codemn2610.h"
  32.  
  33. /*--------------------------------------------------------------------------*/
  34. /* Definitions */
  35.  
  36. typedef struct
  37. {
  38.   const char *pName;
  39.   Word Code;
  40. } tCodeTable;
  41.  
  42. typedef struct
  43. {
  44.   Word Code;
  45.   CPUVar MinCPU;
  46. } tFixedOrder;
  47.  
  48. enum
  49. {
  50.   eAddrRegX0,
  51.   eAddrRegX1,
  52.   eAddrRegIC,
  53.   eAddrRegCnt
  54. };
  55.  
  56. static CPUVar CPUMN1610, CPUMN1613;
  57. static tSymbolSize OpSize;
  58. static LongInt BaseRegVals[4];
  59.  
  60. #define ASSUMEMN1613Count 4
  61. static ASSUMERec ASSUMEMN1613[ASSUMEMN1613Count] =
  62. {
  63.   { "CSBR", BaseRegVals + 0, 0, 15, 16, NULL },
  64.   { "SSBR", BaseRegVals + 1, 0, 15, 16, NULL },
  65.   { "TSR0", BaseRegVals + 2, 0, 15, 16, NULL },
  66.   { "TSR1", BaseRegVals + 3, 0, 15, 16, NULL }
  67. };
  68.  
  69. static tFixedOrder *FixedOrders;
  70.  
  71. /*--------------------------------------------------------------------------*/
  72. /* Adress Decoders */
  73.  
  74. static Boolean DecodeTable(const char *pArg, Word *pResult, const tCodeTable *pTable)
  75. {
  76.   for (; pTable->pName; pTable++)
  77.     if (!as_strcasecmp(pArg, pTable->pName))
  78.     {
  79.       *pResult = pTable->Code;
  80.       return True;
  81.     }
  82.   return False;
  83. }
  84.  
  85. static const tCodeTable RegCodes[] =
  86. {
  87.   { "R0",  0 },
  88.   { "R1",  1 },
  89.   { "R2",  2 },
  90.   { "R3",  3 },
  91.   { "R4",  4 },
  92.   { "SP",  5 },
  93.   { "STR", 6 },
  94.   { "IC",  7 },
  95.   { "X0",  3 },
  96.   { "X1",  4 },
  97.   { NULL,  0 }
  98. };
  99. #define DecodeRegCore(pArg, pResult) (DecodeTable((pArg), (pResult), RegCodes))
  100.  
  101. static Boolean DecodeReg(const tStrComp *pArg, Word *pResult, Byte Mask)
  102. {
  103.   Boolean Result = DecodeRegCore(pArg->str.p_str, pResult) && (Mask & (1 << *pResult));
  104.  
  105.   if (!Result)
  106.     WrStrErrorPos(ErrNum_InvReg, pArg);
  107.   return Result;
  108. }
  109.  
  110. static const tCodeTable DRegCodes[] =
  111. {
  112.   { "DR0",  0 },
  113.   { NULL ,  0 }
  114. };
  115. #define DecodeDRegCore(pArg, pResult) (DecodeTable((pArg), (pResult), DRegCodes))
  116.  
  117. static Boolean DecodeDReg(const tStrComp *pArg)
  118. {
  119.   Word DummyReg;
  120.   Boolean Result = DecodeDRegCore(pArg->str.p_str, &DummyReg) && !DummyReg;
  121.  
  122.   if (!Result)
  123.     WrStrErrorPos(ErrNum_InvReg, pArg);
  124.   return Result;
  125. }
  126.  
  127. static const tCodeTable SkipCodes[] =
  128. {
  129.   { ""   ,  0 },
  130.   { "SKP",  1 },
  131.   { "M"  ,  2 },
  132.   { "PZ" ,  3 },
  133.   { "E"  ,  4 },
  134.   { "Z"  ,  4 },
  135.   { "NE" ,  5 },
  136.   { "NZ" ,  5 },
  137.   { "MZ" ,  6 },
  138.   { "P"  ,  7 },
  139.   { "EZ" ,  8 },
  140.   { "ENZ",  9 },
  141.   { "OZ" , 10 },
  142.   { "ONZ", 11 },
  143.   { "LMZ", 12 },
  144.   { "LP" , 13 },
  145.   { "LPZ", 14 },
  146.   { "LM" , 15 },
  147.   { NULL ,  0 }
  148. };
  149. #define DecodeSkipCore(pArg, pResult) (DecodeTable((pArg), (pResult), SkipCodes))
  150.  
  151. static Boolean DecodeSkip(const tStrComp *pArg, Word *pResult)
  152. {
  153.   Boolean Result = DecodeSkipCore(pArg->str.p_str, pResult);
  154.  
  155.   if (!Result)
  156.     WrStrErrorPos(ErrNum_UndefCond, pArg);
  157.   return Result;
  158. }
  159.  
  160. static const tCodeTable AddrRegCodes[] =
  161. {
  162.   { "(X0)", eAddrRegX0 },
  163.   { "(X1)", eAddrRegX1 },
  164.   { "(IC)", eAddrRegIC },
  165.   { NULL  ,  0         }
  166. };
  167. #define DecodeAddrReg(pArg, pResult) (DecodeTable((pArg), (pResult), AddrRegCodes))
  168.  
  169. static const tCodeTable EECodes[] =
  170. {
  171.   { ""  , 0 },
  172.   { "RE", 1 },
  173.   { "SE", 2 },
  174.   { "CE", 3 },
  175.   { NULL, 0 }
  176. };
  177. #define DecodeEECore(pArg, pResult) (DecodeTable((pArg), (pResult), EECodes))
  178.  
  179. static Boolean DecodeEE(const tStrComp *pArg, Word *pResult)
  180. {
  181.   Boolean Result = DecodeEECore(pArg->str.p_str, pResult);
  182.  
  183.   if (!Result)
  184.     WrStrErrorPos(ErrNum_InvReg, pArg);
  185.   return Result;
  186. }
  187.  
  188. static const tCodeTable AllBRCodes[] =
  189. {
  190.   { "CSBR", 0 },
  191.   { "SSBR", 1 },
  192.   { "TSR0", 2 },
  193.   { "TSR1", 3 },
  194.   { "OSR0", 4 },
  195.   { "OSR1", 5 },
  196.   { "OSR2", 6 },
  197.   { "OSR3", 7 },
  198.   { NULL ,  0 }
  199. };
  200. #define DecodeAllBRCore(pArg, pResult, IsWrite) (DecodeTable((pArg), (pResult), AllBRCodes + IsWrite))
  201.  
  202. static const tCodeTable BRCodes[] =
  203. {
  204.   { "CSBR", 0 },
  205.   { "SSBR", 1 },
  206.   { "TSR0", 2 },
  207.   { "TSR1", 3 },
  208.   { NULL  , 0 }
  209. };
  210. #define DecodeBRCore(pArg, pResult) (DecodeTable((pArg), (pResult), BRCodes))
  211.  
  212. static Boolean DecodeBR(const tStrComp *pArg, Word *pResult)
  213. {
  214.   Boolean Result = DecodeBRCore(pArg->str.p_str, pResult);
  215.  
  216.   if (!Result)
  217.     WrStrErrorPos(ErrNum_UnknownSegReg, pArg);
  218.   return Result;
  219. }
  220.  
  221.  
  222. static const tCodeTable SRegCodes[] =
  223. {
  224.   { "SBRB", 0 },
  225.   { "ICB" , 1 },
  226.   { "NPP" , 2 },
  227.   { NULL  , 0 }
  228. };
  229. #define DecodeSRegCore(pArg, pResult) (DecodeTable((pArg), (pResult), SRegCodes))
  230.  
  231. static Boolean DecodeSOrAllBReg(const tStrComp *pArg, Word *pResult, unsigned IsS, Boolean IsWrite)
  232. {
  233.   Boolean Result = IsS ? DecodeSRegCore(pArg->str.p_str, pResult) : DecodeAllBRCore(pArg->str.p_str, pResult, IsWrite);
  234.  
  235.   if (!Result)
  236.     WrStrErrorPos(ErrNum_InvReg, pArg);
  237.   return Result;
  238. }
  239.  
  240. static tCodeTable HRegCodes[] =
  241. {
  242.   { "TCR" , 0 },
  243.   { "TIR" , 1 },
  244.   { "TSR" , 2 },
  245.   { "SCR" , 3 },
  246.   { "SSR" , 4 },
  247.   { NULL  , 5 }, /* filled @ runtime with SOR/SIR */
  248.   { "IISR", 6 },
  249.   { NULL  , 0 }
  250. };
  251. #define DecodeHRegCore(pArg, pResult) (DecodeTable((pArg), (pResult), HRegCodes))
  252.  
  253. static Boolean DecodeHReg(const tStrComp *pArg, Word *pResult, Boolean IsWrite)
  254. {
  255.   Boolean Result;
  256.  
  257.   HRegCodes[5].pName = IsWrite ? "SOR" : "SIR";
  258.   Result = DecodeHRegCore(pArg->str.p_str, pResult);
  259.  
  260.   if (!Result)
  261.     WrStrErrorPos(ErrNum_InvReg, pArg);
  262.   return Result;
  263. }
  264.  
  265. /*!------------------------------------------------------------------------
  266.  * \fn     Word ChkPage(LongWord Addr, Word Base, const tStrComp *pArg, bool Warn)
  267.  * \brief  check whether a linear address is reachable via the given segment register, and compute offset
  268.  * \param  Addr linear address in 64/256K space
  269.  * \param  Base index of segment register to be used
  270.  * \param  pArg textual argument for warnings (may be NULL)
  271.  * \return resulting offset
  272.  * ------------------------------------------------------------------------ */
  273.  
  274. static Word ChkPage(LongWord Addr, Word Base, const tStrComp *pArg)
  275. {
  276.   Addr -= BaseRegVals[Base] << 14;
  277.   Addr &= SegLimits[SegCode];
  278.   if ((Addr >= 0x10000ul) && pArg)
  279.     WrStrErrorPos(ErrNum_InAccPage, pArg);
  280.   return Addr & 0xffff;
  281. }
  282.  
  283. /*!------------------------------------------------------------------------
  284.  * \fn     DecodeMem(tStrComp *pArg, Word *pResult)
  285.  * \brief  parse memory address expression
  286.  * \param  pArg memory argument in source
  287.  * \param  pResult resulting code for instruction word (xxMMMxxxDDDDDDDD)
  288.  * \return True if successfully parsed
  289.  * ------------------------------------------------------------------------ */
  290.  
  291. static Boolean DecodeMem(tStrComp *pArg, Word *pResult)
  292. {
  293.   tStrComp Arg;
  294.   Boolean TotIndirect = IsIndirect(pArg->str.p_str), OK;
  295.   Word R;
  296.   Integer Disp;
  297.   int l;
  298.   tSymbolFlags Flags;
  299.  
  300.   if (TotIndirect)
  301.   {
  302.     StrCompRefRight(&Arg, pArg, 1);
  303.     KillPrefBlanksStrCompRef(&Arg);
  304.     StrCompShorten(&Arg, 1);
  305.     KillPostBlanksStrComp(&Arg);
  306.   }
  307.   else
  308.     StrCompRefRight(&Arg, pArg, 0);
  309.  
  310.   l = strlen(Arg.str.p_str);
  311.   if ((l >= 4) && DecodeAddrReg(Arg.str.p_str + l - 4, &R))
  312.   {
  313.     Boolean DispIndirect;
  314.  
  315.     StrCompShorten(&Arg, 4);
  316.     KillPostBlanksStrComp(&Arg);
  317.     DispIndirect = IsIndirect(Arg.str.p_str);
  318.     if (Arg.str.p_str[0])
  319.       Disp = EvalStrIntExpression(&Arg, (R == 2) ? SInt8 : UInt8, &OK);
  320.     else
  321.     {
  322.       Disp = 0;
  323.       OK = True;
  324.     }
  325.     if (!OK)
  326.       return False;
  327.     if (R == 2)
  328.     {
  329.       if (DispIndirect)  /* ((disp)(IC)), (disp)(IC) not possible */
  330.       {
  331.         WrStrErrorPos(ErrNum_InvAddrMode, pArg);
  332.         return False;
  333.       }
  334.       else /* (disp(IC)) */
  335.       {
  336.         *pResult = ((TotIndirect ? 3 : 1) << 11) | (Disp & 0xff);
  337.         return True;
  338.       }
  339.     }
  340.     else if (TotIndirect) /* (disp(Xn)), ((disp)(Xn)) not possible */
  341.     {
  342.       WrStrErrorPos(ErrNum_InvAddrMode, pArg);
  343.       return False;
  344.     }
  345.     else /* disp(Xn), (disp)(Xn) */
  346.     {
  347.       *pResult = (((DispIndirect ? 6 : 4) + R) << 11) | (Disp & 0xff);
  348.       return True;
  349.     }
  350.   }
  351.   else if (TotIndirect && DecodeRegCore(Arg.str.p_str, &R)) /* plain (ic) (x0) (x1) without displacement */
  352.   {
  353.     switch (R)
  354.     {
  355.       case 3:
  356.         *pResult = (4 << 11);
  357.         return True;
  358.       case 4:
  359.         *pResult = (5 << 11);
  360.         return True;
  361.       case 7:
  362.         *pResult = (1 << 11);
  363.         return True;
  364.       default:
  365.         goto plaindisp;
  366.     }
  367.   }
  368.   else
  369.   {
  370.     int ArgOffset, ForceMode;
  371.     LongWord Addr;
  372.  
  373. plaindisp:
  374.     /* For (Addr), there is only the 'zero-page' variant: */
  375.  
  376.     if (TotIndirect)
  377.     {
  378.       ArgOffset = 0;
  379.       ForceMode = 1;
  380.     }
  381.  
  382.     /* For direct addressing, either zero-page or IC-relative may be used.
  383.        Check for explicit request: */
  384.  
  385.     else switch (*Arg.str.p_str)
  386.     {
  387.       case '>':
  388.         ArgOffset = 1;
  389.         ForceMode = 2;
  390.         break;
  391.       case '<':
  392.         ArgOffset = 1;
  393.         ForceMode = 1;
  394.         break;
  395.       default:
  396.         ArgOffset = ForceMode = 0;
  397.     }
  398.  
  399.     /* evaluate expression */
  400.  
  401.     Addr = EvalStrIntExpressionOffsWithFlags(&Arg, ArgOffset, (MomCPU == CPUMN1613) ? UInt18 : UInt16, &OK, &Flags);
  402.     if (!OK)
  403.       return False;
  404.  
  405.     /* now generate mode */
  406.  
  407.     switch (ForceMode)
  408.     {
  409.       case 0:
  410.       {
  411.         if (ChkPage(Addr, 0, NULL) < 256)
  412.           goto case1;
  413.         else
  414.           goto case2;
  415.       }
  416.       case 1:
  417.       case1:
  418.       {
  419.         Word Offset = ChkPage(Addr, 0, NULL);
  420.  
  421.         if (!mFirstPassUnknownOrQuestionable(Flags) && (Offset > 255))
  422.         {
  423.           WrStrErrorPos(ErrNum_OverRange, pArg);
  424.           return False;
  425.         }
  426.         else
  427.         {
  428.           *pResult = ((TotIndirect ? 2 : 0) << 11) | (Offset & 0xff);
  429.           return True;
  430.         }
  431.       }
  432.       case 2:
  433.       case2:
  434.       {
  435.         LongInt Disp = Addr - EProgCounter();
  436.  
  437.         if (!mFirstPassUnknownOrQuestionable(Flags) && ((Disp > 127) || (Disp < -128)))
  438.         {
  439.           WrStrErrorPos(ErrNum_DistTooBig, pArg);
  440.           return False;
  441.         }
  442.         else
  443.         {
  444.           *pResult = (1 << 11) | (Disp & 0xff);
  445.           return True;
  446.         }
  447.       }
  448.       default:
  449.         return False;
  450.     }
  451.   }
  452. }
  453.  
  454. static Boolean DecodeIReg(tStrComp *pStrArg, Word *pResult, Word Mask, Word Allowed)
  455. {
  456.   char *pArg = pStrArg->str.p_str;
  457.   int l = strlen(pArg);
  458.   char *pEnd = pArg + l, Save;
  459.   Word Reg;
  460.   Boolean OK;
  461.  
  462.   if ((l > 2) && (*pArg == '(') && (*(pEnd - 1) == ')'))
  463.   {
  464.     pArg++; pEnd--;
  465.     *pResult = 1 << 6;
  466.   }
  467.   else if ((l > 3) && (*pArg == '(') && (*(pEnd - 2) == ')') && (*(pEnd - 1) == '+'))
  468.   {
  469.     pArg++; pEnd -= 2;
  470.     *pResult = 3 << 6;
  471.   }
  472.   else if ((l > 3) && (*pArg == '-') && (pArg[1] == '(') && (*(pEnd - 1) == ')'))
  473.   {
  474.     pArg += 2; pEnd--;
  475.     *pResult = 2 << 6;
  476.   }
  477.   else
  478.     goto error;
  479.  
  480.   while ((pArg < pEnd) && isspace(*pArg))
  481.     pArg++;
  482.   while ((pEnd > pArg) && isspace(*(pEnd - 1)))
  483.     pEnd--;
  484.   Save = *pEnd; *pEnd = '\0';
  485.  
  486.   OK = DecodeRegCore(pArg, &Reg);
  487.   *pEnd = Save;
  488.   if (!OK || (Reg < 1) || (Reg > 4))
  489.     goto error;
  490.  
  491.   *pResult |= (Reg - 1);
  492.   if ((*pResult & Mask) != Allowed)
  493.     goto error;
  494.   return True;
  495.  
  496. error:
  497.   WrStrErrorPos(ErrNum_InvAddrMode, pStrArg);
  498.   return False;
  499. }
  500.  
  501. /*--------------------------------------------------------------------------*/
  502. /* Instruction Decoders */
  503.  
  504. static void DecodeFixed(Word Index)
  505. {
  506.   const tFixedOrder *pOrder = FixedOrders + Index;
  507.  
  508.   if (ChkArgCnt(0, 0) && ChkMinCPU(pOrder->MinCPU))
  509.   {
  510.     WAsmCode[0] = pOrder->Code;
  511.     CodeLen = 1;
  512.   }
  513. }
  514.  
  515. static void DecodeOneReg(Word Code)
  516. {
  517.   Word Reg;
  518.  
  519.   if (ChkArgCnt(1, 1)
  520.    && DecodeReg(&ArgStr[1], &Reg, 0x7f)) /* do not allow IC as register */
  521.   {
  522.     WAsmCode[0] = Code | (Reg << 8);
  523.     CodeLen = 1;
  524.   }
  525. }
  526.  
  527. static void DecodeRegImm(Word Code)
  528. {
  529.   Word Reg;
  530.  
  531.   if (ChkArgCnt(2, 2)
  532.    && DecodeReg(&ArgStr[1], &Reg, 0x7f)) /* do not allow IC as register */
  533.   {
  534.     tEvalResult EvalResult;
  535.  
  536.     WAsmCode[0] = EvalStrIntExpressionWithResult(&ArgStr[2], Int8, &EvalResult) & 0xff;
  537.     if (EvalResult.OK)
  538.     {
  539.       if (Code & 0x1000)
  540.         ChkSpace(SegIO, EvalResult.AddrSpaceMask);
  541.       WAsmCode[0] |= Code | (Reg << 8);
  542.       CodeLen = 1;
  543.     }
  544.   }
  545. }
  546.  
  547. static void DecodeTwoReg(Word Code)
  548. {
  549.   Word Rd, Rs, Skip = 0;
  550.  
  551.   if (ChkArgCnt(2, 3)
  552.    && DecodeReg(&ArgStr[1], &Rd, 0x7f) /* do not allow IC as register */
  553.    && DecodeReg(&ArgStr[2], &Rs, 0x7f) /* do not allow IC as register */
  554.    && ((ArgCnt < 3) || DecodeSkip(&ArgStr[3], &Skip)))
  555.   {
  556.     WAsmCode[0] = Code | (Rd << 8) | (Skip << 4) | Rs;
  557.     CodeLen = 1;
  558.   }
  559. }
  560.  
  561. static void DecodeEAReg(Word Code)
  562. {
  563.   Word R, EA;
  564.  
  565.   if (ChkArgCnt(2, 2)
  566.    && DecodeReg(&ArgStr[1], &R, 0x3f)
  567.    && DecodeMem(&ArgStr[2], &EA))
  568.   {
  569.     WAsmCode[0] = Code | EA | (R << 8);
  570.     CodeLen = 1;
  571.   }
  572. }
  573.  
  574. static void DecodeEA(Word Code)
  575. {
  576.   Word EA;
  577.  
  578.   if (ChkArgCnt(1, 1)
  579.    && DecodeMem(&ArgStr[1], &EA))
  580.   {
  581.     WAsmCode[0] = Code | EA;
  582.     CodeLen = 1;
  583.   }
  584. }
  585.  
  586. static void DecodeShift(Word Code)
  587. {
  588.   Word R, Skip = 0, EE = 0;
  589.  
  590.   if (ChkArgCnt(1, 3)
  591.    && DecodeReg(&ArgStr[1], &R, 0x7f)) /* do not allow IC as register */
  592.   {
  593.     Boolean OK;
  594.  
  595.     if (ArgCnt == 3)
  596.       OK = DecodeEE(&ArgStr[2], &EE) && DecodeSkip(&ArgStr[3], &Skip);
  597.     else if (ArgCnt == 1)
  598.       OK = True;
  599.     else
  600.       OK = DecodeEECore(ArgStr[2].str.p_str, &EE) || DecodeSkip(&ArgStr[2], &Skip);
  601.     if (OK)
  602.     {
  603.       WAsmCode[0] = Code | (R << 8) | (Skip << 4) | EE;
  604.       CodeLen = 1;
  605.     }
  606.   }
  607. }
  608.  
  609. static void DecodeImm4(Word Code)
  610. {
  611.   Word R, Skip = 0;
  612.  
  613.   if (ChkArgCnt(2, 3)
  614.    && DecodeReg(&ArgStr[1], &R, 0x7f)
  615.    && ((ArgCnt < 3) || DecodeSkip(&ArgStr[3], &Skip)))
  616.   {
  617.     Word Num;
  618.     Boolean OK;
  619.  
  620.     Num = EvalStrIntExpression(&ArgStr[2], UInt4, &OK);
  621.     if (OK)
  622.     {
  623.       WAsmCode[0] = Code | (R << 8) | (Skip << 4) | (Num & 15);
  624.       CodeLen = 1;
  625.     }
  626.   }
  627. }
  628.  
  629. static void DecodeImm2(Word Code)
  630. {
  631.   if (ChkArgCnt(1, 1))
  632.   {
  633.     Boolean OK;
  634.  
  635.     WAsmCode[0] = Code | EvalStrIntExpression(&ArgStr[1], UInt2, &OK);
  636.     if (OK)
  637.       CodeLen = 1;
  638.   }
  639. }
  640.  
  641. static void DecodeLD_STD(Word Code)
  642. {
  643.   Word R, Base = 0;
  644.  
  645.   if (ChkArgCnt(2, 3)
  646.    && ChkMinCPU(CPUMN1613)
  647.    && DecodeReg(&ArgStr[1], &R, 0x3f) /* do not allow IC/STR as register */
  648.    && ((ArgCnt <= 2) || DecodeBR(&ArgStr[2], &Base)))
  649.   {
  650.     Boolean OK;
  651.     LongWord Addr;
  652.  
  653.     Addr = EvalStrIntExpression(&ArgStr[ArgCnt], UInt18, &OK);
  654.     if (OK)
  655.     {
  656.       WAsmCode[0] = Code | R | (Base << 4);
  657.       WAsmCode[1] = ChkPage(Addr, Base, &ArgStr[ArgCnt]);
  658.       CodeLen = 2;
  659.     }
  660.   }
  661. }
  662.  
  663. static void DecodeLR_STR(Word Code)
  664. {
  665.   Word R, IR, Base = 0;
  666.  
  667.   if (ChkArgCnt(2, 3)
  668.    && ChkMinCPU(CPUMN1613)
  669.    && DecodeReg(&ArgStr[1], &R, 0x3f) /* do not allow STR/IC as register */
  670.    && ((ArgCnt <= 2) || DecodeBR(&ArgStr[2], &Base))
  671.    && DecodeIReg(&ArgStr[ArgCnt], &IR, 0x00, 0x00))
  672.   {
  673.     WAsmCode[0] = Code | (R << 8) | IR | (Base << 4);
  674.     CodeLen = 1;
  675.   }
  676. }
  677.  
  678. static void DecodeR0RISkip(Word Code)
  679. {
  680.   Word R, RI, Skip = 0;
  681.  
  682.   if (ChkArgCnt(2, 3)
  683.    && ChkMinCPU(CPUMN1613)
  684.    && DecodeReg(&ArgStr[1], &R, 0x01)
  685.    && DecodeIReg(&ArgStr[2], &RI, 0xc0, 0x40)
  686.    && ((ArgCnt < 3) || DecodeSkip(&ArgStr[3], &Skip)))
  687.   {
  688.     WAsmCode[0] = Code | (Skip << 4) | (RI & 3);
  689.     CodeLen = 1;
  690.   }
  691. }
  692.  
  693. static void DecodeRImmSkip(Word Code)
  694. {
  695.   Word R, Skip = 0;
  696.  
  697.   if (ChkArgCnt(2, 3)
  698.    && ChkMinCPU(CPUMN1613)
  699.    && DecodeReg(&ArgStr[1], &R, 0x7f) /* do not allow IC as register */
  700.    && ((ArgCnt < 3) || DecodeSkip(&ArgStr[3], &Skip)))
  701.   {
  702.     Boolean OK;
  703.  
  704.     WAsmCode[1] = EvalStrIntExpression(&ArgStr[2], Int16, &OK);
  705.     if (OK)
  706.     {
  707.       WAsmCode[0] = Code | (R << 8) | (Skip << 4);
  708.       CodeLen = 2;
  709.     }
  710.   }
  711. }
  712.  
  713. static Boolean ChkCarry(int StartIndex, Boolean *pHasCarryArg, Word *pCarryVal)
  714. {
  715.   if (ArgCnt < StartIndex)
  716.   {
  717.     *pHasCarryArg = False;
  718.     *pCarryVal = 0;
  719.     return True;
  720.   }
  721.   else
  722.   {
  723.     Boolean Result;
  724.  
  725.     *pHasCarryArg = !as_strcasecmp(ArgStr[StartIndex].str.p_str, "C")
  726.                  || !as_strcasecmp(ArgStr[StartIndex].str.p_str, "0")
  727.                  || !as_strcasecmp(ArgStr[StartIndex].str.p_str, "1");
  728.     *pCarryVal = *pHasCarryArg && (ArgStr[StartIndex].str.p_str[0] != '0');
  729.     Result = (ArgCnt == StartIndex) || *pHasCarryArg;
  730.     if (!Result)
  731.       WrStrErrorPos(ErrNum_InvReg, &ArgStr[StartIndex]);
  732.     return Result;
  733.   }
  734. }
  735.  
  736. static void DecodeDR0RISkip(Word Code)
  737. {
  738.   Word Skip = 0, Ri, CarryVal = 0;
  739.   Boolean OptCarry = !!(Code & 0x10), HasCarryArg = False;
  740.  
  741.   Code &= ~0x10;
  742.   if (ChkArgCnt(2, 3 + OptCarry)
  743.    && ChkMinCPU(CPUMN1613)
  744.    && DecodeDReg(&ArgStr[1])
  745.    && DecodeIReg(&ArgStr[2], &Ri, 0xc0, 0x40)
  746.    && (!OptCarry || ChkCarry(3, &HasCarryArg, &CarryVal))
  747.    && ((ArgCnt < 3 + HasCarryArg) || DecodeSkip(&ArgStr[3 + HasCarryArg], &Skip)))
  748.   {
  749.     WAsmCode[0] = Code | (Skip << 4) | (Ri & 3) | (CarryVal << 3);
  750.     CodeLen = 1;
  751.   }
  752. }
  753.  
  754. static void DecodeDAA_DAS(Word Code)
  755. {
  756.   Word R, Ri, Skip = 0, CarryVal = 0;
  757.   Boolean HasCarryArg = False;
  758.  
  759.   if (ChkArgCnt(2, 4)
  760.    && ChkMinCPU(CPUMN1613)
  761.    && DecodeReg(&ArgStr[1], &R, 0x01)
  762.    && DecodeIReg(&ArgStr[2], &Ri, 0xc0, 0x40)
  763.    && ChkCarry(3, &HasCarryArg, &CarryVal)
  764.    && ((ArgCnt < 3 + HasCarryArg) || DecodeSkip(&ArgStr[3 + HasCarryArg], &Skip)))
  765.   {
  766.     WAsmCode[0] = Code | (Skip << 4) | (Ri & 3) | (CarryVal << 3);
  767.     CodeLen = 1;
  768.   }
  769. }
  770.  
  771. static void DecodeNEG(Word Code)
  772. {
  773.   Word R, Skip = 0, CarryVal = 0;
  774.   Boolean HasCarryArg = False;
  775.  
  776.   if (ChkArgCnt(1, 3)
  777.    && ChkMinCPU(CPUMN1613)
  778.    && DecodeReg(&ArgStr[1], &R, 0x7f) /* do not allow IC as register */
  779.    && ChkCarry(2, &HasCarryArg, &CarryVal)
  780.    && ((ArgCnt < 2 + HasCarryArg) || DecodeSkip(&ArgStr[2 + HasCarryArg], &Skip)))
  781.   {
  782.     WAsmCode[0] = Code | (Skip << 4) | R | (CarryVal << 3);
  783.     CodeLen = 1;
  784.   }
  785. }
  786.  
  787. static void DecodeRDR_WTR(Word Code)
  788. {
  789.   Word R, Ri;
  790.  
  791.   if (ChkArgCnt(2, 2)
  792.    && ChkMinCPU(CPUMN1613)
  793.    && DecodeReg(&ArgStr[1], &R, 0x3f) /* do not allow IC/STR */
  794.    && DecodeIReg(&ArgStr[2], &Ri, 0xc0, 0x40))
  795.   {
  796.     WAsmCode[0] = Code | (R << 8) | (Ri & 3);
  797.     CodeLen = 1;
  798.   }
  799. }
  800.  
  801. static void DecodeBD_BALD(Word Code)
  802. {
  803.   if (ChkArgCnt(1, 1)
  804.    && ChkMinCPU(CPUMN1613))
  805.   {
  806.     Boolean OK;
  807.     LongWord Addr = EvalStrIntExpression(&ArgStr[1], UInt18, &OK);
  808.  
  809.     if (OK)
  810.     {
  811.       WAsmCode[0] = Code;
  812.       WAsmCode[1] = ChkPage(Addr, 0, &ArgStr[1]);
  813.       CodeLen = 2;
  814.     }
  815.   }
  816. }
  817.  
  818. static void DecodeBL_BALL(Word Code)
  819. {
  820.   if (!ChkArgCnt(1, 1));
  821.   else if (!ChkMinCPU(CPUMN1613));
  822.   else if (!IsIndirect(ArgStr[1].str.p_str)) WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[1]);
  823.   else
  824.   {
  825.     Boolean OK;
  826.     LongWord Addr = EvalStrIntExpression(&ArgStr[1], UInt18, &OK);
  827.  
  828.     if (OK)
  829.     {
  830.       WAsmCode[0] = Code;
  831.       WAsmCode[1] = ChkPage(Addr, 0, &ArgStr[1]);
  832.       CodeLen = 2;
  833.     }
  834.   }
  835. }
  836.  
  837. static void DecodeBR_BALR(Word Code)
  838. {
  839.   Word Ri;
  840.  
  841.   if (ChkArgCnt(1, 1)
  842.    && ChkMinCPU(CPUMN1613)
  843.    && DecodeIReg(&ArgStr[1], &Ri, 0xc0, 0x40))
  844.   {
  845.     WAsmCode[0] = Code | (Ri & 3);
  846.     CodeLen = 1;
  847.   }
  848. }
  849.  
  850. static void DecodeTSET_TRST(Word Code)
  851. {
  852.   Word R, Skip = 0;
  853.  
  854.   if (ChkArgCnt(2, 3)
  855.    && ChkMinCPU(CPUMN1613)
  856.    && DecodeReg(&ArgStr[1], &R, 0x7f) /* do not allow IC as register */
  857.    && ((ArgCnt < 3) || DecodeSkip(&ArgStr[3], &Skip)))
  858.   {
  859.     Boolean OK;
  860.     LongWord Addr = EvalStrIntExpression(&ArgStr[2], UInt18, &OK);
  861.  
  862.     if (OK)
  863.     {
  864.       WAsmCode[0] = Code | R | (Skip << 4);
  865.       WAsmCode[1] = ChkPage(Addr, 0, &ArgStr[2]);
  866.       CodeLen = 2;
  867.     }
  868.   }
  869. }
  870.  
  871. static void DecodeFIX(Word Code)
  872. {
  873.   Word Skip = 0, R;
  874.  
  875.   if (ChkArgCnt(2, 3)
  876.    && ChkMinCPU(CPUMN1613)
  877.    && DecodeReg(&ArgStr[1], &R, 0x01)
  878.    && DecodeDReg(&ArgStr[2])
  879.    && ((ArgCnt < 3) || DecodeSkip(&ArgStr[3], &Skip)))
  880.   {
  881.     WAsmCode[0] = Code | (Skip << 4);
  882.     CodeLen = 1;
  883.   }
  884. }
  885.  
  886. static void DecodeFLT(Word Code)
  887. {
  888.   Word Skip = 0, R;
  889.  
  890.   if (ChkArgCnt(2, 3)
  891.    && ChkMinCPU(CPUMN1613)
  892.    && DecodeDReg(&ArgStr[1])
  893.    && DecodeReg(&ArgStr[2], &R, 0x01)
  894.    && ((ArgCnt < 3) || DecodeSkip(&ArgStr[3], &Skip)))
  895.   {
  896.     WAsmCode[0] = Code | (Skip << 4);
  897.     CodeLen = 1;
  898.   }
  899. }
  900.  
  901. static void DecodeSRBT(Word Code)
  902. {
  903.   Word R;
  904.  
  905.   if (ChkArgCnt(2, 2)
  906.    && ChkMinCPU(CPUMN1613)
  907.    && DecodeReg(&ArgStr[1], &R, 0x01)
  908.    && DecodeReg(&ArgStr[2], &R, 0x7f))
  909.   {
  910.     WAsmCode[0] = Code | R;
  911.     CodeLen = 1;
  912.   }
  913. }
  914.  
  915. static void DecodeDEBP(Word Code)
  916. {
  917.   Word R;
  918.  
  919.   if (ChkArgCnt(2, 2)
  920.    && ChkMinCPU(CPUMN1613)
  921.    && DecodeReg(&ArgStr[2], &R, 0x01)
  922.    && DecodeReg(&ArgStr[1], &R, 0x7f))
  923.   {
  924.     WAsmCode[0] = Code | R;
  925.     CodeLen = 1;
  926.   }
  927. }
  928.  
  929. static void DecodeBLK(Word Code)
  930. {
  931.   Word Ri;
  932.  
  933.   if (ChkArgCnt(3, 3)
  934.    && ChkMinCPU(CPUMN1613)
  935.    && DecodeIReg(&ArgStr[1], &Ri, 0xff, 0x41)
  936.    && DecodeIReg(&ArgStr[2], &Ri, 0xff, 0x40)
  937.    && DecodeReg(&ArgStr[3], &Ri, 0x01))
  938.   {
  939.     WAsmCode[0] = Code;
  940.     CodeLen = 1;
  941.   }
  942. }
  943.  
  944. static void DecodeLBS_STBS(Word Code)
  945. {
  946.   Word R;
  947.  
  948.   if (ChkArgCnt(2, 2)
  949.    && ChkMinCPU(CPUMN1613)
  950.    && DecodeSOrAllBReg(&ArgStr[1], &R, Code & 8, !(Code & 0x80)))
  951.   {
  952.     Boolean OK;
  953.     LongWord Addr = EvalStrIntExpression(&ArgStr[2], UInt18, &OK);
  954.  
  955.     if (OK)
  956.     {
  957.       WAsmCode[0] = Code | (R << 4);
  958.       WAsmCode[1] = ChkPage(Addr, 0, &ArgStr[2]);
  959.       CodeLen = 2;
  960.     }
  961.   }
  962. }
  963.  
  964. static void DecodeCPYBS_SETBS(Word Code)
  965. {
  966.   Word R, BSR;
  967.  
  968.   if (ChkArgCnt(2, 2)
  969.    && ChkMinCPU(CPUMN1613)
  970.    && DecodeReg(&ArgStr[1], &R, 0x7f) /* do not allow IC */
  971.    && DecodeSOrAllBReg(&ArgStr[2], &BSR, Code & 8, !(Code & 0x80)))
  972.   {
  973.     WAsmCode[0] = Code | R | (BSR << 4);
  974.     CodeLen = 1;
  975.   }
  976. }
  977.  
  978. static void DecodeCPYH_SETH(Word Code)
  979. {
  980.   Word R, BSR;
  981.  
  982.   if (ChkArgCnt(2, 2)
  983.    && ChkMinCPU(CPUMN1613)
  984.    && DecodeReg(&ArgStr[1], &R, 0xff)
  985.    && DecodeHReg(&ArgStr[2], &BSR, !(Code & 0x80)))
  986.   {
  987.     WAsmCode[0] = Code | R | (BSR << 4);
  988.     CodeLen = 1;
  989.   }
  990. }
  991.  
  992. static void DecodeCLR(Word Code)
  993. {
  994.   Word R;
  995.  
  996.   if (ChkArgCnt(1, 1)
  997.    && DecodeReg(&ArgStr[1], &R, 0x7f)) /* do not allow IC */
  998.   {
  999.     /* == EOR R,R */
  1000.  
  1001.     WAsmCode[0] = Code | (R << 8) | R;
  1002.     CodeLen = 1;
  1003.   }
  1004. }
  1005.  
  1006. static void DecodeSKIP(Word Code)
  1007. {
  1008.   Word R, Skip;
  1009.  
  1010.   if (ChkArgCnt(2, 2)
  1011.    && DecodeReg(&ArgStr[1], &R, 0x7f) /* do not allow IC */
  1012.    && DecodeSkip(&ArgStr[2], &Skip))
  1013.   {
  1014.     /* == MV R,R,SKIP */
  1015.  
  1016.     WAsmCode[0] = Code | (R << 8) | (Skip << 4) | R;
  1017.   }
  1018. }
  1019.  
  1020. void IncMaxCodeLen(unsigned NumWords)
  1021. {
  1022.   SetMaxCodeLen((CodeLen + NumWords) * 2);
  1023. }
  1024.  
  1025. static void AppendWord(Word data, Boolean *p_half_filled_word)
  1026. {
  1027.   IncMaxCodeLen(1);
  1028.   WAsmCode[CodeLen++] = data;
  1029.   *p_half_filled_word = False;
  1030. }
  1031.  
  1032. static void AppendByte(Byte data, Boolean *p_half_filled_word)
  1033. {
  1034.   if (*p_half_filled_word)
  1035.   {
  1036.     WAsmCode[CodeLen - 1] |= data & 0xff;
  1037.     *p_half_filled_word = False;
  1038.   }
  1039.   else
  1040.   {
  1041.     AppendWord(data << 8, p_half_filled_word);
  1042.     *p_half_filled_word = True;
  1043.   }
  1044. }
  1045.  
  1046. static void DecodeDC(Word Code)
  1047. {
  1048.   Boolean HalfFilledWord = False;
  1049.   TempResult t;
  1050.  
  1051.   UNUSED(Code);
  1052.  
  1053.   as_tempres_ini(&t);
  1054.   if (ChkArgCnt(1, ArgCntMax))
  1055.   {
  1056.     Boolean OK = True;
  1057.     tStrComp *pArg;
  1058.  
  1059.     forallargs(pArg, OK)
  1060.     {
  1061.       EvalStrExpression(pArg, &t);
  1062.       if (mFirstPassUnknown(t.Flags) && (t.Typ == TempInt)) t.Contents.Int &= 0x7fff;
  1063.       switch (t.Typ)
  1064.       {
  1065.         case TempInt:
  1066.           if (Packing)
  1067.           {
  1068.             if (mFirstPassUnknown(t.Flags))
  1069.               t.Contents.Int &= 127;
  1070.             if (ChkRange(t.Contents.Int, -128, 255))
  1071.               AppendByte(t.Contents.Int, &HalfFilledWord);
  1072.             else
  1073.               OK = False;
  1074.           }
  1075.           else
  1076.           {
  1077.           ToInt:
  1078.             if (mFirstPassUnknown(t.Flags))
  1079.               t.Contents.Int &= 32767;
  1080.             if (ChkRange(t.Contents.Int, -32768, 65535))
  1081.               AppendWord(t.Contents.Int, &HalfFilledWord);
  1082.             else
  1083.               OK = False;
  1084.           }
  1085.           break;
  1086.         case TempString:
  1087.         {
  1088.           Word Trans;
  1089.           int z2;
  1090.  
  1091.           if (MultiCharToInt(&t, 2))
  1092.             goto ToInt;
  1093.  
  1094.           if (as_chartrans_xlate_nonz_dynstr(CurrTransTable->p_table, &t.Contents.str, pArg))
  1095.             OK = False;
  1096.           else
  1097.             for (z2 = 0; z2 < (int)t.Contents.str.len; z2++)
  1098.             {
  1099.               Trans = ((usint) t.Contents.str.p_str[z2]) & 0xff;
  1100.               AppendByte(Trans, &HalfFilledWord);
  1101.             }
  1102.           break;
  1103.         }
  1104.         case TempFloat:
  1105.         {
  1106.           int ret;
  1107.  
  1108.           IncMaxCodeLen(2);
  1109.           ret = as_float_2_ibm_float(&WAsmCode[CodeLen], t.Contents.Float, False);
  1110.           if (ret >= 0)
  1111.             CodeLen += 2;
  1112.           else
  1113.           {
  1114.             asmerr_check_fp_dispose_result(ret, pArg);
  1115.             OK = False;
  1116.           }
  1117.           HalfFilledWord = False;
  1118.           break;
  1119.         }
  1120.         default:
  1121.           OK = False;
  1122.       }
  1123.     }
  1124.     if (!OK)
  1125.        CodeLen = 0;
  1126.   }
  1127.   as_tempres_free(&t);
  1128. }
  1129.  
  1130. static void DecodeDS(Word Index)
  1131. {
  1132.   Boolean OK;
  1133.   Word Size;
  1134.   tSymbolFlags Flags;
  1135.  
  1136.   UNUSED(Index);
  1137.  
  1138.   Size = EvalStrIntExpressionWithFlags(&ArgStr[1], UInt16, &OK, &Flags);
  1139.   if (mFirstPassUnknown(Flags)) WrError(ErrNum_FirstPassCalc);
  1140.   if (OK && !mFirstPassUnknown(Flags))
  1141.   {
  1142.     DontPrint = True;
  1143.     if (!Size) WrError(ErrNum_NullResMem);
  1144.     CodeLen = Size;
  1145.     BookKeeping();
  1146.   }
  1147. }
  1148.  
  1149. /*--------------------------------------------------------------------------*/
  1150. /* Codetabellen */
  1151.  
  1152. static void AddFixed(const char *pName, Word Code, CPUVar MinCPU)
  1153. {
  1154.   order_array_rsv_end(FixedOrders, tFixedOrder);
  1155.   FixedOrders[InstrZ].Code = Code;
  1156.   FixedOrders[InstrZ].MinCPU = MinCPU;
  1157.   AddInstTable(InstTable, pName, InstrZ++, DecodeFixed);
  1158. }
  1159.  
  1160. static void InitFields(void)
  1161. {
  1162.   InstTable = CreateInstTable(201);
  1163.  
  1164.   add_null_pseudo(InstTable);
  1165.  
  1166.   InstrZ = 0;
  1167.   AddFixed("H"   , 0x2000 , CPUMN1610);
  1168.   AddFixed("RET" , 0x2003 , CPUMN1610);
  1169.   AddFixed("NOP" , NOPCode, CPUMN1610);
  1170.   AddFixed("PSHM", 0x170f , CPUMN1613);
  1171.   AddFixed("POPM", 0x1707 , CPUMN1613);
  1172.   AddFixed("RETL", 0x3f07 , CPUMN1613);
  1173.  
  1174.   AddInstTable(InstTable, "PUSH", 0x2001, DecodeOneReg);
  1175.   AddInstTable(InstTable, "POP" , 0x2002, DecodeOneReg);
  1176.  
  1177.   /* allow WR as alias to WT */
  1178.  
  1179.   AddInstTable(InstTable, "RD"  , 0x1800, DecodeRegImm);
  1180.   AddInstTable(InstTable, "WT"  , 0x1000, DecodeRegImm);
  1181.   AddInstTable(InstTable, "WR"  , 0x1000, DecodeRegImm);
  1182.   AddInstTable(InstTable, "MVI" , 0x0800, DecodeRegImm);
  1183.  
  1184.   AddInstTable(InstTable, "A"   , 0x5808, DecodeTwoReg);
  1185.   AddInstTable(InstTable, "S"   , 0x5800, DecodeTwoReg);
  1186.   AddInstTable(InstTable, "C"   , 0x5008, DecodeTwoReg);
  1187.   AddInstTable(InstTable, "CB"  , 0x5000, DecodeTwoReg);
  1188.   AddInstTable(InstTable, "MV"  , 0x7808, DecodeTwoReg);
  1189.   AddInstTable(InstTable, "MVB" , 0x7800, DecodeTwoReg);
  1190.   AddInstTable(InstTable, "BSWP", 0x7008, DecodeTwoReg);
  1191.   AddInstTable(InstTable, "DSWP", 0x7000, DecodeTwoReg);
  1192.   AddInstTable(InstTable, "LAD" , 0x6800, DecodeTwoReg);
  1193.   AddInstTable(InstTable, "AND" , 0x6808, DecodeTwoReg);
  1194.   AddInstTable(InstTable, "OR"  , 0x6008, DecodeTwoReg);
  1195.   AddInstTable(InstTable, "EOR" , 0x6000, DecodeTwoReg);
  1196.  
  1197.   AddInstTable(InstTable, "L"   , 0xc000, DecodeEAReg);
  1198.   AddInstTable(InstTable, "ST"  , 0x8000, DecodeEAReg);
  1199.   AddInstTable(InstTable, "B"   , 0xc700, DecodeEA);
  1200.   AddInstTable(InstTable, "BAL" , 0x8700, DecodeEA);
  1201.   AddInstTable(InstTable, "IMS" , 0xc600, DecodeEA);
  1202.   AddInstTable(InstTable, "DMS" , 0x8600, DecodeEA);
  1203.  
  1204.   AddInstTable(InstTable, "SL"  , 0x200c, DecodeShift);
  1205.   AddInstTable(InstTable, "SR"  , 0x2008, DecodeShift);
  1206.  
  1207.   AddInstTable(InstTable, "SBIT", 0x3800, DecodeImm4);
  1208.   AddInstTable(InstTable, "RBIT", 0x3000, DecodeImm4);
  1209.   AddInstTable(InstTable, "TBIT", 0x2800, DecodeImm4);
  1210.   AddInstTable(InstTable, "AI"  , 0x4800, DecodeImm4);
  1211.   AddInstTable(InstTable, "SI"  , 0x4000, DecodeImm4);
  1212.  
  1213.   AddInstTable(InstTable, "LPSW", 0x2004, DecodeImm2);
  1214.  
  1215.   /* new to MN1613 */
  1216.  
  1217.   AddInstTable(InstTable, "LD"  , 0x2708, DecodeLD_STD);
  1218.   AddInstTable(InstTable, "STD" , 0x2748, DecodeLD_STD);
  1219.   AddInstTable(InstTable, "LR"  , 0x2000, DecodeLR_STR);
  1220.   AddInstTable(InstTable, "STR" , 0x2004, DecodeLR_STR);
  1221.  
  1222.   AddInstTable(InstTable, "MVWR", 0x7f08, DecodeR0RISkip);
  1223.   AddInstTable(InstTable, "MVBR", 0x7f00, DecodeR0RISkip);
  1224.   AddInstTable(InstTable, "BSWR", 0x7708, DecodeR0RISkip);
  1225.   AddInstTable(InstTable, "DSWR", 0x7700, DecodeR0RISkip);
  1226.   AddInstTable(InstTable, "AWR" , 0x5f08, DecodeR0RISkip);
  1227.   AddInstTable(InstTable, "SWR" , 0x5f00, DecodeR0RISkip);
  1228.   AddInstTable(InstTable, "CWR" , 0x5708, DecodeR0RISkip);
  1229.   AddInstTable(InstTable, "CBR" , 0x5700, DecodeR0RISkip);
  1230.   AddInstTable(InstTable, "LADR", 0x6f00, DecodeR0RISkip);
  1231.   AddInstTable(InstTable, "ANDR", 0x6f08, DecodeR0RISkip);
  1232.   AddInstTable(InstTable, "ORR" , 0x6708, DecodeR0RISkip);
  1233.   AddInstTable(InstTable, "EORR", 0x6700, DecodeR0RISkip);
  1234.  
  1235.   AddInstTable(InstTable, "MVWI", 0x780f, DecodeRImmSkip);
  1236.   AddInstTable(InstTable, "AWI" , 0x580f, DecodeRImmSkip);
  1237.   AddInstTable(InstTable, "SWI" , 0x5807, DecodeRImmSkip);
  1238.   AddInstTable(InstTable, "CWI" , 0x500f, DecodeRImmSkip);
  1239.   AddInstTable(InstTable, "CBI" , 0x5007, DecodeRImmSkip);
  1240.   AddInstTable(InstTable, "LADI", 0x6807, DecodeRImmSkip);
  1241.   AddInstTable(InstTable, "ANDI", 0x680f, DecodeRImmSkip);
  1242.   AddInstTable(InstTable, "ORI" , 0x600f, DecodeRImmSkip);
  1243.   AddInstTable(InstTable, "EORI", 0x6007, DecodeRImmSkip);
  1244.  
  1245.   AddInstTable(InstTable, "AD"  , 0x4f14, DecodeDR0RISkip);
  1246.   AddInstTable(InstTable, "SD"  , 0x4714, DecodeDR0RISkip);
  1247.   AddInstTable(InstTable, "M"   , 0x7f0c, DecodeDR0RISkip);
  1248.   AddInstTable(InstTable, "D"   , 0x770c, DecodeDR0RISkip);
  1249.   AddInstTable(InstTable, "FA"  , 0x6f0c, DecodeDR0RISkip);
  1250.   AddInstTable(InstTable, "FS"  , 0x6f04, DecodeDR0RISkip);
  1251.   AddInstTable(InstTable, "FM"  , 0x670c, DecodeDR0RISkip);
  1252.   AddInstTable(InstTable, "FD"  , 0x6704, DecodeDR0RISkip);
  1253.  
  1254.   AddInstTable(InstTable, "DAA" , 0x5f04, DecodeDAA_DAS);
  1255.   AddInstTable(InstTable, "DAS" , 0x5704, DecodeDAA_DAS);
  1256.  
  1257.   AddInstTable(InstTable, "RDR" , 0x2014, DecodeRDR_WTR);
  1258.   AddInstTable(InstTable, "WTR" , 0x2010, DecodeRDR_WTR);
  1259.  
  1260.   AddInstTable(InstTable, "BD"  , 0x2607, DecodeBD_BALD);
  1261.   AddInstTable(InstTable, "BALD", 0x2617, DecodeBD_BALD);
  1262.  
  1263.   AddInstTable(InstTable, "BL"  , 0x270f, DecodeBL_BALL);
  1264.   AddInstTable(InstTable, "BALL", 0x271f, DecodeBL_BALL);
  1265.  
  1266.   AddInstTable(InstTable, "BR"  , 0x2704, DecodeBR_BALR);
  1267.   AddInstTable(InstTable, "BALR", 0x2714, DecodeBR_BALR);
  1268.  
  1269.   AddInstTable(InstTable, "TSET", 0x1708, DecodeTSET_TRST);
  1270.   AddInstTable(InstTable, "TRST", 0x1700, DecodeTSET_TRST);
  1271.  
  1272.   AddInstTable(InstTable, "NEG" , 0x1f00, DecodeNEG);
  1273.   AddInstTable(InstTable, "FIX" , 0x1f0f, DecodeFIX);
  1274.   AddInstTable(InstTable, "FLT" , 0x1f07, DecodeFLT);
  1275.  
  1276.   AddInstTable(InstTable, "SRBT", 0x3f70, DecodeSRBT);
  1277.   AddInstTable(InstTable, "DEBP", 0x3ff0, DecodeDEBP);
  1278.   AddInstTable(InstTable, "BLK" , 0x3f17, DecodeBLK);
  1279.  
  1280.   AddInstTable(InstTable, "LB"  , 0x0f07, DecodeLBS_STBS);
  1281.   AddInstTable(InstTable, "LS"  , 0x0f0f, DecodeLBS_STBS);
  1282.   AddInstTable(InstTable, "STB" , 0x0f87, DecodeLBS_STBS);
  1283.   AddInstTable(InstTable, "STS" , 0x0f8f, DecodeLBS_STBS);
  1284.  
  1285.   AddInstTable(InstTable, "CPYB", 0x0f80, DecodeCPYBS_SETBS);
  1286.   AddInstTable(InstTable, "CPYS", 0x0f88, DecodeCPYBS_SETBS);
  1287.   AddInstTable(InstTable, "SETB", 0x0f00, DecodeCPYBS_SETBS);
  1288.   AddInstTable(InstTable, "SETS", 0x0f08, DecodeCPYBS_SETBS);
  1289.  
  1290.   AddInstTable(InstTable, "CPYH", 0x3f80, DecodeCPYH_SETH);
  1291.   AddInstTable(InstTable, "SETH", 0x3f00, DecodeCPYH_SETH);
  1292.  
  1293.   /* aliases */
  1294.  
  1295.   AddInstTable(InstTable, "CLR",   0x6000, DecodeCLR);
  1296.   AddInstTable(InstTable, "CLEAR", 0x6000, DecodeCLR);
  1297.   AddInstTable(InstTable, "SKIP",  0x7808, DecodeSKIP);
  1298.  
  1299.   /* pseudo instructions */
  1300.  
  1301.   AddInstTable(InstTable, "DC"  , 0, DecodeDC);
  1302.   AddInstTable(InstTable, "DS"  , 0, DecodeDS);
  1303. }
  1304.  
  1305. static void DeinitFields(void)
  1306. {
  1307.   DestroyInstTable(InstTable);
  1308.   order_array_free(FixedOrders);
  1309. }
  1310.  
  1311. /*--------------------------------------------------------------------------*/
  1312. /* Interface to AS */
  1313.  
  1314. static Boolean DecodeAttrPart_MN1610_Alt(void)
  1315. {
  1316.   if (strlen(AttrPart.str.p_str) > 1)
  1317.   {
  1318.     WrStrErrorPos(ErrNum_UndefAttr, &AttrPart);
  1319.     return False;
  1320.   }
  1321.  
  1322.   return DecodeMoto16AttrSize(*AttrPart.str.p_str, &AttrPartOpSize[0], False);
  1323. }
  1324.  
  1325. static void MakeCode_MN1610_Alt(void)
  1326. {
  1327.   OpSize = (AttrPartOpSize[0] != eSymbolSizeUnknown) ? AttrPartOpSize[0] : eSymbolSize16Bit;
  1328.  
  1329.   if (!LookupInstTable(InstTable, OpPart.str.p_str))
  1330.     WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
  1331. }
  1332.  
  1333. static Boolean IsDef_MN1610_Alt(void)
  1334. {
  1335.   return FALSE;
  1336. }
  1337.  
  1338. static void SwitchFrom_MN1610_Alt(void)
  1339. {
  1340.   DeinitFields();
  1341. }
  1342.  
  1343. static void SwitchTo_MN1610_Alt(void)
  1344. {
  1345.   const TFamilyDescr *FoundDescr;
  1346.  
  1347.   FoundDescr = FindFamilyByName("MN161x");
  1348.  
  1349.   TurnWords = True;
  1350.   SetIntConstMode(eIntConstModeIBM);
  1351.  
  1352.   PCSymbol = "*";
  1353.   HeaderID = FoundDescr->Id;
  1354.   NOPCode = 0x7808; /* MV R0,R0 */
  1355.   DivideChars = ",";
  1356.   HasAttrs = False;
  1357.   AttrChars = ".";
  1358.  
  1359.   ValidSegs = (1 << SegCode) | (1 << SegIO);
  1360.   Grans[SegCode]     = Grans[SegIO]     = 2;
  1361.   ListGrans[SegCode] = ListGrans[SegIO] = 2;
  1362.   SegInits[SegCode]  = SegInits[SegIO]  = 0;
  1363.   if (MomCPU == CPUMN1613)
  1364.   {
  1365.     SegLimits[SegCode] = 0x3ffff;
  1366.     SegLimits[SegIO] = 0xffff;
  1367.     pASSUMERecs = ASSUMEMN1613;
  1368.     ASSUMERecCnt = ASSUMEMN1613Count;
  1369.   }
  1370.   else
  1371.   {
  1372.     SegLimits[SegCode] = 0xffff;
  1373.     SegLimits[SegIO] = 0xff; /* no RDR/WTR insn */
  1374.   }
  1375.  
  1376.   onoff_packing_add(False);
  1377.  
  1378.   DecodeAttrPart = DecodeAttrPart_MN1610_Alt;
  1379.   MakeCode = MakeCode_MN1610_Alt;
  1380.   IsDef = IsDef_MN1610_Alt;
  1381.   SwitchFrom = SwitchFrom_MN1610_Alt;
  1382.   InitFields();
  1383. }
  1384.  
  1385. /*--------------------------------------------------------------------------*/
  1386. /* Initialisierung */
  1387.  
  1388. void codemn2610_init(void)
  1389. {
  1390.   CPUMN1610 = AddCPU("MN1610ALT", SwitchTo_MN1610_Alt);
  1391.   CPUMN1613 = AddCPU("MN1613ALT", SwitchTo_MN1610_Alt);
  1392. }
  1393.