Subversion Repositories pentevo

Rev

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

  1. /* codemn1610.c */
  2. /*****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
  4. /*                                                                           */
  5. /* AS-Portierung                                                             */
  6. /*                                                                           */
  7. /* Codegenerator Panafacom MN1610 / MN1613                                   */
  8. /*                                                                           */
  9. /*****************************************************************************/
  10.  
  11. #include "stdinc.h"
  12. #include <ctype.h>
  13. #include <string.h>
  14.  
  15. #include "nls.h"
  16. #include "strutil.h"
  17. #include "chunks.h"
  18. #include "asmdef.h"
  19. #include "asmsub.h"
  20. #include "asmpars.h"
  21. #include "asmallg.h"
  22. #include "onoff_common.h"
  23. #include "asmitree.h"
  24. #include "codevars.h"
  25. #include "codepseudo.h"
  26. #include "errmsg.h"
  27. #include "ibmfloat.h"
  28. #include "chartrans.h"
  29.  
  30. #include "codemn1610.h"
  31.  
  32. /*---------------------------------------------------------------------------*/
  33.  
  34. static CPUVar CPUMN1610;
  35. static CPUVar CPUMN1613;
  36.  
  37. static tStrComp Inner;
  38. static tStrComp InnerZ;
  39.  
  40. /*---------------------------------------------------------------------------*/
  41.  
  42. static Boolean DecReg(const char *pAsc, Word *pErg, Boolean errMsg)
  43. {
  44.         if (!as_strcasecmp(pAsc, "SP"))
  45.         {
  46.                 *pErg = 5;
  47.                 return True;
  48.         }
  49.  
  50.         if (!as_strcasecmp(pAsc, "STR"))
  51.         {
  52.                 *pErg = 6;
  53.                 return True;
  54.         }
  55.  
  56.         if (!as_strcasecmp(pAsc, "IC"))
  57.         {
  58.                 *pErg = 7;
  59.                 return True;
  60.         }
  61.  
  62.         if (strlen(pAsc) != 2)
  63.         {
  64.                 WrError(ErrNum_InvRegName);
  65.                 return False;
  66.         }
  67.  
  68.         if (toupper(pAsc[0]) == 'R' && pAsc[1] >= '0' && pAsc[1] <= '4')
  69.         {
  70.                 *pErg = pAsc[1] - '0';
  71.                 return True;
  72.         }
  73.  
  74.         if (toupper(pAsc[0]) == 'X' && pAsc[1] >= '0' && pAsc[1] <= '1')
  75.         {
  76.                 *pErg = pAsc[1] - '0' + 3;
  77.                 return True;
  78.         }
  79.  
  80.         if (errMsg) WrError(ErrNum_InvRegName);
  81.         return False;
  82. }
  83.  
  84. static Boolean DecSkip(const char *pAsc, Word *pErg, Boolean errMsg)
  85. {
  86.         static struct {
  87.                 const char *str;
  88.                 Word skip;
  89.         } SkipTable[] = {
  90.                 { "SKP", 0x1 },
  91.                 { "M",   0x2 },
  92.                 { "PZ",  0x3 },
  93.                 { "Z",   0x4 }, { "E",   0x4 },
  94.                 { "NZ",  0x5 }, { "NE",  0x5 },
  95.                 { "MZ",  0x6 },
  96.                 { "P",   0x7 },
  97.                 { "EZ",  0x8 },
  98.                 { "ENZ", 0x9 },
  99.                 { "OZ",  0xa },
  100.                 { "ONZ", 0xb },
  101.                 { "LMZ", 0xc },
  102.                 { "LP",  0xd },
  103.                 { "LPZ", 0xe },
  104.                 { "LM",  0xf },
  105.                 { NULL,  0x0 } };
  106.         int i;
  107.  
  108.         for (i = 0; SkipTable[i].str; i++)
  109.         {
  110.                 if (!as_strcasecmp(pAsc, SkipTable[i].str))
  111.                 {
  112.                         *pErg = SkipTable[i].skip;
  113.                         return True;
  114.                 }
  115.         }
  116.  
  117.         if (errMsg) WrError(ErrNum_UndefCond);
  118.         return False;
  119. }
  120.  
  121. static Boolean DecEM(const char *pAsc, Word *pErg, Boolean errMsg)
  122. {
  123.         static struct {
  124.                 const char *str;
  125.                 Word em;
  126.         } EMTable[] = {
  127.                 { "RE", 0x1 },
  128.                 { "SE", 0x2 },
  129.                 { "CE", 0x3 },
  130.                 { NULL, 0x0 } };
  131.         int i;
  132.  
  133.         for (i = 0; EMTable[i].str; i++)
  134.         {
  135.                 if (!as_strcasecmp(pAsc, EMTable[i].str))
  136.                 {
  137.                         *pErg = EMTable[i].em;
  138.                         return True;
  139.                 }
  140.         }
  141.  
  142.         if (errMsg) WrError(ErrNum_InvShiftArg);
  143.         return False;
  144. }
  145.  
  146. static Boolean DecBB(const char *pAsc, Word *pErg)
  147. {
  148.         static struct {
  149.                 const char *str;
  150.                 Word bb;
  151.         } BBTable[] = {
  152.                 { "CSBR", 0x0 },
  153.                 { "SSBR", 0x1 },
  154.                 { "TSR0", 0x2 },
  155.                 { "TSR1", 0x3 },
  156.                 { NULL,   0x0 } };
  157.         int i;
  158.  
  159.         for (i = 0; BBTable[i].str; i++)
  160.         {
  161.                 if (!as_strcasecmp(pAsc, BBTable[i].str))
  162.                 {
  163.                         *pErg = BBTable[i].bb;
  164.                         return True;
  165.                 }
  166.         }
  167.  
  168.         WrError(ErrNum_UnknownSegReg);
  169.         return False;
  170. }
  171.  
  172. static Boolean DecRIndirect(const char *pAsc, Word *mm, Word *ii, Boolean bAuto)
  173. {
  174.         int l = strlen(pAsc);
  175.         int rp;
  176.         char MinReg, MaxReg;
  177.         Word RegOffs;
  178.  
  179.         if (l == 4 && pAsc[0] == '(' && pAsc[3] == ')')
  180.         {
  181.                 *mm = 0x1;
  182.                 rp = 1;
  183.         }
  184.         else if (l == 5 && pAsc[0] == '-' && pAsc[1] == '(' && pAsc[4] == ')')
  185.         {
  186.                 *mm = 0x2;
  187.                 rp = 2;
  188.         }
  189.         else if (l == 5 && pAsc[0] == '(' && pAsc[3] == ')' && pAsc[4] == '+')
  190.         {
  191.                 *mm = 0x3;
  192.                 rp = 1;
  193.         }
  194.         else
  195.         {
  196.                 WrError(ErrNum_InvArg);
  197.                 return False;
  198.         }
  199.  
  200.         if (!bAuto && *mm != 0x1)
  201.         {
  202.                 WrError(ErrNum_InvArg);
  203.                 return False;
  204.         }
  205.  
  206.         switch (toupper(pAsc[rp]))
  207.         {
  208.                 case 'R':
  209.                         MinReg = '1'; MaxReg = '4';
  210.                         RegOffs = 0;
  211.                         break;
  212.                 case 'X':
  213.                         MinReg = '0'; MaxReg = '1';
  214.                         RegOffs = 2;
  215.                         break;
  216.                 default:
  217.                         WrError(ErrNum_InvReg);
  218.                         return False;
  219.         }
  220.  
  221.         if (pAsc[rp + 1] < MinReg || pAsc[rp + 1] > MaxReg)
  222.         {
  223.                 WrError(ErrNum_InvReg);
  224.                 return False;
  225.         }
  226.  
  227.         *ii = pAsc[rp + 1] - MinReg + RegOffs;
  228.  
  229.         return True;
  230. }
  231.  
  232. static Boolean DecC(const char *pAsc, Word *pErg, Boolean errMsg)
  233. {
  234.         if (strlen(pAsc) == 1)
  235.         {
  236.                 if (pAsc[0] == '0')
  237.                 {
  238.                         *pErg = 0;
  239.                         return True;
  240.                 }
  241.                 if (pAsc[0] == '1' || toupper(pAsc[0]) == 'C')
  242.                 {
  243.                         *pErg = 1;
  244.                         return True;
  245.                 }
  246.         }
  247.  
  248.         if (errMsg) WrError(ErrNum_InvArg);
  249.         return False;
  250. }
  251.  
  252. static Boolean DecDReg(const char *pAsc, Boolean errMsg)
  253. {
  254.         if (as_strcasecmp(pAsc, "DR0") == 0) return True;
  255.  
  256.         if (errMsg) WrError(ErrNum_InvReg);
  257.         return False;
  258. }
  259.  
  260. static Boolean DecBR(const char *pAsc, Word *pErg)
  261. {
  262.         static struct {
  263.                 const char *str;
  264.                 Word bbb;
  265.         } BRTable[] = {
  266.                 { "CSBR", 0x0 },
  267.                 { "SSBR", 0x1 },
  268.                 { "TSR0", 0x2 },
  269.                 { "TSR1", 0x3 },
  270.                 { "OSR0", 0x4 },
  271.                 { "OSR1", 0x5 },
  272.                 { "OSR2", 0x6 },
  273.                 { "OSR3", 0x7 },
  274.                 { NULL,   0x0 } };
  275.         int i;
  276.  
  277.         for (i = 0; BRTable[i].str; i++)
  278.         {
  279.                 if (!as_strcasecmp(pAsc, BRTable[i].str))
  280.                 {
  281.                         *pErg = BRTable[i].bbb;
  282.                         return True;
  283.                 }
  284.         }
  285.  
  286.         WrError(ErrNum_UnknownSegReg);
  287.         return False;
  288. }
  289.  
  290. static Boolean DecSR(const char *pAsc, Word *pErg)
  291. {
  292.         static struct {
  293.                 const char *str;
  294.                 Word ppp;
  295.         } SRTable[] = {
  296.                 { "SBRB", 0x0 },
  297.                 { "ICB",  0x1 },
  298.                 { "NPP",  0x2 },
  299.                 { NULL,   0x0 } };
  300.         int i;
  301.  
  302.         for (i = 0; SRTable[i].str; i++)
  303.         {
  304.                 if (!as_strcasecmp(pAsc, SRTable[i].str))
  305.                 {
  306.                         *pErg = SRTable[i].ppp;
  307.                         return True;
  308.                 }
  309.         }
  310.  
  311.         WrError(ErrNum_InvRegName);
  312.         return False;
  313. }
  314.  
  315. static Boolean DecHR(const char *pAsc, Word *pErg)
  316. {
  317.         static struct {
  318.                 const char *str;
  319.                 Word hhh;
  320.         } HRTable[] = {
  321.                 { "TCR",  0x0 },
  322.                 { "TIR",  0x1 },
  323.                 { "TSR",  0x2 },
  324.                 { "SCR",  0x3 },
  325.                 { "SSR",  0x4 },
  326.                 { "SOR",  0x5 },
  327.                 { "SIR",  0x5 },
  328.                 { "IISR", 0x6 },
  329.                 { NULL,   0x0 } };
  330.         int i;
  331.  
  332.         for (i = 0; HRTable[i].str; i++)
  333.         {
  334.                 if (!as_strcasecmp(pAsc, HRTable[i].str))
  335.                 {
  336.                         *pErg = HRTable[i].hhh;
  337.                         return True;
  338.                 }
  339.         }
  340.  
  341.         WrError(ErrNum_InvRegName);
  342.         return False;
  343. }
  344.  
  345. /* MN1610 */
  346.  
  347. /* XXXX Rn, Adr  or  XXXX Adr */
  348. static void DecodeAdr(Word Index)
  349. {
  350.         int idx;
  351.         Boolean indirect;
  352.         tStrComp Left, Right;
  353.         Word preg;
  354.         Boolean index;
  355.         tStrComp *sc;
  356.         Word reg = 0;
  357.         Word mode = 0;
  358.         LongInt adr;
  359.         Boolean OK;
  360.         int disp = 0;
  361.         int l;
  362.        
  363.         if ((Index & 0x0700) == 0x0600) /* IMS/DMS */
  364.         {
  365.                 if (!ChkArgCnt(1,1)) return;
  366.                 idx = 1;
  367.         }
  368.         else if ((Index & 0x0700) == 0x0700)    /* B/BAL */
  369.         {
  370.                 if (!ChkArgCnt(1,1)) return;
  371.                 idx = 1;
  372.         }
  373.         else
  374.         {
  375.                 if (!ChkArgCnt(2,2)) return;
  376.                 if (!DecReg(ArgStr[1].str.p_str, &reg, True)) return;
  377.                 if (reg == 6 || reg == 7)
  378.                 {
  379.                         WrStrErrorPos(ErrNum_InvRegName, &ArgStr[1]);
  380.                         return;
  381.                 }
  382.                 idx = 2;
  383.         }
  384.  
  385.         sc = &ArgStr[idx];
  386.         indirect = IsIndirect(ArgStr[idx].str.p_str);
  387.         if (indirect)
  388.         {
  389.                 l = strlen(ArgStr[idx].str.p_str);
  390.                 StrCompCopySub(&Inner, &ArgStr[idx], 1, l - 2);
  391.                 sc = &Inner;
  392.         }
  393.  
  394.         index = False;
  395.         l = strlen(sc->str.p_str);
  396.         if (l > 4 && sc->str.p_str[l - 4] == '(' && sc->str.p_str[l - 1] == ')')
  397.         {
  398.                 StrCompSplitRef(&Left, &Right, sc, sc->str.p_str + l - 4);
  399.                 StrCompShorten(&Right, 1);
  400.  
  401.                 if (DecReg(Right.str.p_str, &preg, False))
  402.                 {
  403.                         switch (preg) {
  404.                         case 3:
  405.                                 index = True;
  406.                                 break;
  407.                         case 4:
  408.                                 index = True;
  409.                                 break;
  410.                         case 7:
  411.                                 index = True;
  412.                                 break;
  413.                         default:
  414.                                 break;
  415.                         }
  416.                 }
  417.         }
  418.  
  419.         if (as_strcasecmp(ArgStr[idx].str.p_str, "(X0)") == 0)
  420.         {
  421.                 mode = 4;
  422.                 disp = 0;
  423.         }
  424.         else if (as_strcasecmp(ArgStr[idx].str.p_str, "(X1)") == 0)
  425.         {
  426.                 mode = 5;
  427.                 disp = 0;
  428.         }
  429.         else if (index)
  430.         {
  431.                 if (IsIndirect(Left.str.p_str))
  432.                 {       /* (zadr)(X0) , (zadr)(X1) */
  433.                         tEvalResult EvalResult;
  434.  
  435.                         l = strlen(Left.str.p_str);
  436.                         StrCompCopySub(&InnerZ, &Left, 1, l - 2);
  437.                         disp = EvalStrIntExpressionWithResult(&InnerZ, Int16, &EvalResult);
  438.                         if (!EvalResult.OK) return;
  439.                         ChkSpace(SegCode, EvalResult.AddrSpaceMask);
  440.                         if (disp < 0 || disp > 0xff)
  441.                         {
  442.                                 WrError(ErrNum_OverRange);
  443.                                 return;
  444.                         }
  445.  
  446.                         switch (preg)
  447.                         {
  448.                         case 3:
  449.                                 mode = 6;
  450.                                 break;
  451.                         case 4:
  452.                                 mode = 7;
  453.                                 break;
  454.                         default:
  455.                                 WrError(ErrNum_InvRegisterPointer);
  456.                                 return;
  457.                         }
  458.                 }
  459.                 else
  460.                 {
  461.                         disp = EvalStrIntExpression(&Left, Int8, &OK);
  462.                         if (!OK) return;
  463.  
  464.                         if (preg == 7)
  465.                         {       /* disp(IC) , (disp(IC)) */
  466.                                 if( disp > 0x7f || disp < -0x80)
  467.                                 {
  468.                                         WrError(ErrNum_OverRange);
  469.                                         return;
  470.                                 }
  471.  
  472.                                 mode = indirect ? 0x3 : 0x1;
  473.                         }
  474.                         else
  475.                         {       /* disp(X0) , disp(X1) */
  476.                                 if( disp > 0xff || disp < -0x00)
  477.                                 {
  478.                                         WrError(ErrNum_OverRange);
  479.                                         return;
  480.                                 }
  481.                                 switch (preg)
  482.                                 {
  483.                                 case 3:
  484.                                         mode = 4;
  485.                                         break;
  486.                                 case 4:
  487.                                         mode = 5;
  488.                                         break;
  489.                                 default:
  490.                                         WrError(ErrNum_InvRegisterPointer);
  491.                                         return;
  492.                                 }
  493.                         }
  494.                 }
  495.         }
  496.         else
  497.         {       /* !index */
  498.                 tEvalResult EvalResult;
  499.  
  500.                 adr = EvalStrIntExpressionWithResult(sc, UInt16, &EvalResult);
  501.                 if (!EvalResult.OK) return;
  502.                 ChkSpace(SegCode, EvalResult.AddrSpaceMask);
  503.                
  504.                 if (adr < 0x100)
  505.                 {
  506.                         mode = indirect ? 0x2 : 0x0;
  507.                         disp = adr;
  508.                 }
  509.                 else
  510.                 {
  511.                         adr -= EProgCounter();
  512.                         if( adr <= 0x7fL && adr >= -0x80L)
  513.                         {
  514.                                 mode = indirect ? 0x3 : 0x1;
  515.                                 disp = adr & 0xff;
  516.                         }
  517.                         else WrError(ErrNum_JmpDistTooBig);
  518.                 }
  519.         }
  520.        
  521.         WAsmCode[0] = Index | (mode << 11 ) | (reg << 8) | (disp & 0xff);
  522.         CodeLen = 1;
  523. }
  524.  
  525. /* XXXX */
  526. static void DecodeFixed(Word Index)
  527. {
  528.         if (ChkArgCnt(0, 0))
  529.         {
  530.                 WAsmCode[0] = Index;
  531.                 CodeLen = 1;
  532.         }
  533. }
  534.  
  535. /* XXXX Rn,Imm8 */
  536. static void DecodeRegImm8(Word Index)
  537. {
  538.         Word reg;
  539.         Byte imm8;
  540.        
  541.         if (ChkArgCnt(2, 2))
  542.         {
  543.                 if (DecReg(ArgStr[1].str.p_str, &reg, True))
  544.                 {
  545.                         tEvalResult EvalResult;
  546.  
  547.                         if (reg == 7)
  548.                         {
  549.                                 WrStrErrorPos(ErrNum_InvRegName, &ArgStr[1]);
  550.                                 return;                        
  551.                         }
  552.                        
  553.                         imm8 = EvalStrIntExpressionWithResult(&ArgStr[2], Int8, &EvalResult);
  554.                         if (EvalResult.OK)
  555.                         {
  556.                                 if (Index & 0x1000) ChkSpace(SegIO, EvalResult.AddrSpaceMask);  /* RD/WR */
  557.  
  558.                                 WAsmCode[0] = Index | ((Word)reg << 8) | imm8;
  559.                                 CodeLen = 1;
  560.                         }
  561.                 }
  562.         }
  563. }
  564.  
  565. /* XXXX Rn */
  566. static void DecodeReg(Word Index)
  567. {
  568.         Word reg;
  569.        
  570.         if (!ChkArgCnt(1,1)) return;
  571.  
  572.         if (!DecReg(ArgStr[1].str.p_str, &reg, True)) return;
  573.         if (reg == 7)
  574.         {
  575.                 WrStrErrorPos(ErrNum_InvRegName, &ArgStr[1]);
  576.                 return;
  577.         }
  578.        
  579.         WAsmCode[0] = Index | (reg << 8);
  580.         CodeLen = 1;
  581. }
  582.  
  583. /* XXXX Rd, Rs[, Skip] */
  584. static void DecodeRegRegSkip(Word Index)
  585. {
  586.         Word reg1;
  587.         Word reg2;
  588.         Word skip = 0;
  589.  
  590.         if (!ChkArgCnt(2,3)) return;
  591.  
  592.         if (!DecReg(ArgStr[1].str.p_str, &reg1, True)) return;
  593.         if (reg1 == 7)
  594.         {
  595.                 WrStrErrorPos(ErrNum_InvRegName, &ArgStr[1]);
  596.                 return;
  597.         }
  598.         if (!DecReg(ArgStr[2].str.p_str, &reg2, True)) return;
  599.         if (reg2 == 7)
  600.         {
  601.                 WrStrErrorPos(ErrNum_InvRegName, &ArgStr[2]);
  602.                 return;
  603.         }
  604.        
  605.         if (ArgCnt == 3)
  606.         {
  607.                 if (!DecSkip(ArgStr[3].str.p_str, &skip, True)) return;
  608.         }
  609.  
  610.         WAsmCode[0] = Index | (reg1 << 8) | reg2 | (skip << 4);
  611.         CodeLen = 1;
  612. }
  613.  
  614. static void DecodeShift(Word Index)
  615. {
  616.         Word reg;
  617.         Word em;
  618.         Word skip;
  619.  
  620.         if (!ChkArgCnt(1,3)) return;
  621.  
  622.         if (!DecReg(ArgStr[1].str.p_str, &reg, True)) return;
  623.         if (reg == 7)
  624.         {
  625.                 WrStrErrorPos(ErrNum_InvRegName, &ArgStr[1]);
  626.                 return;
  627.         }
  628.        
  629.         switch (ArgCnt)
  630.         {
  631.         case 1:
  632.                 em = 0;
  633.                 skip = 0;
  634.                 break;
  635.         case 2:
  636.                 if (DecEM(ArgStr[2].str.p_str, &em, False))
  637.                 {
  638.                         skip = 0;
  639.                 }
  640.                 else if (DecSkip(ArgStr[2].str.p_str, &skip, False))
  641.                 {
  642.                         em = 0;
  643.                 }
  644.                 else
  645.                 {
  646.                         WrStrErrorPos(ErrNum_InvFormat, &ArgStr[2]);
  647.                         return;
  648.                 }
  649.                 break;
  650.         case 3:
  651.                 if (!DecEM(ArgStr[2].str.p_str, &em, True)) return;
  652.                 if (!DecSkip(ArgStr[3].str.p_str, &skip, True)) return;
  653.                 break;
  654.         default:
  655.                 return;
  656.         }
  657.        
  658.         WAsmCode[0] = Index | (reg << 8) | (skip << 4) | em;
  659.         CodeLen = 1;
  660. }
  661.  
  662. static void DecodeBit(Word Index)
  663. {
  664.         Word reg;
  665.         Word skip = 0;
  666.         Byte imm4;
  667.         Boolean OK;
  668.        
  669.         if (!ChkArgCnt(2,3)) return;
  670.  
  671.         if (!DecReg(ArgStr[1].str.p_str, &reg, True)) return;
  672.         if (reg == 7)
  673.         {
  674.                 WrStrErrorPos(ErrNum_InvRegName, &ArgStr[1]);
  675.                 return;
  676.         }
  677.        
  678.         imm4 = EvalStrIntExpression(&ArgStr[2], Int8, &OK);
  679.         if (!OK) return;
  680.         if (/*imm4 < 0 ||*/ imm4 > 0x0f)
  681.         {
  682.                 WrStrErrorPos(ErrNum_OverRange, &ArgStr[2]);
  683.                 return;
  684.         }
  685.  
  686.         if (ArgCnt == 3)
  687.         {
  688.                 if (!DecSkip(ArgStr[3].str.p_str, &skip, True)) return;
  689.         }
  690.        
  691.         WAsmCode[0] = Index | (reg << 8) | (skip << 4) | imm4;
  692.         CodeLen = 1;
  693. }
  694.  
  695. static void DecodeLevel(Word Index)
  696. {
  697.         Word l;
  698.         Boolean OK;
  699.        
  700.         if (!ChkArgCnt(1,1)) return;
  701.  
  702.         l = EvalStrIntExpression(&ArgStr[1], Int8, &OK);
  703.         if (!OK) return;
  704.        
  705.         WAsmCode[0] = Index | l;
  706.         CodeLen = 1;
  707. }
  708.  
  709. /* MN1613 */
  710.  
  711. static void DecodeLD(Word Index)
  712. {
  713.         Word reg;
  714.         Word br = 0x0;  /* CSBR when not specified */
  715.         Word exp;
  716.         tEvalResult EvalResult;
  717.        
  718.         if (!ChkMinCPU(CPUMN1613)) return;
  719.  
  720.         if (!ChkArgCnt(2,3)) return;
  721.  
  722.         if (!DecReg(ArgStr[1].str.p_str, &reg, True)) return;
  723.         if (reg == 6 || reg == 7)
  724.         {
  725.                 WrStrErrorPos(ErrNum_InvRegName, &ArgStr[1]);
  726.                 return;
  727.         }
  728.  
  729.         if (ArgCnt == 3)
  730.         {
  731.                 if (!DecBB(ArgStr[2].str.p_str, &br)) return;
  732.         }
  733.  
  734.         exp = EvalStrIntExpressionWithResult(&ArgStr[ArgCnt], Int16, &EvalResult);
  735.         if (!EvalResult.OK) return;
  736.         ChkSpace(SegCode, EvalResult.AddrSpaceMask);
  737.        
  738.         WAsmCode[0] = Index | (br << 4) | reg;
  739.         WAsmCode[1] = exp;
  740.         CodeLen = 2;
  741. }
  742.  
  743. /* */
  744. static void DecodeLR(Word Index)
  745. {
  746.         Word reg;
  747.         Word br = 0x0;  /* CSBR when not specified */
  748.         Word mm;
  749.         Word ii;
  750.        
  751.         if (!ChkMinCPU(CPUMN1613)) return;
  752.  
  753.         if (!ChkArgCnt(2,3)) return;
  754.  
  755.         if (!DecReg(ArgStr[1].str.p_str, &reg, True)) return;
  756.         if (reg == 6 || reg == 7)
  757.         {
  758.                 WrStrErrorPos(ErrNum_InvRegName, &ArgStr[1]);
  759.                 return;
  760.         }
  761.  
  762.         if (ArgCnt == 3)
  763.         {
  764.                 if (!DecBB(ArgStr[2].str.p_str, &br)) return;
  765.         }
  766.  
  767.         if (!DecRIndirect(ArgStr[ArgCnt].str.p_str, &mm, &ii, True)) return;
  768.  
  769.         WAsmCode[0] = Index | (reg << 8) | (mm << 6) | (br << 4) | ii;
  770.         CodeLen = 1;
  771. }
  772.  
  773. /* XXXX R0,(Ri)[,kkkk] */
  774. static void DecodeMVWR(Word Index)
  775. {
  776.         Word reg;
  777.         Word mm;
  778.         Word ii;
  779.         Word skip = 0;
  780.        
  781.         if (!ChkMinCPU(CPUMN1613)) return;
  782.  
  783.         if (!ChkArgCnt(2,3)) return;
  784.  
  785.         if (!DecReg(ArgStr[1].str.p_str, &reg, True)) return;
  786.         if (reg != 0)
  787.         {
  788.                 WrStrErrorPos(ErrNum_InvReg, &ArgStr[1]);
  789.                 return;
  790.         }
  791.  
  792.         if (!DecRIndirect(ArgStr[2].str.p_str, &mm, &ii, False)) return;
  793.        
  794.         if (ArgCnt == 3)
  795.         {
  796.                 if (!DecSkip(ArgStr[3].str.p_str, &skip, True)) return;
  797.         }
  798.  
  799.  
  800.         WAsmCode[0] = Index | (skip << 4) | ii;
  801.         CodeLen = 1;
  802. }
  803.  
  804. /* XXXX Rd, Exp[, kkkk] */
  805. static void DecodeMVWI(Word Index)
  806. {
  807.         Word reg;
  808.         Word exp;
  809.         Boolean OK;
  810.         Word skip = 0;
  811.        
  812.         if (!ChkMinCPU(CPUMN1613)) return;
  813.  
  814.         if (!ChkArgCnt(2,3)) return;
  815.  
  816.         if (!DecReg(ArgStr[1].str.p_str, &reg, True)) return;
  817.         if (reg == 7)
  818.         {
  819.                 WrStrErrorPos(ErrNum_InvRegName, &ArgStr[1]);
  820.                 return;
  821.         }
  822.        
  823.         exp = EvalStrIntExpression(&ArgStr[2], Int16, &OK);
  824.         if (!OK) return;
  825.        
  826.         if (ArgCnt == 3)
  827.         {
  828.                 if (!DecSkip(ArgStr[3].str.p_str, &skip, True)) return;
  829.         }
  830.  
  831.  
  832.         WAsmCode[0] = Index | (reg << 8) | (skip << 4);
  833.         WAsmCode[1] = exp;
  834.         CodeLen = 2;
  835. }
  836.  
  837. /* XXXX */
  838. static void DecodeFixed1613(Word Index)
  839. {
  840.         if (!ChkMinCPU(CPUMN1613)) return;
  841.  
  842.         if (ChkArgCnt(0, 0))
  843.         {
  844.                 WAsmCode[0] = Index;
  845.                 CodeLen = 1;
  846.         }
  847. }
  848.  
  849. /* XXXX Rd[, C][, kkkk] */
  850. static void DecodeNEG(Word Index)
  851. {
  852.         Word reg;
  853.         Word c = 0;
  854.         Word skip = 0;
  855.        
  856.         if (!ChkMinCPU(CPUMN1613)) return;
  857.  
  858.         if (!ChkArgCnt(1,3)) return;
  859.  
  860.         if (!DecReg(ArgStr[1].str.p_str, &reg, True)) return;
  861.         if (reg == 7)
  862.         {
  863.                 WrStrErrorPos(ErrNum_InvRegName, &ArgStr[1]);
  864.                 return;
  865.         }
  866.  
  867.         if (ArgCnt == 2)
  868.         {
  869.                 if (!DecC(ArgStr[2].str.p_str, &c, False))
  870.                 {
  871.                         if (!DecSkip(ArgStr[2].str.p_str, &skip, True)) return;
  872.                 }
  873.         }
  874.  
  875.         if (ArgCnt == 3)
  876.         {
  877.                 if (!DecC(ArgStr[2].str.p_str, &c, True)) return;
  878.  
  879.                 if (!DecSkip(ArgStr[3].str.p_str, &skip, True)) return;
  880.         }
  881.  
  882.         WAsmCode[0] = Index | (skip << 4) | (c << 3) | reg;
  883.         CodeLen = 1;
  884. }
  885.  
  886. /* XXXX DR0, (Ri)[, C][, kkkk] */
  887. static void DecodeAD(Word Index)
  888. {
  889.         Word mm;
  890.         Word ii;
  891.         Word c = 0;
  892.         Word skip = 0;
  893.        
  894.         if (!ChkMinCPU(CPUMN1613)) return;
  895.  
  896.         if (!ChkArgCnt(2,4)) return;
  897.  
  898.         if (!DecDReg(ArgStr[1].str.p_str, True)) return;
  899.  
  900.         if (!DecRIndirect(ArgStr[2].str.p_str, &mm, &ii, False)) return;
  901.        
  902.         if (ArgCnt == 3)
  903.         {
  904.                 if (!DecC(ArgStr[3].str.p_str, &c, False))
  905.                 {
  906.                         if (!DecSkip(ArgStr[3].str.p_str, &skip, True)) return;
  907.                 }
  908.         }
  909.  
  910.         if (ArgCnt == 4)
  911.         {
  912.                 if (!DecC(ArgStr[3].str.p_str, &c, True)) return;
  913.  
  914.                 if (!DecSkip(ArgStr[4].str.p_str, &skip, True)) return;
  915.         }
  916.  
  917.         WAsmCode[0] = Index | (skip << 4) | (c << 3) | ii;
  918.         CodeLen = 1;
  919. }
  920.  
  921. /* XXXX DR0, (Ri)[, kkkk] */
  922. static void DecodeM(Word Index)
  923. {
  924.         Word mm;
  925.         Word ii;
  926.         Word skip = 0;
  927.        
  928.         if (!ChkMinCPU(CPUMN1613)) return;
  929.  
  930.         if (!ChkArgCnt(2,3)) return;
  931.  
  932.         if (!DecDReg(ArgStr[1].str.p_str, True)) return;
  933.  
  934.         if (!DecRIndirect(ArgStr[2].str.p_str, &mm, &ii, False)) return;
  935.        
  936.         if (ArgCnt == 3)
  937.         {
  938.                 if (!DecSkip(ArgStr[3].str.p_str, &skip, True)) return;
  939.         }
  940.  
  941.         WAsmCode[0] = Index | (skip << 4) | ii;
  942.         CodeLen = 1;
  943. }
  944.  
  945. /* XXXX R0, (Ri)[, C][, kkkk] */
  946. static void DecodeDAA(Word Index)
  947. {
  948.         Word reg;
  949.         Word mm;
  950.         Word ii;
  951.         Word c = 0;
  952.         Word skip = 0;
  953.        
  954.         if (!ChkMinCPU(CPUMN1613)) return;
  955.  
  956.         if (!ChkArgCnt(2,4)) return;
  957.  
  958.         if (!DecReg(ArgStr[1].str.p_str, &reg, True)) return;
  959.         if (reg != 0)
  960.         {
  961.                 WrStrErrorPos(ErrNum_InvReg, &ArgStr[1]);
  962.                 return;
  963.         }
  964.  
  965.         if (!DecRIndirect(ArgStr[2].str.p_str, &mm, &ii, False)) return;
  966.        
  967.         if (ArgCnt == 3)
  968.         {
  969.                 if (!DecC(ArgStr[3].str.p_str, &c, False))
  970.                 {
  971.                         if (!DecSkip(ArgStr[3].str.p_str, &skip, True)) return;
  972.                 }
  973.         }
  974.  
  975.         if (ArgCnt == 4)
  976.         {
  977.                 if (!DecC(ArgStr[3].str.p_str, &c, True)) return;
  978.  
  979.                 if (!DecSkip(ArgStr[4].str.p_str, &skip, True)) return;
  980.         }
  981.  
  982.         WAsmCode[0] = Index | (skip << 4) | (c << 3) | ii;
  983.         CodeLen = 1;
  984. }
  985.  
  986. /* XXXX R0, DR0[, kkkk] */
  987. static void DecodeFIX(Word Index)
  988. {
  989.         Word reg;
  990.         Word skip = 0;
  991.        
  992.         if (!ChkMinCPU(CPUMN1613)) return;
  993.  
  994.         if (!ChkArgCnt(2,3)) return;
  995.  
  996.         if (!DecReg(ArgStr[1].str.p_str, &reg, True)) return;
  997.         if (reg != 0)
  998.         {
  999.                 WrStrErrorPos(ErrNum_InvReg, &ArgStr[1]);
  1000.                 return;
  1001.         }
  1002.  
  1003.         if (!DecDReg(ArgStr[2].str.p_str, True)) return;
  1004.        
  1005.         if (ArgCnt == 3)
  1006.         {
  1007.                 if (!DecSkip(ArgStr[3].str.p_str, &skip, True)) return;
  1008.         }
  1009.  
  1010.         WAsmCode[0] = Index | (skip << 4);
  1011.         CodeLen = 1;
  1012. }
  1013.  
  1014. /* XXXX DR0, R0[, kkkk] */
  1015. static void DecodeFLT(Word Index)
  1016. {
  1017.         Word reg;
  1018.         Word skip = 0;
  1019.        
  1020.         if (!ChkMinCPU(CPUMN1613)) return;
  1021.  
  1022.         if (!ChkArgCnt(2,3)) return;
  1023.  
  1024.         if (!DecDReg(ArgStr[1].str.p_str, True)) return;
  1025.        
  1026.         if (!DecReg(ArgStr[2].str.p_str, &reg, True)) return;
  1027.         if (reg != 0)
  1028.         {
  1029.                 WrStrErrorPos(ErrNum_InvReg, &ArgStr[2]);
  1030.                 return;
  1031.         }
  1032.  
  1033.         if (ArgCnt == 3)
  1034.         {
  1035.                 if (!DecSkip(ArgStr[3].str.p_str, &skip, True)) return;
  1036.         }
  1037.  
  1038.         WAsmCode[0] = Index | (skip << 4);
  1039.         CodeLen = 1;
  1040. }
  1041.  
  1042. /* XXXX Exp */
  1043. static void DecodeBD(Word Index)
  1044. {
  1045.         Word exp;
  1046.         tEvalResult EvalResult;
  1047.        
  1048.         if (!ChkMinCPU(CPUMN1613)) return;
  1049.  
  1050.         if (!ChkArgCnt(1,1)) return;
  1051.  
  1052.         exp = EvalStrIntExpressionWithResult(&ArgStr[1], Int16, &EvalResult);
  1053.         if (!EvalResult.OK) return;
  1054.         ChkSpace(SegCode, EvalResult.AddrSpaceMask);
  1055.  
  1056.         WAsmCode[0] = Index;
  1057.         WAsmCode[1] = exp;
  1058.         CodeLen = 2;
  1059. }
  1060.  
  1061. /* XXXX (Exp) */
  1062. static void DecodeBL(Word Index)
  1063. {
  1064.         int l;
  1065.         Word exp;
  1066.         tEvalResult EvalResult;
  1067.        
  1068.         if (!ChkMinCPU(CPUMN1613)) return;
  1069.  
  1070.         if (!ChkArgCnt(1,1)) return;
  1071.  
  1072.         l = strlen(ArgStr[1].str.p_str);
  1073.  
  1074.         if (l < 3 || ArgStr[1].str.p_str[0] != '(' || ArgStr[1].str.p_str[l - 1] != ')')
  1075.         {
  1076.                 WrStrErrorPos(ErrNum_InvArg, &ArgStr[1]);
  1077.                 return;
  1078.         }
  1079.  
  1080.         StrCompCopySub(&Inner, &ArgStr[1], 1, l - 2);
  1081.         exp = EvalStrIntExpressionWithResult(&Inner, Int16, &EvalResult);
  1082.         if (!EvalResult.OK) return;
  1083.         ChkSpace(SegCode, EvalResult.AddrSpaceMask);
  1084.  
  1085.         WAsmCode[0] = Index;
  1086.         WAsmCode[1] = exp;
  1087.         CodeLen = 2;
  1088. }
  1089.  
  1090. /* XXXX (Ri) */
  1091. static void DecodeBR(Word Index)
  1092. {
  1093.         Word mm;
  1094.         Word ii;
  1095.        
  1096.         if (!ChkMinCPU(CPUMN1613)) return;
  1097.  
  1098.         if (!ChkArgCnt(1,1)) return;
  1099.  
  1100.         if (!DecRIndirect(ArgStr[1].str.p_str, &mm, &ii, False)) return;
  1101.  
  1102.         WAsmCode[0] = Index | ii;
  1103.         CodeLen = 1;
  1104. }
  1105.  
  1106. /* XXXX Rs, Exp[, Skip] */
  1107. static void DecodeTSET(Word Index)
  1108. {
  1109.         Word reg;
  1110.         Word exp;
  1111.         tEvalResult EvalResult;
  1112.         Word skip = 0;
  1113.  
  1114.         if (!ChkMinCPU(CPUMN1613)) return;
  1115.  
  1116.         if (!ChkArgCnt(2,3)) return;
  1117.  
  1118.         if (!DecReg(ArgStr[1].str.p_str, &reg, True)) return;
  1119.         if (reg == 7)
  1120.         {
  1121.                 WrStrErrorPos(ErrNum_InvRegName, &ArgStr[1]);
  1122.                 return;
  1123.         }
  1124.  
  1125.         exp = EvalStrIntExpressionWithResult(&ArgStr[2], Int16, &EvalResult);
  1126.         if (!EvalResult.OK) return;
  1127.         ChkSpace(SegCode, EvalResult.AddrSpaceMask);
  1128.  
  1129.         if (ArgCnt == 3)
  1130.         {
  1131.                 if(!DecSkip(ArgStr[3].str.p_str, &skip, True)) return;
  1132.         }
  1133.  
  1134.         WAsmCode[0] = Index | (skip << 4) | reg;
  1135.         WAsmCode[1] = exp;
  1136.         CodeLen = 2;
  1137. }
  1138.  
  1139. /* XXXX Rd, Rs */
  1140. static void DecodeSRBT(Word Index)
  1141. {
  1142.         Word reg1;
  1143.         Word reg2;
  1144.        
  1145.         if (!ChkMinCPU(CPUMN1613)) return;
  1146.  
  1147.         if (!ChkArgCnt(2,2)) return;
  1148.  
  1149.         if (!DecReg(ArgStr[1].str.p_str, &reg1, True)) return;
  1150.         if (reg1 == 7)
  1151.         {
  1152.                 WrStrErrorPos(ErrNum_InvRegName, &ArgStr[1]);
  1153.                 return;
  1154.         }
  1155.  
  1156.         if (!DecReg(ArgStr[2].str.p_str, &reg2, True)) return;
  1157.         if (reg2 == 7)
  1158.         {
  1159.                 WrStrErrorPos(ErrNum_InvRegName, &ArgStr[2]);
  1160.                 return;
  1161.         }
  1162.  
  1163.         switch (Index)
  1164.         {
  1165.         case 0x3f70:    /* SRBT */
  1166.                 if (reg1 != 0)
  1167.                 {
  1168.                         WrStrErrorPos(ErrNum_InvReg, &ArgStr[1]);
  1169.                         return;
  1170.                 }
  1171.                 break;
  1172.         case 0x3ff0:    /* DEBP */
  1173.                 if (reg2 != 0)
  1174.                 {
  1175.                         WrStrErrorPos(ErrNum_InvReg, &ArgStr[2]);
  1176.                         return;
  1177.                 }
  1178.                 break;
  1179.         default:
  1180.                 WrError(ErrNum_InternalError);
  1181.                 return;
  1182.         }
  1183.  
  1184.         WAsmCode[0] = Index | reg1 | reg2;
  1185.         CodeLen = 1;
  1186. }
  1187.  
  1188. /* XXXX (R2), (R1), R0 */
  1189. static void DecodeBLK(Word Index)
  1190. {
  1191.         Word mm;
  1192.         Word ii1;
  1193.         Word ii2;
  1194.         Word reg;
  1195.        
  1196.         if (!ChkMinCPU(CPUMN1613)) return;
  1197.  
  1198.         if (!ChkArgCnt(3,3)) return;
  1199.  
  1200.         if (!DecRIndirect(ArgStr[1].str.p_str, &mm, &ii1, False)) return;
  1201.         if (ii1 != 1)
  1202.         {
  1203.                 WrStrErrorPos(ErrNum_InvReg, &ArgStr[1]);
  1204.                 return;
  1205.         }
  1206.        
  1207.         if (!DecRIndirect(ArgStr[2].str.p_str, &mm, &ii2, False)) return;
  1208.         if (ii2 != 0)
  1209.         {
  1210.                 WrStrErrorPos(ErrNum_InvReg, &ArgStr[2]);
  1211.                 return;
  1212.         }
  1213.  
  1214.         if (!DecReg(ArgStr[3].str.p_str, &reg, True)) return;
  1215.         if (reg != 0)
  1216.         {
  1217.                 WrStrErrorPos(ErrNum_InvReg, &ArgStr[3]);
  1218.                 return;
  1219.         }
  1220.  
  1221.         WAsmCode[0] = Index;
  1222.         CodeLen = 1;
  1223. }
  1224.  
  1225. /* XXXX R, (Ri) */
  1226. static void DecodeRDR(Word Index)
  1227. {
  1228.         Word reg;
  1229.         Word mm;
  1230.         Word ii;
  1231.  
  1232.         if (!ChkMinCPU(CPUMN1613)) return;
  1233.  
  1234.         if (!ChkArgCnt(2,2)) return;
  1235.  
  1236.         if (!DecReg(ArgStr[1].str.p_str, &reg, True)) return;
  1237.         if (reg == 6 || reg == 7)
  1238.         {
  1239.                 WrStrErrorPos(ErrNum_InvRegName, &ArgStr[1]);
  1240.                 return;
  1241.         }
  1242.  
  1243.         if (!DecRIndirect(ArgStr[2].str.p_str, &mm, &ii, False)) return;
  1244.  
  1245.         WAsmCode[0] = Index | (reg << 8) | ii;
  1246.         CodeLen = 1;
  1247. }
  1248.  
  1249. /* XXXX BRn/SRn, Exp */
  1250. static void DecodeLB(Word Index)
  1251. {
  1252.         Word reg;
  1253.         Word exp;
  1254.         tEvalResult EvalResult;
  1255.  
  1256.         if (!ChkMinCPU(CPUMN1613)) return;
  1257.  
  1258.         if (!ChkArgCnt(2,2)) return;
  1259.  
  1260.         if (Index & 0x0008)
  1261.         {       /* SR */
  1262.                 if (!DecSR(ArgStr[1].str.p_str, &reg)) return;
  1263.         }
  1264.         else
  1265.         {       /* BR */
  1266.                 if (!DecBR(ArgStr[1].str.p_str, &reg)) return;
  1267.                 if (reg == 0 && !(Index & 0x0080))
  1268.                 {
  1269.                         WrStrErrorPos(ErrNum_InvReg, &ArgStr[1]);
  1270.                         return;
  1271.                 }
  1272.         }
  1273.  
  1274.         exp = EvalStrIntExpressionWithResult(&ArgStr[2], Int16, &EvalResult);
  1275.         if (!EvalResult.OK) return;
  1276.         ChkSpace(SegCode, EvalResult.AddrSpaceMask);
  1277.  
  1278.         WAsmCode[0] = Index | (reg << 4);
  1279.         WAsmCode[1] = exp;
  1280.         CodeLen = 2;
  1281. }
  1282.  
  1283. /* XXXX Rn, BRn/SRn/HRn */
  1284. static void DecodeCPYB(Word Index)
  1285. {
  1286.         Word reg1;
  1287.         Word reg2;
  1288.        
  1289.         if (!ChkMinCPU(CPUMN1613)) return;
  1290.  
  1291.         if (!ChkArgCnt(2,2)) return;
  1292.  
  1293.         if (!DecReg(ArgStr[1].str.p_str, &reg1, True)) return;
  1294.         if (reg1 == 7)
  1295.         {
  1296.                 WrStrErrorPos(ErrNum_InvRegName, &ArgStr[1]);
  1297.                 return;
  1298.         }
  1299.  
  1300.         switch (Index & 0x3008)
  1301.         {
  1302.         case 0x0000:    /* BR */
  1303.                 if (!DecBR(ArgStr[2].str.p_str, &reg2)) return;
  1304.                 if (reg2 == 0 && !(Index & 0x0080))
  1305.                 {
  1306.                         WrStrErrorPos(ErrNum_InvReg, &ArgStr[2]);
  1307.                         return;
  1308.                 }
  1309.                 break;
  1310.         case 0x0008:    /* SR */
  1311.                 if (!DecSR(ArgStr[2].str.p_str, &reg2)) return;
  1312.                 break;
  1313.         case 0x3000:    /* HR */
  1314.                 if (!DecHR(ArgStr[2].str.p_str, &reg2)) return;
  1315.                 break;
  1316.         default:
  1317.                 WrError(ErrNum_InternalError);
  1318.                 return;
  1319.         }
  1320.  
  1321.         WAsmCode[0] = Index | (reg2 << 4) | reg1;
  1322.         CodeLen = 1;
  1323. }
  1324.  
  1325. /* Alias */
  1326.  
  1327. static void DecodeCLR(Word Index)
  1328. {
  1329.         Word reg;
  1330.        
  1331.         if (!ChkArgCnt(1,1)) return;
  1332.  
  1333.         if (!DecReg(ArgStr[1].str.p_str, &reg, True)) return;
  1334.         if (reg == 7)
  1335.         {
  1336.                 WrStrErrorPos(ErrNum_InvRegName, &ArgStr[1]);
  1337.                 return;
  1338.         }
  1339.  
  1340.         WAsmCode[0] = Index | (reg << 8) | reg;
  1341.         CodeLen = 1;
  1342. }
  1343.  
  1344. static void DecodeSKIP(Word Index)
  1345. {
  1346.         Word reg;
  1347.         Word skip;
  1348.  
  1349.         if (!ChkArgCnt(2,2)) return;
  1350.  
  1351.         if (!DecReg(ArgStr[1].str.p_str, &reg, True)) return;
  1352.         if (reg == 7)
  1353.         {
  1354.                 WrStrErrorPos(ErrNum_InvRegName, &ArgStr[1]);
  1355.                 return;
  1356.         }
  1357.  
  1358.         if (!DecSkip(ArgStr[2].str.p_str, &skip, True)) return;
  1359.  
  1360.         WAsmCode[0] = Index | (reg << 8) | (skip << 4) | reg;
  1361.         CodeLen = 1;
  1362. }
  1363.  
  1364. /* Pseudo Instruction */
  1365.  
  1366. static void PutByte(Byte data, Boolean *p_lower_byte)
  1367. {
  1368.         if (*p_lower_byte)
  1369.         {
  1370.                 WAsmCode[CodeLen - 1] |= data;
  1371.                 *p_lower_byte = False;
  1372.         }
  1373.         else
  1374.         {
  1375.                 SetMaxCodeLen((CodeLen + 1) * 2);
  1376.                 WAsmCode[CodeLen++] = data << 8;
  1377.                 *p_lower_byte = True;
  1378.         }
  1379. }
  1380.  
  1381. static void PutWord(Word data, Boolean *p_lower_byte)
  1382. {
  1383.         SetMaxCodeLen((CodeLen + 1) * 2);      
  1384.         WAsmCode[CodeLen++] = data;
  1385.   *p_lower_byte = False;
  1386. }
  1387.  
  1388. static void DecodeDC(Word Index)
  1389. {
  1390.         int c;
  1391.         Boolean LowerByte = False;
  1392.         TempResult t;
  1393.        
  1394.         UNUSED(Index);
  1395.  
  1396.         as_tempres_ini(&t);
  1397.         if (ChkArgCnt(1, ArgCntMax))
  1398.         {
  1399.                 Boolean OK = True;
  1400.                 tStrComp *pArg;
  1401.  
  1402.                 forallargs(pArg, OK)
  1403.                 {
  1404.                         EvalStrExpression(pArg, &t);
  1405.                         if (mFirstPassUnknown(t.Flags) && t.Typ == TempInt) t.Contents.Int &= 65535;
  1406.                         switch (t.Typ)
  1407.                         {
  1408.                         case TempInt:
  1409.                                 if (Packing)
  1410.                                 {
  1411.                                         if (ChkRange(t.Contents.Int, -128, 255))
  1412.                                         {
  1413.                                                 PutByte(t.Contents.Int, &LowerByte);
  1414.                                         }
  1415.                                 }
  1416.                                 else
  1417.                                 {
  1418.                                 ToInt:
  1419.                                         if (ChkRange(t.Contents.Int, -32768, 65535))
  1420.                                         {
  1421.                                                 PutWord(t.Contents.Int, &LowerByte);
  1422.                                         }
  1423.                                 }
  1424.                                 break;
  1425.                         case TempFloat:
  1426.                                 SetMaxCodeLen((CodeLen + 2) * 2);
  1427.                                 if (Double2IBMFloat(&WAsmCode[CodeLen], t.Contents.Float, False))
  1428.                                 {
  1429.                                         CodeLen += 2;
  1430.                                 }
  1431.                                 else
  1432.                                 {
  1433.                                         OK = False;
  1434.                                 }
  1435.                                 LowerByte = False;
  1436.                                 break;
  1437.                         case TempString:
  1438.                                 if (MultiCharToInt(&t, 2))
  1439.                                         goto ToInt;
  1440.                                 if (as_chartrans_xlate_nonz_dynstr(CurrTransTable->p_table, &t.Contents.str, pArg))
  1441.                                         OK = False;
  1442.                                 else
  1443.                                         for (c = 0; c < (int)t.Contents.str.len; c++)
  1444.                                         {
  1445.                                                 PutByte(((usint)t.Contents.str.p_str[c]) & 0xff, &LowerByte);
  1446.                                         }
  1447.                                 break;
  1448.                         default:
  1449.                                 OK = False;
  1450.                         }
  1451.                 }
  1452.                 if (!OK) CodeLen = 0;
  1453.         }
  1454.   as_tempres_free(&t);
  1455. }
  1456.  
  1457. static void DecodeDS(Word Index)
  1458. {
  1459.         LongInt Size;
  1460.         Boolean OK;
  1461.         tSymbolFlags Flags;
  1462.        
  1463.         UNUSED(Index);
  1464.  
  1465.         if (!ChkArgCnt(1, 1)) return;
  1466.  
  1467.         Size = EvalStrIntExpressionWithFlags(&ArgStr[1], Int32, &OK, &Flags);
  1468.         if (!OK) return;
  1469.         if (mFirstPassUnknown(Flags))
  1470.         {
  1471.                 WrStrErrorPos(ErrNum_FirstPassCalc, &ArgStr[1]);
  1472.                 return;
  1473.         }
  1474.  
  1475.         DontPrint = True;
  1476.         CodeLen = Size;
  1477.         BookKeeping();
  1478. }
  1479.  
  1480. /*---------------------------------------------------------------------------*/
  1481.  
  1482. /* MN1610 */
  1483.  
  1484. static void AddAdr(const char *NName, Word NCode)
  1485. {
  1486.         AddInstTable(InstTable, NName, NCode, DecodeAdr);
  1487. }
  1488.  
  1489. static void AddFixed(const char *NName, Word NCode)
  1490. {
  1491.         AddInstTable(InstTable, NName, NCode, DecodeFixed);
  1492. }
  1493.  
  1494. static void AddRegImm8(const char *NName, Word NCode)
  1495. {
  1496.         AddInstTable(InstTable, NName, NCode, DecodeRegImm8);
  1497. }
  1498.  
  1499. static void AddReg(const char *NName, Word NCode)
  1500. {
  1501.         AddInstTable(InstTable, NName, NCode, DecodeReg);
  1502. }
  1503.  
  1504. static void AddRegRegSkip(const char *NName, Word NCode)
  1505. {
  1506.         AddInstTable(InstTable, NName, NCode, DecodeRegRegSkip);
  1507. }
  1508.  
  1509. static void AddShift(const char *NName, Word NCode)
  1510. {
  1511.         AddInstTable(InstTable, NName, NCode, DecodeShift);
  1512. }
  1513.        
  1514. static void AddBit(const char *NName, Word NCode)
  1515. {
  1516.         AddInstTable(InstTable, NName, NCode, DecodeBit);
  1517. }
  1518.        
  1519. static void AddLevel(const char *NName, Word NCode)
  1520. {
  1521.         AddInstTable(InstTable, NName, NCode, DecodeLevel);
  1522. }
  1523.  
  1524. /* MN1613 */
  1525.  
  1526. static void AddLD(const char *NName, Word NCode)
  1527. {
  1528.         AddInstTable(InstTable, NName, NCode, DecodeLD);
  1529. }
  1530.  
  1531. static void AddLR(const char *NName, Word NCode)
  1532. {
  1533.         AddInstTable(InstTable, NName, NCode, DecodeLR);
  1534. }
  1535.  
  1536. static void AddMVWR(const char *NName, Word NCode)
  1537. {
  1538.         AddInstTable(InstTable, NName, NCode, DecodeMVWR);
  1539. }
  1540.  
  1541. static void AddMVWI(const char *NName, Word NCode)
  1542. {
  1543.         AddInstTable(InstTable, NName, NCode, DecodeMVWI);
  1544. }
  1545.  
  1546. static void AddFixed1613(const char *NName, Word NCode)
  1547. {
  1548.         AddInstTable(InstTable, NName, NCode, DecodeFixed1613);
  1549. }
  1550.  
  1551. static void AddNEG(const char *NName, Word NCode)
  1552. {
  1553.         AddInstTable(InstTable, NName, NCode, DecodeNEG);
  1554. }
  1555.  
  1556. static void AddAD(const char *NName, Word NCode)
  1557. {
  1558.         AddInstTable(InstTable, NName, NCode, DecodeAD);
  1559. }
  1560.  
  1561. static void AddM(const char *NName, Word NCode)
  1562. {
  1563.         AddInstTable(InstTable, NName, NCode, DecodeM);
  1564. }
  1565.  
  1566. static void AddDAA(const char *NName, Word NCode)
  1567. {
  1568.         AddInstTable(InstTable, NName, NCode, DecodeDAA);
  1569. }
  1570.  
  1571. static void AddFIX(const char *NName, Word NCode)
  1572. {
  1573.         AddInstTable(InstTable, NName, NCode, DecodeFIX);
  1574. }
  1575.  
  1576. static void AddFLT(const char *NName, Word NCode)
  1577. {
  1578.         AddInstTable(InstTable, NName, NCode, DecodeFLT);
  1579. }
  1580.  
  1581. static void AddBD(const char *NName, Word NCode)
  1582. {
  1583.         AddInstTable(InstTable, NName, NCode, DecodeBD);
  1584. }
  1585.  
  1586. static void AddBL(const char *NName, Word NCode)
  1587. {
  1588.         AddInstTable(InstTable, NName, NCode, DecodeBL);
  1589. }
  1590.  
  1591. static void AddBR(const char *NName, Word NCode)
  1592. {
  1593.         AddInstTable(InstTable, NName, NCode, DecodeBR);
  1594. }
  1595.  
  1596. static void AddTSET(const char *NName, Word NCode)
  1597. {
  1598.         AddInstTable(InstTable, NName, NCode, DecodeTSET);
  1599. }
  1600.  
  1601. static void AddSRBT(const char *NName, Word NCode)
  1602. {
  1603.         AddInstTable(InstTable, NName, NCode, DecodeSRBT);
  1604. }
  1605.  
  1606. static void AddBLK(const char *NName, Word NCode)
  1607. {
  1608.         AddInstTable(InstTable, NName, NCode, DecodeBLK);
  1609. }
  1610.  
  1611. static void AddRDR(const char *NName, Word NCode)
  1612. {
  1613.         AddInstTable(InstTable, NName, NCode, DecodeRDR);
  1614. }
  1615.  
  1616. static void AddLB(const char *NName, Word NCode)
  1617. {
  1618.         AddInstTable(InstTable, NName, NCode, DecodeLB);
  1619. }
  1620.  
  1621. static void AddCPYB(const char *NName, Word NCode)
  1622. {
  1623.         AddInstTable(InstTable, NName, NCode, DecodeCPYB);
  1624. }
  1625.  
  1626. static void InitFields(void)
  1627. {
  1628.         InstTable = CreateInstTable(128);
  1629.  
  1630.         /* Basic MN1610 Instructions */
  1631.        
  1632.         AddAdr("L",   0xc000);
  1633.         AddAdr("ST",  0x8000);
  1634.         AddAdr("B",   0xc700);
  1635.         AddAdr("BAL", 0x8700);
  1636.         AddAdr("IMS", 0xc600);
  1637.         AddAdr("DMS", 0x8600);
  1638.        
  1639.         AddRegRegSkip("A",    0x5808);
  1640.         AddRegRegSkip("S",    0x5800);
  1641.         AddRegRegSkip("AND",  0x6808);
  1642.         AddRegRegSkip("OR",   0x6008);
  1643.         AddRegRegSkip("EOR",  0x6000);
  1644.         AddRegRegSkip("C",    0x5008);
  1645.         AddRegRegSkip("CB",   0x5000);
  1646.         AddRegRegSkip("MV",   0x7808);
  1647.         AddRegRegSkip("MVB",  0x7800);
  1648.         AddRegRegSkip("BSWP", 0x7008);
  1649.         AddRegRegSkip("DSWP", 0x7000);
  1650.         AddRegRegSkip("LAD",  0x6800);
  1651.  
  1652.         AddShift("SL", 0x200c);
  1653.         AddShift("SR", 0x2008);
  1654.  
  1655.         AddBit("SBIT", 0x3800);
  1656.         AddBit("RBIT", 0x3000);
  1657.         AddBit("TBIT", 0x2800);
  1658.         AddBit("AI",   0x4800);
  1659.         AddBit("SI",   0x4000);
  1660.        
  1661.         AddRegImm8("RD",  0x1800);
  1662.         AddRegImm8("WR",  0x1000);
  1663.         AddRegImm8("WT",  0x1000);
  1664.         AddRegImm8("MVI", 0x0800);
  1665.  
  1666.         AddLevel("LPSW", 0x2004);
  1667.         AddFixed("H",   0x2000);
  1668.         AddReg("PUSH", 0x2001);
  1669.         AddReg("POP",  0x2002);
  1670.         AddFixed("RET", 0x2003);
  1671.  
  1672.         /* MN1613 Instructions */
  1673.  
  1674.         AddLD("LD",  0x2708);
  1675.         AddLD("STD", 0x2748);
  1676.  
  1677.         AddLR("LR",  0x2000);
  1678.         AddLR("STR", 0x2004);
  1679.  
  1680.         AddMVWR("MVWR", 0x7f08);
  1681.         AddMVWR("MVBR", 0x7f00);
  1682.         AddMVWR("BSWR", 0x7708);
  1683.         AddMVWR("DSWR", 0x7700);
  1684.         AddMVWR("AWR",  0x5f08);
  1685.         AddMVWR("SWR",  0x5f00);
  1686.         AddMVWR("CWR",  0x5708);
  1687.         AddMVWR("CBR",  0x5700);
  1688.         AddMVWR("LADR", 0x6f00);
  1689.         AddMVWR("ANDR", 0x6f08);
  1690.         AddMVWR("ORR",  0x6708);
  1691.         AddMVWR("EORR", 0x6700);
  1692.  
  1693.         AddMVWI("MVWI", 0x780f);
  1694.         AddMVWI("AWI",  0x580f);
  1695.         AddMVWI("SWI",  0x5807);
  1696.         AddMVWI("CWI",  0x500f);
  1697.         AddMVWI("CBI",  0x5007);
  1698.         AddMVWI("LADI", 0x6807);
  1699.         AddMVWI("ANDI", 0x680f);
  1700.         AddMVWI("ORI",  0x600f);
  1701.         AddMVWI("EORI", 0x6007);
  1702.  
  1703.         AddFixed1613("PSHM", 0x170f);
  1704.         AddFixed1613("POPM", 0x1707);
  1705.         AddFixed1613("RETL", 0x3f07);
  1706.  
  1707.         AddNEG("NEG", 0x1f00);
  1708.  
  1709.         AddAD("AD", 0x4f04);
  1710.         AddAD("SD", 0x4704);
  1711.  
  1712.         AddM("M",  0x7f0c);
  1713.         AddM("D",  0x770c);
  1714.         AddM("FA", 0x6f0c);
  1715.         AddM("FS", 0x6f04);
  1716.         AddM("FM", 0x670c);
  1717.         AddM("FD", 0x6704);
  1718.  
  1719.         AddDAA("DAA", 0x5f04);
  1720.         AddDAA("DAS", 0x5704);
  1721.  
  1722.         AddFIX("FIX", 0x1f0f);
  1723.        
  1724.         AddFLT("FLT", 0x1f07);
  1725.  
  1726.         AddBD("BD",   0x2607);
  1727.         AddBD("BALD", 0x2617);
  1728.        
  1729.         AddBL("BL",   0x270f);
  1730.         AddBL("BALL", 0x271f);
  1731.        
  1732.         AddBR("BR",   0x2704);
  1733.         AddBR("BALR", 0x2714);
  1734.  
  1735.         AddTSET("TSET", 0x1708);
  1736.         AddTSET("TRST", 0x1700);
  1737.  
  1738.         AddSRBT("SRBT", 0x3f70);
  1739.         AddSRBT("DEBP", 0x3ff0);
  1740.  
  1741.         AddBLK("BLK", 0x3f17);
  1742.  
  1743.         AddRDR("RDR", 0x2014);
  1744.         AddRDR("WTR", 0x2010);
  1745.  
  1746.         AddLB("LB",  0x0f07);
  1747.         AddLB("LS",  0x0f0f);
  1748.         AddLB("STB", 0x0f87);
  1749.         AddLB("STS", 0x0f8f);
  1750.  
  1751.         AddCPYB("CPYB", 0x0f80);
  1752.         AddCPYB("CPYS", 0x0f88);
  1753.         AddCPYB("CPYH", 0x3f80);
  1754.         AddCPYB("SETB", 0x0f00);
  1755.         AddCPYB("SETS", 0x0f08);
  1756.         AddCPYB("SETH", 0x3f00);
  1757.  
  1758.         /* Alias */
  1759.  
  1760.         AddFixed("NOP", 0x7808);        /* MOV R0,R0*/
  1761.         AddInstTable(InstTable, "CLR",   0x6000, DecodeCLR);    /* EOR Rn,Rn */
  1762.         AddInstTable(InstTable, "CLEAR", 0x6000, DecodeCLR);    /* EOR Rn,Rn */
  1763.         AddInstTable(InstTable, "SKIP",  0x7808, DecodeSKIP);   /* MV  Rn,Rn,Skip */
  1764.        
  1765.         /* Pseudo Instructions */
  1766.  
  1767.         AddInstTable(InstTable, "DC", 0, DecodeDC);
  1768.         AddInstTable(InstTable, "DS", 0, DecodeDS);
  1769.        
  1770.         StrCompAlloc(&Inner, STRINGSIZE);
  1771.         StrCompAlloc(&InnerZ, STRINGSIZE);
  1772. }
  1773.  
  1774. static void DeinitFields(void)
  1775. {
  1776.         DestroyInstTable(InstTable);
  1777.  
  1778.         StrCompFree(&InnerZ);
  1779.         StrCompFree(&Inner);
  1780. }
  1781.  
  1782. /*---------------------------------------------------------------------------*/
  1783.  
  1784. static void MakeCode_MN1610(void)
  1785. {
  1786.         CodeLen = 0;
  1787.         DontPrint = False;
  1788.  
  1789.         if (Memo("")) return;
  1790.  
  1791.         /* if (DecodeIntelPseudo(False)) return; */
  1792.         /* if (DecodeMoto16Pseudo(eSymbolSize16Bit, True)) return; */
  1793.        
  1794.         if (!LookupInstTable(InstTable, OpPart.str.p_str))
  1795.                 WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
  1796. }
  1797.  
  1798. static Boolean IsDef_MN1610(void)
  1799. {
  1800.         return False;
  1801. }
  1802.  
  1803. static void SwitchFrom_MN1610(void)
  1804. {
  1805.         DeinitFields();
  1806. }
  1807.  
  1808. static void SwitchTo_MN1610(void)
  1809. {
  1810.         TurnWords = True;
  1811.         SetIntConstMode(eIntConstModeIBM); /*ConstModeC;*/
  1812.  
  1813.         PCSymbol = "*";
  1814.         HeaderID = 0x36;
  1815.         NOPCode = 0x7808;       /* MV R0,R0 */
  1816.         DivideChars = ",";
  1817.         HasAttrs = False;
  1818.  
  1819.         ValidSegs = (1 << SegCode) | (1 << SegIO);
  1820.         Grans[SegCode] = 2;
  1821.         ListGrans[SegCode] = 2;
  1822.         SegInits[SegCode] = 0;
  1823.         SegLimits[SegCode] = 0xffff;
  1824.         Grans[SegIO] = 2;
  1825.         ListGrans[SegIO] = 2;
  1826.         SegInits[SegIO] = 0;
  1827.         SegLimits[SegIO] = 0xffff;
  1828.  
  1829.         onoff_packing_add(False);
  1830.  
  1831.         MakeCode = MakeCode_MN1610;
  1832.         IsDef = IsDef_MN1610;
  1833.         SwitchFrom = SwitchFrom_MN1610;
  1834.         InitFields();
  1835. }
  1836.  
  1837. void codemn1610_init(void)
  1838. {
  1839.         CPUMN1610 = AddCPU("MN1610", SwitchTo_MN1610);
  1840.         CPUMN1613 = AddCPU("MN1613", SwitchTo_MN1610);
  1841.  
  1842.         AddCopyright("Panafacom MN1610/1613-Generator (C) 2019 Haruo Asano");
  1843. }
  1844.