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.     Disp = EvalStrIntExpression(&Arg, (R == 2) ? SInt8 : UInt8, &OK);
  319.     if (!OK)
  320.       return False;
  321.     if (R == 2)
  322.     {
  323.       if (DispIndirect)  /* ((disp)(IC)), (disp)(IC) not possible */
  324.       {
  325.         WrStrErrorPos(ErrNum_InvAddrMode, pArg);
  326.         return False;
  327.       }
  328.       else /* (disp(IC)) */
  329.       {
  330.         *pResult = ((TotIndirect ? 3 : 1) << 11) | (Disp & 0xff);
  331.         return True;
  332.       }
  333.     }
  334.     else if (TotIndirect) /* (disp(Xn)), ((disp)(Xn)) not possible */
  335.     {
  336.       WrStrErrorPos(ErrNum_InvAddrMode, pArg);
  337.       return False;
  338.     }
  339.     else /* disp(Xn), (disp)(Xn) */
  340.     {
  341.       *pResult = (((DispIndirect ? 6 : 4) + R) << 11) | (Disp & 0xff);
  342.       return True;
  343.     }
  344.   }
  345.   else if (TotIndirect && DecodeRegCore(Arg.str.p_str, &R)) /* plain (ic) (x0) (x1) without displacement */
  346.   {
  347.     switch (R)
  348.     {
  349.       case 3:
  350.         *pResult = (4 << 11);
  351.         return True;
  352.       case 4:
  353.         *pResult = (5 << 11);
  354.         return True;
  355.       case 7:
  356.         *pResult = (1 << 11);
  357.         return True;
  358.       default:
  359.         goto plaindisp;
  360.     }
  361.   }
  362.   else
  363.   {
  364.     int ArgOffset, ForceMode;
  365.     LongWord Addr;
  366.  
  367. plaindisp:
  368.     /* For (Addr), there is only the 'zero-page' variant: */
  369.  
  370.     if (TotIndirect)
  371.     {
  372.       ArgOffset = 0;
  373.       ForceMode = 1;
  374.     }
  375.  
  376.     /* For direct addressing, either zero-page or IC-relative may be used.
  377.        Check for explicit request: */
  378.  
  379.     else switch (*Arg.str.p_str)
  380.     {
  381.       case '>':
  382.         ArgOffset = 1;
  383.         ForceMode = 2;
  384.         break;
  385.       case '<':
  386.         ArgOffset = 1;
  387.         ForceMode = 1;
  388.         break;
  389.       default:
  390.         ArgOffset = ForceMode = 0;
  391.     }
  392.  
  393.     /* evaluate expression */
  394.  
  395.     Addr = EvalStrIntExpressionOffsWithFlags(&Arg, ArgOffset, (MomCPU == CPUMN1613) ? UInt18 : UInt16, &OK, &Flags);
  396.     if (!OK)
  397.       return False;
  398.  
  399.     /* now generate mode */
  400.  
  401.     switch (ForceMode)
  402.     {
  403.       case 0:
  404.       {
  405.         if (ChkPage(Addr, 0, NULL) < 256)
  406.           goto case1;
  407.         else
  408.           goto case2;
  409.       }
  410.       case 1:
  411.       case1:
  412.       {
  413.         Word Offset = ChkPage(Addr, 0, NULL);
  414.  
  415.         if (!mFirstPassUnknownOrQuestionable(Flags) && (Offset > 255))
  416.         {
  417.           WrStrErrorPos(ErrNum_OverRange, pArg);
  418.           return False;
  419.         }
  420.         else
  421.         {
  422.           *pResult = ((TotIndirect ? 2 : 0) << 11) | (Offset & 0xff);
  423.           return True;
  424.         }
  425.       }
  426.       case 2:
  427.       case2:
  428.       {
  429.         LongInt Disp = Addr - EProgCounter();
  430.  
  431.         if (!mFirstPassUnknownOrQuestionable(Flags) && ((Disp > 127) || (Disp < -128)))
  432.         {
  433.           WrStrErrorPos(ErrNum_DistTooBig, pArg);
  434.           return False;
  435.         }
  436.         else
  437.         {
  438.           *pResult = (1 << 11) | (Disp & 0xff);
  439.           return True;
  440.         }
  441.       }
  442.       default:
  443.         return False;
  444.     }
  445.   }
  446. }
  447.  
  448. static Boolean DecodeIReg(tStrComp *pStrArg, Word *pResult, Word Mask, Word Allowed)
  449. {
  450.   char *pArg = pStrArg->str.p_str;
  451.   int l = strlen(pArg);
  452.   char *pEnd = pArg + l, Save;
  453.   Word Reg;
  454.   Boolean OK;
  455.  
  456.   if ((l > 2) && (*pArg == '(') && (*(pEnd - 1) == ')'))
  457.   {
  458.     pArg++; pEnd--;
  459.     *pResult = 1 << 6;
  460.   }
  461.   else if ((l > 3) && (*pArg == '(') && (*(pEnd - 2) == ')') && (*(pEnd - 1) == '+'))
  462.   {
  463.     pArg++; pEnd -= 2;
  464.     *pResult = 3 << 6;
  465.   }
  466.   else if ((l > 3) && (*pArg == '-') && (pArg[1] == '(') && (*(pEnd - 1) == ')'))
  467.   {
  468.     pArg += 2; pEnd--;
  469.     *pResult = 2 << 6;
  470.   }
  471.   else
  472.     goto error;
  473.  
  474.   while ((pArg < pEnd) && isspace(*pArg))
  475.     pArg++;
  476.   while ((pEnd > pArg) && isspace(*(pEnd - 1)))
  477.     pEnd--;
  478.   Save = *pEnd; *pEnd = '\0';
  479.  
  480.   OK = DecodeRegCore(pArg, &Reg);
  481.   *pEnd = Save;
  482.   if (!OK || (Reg < 1) || (Reg > 4))
  483.     goto error;
  484.  
  485.   *pResult |= (Reg - 1);
  486.   if ((*pResult & Mask) != Allowed)
  487.     goto error;
  488.   return True;
  489.  
  490. error:
  491.   WrStrErrorPos(ErrNum_InvAddrMode, pStrArg);
  492.   return False;
  493. }
  494.  
  495. /*--------------------------------------------------------------------------*/
  496. /* Instruction Decoders */
  497.  
  498. static void DecodeFixed(Word Index)
  499. {
  500.   const tFixedOrder *pOrder = FixedOrders + Index;
  501.  
  502.   if (ChkArgCnt(0, 0) && ChkMinCPU(pOrder->MinCPU))
  503.   {
  504.     WAsmCode[0] = pOrder->Code;
  505.     CodeLen = 1;
  506.   }
  507. }
  508.  
  509. static void DecodeOneReg(Word Code)
  510. {
  511.   Word Reg;
  512.  
  513.   if (ChkArgCnt(1, 1)
  514.    && DecodeReg(&ArgStr[1], &Reg, 0x7f)) /* do not allow IC as register */
  515.   {
  516.     WAsmCode[0] = Code | (Reg << 8);
  517.     CodeLen = 1;
  518.   }
  519. }
  520.  
  521. static void DecodeRegImm(Word Code)
  522. {
  523.   Word Reg;
  524.  
  525.   if (ChkArgCnt(2, 2)
  526.    && DecodeReg(&ArgStr[1], &Reg, 0x7f)) /* do not allow IC as register */
  527.   {
  528.     tEvalResult EvalResult;
  529.  
  530.     WAsmCode[0] = EvalStrIntExpressionWithResult(&ArgStr[2], Int8, &EvalResult) & 0xff;
  531.     if (EvalResult.OK)
  532.     {
  533.       if (Code & 0x1000)
  534.         ChkSpace(SegIO, EvalResult.AddrSpaceMask);
  535.       WAsmCode[0] |= Code | (Reg << 8);
  536.       CodeLen = 1;
  537.     }
  538.   }
  539. }
  540.  
  541. static void DecodeTwoReg(Word Code)
  542. {
  543.   Word Rd, Rs, Skip = 0;
  544.  
  545.   if (ChkArgCnt(2, 3)
  546.    && DecodeReg(&ArgStr[1], &Rd, 0x7f) /* do not allow IC as register */
  547.    && DecodeReg(&ArgStr[2], &Rs, 0x7f) /* do not allow IC as register */
  548.    && ((ArgCnt < 3) || DecodeSkip(&ArgStr[3], &Skip)))
  549.   {
  550.     WAsmCode[0] = Code | (Rd << 8) | (Skip << 4) | Rs;
  551.     CodeLen = 1;
  552.   }
  553. }
  554.  
  555. static void DecodeEAReg(Word Code)
  556. {
  557.   Word R, EA;
  558.  
  559.   if (ChkArgCnt(2, 2)
  560.    && DecodeReg(&ArgStr[1], &R, 0x3f)
  561.    && DecodeMem(&ArgStr[2], &EA))
  562.   {
  563.     WAsmCode[0] = Code | EA | (R << 8);
  564.     CodeLen = 1;
  565.   }
  566. }
  567.  
  568. static void DecodeEA(Word Code)
  569. {
  570.   Word EA;
  571.  
  572.   if (ChkArgCnt(1, 1)
  573.    && DecodeMem(&ArgStr[1], &EA))
  574.   {
  575.     WAsmCode[0] = Code | EA;
  576.     CodeLen = 1;
  577.   }
  578. }
  579.  
  580. static void DecodeShift(Word Code)
  581. {
  582.   Word R, Skip = 0, EE = 0;
  583.  
  584.   if (ChkArgCnt(1, 3)
  585.    && DecodeReg(&ArgStr[1], &R, 0x7f)) /* do not allow IC as register */
  586.   {
  587.     Boolean OK;
  588.  
  589.     if (ArgCnt == 3)
  590.       OK = DecodeEE(&ArgStr[2], &EE) && DecodeSkip(&ArgStr[3], &Skip);
  591.     else if (ArgCnt == 1)
  592.       OK = True;
  593.     else
  594.       OK = DecodeEECore(ArgStr[2].str.p_str, &EE) || DecodeSkip(&ArgStr[2], &Skip);
  595.     if (OK)
  596.     {
  597.       WAsmCode[0] = Code | (R << 8) | (Skip << 4) | EE;
  598.       CodeLen = 1;
  599.     }
  600.   }
  601. }
  602.  
  603. static void DecodeImm4(Word Code)
  604. {
  605.   Word R, Skip = 0;
  606.  
  607.   if (ChkArgCnt(2, 3)
  608.    && DecodeReg(&ArgStr[1], &R, 0x7f)
  609.    && ((ArgCnt < 3) || DecodeSkip(&ArgStr[3], &Skip)))
  610.   {
  611.     Word Num;
  612.     Boolean OK;
  613.  
  614.     Num = EvalStrIntExpression(&ArgStr[2], UInt4, &OK);
  615.     if (OK)
  616.     {
  617.       WAsmCode[0] = Code | (R << 8) | (Skip << 4) | (Num & 15);
  618.       CodeLen = 1;
  619.     }
  620.   }
  621. }
  622.  
  623. static void DecodeImm2(Word Code)
  624. {
  625.   if (ChkArgCnt(1, 1))
  626.   {
  627.     Boolean OK;
  628.  
  629.     WAsmCode[0] = Code | EvalStrIntExpression(&ArgStr[1], UInt2, &OK);
  630.     if (OK)
  631.       CodeLen = 1;
  632.   }
  633. }
  634.  
  635. static void DecodeLD_STD(Word Code)
  636. {
  637.   Word R, Base = 0;
  638.  
  639.   if (ChkArgCnt(2, 3)
  640.    && ChkMinCPU(CPUMN1613)
  641.    && DecodeReg(&ArgStr[1], &R, 0x3f) /* do not allow IC/STR as register */
  642.    && ((ArgCnt <= 2) || DecodeBR(&ArgStr[2], &Base)))
  643.   {
  644.     Boolean OK;
  645.     LongWord Addr;
  646.  
  647.     Addr = EvalStrIntExpression(&ArgStr[ArgCnt], UInt18, &OK);
  648.     if (OK)
  649.     {
  650.       WAsmCode[0] = Code | R | (Base << 4);
  651.       WAsmCode[1] = ChkPage(Addr, Base, &ArgStr[ArgCnt]);
  652.       CodeLen = 2;
  653.     }
  654.   }
  655. }
  656.  
  657. static void DecodeLR_STR(Word Code)
  658. {
  659.   Word R, IR, Base = 0;
  660.  
  661.   if (ChkArgCnt(2, 3)
  662.    && ChkMinCPU(CPUMN1613)
  663.    && DecodeReg(&ArgStr[1], &R, 0x3f) /* do not allow STR/IC as register */
  664.    && ((ArgCnt <= 2) || DecodeBR(&ArgStr[2], &Base))
  665.    && DecodeIReg(&ArgStr[ArgCnt], &IR, 0x00, 0x00))
  666.   {
  667.     WAsmCode[0] = Code | (R << 8) | IR | (Base << 4);
  668.     CodeLen = 1;
  669.   }
  670. }
  671.  
  672. static void DecodeR0RISkip(Word Code)
  673. {
  674.   Word R, RI, Skip = 0;
  675.  
  676.   if (ChkArgCnt(2, 3)
  677.    && ChkMinCPU(CPUMN1613)
  678.    && DecodeReg(&ArgStr[1], &R, 0x01)
  679.    && DecodeIReg(&ArgStr[2], &RI, 0xc0, 0x40)
  680.    && ((ArgCnt < 3) || DecodeSkip(&ArgStr[3], &Skip)))
  681.   {
  682.     WAsmCode[0] = Code | (Skip << 4) | (RI & 3);
  683.     CodeLen = 1;
  684.   }
  685. }
  686.  
  687. static void DecodeRImmSkip(Word Code)
  688. {
  689.   Word R, Skip = 0;
  690.  
  691.   if (ChkArgCnt(2, 3)
  692.    && ChkMinCPU(CPUMN1613)
  693.    && DecodeReg(&ArgStr[1], &R, 0x7f) /* do not allow IC as register */
  694.    && ((ArgCnt < 3) || DecodeSkip(&ArgStr[3], &Skip)))
  695.   {
  696.     Boolean OK;
  697.  
  698.     WAsmCode[1] = EvalStrIntExpression(&ArgStr[2], Int16, &OK);
  699.     if (OK)
  700.     {
  701.       WAsmCode[0] = Code | (R << 8) | (Skip << 4);
  702.       CodeLen = 2;
  703.     }
  704.   }
  705. }
  706.  
  707. static Boolean ChkCarry(int StartIndex, Boolean *pHasCarryArg, Word *pCarryVal)
  708. {
  709.   if (ArgCnt < StartIndex)
  710.   {
  711.     *pHasCarryArg = False;
  712.     *pCarryVal = 0;
  713.     return True;
  714.   }
  715.   else
  716.   {
  717.     Boolean Result;
  718.  
  719.     *pHasCarryArg = !as_strcasecmp(ArgStr[StartIndex].str.p_str, "C")
  720.                  || !as_strcasecmp(ArgStr[StartIndex].str.p_str, "0")
  721.                  || !as_strcasecmp(ArgStr[StartIndex].str.p_str, "1");
  722.     *pCarryVal = *pHasCarryArg && (ArgStr[StartIndex].str.p_str[0] != '0');
  723.     Result = (ArgCnt == StartIndex) || *pHasCarryArg;
  724.     if (!Result)
  725.       WrStrErrorPos(ErrNum_InvReg, &ArgStr[StartIndex]);
  726.     return Result;
  727.   }
  728. }
  729.  
  730. static void DecodeDR0RISkip(Word Code)
  731. {
  732.   Word Skip = 0, Ri, CarryVal = 0;
  733.   Boolean OptCarry = !!(Code & 0x10), HasCarryArg = False;
  734.  
  735.   Code &= ~0x10;
  736.   if (ChkArgCnt(2, 3 + OptCarry)
  737.    && ChkMinCPU(CPUMN1613)
  738.    && DecodeDReg(&ArgStr[1])
  739.    && DecodeIReg(&ArgStr[2], &Ri, 0xc0, 0x40)
  740.    && (!OptCarry || ChkCarry(3, &HasCarryArg, &CarryVal))
  741.    && ((ArgCnt < 3 + HasCarryArg) || DecodeSkip(&ArgStr[3 + HasCarryArg], &Skip)))
  742.   {
  743.     WAsmCode[0] = Code | (Skip << 4) | (Ri & 3) | (CarryVal << 3);
  744.     CodeLen = 1;
  745.   }
  746. }
  747.  
  748. static void DecodeDAA_DAS(Word Code)
  749. {
  750.   Word R, Ri, Skip = 0, CarryVal = 0;
  751.   Boolean HasCarryArg = False;
  752.  
  753.   if (ChkArgCnt(2, 4)
  754.    && ChkMinCPU(CPUMN1613)
  755.    && DecodeReg(&ArgStr[1], &R, 0x01)
  756.    && DecodeIReg(&ArgStr[2], &Ri, 0xc0, 0x40)
  757.    && ChkCarry(3, &HasCarryArg, &CarryVal)
  758.    && ((ArgCnt < 3 + HasCarryArg) || DecodeSkip(&ArgStr[3 + HasCarryArg], &Skip)))
  759.   {
  760.     WAsmCode[0] = Code | (Skip << 4) | (Ri & 3) | (CarryVal << 3);
  761.     CodeLen = 1;
  762.   }
  763. }
  764.  
  765. static void DecodeNEG(Word Code)
  766. {
  767.   Word R, Skip = 0, CarryVal = 0;
  768.   Boolean HasCarryArg = False;
  769.  
  770.   if (ChkArgCnt(1, 3)
  771.    && ChkMinCPU(CPUMN1613)
  772.    && DecodeReg(&ArgStr[1], &R, 0x7f) /* do not allow IC as register */
  773.    && ChkCarry(2, &HasCarryArg, &CarryVal)
  774.    && ((ArgCnt < 2 + HasCarryArg) || DecodeSkip(&ArgStr[2 + HasCarryArg], &Skip)))
  775.   {
  776.     WAsmCode[0] = Code | (Skip << 4) | R | (CarryVal << 3);
  777.     CodeLen = 1;
  778.   }
  779. }
  780.  
  781. static void DecodeRDR_WTR(Word Code)
  782. {
  783.   Word R, Ri;
  784.  
  785.   if (ChkArgCnt(2, 2)
  786.    && ChkMinCPU(CPUMN1613)
  787.    && DecodeReg(&ArgStr[1], &R, 0x3f) /* do not allow IC/STR */
  788.    && DecodeIReg(&ArgStr[2], &Ri, 0xc0, 0x40))
  789.   {
  790.     WAsmCode[0] = Code | (R << 8) | (Ri & 3);
  791.     CodeLen = 1;
  792.   }
  793. }
  794.  
  795. static void DecodeBD_BALD(Word Code)
  796. {
  797.   if (ChkArgCnt(1, 1)
  798.    && ChkMinCPU(CPUMN1613))
  799.   {
  800.     Boolean OK;
  801.     LongWord Addr = EvalStrIntExpression(&ArgStr[1], UInt18, &OK);
  802.  
  803.     if (OK)
  804.     {
  805.       WAsmCode[0] = Code;
  806.       WAsmCode[1] = ChkPage(Addr, 0, &ArgStr[1]);
  807.       CodeLen = 2;
  808.     }
  809.   }
  810. }
  811.  
  812. static void DecodeBL_BALL(Word Code)
  813. {
  814.   if (!ChkArgCnt(1, 1));
  815.   else if (!ChkMinCPU(CPUMN1613));
  816.   else if (!IsIndirect(ArgStr[1].str.p_str)) WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[1]);
  817.   else
  818.   {
  819.     Boolean OK;
  820.     LongWord Addr = EvalStrIntExpression(&ArgStr[1], UInt18, &OK);
  821.  
  822.     if (OK)
  823.     {
  824.       WAsmCode[0] = Code;
  825.       WAsmCode[1] = ChkPage(Addr, 0, &ArgStr[1]);
  826.       CodeLen = 2;
  827.     }
  828.   }
  829. }
  830.  
  831. static void DecodeBR_BALR(Word Code)
  832. {
  833.   Word Ri;
  834.  
  835.   if (ChkArgCnt(1, 1)
  836.    && ChkMinCPU(CPUMN1613)
  837.    && DecodeIReg(&ArgStr[1], &Ri, 0xc0, 0x40))
  838.   {
  839.     WAsmCode[0] = Code | (Ri & 3);
  840.     CodeLen = 1;
  841.   }
  842. }
  843.  
  844. static void DecodeTSET_TRST(Word Code)
  845. {
  846.   Word R, Skip = 0;
  847.  
  848.   if (ChkArgCnt(2, 3)
  849.    && ChkMinCPU(CPUMN1613)
  850.    && DecodeReg(&ArgStr[1], &R, 0x7f) /* do not allow IC as register */
  851.    && ((ArgCnt < 3) || DecodeSkip(&ArgStr[3], &Skip)))
  852.   {
  853.     Boolean OK;
  854.     LongWord Addr = EvalStrIntExpression(&ArgStr[2], UInt18, &OK);
  855.  
  856.     if (OK)
  857.     {
  858.       WAsmCode[0] = Code | R | (Skip << 4);
  859.       WAsmCode[1] = ChkPage(Addr, 0, &ArgStr[2]);
  860.       CodeLen = 2;
  861.     }
  862.   }
  863. }
  864.  
  865. static void DecodeFIX(Word Code)
  866. {
  867.   Word Skip = 0, R;
  868.  
  869.   if (ChkArgCnt(2, 3)
  870.    && ChkMinCPU(CPUMN1613)
  871.    && DecodeReg(&ArgStr[1], &R, 0x01)
  872.    && DecodeDReg(&ArgStr[2])
  873.    && ((ArgCnt < 3) || DecodeSkip(&ArgStr[3], &Skip)))
  874.   {
  875.     WAsmCode[0] = Code | (Skip << 4);
  876.     CodeLen = 1;
  877.   }
  878. }
  879.  
  880. static void DecodeFLT(Word Code)
  881. {
  882.   Word Skip = 0, R;
  883.  
  884.   if (ChkArgCnt(2, 3)
  885.    && ChkMinCPU(CPUMN1613)
  886.    && DecodeDReg(&ArgStr[1])
  887.    && DecodeReg(&ArgStr[2], &R, 0x01)
  888.    && ((ArgCnt < 3) || DecodeSkip(&ArgStr[3], &Skip)))
  889.   {
  890.     WAsmCode[0] = Code | (Skip << 4);
  891.     CodeLen = 1;
  892.   }
  893. }
  894.  
  895. static void DecodeSRBT(Word Code)
  896. {
  897.   Word R;
  898.  
  899.   if (ChkArgCnt(2, 2)
  900.    && ChkMinCPU(CPUMN1613)
  901.    && DecodeReg(&ArgStr[1], &R, 0x01)
  902.    && DecodeReg(&ArgStr[2], &R, 0x7f))
  903.   {
  904.     WAsmCode[0] = Code | R;
  905.     CodeLen = 1;
  906.   }
  907. }
  908.  
  909. static void DecodeDEBP(Word Code)
  910. {
  911.   Word R;
  912.  
  913.   if (ChkArgCnt(2, 2)
  914.    && ChkMinCPU(CPUMN1613)
  915.    && DecodeReg(&ArgStr[2], &R, 0x01)
  916.    && DecodeReg(&ArgStr[1], &R, 0x7f))
  917.   {
  918.     WAsmCode[0] = Code | R;
  919.     CodeLen = 1;
  920.   }
  921. }
  922.  
  923. static void DecodeBLK(Word Code)
  924. {
  925.   Word Ri;
  926.  
  927.   if (ChkArgCnt(3, 3)
  928.    && ChkMinCPU(CPUMN1613)
  929.    && DecodeIReg(&ArgStr[1], &Ri, 0xff, 0x41)
  930.    && DecodeIReg(&ArgStr[2], &Ri, 0xff, 0x40)
  931.    && DecodeReg(&ArgStr[3], &Ri, 0x01))
  932.   {
  933.     WAsmCode[0] = Code;
  934.     CodeLen = 1;
  935.   }
  936. }
  937.  
  938. static void DecodeLBS_STBS(Word Code)
  939. {
  940.   Word R;
  941.  
  942.   if (ChkArgCnt(2, 2)
  943.    && ChkMinCPU(CPUMN1613)
  944.    && DecodeSOrAllBReg(&ArgStr[1], &R, Code & 8, !(Code & 0x80)))
  945.   {
  946.     Boolean OK;
  947.     LongWord Addr = EvalStrIntExpression(&ArgStr[2], UInt18, &OK);
  948.  
  949.     if (OK)
  950.     {
  951.       WAsmCode[0] = Code | (R << 4);
  952.       WAsmCode[1] = ChkPage(Addr, 0, &ArgStr[2]);
  953.       CodeLen = 2;
  954.     }
  955.   }
  956. }
  957.  
  958. static void DecodeCPYBS_SETBS(Word Code)
  959. {
  960.   Word R, BSR;
  961.  
  962.   if (ChkArgCnt(2, 2)
  963.    && ChkMinCPU(CPUMN1613)
  964.    && DecodeReg(&ArgStr[1], &R, 0x7f) /* do not allow IC */
  965.    && DecodeSOrAllBReg(&ArgStr[2], &BSR, Code & 8, !(Code & 0x80)))
  966.   {
  967.     WAsmCode[0] = Code | R | (BSR << 4);
  968.     CodeLen = 1;
  969.   }
  970. }
  971.  
  972. static void DecodeCPYH_SETH(Word Code)
  973. {
  974.   Word R, BSR;
  975.  
  976.   if (ChkArgCnt(2, 2)
  977.    && ChkMinCPU(CPUMN1613)
  978.    && DecodeReg(&ArgStr[1], &R, 0xff)
  979.    && DecodeHReg(&ArgStr[2], &BSR, !(Code & 0x80)))
  980.   {
  981.     WAsmCode[0] = Code | R | (BSR << 4);
  982.     CodeLen = 1;
  983.   }
  984. }
  985.  
  986. static void DecodeCLR(Word Code)
  987. {
  988.   Word R;
  989.  
  990.   if (ChkArgCnt(1, 1)
  991.    && DecodeReg(&ArgStr[1], &R, 0x7f)) /* do not allow IC */
  992.   {
  993.     /* == EOR R,R */
  994.  
  995.     WAsmCode[0] = Code | (R << 8) | R;
  996.     CodeLen = 1;
  997.   }
  998. }
  999.  
  1000. static void DecodeSKIP(Word Code)
  1001. {
  1002.   Word R, Skip;
  1003.  
  1004.   if (ChkArgCnt(2, 2)
  1005.    && DecodeReg(&ArgStr[1], &R, 0x7f) /* do not allow IC */
  1006.    && DecodeSkip(&ArgStr[2], &Skip))
  1007.   {
  1008.     /* == MV R,R,SKIP */
  1009.  
  1010.     WAsmCode[0] = Code | (R << 8) | (Skip << 4) | R;
  1011.   }
  1012. }
  1013.  
  1014. void IncMaxCodeLen(unsigned NumWords)
  1015. {
  1016.   SetMaxCodeLen((CodeLen + NumWords) * 2);
  1017. }
  1018.  
  1019. static void AppendWord(Word data, Boolean *p_half_filled_word)
  1020. {
  1021.   IncMaxCodeLen(1);
  1022.   WAsmCode[CodeLen++] = data;
  1023.   *p_half_filled_word = False;
  1024. }
  1025.  
  1026. static void AppendByte(Byte data, Boolean *p_half_filled_word)
  1027. {
  1028.   if (*p_half_filled_word)
  1029.   {
  1030.     WAsmCode[CodeLen - 1] |= data & 0xff;
  1031.     *p_half_filled_word = False;
  1032.   }
  1033.   else
  1034.   {
  1035.     AppendWord(data << 8, p_half_filled_word);
  1036.     *p_half_filled_word = True;
  1037.   }
  1038. }
  1039.  
  1040. static void DecodeDC(Word Code)
  1041. {
  1042.   Boolean HalfFilledWord = False;
  1043.   TempResult t;
  1044.  
  1045.   UNUSED(Code);
  1046.  
  1047.   as_tempres_ini(&t);
  1048.   if (ChkArgCnt(1, ArgCntMax))
  1049.   {
  1050.     Boolean OK = True;
  1051.     tStrComp *pArg;
  1052.  
  1053.     forallargs(pArg, OK)
  1054.     {
  1055.       EvalStrExpression(pArg, &t);
  1056.       if (mFirstPassUnknown(t.Flags) && (t.Typ == TempInt)) t.Contents.Int &= 0x7fff;
  1057.       switch (t.Typ)
  1058.       {
  1059.         case TempInt:
  1060.           if (Packing)
  1061.           {
  1062.             if (mFirstPassUnknown(t.Flags))
  1063.               t.Contents.Int &= 127;
  1064.             if (ChkRange(t.Contents.Int, -128, 255))
  1065.               AppendByte(t.Contents.Int, &HalfFilledWord);
  1066.             else
  1067.               OK = False;
  1068.           }
  1069.           else
  1070.           {
  1071.           ToInt:
  1072.             if (mFirstPassUnknown(t.Flags))
  1073.               t.Contents.Int &= 32767;
  1074.             if (ChkRange(t.Contents.Int, -32768, 65535))
  1075.               AppendWord(t.Contents.Int, &HalfFilledWord);
  1076.             else
  1077.               OK = False;
  1078.           }
  1079.           break;
  1080.         case TempString:
  1081.         {
  1082.           Word Trans;
  1083.           int z2;
  1084.  
  1085.           if (MultiCharToInt(&t, 2))
  1086.             goto ToInt;
  1087.  
  1088.           if (as_chartrans_xlate_nonz_dynstr(CurrTransTable->p_table, &t.Contents.str, pArg))
  1089.             OK = False;
  1090.           else
  1091.             for (z2 = 0; z2 < (int)t.Contents.str.len; z2++)
  1092.             {
  1093.               Trans = ((usint) t.Contents.str.p_str[z2]) & 0xff;
  1094.               AppendByte(Trans, &HalfFilledWord);
  1095.             }
  1096.           break;
  1097.         }
  1098.         case TempFloat:
  1099.         {
  1100.           IncMaxCodeLen(2);
  1101.           if (Double2IBMFloat(&WAsmCode[CodeLen], t.Contents.Float, False))
  1102.             CodeLen += 2;
  1103.           else
  1104.             OK = False;
  1105.           HalfFilledWord = False;
  1106.           break;
  1107.         }
  1108.         default:
  1109.           OK = False;
  1110.       }
  1111.     }
  1112.     if (!OK)
  1113.        CodeLen = 0;
  1114.   }
  1115.   as_tempres_free(&t);
  1116. }
  1117.  
  1118. static void DecodeDS(Word Index)
  1119. {
  1120.   Boolean OK;
  1121.   Word Size;
  1122.   tSymbolFlags Flags;
  1123.  
  1124.   UNUSED(Index);
  1125.  
  1126.   Size = EvalStrIntExpressionWithFlags(&ArgStr[1], UInt16, &OK, &Flags);
  1127.   if (mFirstPassUnknown(Flags)) WrError(ErrNum_FirstPassCalc);
  1128.   if (OK && !mFirstPassUnknown(Flags))
  1129.   {
  1130.     DontPrint = True;
  1131.     if (!Size) WrError(ErrNum_NullResMem);
  1132.     CodeLen = Size;
  1133.     BookKeeping();
  1134.   }
  1135. }
  1136.  
  1137. /*--------------------------------------------------------------------------*/
  1138. /* Codetabellen */
  1139.  
  1140. static void AddFixed(const char *pName, Word Code, CPUVar MinCPU)
  1141. {
  1142.   order_array_rsv_end(FixedOrders, tFixedOrder);
  1143.   FixedOrders[InstrZ].Code = Code;
  1144.   FixedOrders[InstrZ].MinCPU = MinCPU;
  1145.   AddInstTable(InstTable, pName, InstrZ++, DecodeFixed);
  1146. }
  1147.  
  1148. static void InitFields(void)
  1149. {
  1150.   InstTable = CreateInstTable(201);
  1151.  
  1152.   InstrZ = 0;
  1153.   AddFixed("H"   , 0x2000 , CPUMN1610);
  1154.   AddFixed("RET" , 0x2003 , CPUMN1610);
  1155.   AddFixed("NOP" , NOPCode, CPUMN1610);
  1156.   AddFixed("PSHM", 0x170f , CPUMN1613);
  1157.   AddFixed("POPM", 0x1707 , CPUMN1613);
  1158.   AddFixed("RETL", 0x3f07 , CPUMN1613);
  1159.  
  1160.   AddInstTable(InstTable, "PUSH", 0x2001, DecodeOneReg);
  1161.   AddInstTable(InstTable, "POP" , 0x2002, DecodeOneReg);
  1162.  
  1163.   /* allow WR as alias to WT */
  1164.  
  1165.   AddInstTable(InstTable, "RD"  , 0x1800, DecodeRegImm);
  1166.   AddInstTable(InstTable, "WT"  , 0x1000, DecodeRegImm);
  1167.   AddInstTable(InstTable, "WR"  , 0x1000, DecodeRegImm);
  1168.   AddInstTable(InstTable, "MVI" , 0x0800, DecodeRegImm);
  1169.  
  1170.   AddInstTable(InstTable, "A"   , 0x5808, DecodeTwoReg);
  1171.   AddInstTable(InstTable, "S"   , 0x5800, DecodeTwoReg);
  1172.   AddInstTable(InstTable, "C"   , 0x5008, DecodeTwoReg);
  1173.   AddInstTable(InstTable, "CB"  , 0x5000, DecodeTwoReg);
  1174.   AddInstTable(InstTable, "MV"  , 0x7808, DecodeTwoReg);
  1175.   AddInstTable(InstTable, "MVB" , 0x7800, DecodeTwoReg);
  1176.   AddInstTable(InstTable, "BSWP", 0x7008, DecodeTwoReg);
  1177.   AddInstTable(InstTable, "DSWP", 0x7000, DecodeTwoReg);
  1178.   AddInstTable(InstTable, "LAD" , 0x6800, DecodeTwoReg);
  1179.   AddInstTable(InstTable, "AND" , 0x6808, DecodeTwoReg);
  1180.   AddInstTable(InstTable, "OR"  , 0x6008, DecodeTwoReg);
  1181.   AddInstTable(InstTable, "EOR" , 0x6000, DecodeTwoReg);
  1182.  
  1183.   AddInstTable(InstTable, "L"   , 0xc000, DecodeEAReg);
  1184.   AddInstTable(InstTable, "ST"  , 0x8000, DecodeEAReg);
  1185.   AddInstTable(InstTable, "B"   , 0xc700, DecodeEA);
  1186.   AddInstTable(InstTable, "BAL" , 0x8700, DecodeEA);
  1187.   AddInstTable(InstTable, "IMS" , 0xc600, DecodeEA);
  1188.   AddInstTable(InstTable, "DMS" , 0x8600, DecodeEA);
  1189.  
  1190.   AddInstTable(InstTable, "SL"  , 0x200c, DecodeShift);
  1191.   AddInstTable(InstTable, "SR"  , 0x2008, DecodeShift);
  1192.  
  1193.   AddInstTable(InstTable, "SBIT", 0x3800, DecodeImm4);
  1194.   AddInstTable(InstTable, "RBIT", 0x3000, DecodeImm4);
  1195.   AddInstTable(InstTable, "TBIT", 0x2800, DecodeImm4);
  1196.   AddInstTable(InstTable, "AI"  , 0x4800, DecodeImm4);
  1197.   AddInstTable(InstTable, "SI"  , 0x4000, DecodeImm4);
  1198.  
  1199.   AddInstTable(InstTable, "LPSW", 0x2004, DecodeImm2);
  1200.  
  1201.   /* new to MN1613 */
  1202.  
  1203.   AddInstTable(InstTable, "LD"  , 0x2708, DecodeLD_STD);
  1204.   AddInstTable(InstTable, "STD" , 0x2748, DecodeLD_STD);
  1205.   AddInstTable(InstTable, "LR"  , 0x2000, DecodeLR_STR);
  1206.   AddInstTable(InstTable, "STR" , 0x2004, DecodeLR_STR);
  1207.  
  1208.   AddInstTable(InstTable, "MVWR", 0x7f08, DecodeR0RISkip);
  1209.   AddInstTable(InstTable, "MVBR", 0x7f00, DecodeR0RISkip);
  1210.   AddInstTable(InstTable, "BSWR", 0x7708, DecodeR0RISkip);
  1211.   AddInstTable(InstTable, "DSWR", 0x7700, DecodeR0RISkip);
  1212.   AddInstTable(InstTable, "AWR" , 0x5f08, DecodeR0RISkip);
  1213.   AddInstTable(InstTable, "SWR" , 0x5f00, DecodeR0RISkip);
  1214.   AddInstTable(InstTable, "CWR" , 0x5708, DecodeR0RISkip);
  1215.   AddInstTable(InstTable, "CBR" , 0x5700, DecodeR0RISkip);
  1216.   AddInstTable(InstTable, "LADR", 0x6f00, DecodeR0RISkip);
  1217.   AddInstTable(InstTable, "ANDR", 0x6f08, DecodeR0RISkip);
  1218.   AddInstTable(InstTable, "ORR" , 0x6708, DecodeR0RISkip);
  1219.   AddInstTable(InstTable, "EORR", 0x6700, DecodeR0RISkip);
  1220.  
  1221.   AddInstTable(InstTable, "MVWI", 0x780f, DecodeRImmSkip);
  1222.   AddInstTable(InstTable, "AWI" , 0x580f, DecodeRImmSkip);
  1223.   AddInstTable(InstTable, "SWI" , 0x5807, DecodeRImmSkip);
  1224.   AddInstTable(InstTable, "CWI" , 0x500f, DecodeRImmSkip);
  1225.   AddInstTable(InstTable, "CBI" , 0x5007, DecodeRImmSkip);
  1226.   AddInstTable(InstTable, "LADI", 0x6807, DecodeRImmSkip);
  1227.   AddInstTable(InstTable, "ANDI", 0x680f, DecodeRImmSkip);
  1228.   AddInstTable(InstTable, "ORI" , 0x600f, DecodeRImmSkip);
  1229.   AddInstTable(InstTable, "EORI", 0x6007, DecodeRImmSkip);
  1230.  
  1231.   AddInstTable(InstTable, "AD"  , 0x4f14, DecodeDR0RISkip);
  1232.   AddInstTable(InstTable, "SD"  , 0x4714, DecodeDR0RISkip);
  1233.   AddInstTable(InstTable, "M"   , 0x7f0c, DecodeDR0RISkip);
  1234.   AddInstTable(InstTable, "D"   , 0x770c, DecodeDR0RISkip);
  1235.   AddInstTable(InstTable, "FA"  , 0x6f0c, DecodeDR0RISkip);
  1236.   AddInstTable(InstTable, "FS"  , 0x6f04, DecodeDR0RISkip);
  1237.   AddInstTable(InstTable, "FM"  , 0x670c, DecodeDR0RISkip);
  1238.   AddInstTable(InstTable, "FD"  , 0x6704, DecodeDR0RISkip);
  1239.  
  1240.   AddInstTable(InstTable, "DAA" , 0x5f04, DecodeDAA_DAS);
  1241.   AddInstTable(InstTable, "DAS" , 0x5704, DecodeDAA_DAS);
  1242.  
  1243.   AddInstTable(InstTable, "RDR" , 0x2014, DecodeRDR_WTR);
  1244.   AddInstTable(InstTable, "WTR" , 0x2010, DecodeRDR_WTR);
  1245.  
  1246.   AddInstTable(InstTable, "BD"  , 0x2607, DecodeBD_BALD);
  1247.   AddInstTable(InstTable, "BALD", 0x2617, DecodeBD_BALD);
  1248.  
  1249.   AddInstTable(InstTable, "BL"  , 0x270f, DecodeBL_BALL);
  1250.   AddInstTable(InstTable, "BALL", 0x271f, DecodeBL_BALL);
  1251.  
  1252.   AddInstTable(InstTable, "BR"  , 0x2704, DecodeBR_BALR);
  1253.   AddInstTable(InstTable, "BALR", 0x2714, DecodeBR_BALR);
  1254.  
  1255.   AddInstTable(InstTable, "TSET", 0x1708, DecodeTSET_TRST);
  1256.   AddInstTable(InstTable, "TRST", 0x1700, DecodeTSET_TRST);
  1257.  
  1258.   AddInstTable(InstTable, "NEG" , 0x1f00, DecodeNEG);
  1259.   AddInstTable(InstTable, "FIX" , 0x1f0f, DecodeFIX);
  1260.   AddInstTable(InstTable, "FLT" , 0x1f07, DecodeFLT);
  1261.  
  1262.   AddInstTable(InstTable, "SRBT", 0x3f70, DecodeSRBT);
  1263.   AddInstTable(InstTable, "DEBP", 0x3ff0, DecodeDEBP);
  1264.   AddInstTable(InstTable, "BLK" , 0x3f17, DecodeBLK);
  1265.  
  1266.   AddInstTable(InstTable, "LB"  , 0x0f07, DecodeLBS_STBS);
  1267.   AddInstTable(InstTable, "LS"  , 0x0f0f, DecodeLBS_STBS);
  1268.   AddInstTable(InstTable, "STB" , 0x0f87, DecodeLBS_STBS);
  1269.   AddInstTable(InstTable, "STS" , 0x0f8f, DecodeLBS_STBS);
  1270.  
  1271.   AddInstTable(InstTable, "CPYB", 0x0f80, DecodeCPYBS_SETBS);
  1272.   AddInstTable(InstTable, "CPYS", 0x0f88, DecodeCPYBS_SETBS);
  1273.   AddInstTable(InstTable, "SETB", 0x0f00, DecodeCPYBS_SETBS);
  1274.   AddInstTable(InstTable, "SETS", 0x0f08, DecodeCPYBS_SETBS);
  1275.  
  1276.   AddInstTable(InstTable, "CPYH", 0x3f80, DecodeCPYH_SETH);
  1277.   AddInstTable(InstTable, "SETH", 0x3f00, DecodeCPYH_SETH);
  1278.  
  1279.   /* aliases */
  1280.  
  1281.   AddInstTable(InstTable, "CLR",   0x6000, DecodeCLR);
  1282.   AddInstTable(InstTable, "CLEAR", 0x6000, DecodeCLR);
  1283.   AddInstTable(InstTable, "SKIP",  0x7808, DecodeSKIP);
  1284.  
  1285.   /* pseudo instructions */
  1286.  
  1287.   AddInstTable(InstTable, "DC"  , 0, DecodeDC);
  1288.   AddInstTable(InstTable, "DS"  , 0, DecodeDS);
  1289. }
  1290.  
  1291. static void DeinitFields(void)
  1292. {
  1293.   DestroyInstTable(InstTable);
  1294.   order_array_free(FixedOrders);
  1295. }
  1296.  
  1297. /*--------------------------------------------------------------------------*/
  1298. /* Interface to AS */
  1299.  
  1300. static Boolean DecodeAttrPart_MN1610_Alt(void)
  1301. {
  1302.   if (strlen(AttrPart.str.p_str) > 1)
  1303.   {
  1304.     WrStrErrorPos(ErrNum_UndefAttr, &AttrPart);
  1305.     return False;
  1306.   }
  1307.  
  1308.   return DecodeMoto16AttrSize(*AttrPart.str.p_str, &AttrPartOpSize[0], False);
  1309. }
  1310.  
  1311. static void MakeCode_MN1610_Alt(void)
  1312. {
  1313.   OpSize = (AttrPartOpSize[0] != eSymbolSizeUnknown) ? AttrPartOpSize[0] : eSymbolSize16Bit;
  1314.  
  1315.   /* Ignore empty instruction */
  1316.  
  1317.   if (Memo("")) return;
  1318.  
  1319.   /* Pseudo Instructions */
  1320.  
  1321.   if (!LookupInstTable(InstTable, OpPart.str.p_str))
  1322.     WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
  1323. }
  1324.  
  1325. static Boolean IsDef_MN1610_Alt(void)
  1326. {
  1327.   return FALSE;
  1328. }
  1329.  
  1330. static void SwitchFrom_MN1610_Alt(void)
  1331. {
  1332.   DeinitFields();
  1333. }
  1334.  
  1335. static void SwitchTo_MN1610_Alt(void)
  1336. {
  1337.   const TFamilyDescr *FoundDescr;
  1338.  
  1339.   FoundDescr = FindFamilyByName("MN161x");
  1340.  
  1341.   TurnWords = True;
  1342.   SetIntConstMode(eIntConstModeIBM);
  1343.  
  1344.   PCSymbol = "*";
  1345.   HeaderID = FoundDescr->Id;
  1346.   NOPCode = 0x7808; /* MV R0,R0 */
  1347.   DivideChars = ",";
  1348.   HasAttrs = False;
  1349.   AttrChars = ".";
  1350.  
  1351.   ValidSegs = (1 << SegCode) | (1 << SegIO);
  1352.   Grans[SegCode]     = Grans[SegIO]     = 2;
  1353.   ListGrans[SegCode] = ListGrans[SegIO] = 2;
  1354.   SegInits[SegCode]  = SegInits[SegIO]  = 0;
  1355.   if (MomCPU == CPUMN1613)
  1356.   {
  1357.     SegLimits[SegCode] = 0x3ffff;
  1358.     SegLimits[SegIO] = 0xffff;
  1359.     pASSUMERecs = ASSUMEMN1613;
  1360.     ASSUMERecCnt = ASSUMEMN1613Count;
  1361.   }
  1362.   else
  1363.   {
  1364.     SegLimits[SegCode] = 0xffff;
  1365.     SegLimits[SegIO] = 0xff; /* no RDR/WTR insn */
  1366.   }
  1367.  
  1368.   onoff_packing_add(False);
  1369.  
  1370.   DecodeAttrPart = DecodeAttrPart_MN1610_Alt;
  1371.   MakeCode = MakeCode_MN1610_Alt;
  1372.   IsDef = IsDef_MN1610_Alt;
  1373.   SwitchFrom = SwitchFrom_MN1610_Alt;
  1374.   InitFields();
  1375. }
  1376.  
  1377. /*--------------------------------------------------------------------------*/
  1378. /* Initialisierung */
  1379.  
  1380. void codemn2610_init(void)
  1381. {
  1382.   CPUMN1610 = AddCPU("MN1610ALT", SwitchTo_MN1610_Alt);
  1383.   CPUMN1613 = AddCPU("MN1613ALT", SwitchTo_MN1610_Alt);
  1384. }
  1385.