Subversion Repositories pentevo

Rev

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

  1. /* codecp1600.c */
  2. /*****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
  4. /*                                                                           */
  5. /* AS-Portierung                                                             */
  6. /*                                                                           */
  7. /* Codegenerator GI CP-1600                                                  */
  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 "asmitree.h"
  22. #include "codevars.h"
  23. #include "codepseudo.h"
  24. #include "headids.h"
  25. #include "errmsg.h"
  26. #include "onoff_common.h"
  27.  
  28. #include "codecp1600.h"
  29.  
  30. /*---------------------------------------------------------------------------*/
  31.  
  32. static CPUVar CPUCP1600;
  33.  
  34. static Word Bits;
  35. static Word Mask;
  36. static Boolean PrefixedSDBD;
  37.  
  38. /*---------------------------------------------------------------------------*/
  39.  
  40. static Boolean DecReg(const char *pAsc, Word *reg, Boolean errMsg)
  41. {
  42.         if (strlen(pAsc) != 2)
  43.         {
  44.                 if(errMsg) WrError(ErrNum_InvRegName);
  45.                 return False;
  46.         }
  47.  
  48.         if (toupper(pAsc[0]) == 'R' && pAsc[1] >= '0' && pAsc[1] <= '7' )
  49.         {
  50.                 *reg = pAsc[1] - '0';
  51.                 return True;
  52.         }
  53.  
  54.         if (errMsg) WrError(ErrNum_InvRegName);
  55.         return False;
  56. }
  57.  
  58. /*---------------------------------------------------------------------------*/
  59.  
  60. static void DecodeRegAdrMVO(Word Index)
  61. {
  62.         Word reg;
  63.         Word adr;
  64.         Boolean OK;
  65.  
  66.         PrefixedSDBD = False;
  67.                
  68.         if (ChkArgCnt(2,2))
  69.         {
  70.                 if (!DecReg(ArgStr[1].str.p_str, &reg, True)) return;
  71.  
  72.                 adr = EvalStrIntExpression(&ArgStr[2], UInt16, &OK);
  73.                 if (!OK) return;
  74.  
  75.                 if (adr & Mask)
  76.                 {
  77.                         WrError(ErrNum_OverRange);
  78.                         return;
  79.                 }
  80.  
  81.                 WAsmCode[0] = Index | reg;
  82.                 WAsmCode[1] = adr;
  83.                 CodeLen = 2;
  84.         }
  85. }
  86.  
  87. static void DecodeRegRegMVO(Word Index)
  88. {
  89.         Word regs;
  90.         Word regd;
  91.  
  92.         PrefixedSDBD = False;
  93.  
  94.         if (ChkArgCnt(2,2))
  95.         {
  96.                 if(!DecReg(ArgStr[1].str.p_str, &regs, True)) return;
  97.  
  98.                 if(!DecReg(ArgStr[2].str.p_str, &regd, True)) return;
  99.                 if (regd == 0 || regd == 7)
  100.                 {
  101.                         WrError(ErrNum_InvReg);
  102.                         return;
  103.                 }
  104.  
  105.                 WAsmCode[0] = Index | (regd << 3) | regs;
  106.                 CodeLen = 1;
  107.         }
  108. }
  109.  
  110. static void DecodeRegImmMVO(Word Index)
  111. {
  112.         Word reg;
  113.         LongInt val;
  114.         Boolean OK;
  115.  
  116.         PrefixedSDBD = False;
  117.                
  118.         if (ChkArgCnt(2,2))
  119.         {
  120.                 if (!DecReg(ArgStr[1].str.p_str, &reg, True)) return;
  121.  
  122.                 val = EvalStrIntExpression(&ArgStr[2], Int32, &OK);
  123.                 if (!OK) return;
  124.                 if (!ChkRange(val, -32768, 65535)) return;
  125.  
  126.                 if (val & Mask)
  127.                 {
  128.                         WrError(ErrNum_OverRange);
  129.                         return;
  130.                 }
  131.  
  132.                 WAsmCode[0] = Index | reg;
  133.                 WAsmCode[1] = val;
  134.                 CodeLen = 2;
  135.         }
  136. }
  137.  
  138. static void DecodeAdrReg(Word Index)
  139. {
  140.         Word reg;
  141.         Word adr;
  142.         Boolean OK;
  143.  
  144.         PrefixedSDBD = False;
  145.                
  146.         if (ChkArgCnt(2,2))
  147.         {
  148.                 adr = EvalStrIntExpression(&ArgStr[1], UInt16, &OK);
  149.                 if (!OK) return;
  150.  
  151.                 if (adr & Mask)
  152.                 {
  153.                         WrError(ErrNum_OverRange);
  154.                         return;
  155.                 }
  156.  
  157.                 if (!DecReg(ArgStr[2].str.p_str, &reg, True)) return;
  158.  
  159.                 WAsmCode[0] = Index | reg;
  160.                 WAsmCode[1] = adr;
  161.                 CodeLen = 2;
  162.         }
  163. }
  164.  
  165. static void DecodeRegReg(Word Index)
  166. {
  167.         Word regs;
  168.         Word regd;
  169.  
  170.         PrefixedSDBD = False;
  171.  
  172.         if (ChkArgCnt(2,2))
  173.         {
  174.                 if(!DecReg(ArgStr[1].str.p_str, &regs, True)) return;
  175.                 if (Index & 0x0200)
  176.                 {
  177.                         if (regs == 0 || regs == 7)
  178.                         {
  179.                                 WrError(ErrNum_InvReg);
  180.                                 return;
  181.                         }
  182.                 }
  183.  
  184.                 if(!DecReg(ArgStr[2].str.p_str, &regd, True)) return;
  185.  
  186.                 WAsmCode[0] = Index | (regs << 3) | regd;
  187.                 CodeLen = 1;
  188.         }
  189. }
  190.  
  191. static void DecodeImmReg(Word Index)
  192. {
  193.         LongInt val;
  194.         Word regd;
  195.         Boolean OK;
  196.         Boolean prefixed = PrefixedSDBD;
  197.        
  198.         PrefixedSDBD = False;
  199.  
  200.         if (ChkArgCnt(2,2))
  201.         {
  202.                 val = EvalStrIntExpression(&ArgStr[1], Int32, &OK);
  203.                 if (!OK) return;
  204.                 if (!ChkRange(val, -32768, 65535)) return;
  205.  
  206.                 if(!DecReg(ArgStr[2].str.p_str, &regd, True)) return;
  207.  
  208.                 if (prefixed)
  209.                 {
  210.                         WAsmCode[0] = Index | regd;
  211.                         WAsmCode[1] = val & 0x00FF;
  212.                         WAsmCode[2] = val >> 8;
  213.                         CodeLen = 3;
  214.                 }
  215.                 else
  216.                 {
  217.                         if (val & Mask)
  218.                         {
  219.                                 WAsmCode[0] = 0x0001; /* SDBD */
  220.                                 WAsmCode[1] = Index | regd;
  221.                                 WAsmCode[2] = val & 0x00FF;
  222.                                 WAsmCode[3] = val >> 8;
  223.                                 CodeLen = 4;
  224.                         }
  225.                         else
  226.                         {
  227.                                 WAsmCode[0] = Index | regd;
  228.                                 WAsmCode[1] = val;
  229.                                 CodeLen = 2;
  230.                         }
  231.                 }
  232.         }
  233. }
  234.  
  235. static void DecodeRegDup(Word Index)
  236. {
  237.         Word reg;
  238.  
  239.         PrefixedSDBD = False;
  240.  
  241.         if (ChkArgCnt(1,1))
  242.         {
  243.                 if(!DecReg(ArgStr[1].str.p_str, &reg, True)) return;
  244.  
  245.                 WAsmCode[0] = Index | (reg << 3) | reg;
  246.                 CodeLen = 1;
  247.         }
  248. }
  249.  
  250. static void DecodeBranch(Word Index)
  251. {
  252.         Word cond = 0;
  253.         Word adr;
  254.         Boolean OK;
  255.         Word PC = EProgCounter();
  256.  
  257.         PrefixedSDBD = False;
  258.  
  259.         if (Index & 0x0010)
  260.         {
  261.                 /* BEXT */
  262.                 if (!ChkArgCnt(2,2)) return;
  263.  
  264.                 cond = EvalStrIntExpression(&ArgStr[2], UInt4, &OK);
  265.         }
  266.         else
  267.         {
  268.                 if (!ChkArgCnt(1,1)) return;
  269.  
  270.                 cond = 0;
  271.         }
  272.  
  273.         adr = EvalStrIntExpression(&ArgStr[1], UInt16, &OK);
  274.         if (!OK) return;
  275.  
  276.         if (adr >= PC + 2)
  277.         {
  278.                 WAsmCode[0] = Index | cond;
  279.                 WAsmCode[1] = adr - (PC + 2);
  280.         }
  281.         else
  282.         {
  283.                 WAsmCode[0] = Index | 0x0020 | cond;
  284.                 WAsmCode[1] = PC + 2 - adr - 1;
  285.         }
  286.  
  287.         if (WAsmCode[1] & Mask)
  288.         {
  289.                 WrError(ErrNum_JmpDistTooBig);
  290.                 return;
  291.         }
  292.  
  293.         CodeLen = 2;
  294. }
  295.  
  296. static void DecodeNOPP(Word Index)
  297. {
  298.         PrefixedSDBD = False;
  299.  
  300.         if (ChkArgCnt(0, 0))
  301.         {
  302.                 WAsmCode[0] = Index;
  303.                 WAsmCode[1] = 0;
  304.                 CodeLen = 2;
  305.         }
  306. }
  307.  
  308. static void DecodeReg(Word Index)
  309. {
  310.         Word reg;
  311.  
  312.         PrefixedSDBD = False;
  313.  
  314.         if (ChkArgCnt(1,1))
  315.         {
  316.                 if(!DecReg(ArgStr[1].str.p_str, &reg, True)) return;
  317.  
  318.                 if (Index == 0x0030)
  319.                 {
  320.                         /* GSWD */
  321.                         if (reg > 3)
  322.                         {
  323.                                 WrError(ErrNum_InvReg);
  324.                                 return;
  325.                         }
  326.                 }
  327.  
  328.                 WAsmCode[0] = Index | reg;
  329.                 CodeLen = 1;
  330.         }
  331. }
  332.  
  333. static void DecodeShift(Word Index)
  334. {
  335.         Word reg;
  336.         Word bit = 0;
  337.  
  338.         PrefixedSDBD = False;
  339.  
  340.         if (ChkArgCnt(1,2))
  341.         {
  342.                 if(!DecReg(ArgStr[1].str.p_str, &reg, True)) return;
  343.                 if (reg > 3)
  344.                 {
  345.                         WrError(ErrNum_InvReg);
  346.                         return;
  347.                 }
  348.  
  349.                 if (ArgCnt == 2)
  350.                 {
  351.                         Word val;
  352.                         Boolean OK;
  353.                        
  354.                         val = EvalStrIntExpression(&ArgStr[2], UInt16, &OK);
  355.                         if (!OK) return;
  356.  
  357.                         if (val == 1)
  358.                         {
  359.                                 bit = 0x0000;
  360.                         }
  361.                         else if (val == 2)
  362.                         {
  363.                                 bit = 0x0004;
  364.                         }
  365.                         else
  366.                         {
  367.                                 WrError(ErrNum_InvShiftArg);
  368.                                 return;
  369.                         }
  370.                 }
  371.  
  372.                 WAsmCode[0] = Index | bit | reg;
  373.                 CodeLen = 1;
  374.         }
  375. }
  376.  
  377. static void DecodeOptionalImm(Word Index)
  378. {
  379.         Word bit = 0;
  380.  
  381.         PrefixedSDBD = False;
  382.  
  383.         if (ChkArgCnt(0, 1))
  384.         {
  385.                 if (ArgCnt == 0)
  386.                 {
  387.                         bit = 0x0000;
  388.                 }
  389.                 else{
  390.                         Word val;
  391.                         Boolean OK;
  392.  
  393.                         val = EvalStrIntExpression(&ArgStr[1], UInt16, &OK);
  394.                         if (!OK) return;
  395.  
  396.                         if (val == 1)
  397.                         {
  398.                                 bit = 0x0000;
  399.                         }
  400.                         else if (val == 2)
  401.                         {
  402.                                 bit = 0x0001;
  403.                         }
  404.                         else
  405.                         {
  406.                                 WrError(ErrNum_InvShiftArg);
  407.                                 return;
  408.                         }
  409.                 }
  410.                 WAsmCode[0] = Index | bit;
  411.                 CodeLen = 1;
  412.         }
  413. }
  414.  
  415. static void DecodeFixed(Word Index)
  416. {
  417.         if (ChkArgCnt(0, 0))
  418.         {
  419.                 WAsmCode[0] = Index;
  420.                 CodeLen = 1;
  421.         }
  422.  
  423.         if (Index == 0x0001) PrefixedSDBD = True;
  424.         else PrefixedSDBD = False;
  425. }
  426.  
  427. static void DecodeJump(Word Index)
  428. {
  429.         Word adr;
  430.         Boolean OK;
  431.         Word reg;
  432.  
  433.         PrefixedSDBD = False;
  434.  
  435.         if (Index & 0x0300)
  436.         {
  437.                 /* J/JD/JE */
  438.                 if (!ChkArgCnt(1, 1)) return;
  439.  
  440.                 reg = 0;
  441.  
  442.                 adr = EvalStrIntExpression(&ArgStr[1], UInt16, &OK);           
  443.         }
  444.         else
  445.         {
  446.                 /* JSR/JSRD/JSRE */
  447.                 if (!ChkArgCnt(2, 2)) return;
  448.  
  449.                 if (!DecReg(ArgStr[1].str.p_str, &reg, True)) return;
  450.                 if (reg < 4 || reg > 6)
  451.                 {
  452.                         WrError(ErrNum_InvReg);
  453.                         return;
  454.                 }
  455.                 reg = (reg - 4) << 8;
  456.  
  457.                 adr = EvalStrIntExpression(&ArgStr[2], UInt16, &OK);
  458.         }
  459.         if (!OK) return;
  460.  
  461.         WAsmCode[0] = 0x0004;
  462.         WAsmCode[1] = Index | reg | ((adr & 0xFC00) >> 8);
  463.         WAsmCode[2] = adr & 0x03FF;
  464.         CodeLen = 3;
  465. }
  466.  
  467. static void DecodeJR(Word Index)
  468. {
  469.         Word reg;
  470.  
  471.         PrefixedSDBD = False;
  472.  
  473.         if (ChkArgCnt(1,1))
  474.         {
  475.                 if(!DecReg(ArgStr[1].str.p_str, &reg, True)) return;
  476.  
  477.                 WAsmCode[0] = Index | (reg << 3);
  478.                 CodeLen = 1;
  479.         }
  480. }
  481.  
  482. static void DecodeRES(Word Index)
  483. {
  484.         Word Size;
  485.         Boolean OK;
  486.         tSymbolFlags Flags;
  487.         int i;
  488.  
  489.         PrefixedSDBD = False;
  490.  
  491.         if (!ChkArgCnt(1, 1)) return;
  492.  
  493.         Size = EvalStrIntExpressionWithFlags(&ArgStr[1], Int16, &OK, &Flags);
  494.         if (!OK) return;
  495.         if (mFirstPassUnknown(Flags))
  496.         {
  497.                 WrStrErrorPos(ErrNum_FirstPassCalc, &ArgStr[1]);
  498.                 return;
  499.         }
  500.  
  501.         if (Index)
  502.         {
  503.                 for (i = 0; i < Size; i++)
  504.                 {
  505.                         WAsmCode[i] = 0;
  506.                 }
  507.         }
  508.         else
  509.         {
  510.                 DontPrint = True;
  511.         }
  512.         CodeLen = Size;
  513.         BookKeeping();
  514. }
  515.  
  516. static void PutByte(Word value, int *p_half)
  517. {
  518.         if (*p_half & 1)
  519.         {
  520.                 WAsmCode[CodeLen - 1] |= value << 8;
  521.         }
  522.         else
  523.         {
  524.                 WAsmCode[CodeLen++] = value & 0xFF;
  525.         }
  526.         if (Packing)
  527.                 (*p_half)++;
  528. }
  529.  
  530. static void DecodeWORD(Word Index)
  531. {
  532.         int c;
  533.         int b = 0;
  534.         TempResult t;
  535.  
  536.         PrefixedSDBD = False;
  537.  
  538.         as_tempres_ini(&t);
  539.         if (ChkArgCnt(1, ArgCntMax))
  540.         {
  541.                 Boolean OK = True;
  542.                 tStrComp *pArg;
  543.  
  544.                 forallargs (pArg, OK)
  545.                 {
  546.                         EvalStrExpression(pArg, &t);
  547.                         if (mFirstPassUnknown(t.Flags) && t.Typ == TempInt) t.Contents.Int &= 65535;
  548.  
  549.                         switch (t.Typ)
  550.                         {
  551.                         case TempInt:
  552.                                 switch (Index)
  553.                                 {
  554.                                 case 0x0000: /* WORD */
  555.                                         if (ChkRange(t.Contents.Int, -32768, 65535))
  556.                                         {
  557.                                                 WAsmCode[CodeLen++] = t.Contents.Int;
  558.                                         }
  559.                                         b = 0;
  560.                                         break;
  561.                                 case 0x0001: /* BYTE */
  562.                                         if (ChkRange(t.Contents.Int, -32768, 65535))
  563.                                         {
  564.                                                 WAsmCode[CodeLen++] = t.Contents.Int & 0x00FF;
  565.                                                 WAsmCode[CodeLen++] = (t.Contents.Int >> 8) & 0x00FF;
  566.                                         }
  567.                                         b = 0;
  568.                                         break;
  569.                                 case 0x0002: /* TEXT */
  570.                                         if (ChkRange(t.Contents.Int, 0, 255))
  571.                                                 PutByte(t.Contents.Int & 0xff, &b);
  572.                                         break;
  573.                                 default:
  574.                                         OK = False;
  575.                                 }
  576.                                 break;
  577.                         case TempFloat:
  578.                                 WrStrErrorPos(ErrNum_StringOrIntButFloat, pArg);
  579.                                 OK = False;
  580.                                 break;
  581.                         case TempString:
  582.                                 if (Index != 0x0002)
  583.                                 {
  584.                                         OK = False;
  585.                                         break;
  586.                                 }
  587.                                 if (as_chartrans_xlate_nonz_dynstr(CurrTransTable->p_table, &t.Contents.str, pArg))
  588.                                         OK = False;
  589.                                 else
  590.                                         for (c = 0; c < (int)t.Contents.str.len; c++)
  591.                                                 PutByte(t.Contents.str.p_str[c], &b);
  592.                                 break;
  593.                         default:
  594.                                 OK = False;
  595.                         }
  596.                 }
  597.                 if (!OK) CodeLen = 0;
  598.         }
  599.         as_tempres_free(&t);
  600. }
  601.  
  602. static void DecodeBITS(Word Index)
  603. {
  604.         Word val;
  605.         Boolean OK;
  606.  
  607.         UNUSED(Index);
  608.  
  609.         PrefixedSDBD = False;
  610.  
  611.         if (!ChkArgCnt(1, 1)) return;
  612.  
  613.         val = EvalStrIntExpression(&ArgStr[1], Int16, &OK);
  614.         if (!OK) return;
  615.         if (ChkRange(val, 10, 16))
  616.         {
  617.                 Bits = val;
  618.                 Mask = ~((1 << val) - 1);
  619.         }
  620. }
  621.  
  622. /*---------------------------------------------------------------------------*/
  623.  
  624. static void AddRegAdrMVO(const char *NName, Word NCode)
  625. {
  626.         AddInstTable(InstTable, NName, NCode, DecodeRegAdrMVO);
  627. }
  628.  
  629. static void AddRegRegMVO(const char *NName, Word NCode)
  630. {
  631.         AddInstTable(InstTable, NName, NCode, DecodeRegRegMVO);
  632. }
  633.  
  634. static void AddRegImmMVO(const char *NName, Word NCode)
  635. {
  636.         AddInstTable(InstTable, NName, NCode, DecodeRegImmMVO);
  637. }
  638.  
  639. static void AddAdrReg(const char *NName, Word NCode)
  640. {
  641.         AddInstTable(InstTable, NName, NCode, DecodeAdrReg);
  642. }
  643.  
  644. static void AddRegReg(const char *NName, Word NCode)
  645. {
  646.         AddInstTable(InstTable, NName, NCode, DecodeRegReg);
  647. }
  648.  
  649. static void AddImmReg(const char *NName, Word NCode)
  650. {
  651.         AddInstTable(InstTable, NName, NCode, DecodeImmReg);
  652. }
  653.  
  654. static void AddRegDup(const char *NName, Word NCode)
  655. {
  656.         AddInstTable(InstTable, NName, NCode, DecodeRegDup);
  657. }
  658.  
  659. static void AddBranch(const char *NName, Word NCode)
  660. {
  661.         AddInstTable(InstTable, NName, NCode, DecodeBranch);
  662. }
  663.  
  664. static void AddNOPP(const char *NName, Word NCode)
  665. {
  666.         AddInstTable(InstTable, NName, NCode, DecodeNOPP);
  667. }
  668.  
  669. static void AddReg(const char *NName, Word NCode)
  670. {
  671.         AddInstTable(InstTable, NName, NCode, DecodeReg);
  672. }
  673.  
  674. static void AddShift(const char *NName, Word NCode)
  675. {
  676.         AddInstTable(InstTable, NName, NCode, DecodeShift);
  677. }
  678.  
  679. static void AddOptionalImm(const char *NName, Word NCode)
  680. {
  681.         AddInstTable(InstTable, NName, NCode, DecodeOptionalImm);
  682. }
  683.  
  684. static void AddFixed(const char *NName, Word NCode)
  685. {
  686.         AddInstTable(InstTable, NName, NCode, DecodeFixed);
  687. }
  688.  
  689. static void AddJump(const char *NName, Word NCode)
  690. {
  691.         AddInstTable(InstTable, NName, NCode, DecodeJump);
  692. }
  693.  
  694. static void AddJR(const char *NName, Word NCode)
  695. {
  696.         AddInstTable(InstTable, NName, NCode, DecodeJR);
  697. }
  698.  
  699. static void AddRES(const char *NName, Word NCode)
  700. {
  701.         AddInstTable(InstTable, NName, NCode, DecodeRES);
  702. }
  703.  
  704. static void AddWORD(const char *NName, Word NCode)
  705. {
  706.         AddInstTable(InstTable, NName, NCode, DecodeWORD);
  707. }
  708.  
  709. static void InitFields(void)
  710. {
  711.         InstTable = CreateInstTable(128);
  712.  
  713.         /* Data Access Instructions */
  714.         AddRegAdrMVO("MVO", 0x0240);
  715.         AddRegRegMVO("MVO@", 0x0240);
  716.         AddRegImmMVO("MVOI", 0x0278);
  717.         AddAdrReg("MVI", 0x0280);
  718.         AddRegReg("MVI@", 0x0280);
  719.         AddImmReg("MVII", 0x02B8);
  720.         AddAdrReg("ADD", 0x02C0);
  721.         AddRegReg("ADD@", 0x02C0);
  722.         AddImmReg("ADDI", 0x02F8);
  723.         AddAdrReg("SUB", 0x300);
  724.         AddRegReg("SUB@", 0x0300);
  725.         AddImmReg("SUBI", 0x0338);
  726.         AddAdrReg("CMP", 0x0340);
  727.         AddRegReg("CMP@", 0x0340);
  728.         AddImmReg("CMPI", 0x0378);
  729.         AddAdrReg("AND", 0x0380);
  730.         AddRegReg("AND@", 0x0380);
  731.         AddImmReg("ANDI", 0x03B8);
  732.         AddAdrReg("XOR", 0x03C0);
  733.         AddRegReg("XOR@", 0x03C0);
  734.         AddImmReg("XORI", 0x03F8);
  735.  
  736.         /* Conditional Branch Instructions */
  737.         AddBranch("B", 0x0200);
  738.         AddBranch("BC", 0x0201);
  739.         AddBranch("BLGT", 0x0201);
  740.         AddBranch("BNC", 0x0209);
  741.         AddBranch("BLLT", 0x0209);
  742.         AddBranch("BOV", 0x0202);
  743.         AddBranch("BNOV", 0x020A);
  744.         AddBranch("BPL", 0x0203);
  745.         AddBranch("BMI", 0x020B);
  746.         AddBranch("BZE", 0x0204);
  747.         AddBranch("BEQ", 0x0204);
  748.         AddBranch("BNZE", 0x020C);
  749.         AddBranch("BNEQ", 0x020C);
  750.         AddBranch("BLT", 0x0205);
  751.         AddBranch("BGE", 0x020D);
  752.         AddBranch("BLE", 0x0206);
  753.         AddBranch("BGT", 0x020E);
  754.         AddBranch("BUSC", 0x0207);
  755.         AddBranch("BESC", 0x020F);
  756.         AddBranch("BEXT", 0x0210);
  757.         AddNOPP("NOPP", 0x0208);
  758.  
  759.         /* Register to Register */
  760.         AddRegReg("MOVR", 0x0080);
  761.         AddRegReg("ADDR", 0x00C0);
  762.         AddRegReg("SUBR", 0x0100);
  763.         AddRegReg("CMPR", 0x0140);
  764.         AddRegReg("ANDR", 0x0180);
  765.         AddRegReg("XORR", 0x01C0);
  766.  
  767.         /* Register Shift */
  768.         AddShift("SWAP", 0x0040);
  769.         AddShift("SLL", 0x0048);
  770.         AddShift("RLC", 0x0050);
  771.         AddShift("SLLC", 0x0058);
  772.         AddShift("SLR", 0x0060);
  773.         AddShift("SAR", 0x0068);
  774.         AddShift("RRC", 0x0070);
  775.         AddShift("SARC", 0x0078);
  776.  
  777.         /* Single Register */
  778.         AddReg("INCR", 0x0008);
  779.         AddReg("DECR", 0x0010);
  780.         AddReg("COMR", 0x0018);
  781.         AddReg("NEGR", 0x0020);
  782.         AddReg("ADCR", 0x0028);
  783.         AddReg("GSWD", 0x0030);
  784.         /* AddFixed("NOP", 0x0034);     */
  785.         AddOptionalImm("NOP", 0x0034);
  786.         /* AddFixed("SIN", 0x0036);     */
  787.         AddOptionalImm("SIN", 0x0036);
  788.         AddReg("RSWD", 0x0038);
  789.  
  790.         /* Internal Control */
  791.         AddFixed("HLT", 0x0000);
  792.         AddFixed("SDBD", 0x0001);
  793.         AddFixed("EIS", 0x0002);
  794.         AddFixed("DIS", 0x0003);
  795.         AddFixed("TCI", 0x0005);
  796.         AddFixed("CLRC", 0x0006);
  797.         AddFixed("SETC", 0x0007);
  798.  
  799.         /* Jump / Jump and Save Return */
  800.         AddJump("J", 0x0300); /* Second Word */
  801.         AddJump("JE", 0x0301); /* Second Word */
  802.         AddJump("JD", 0x0302); /* Second Word */
  803.         AddJump("JSR", 0x0000); /* Second Word */
  804.         AddJump("JSRE", 0x0001); /* Second Word */
  805.         AddJump("JSRD", 0x0002); /* Second Word */
  806.  
  807.         /* Alias */
  808.         AddRegDup("TSTR", 0x0080);
  809.         AddRegDup("CLRR", 0x01C0);
  810.         AddJR("JR", 0x0087);
  811.         AddReg("PSHR", 0x0270);
  812.         AddReg("PULR", 0x02B0);
  813.  
  814.         /* Pseudo Instructions */
  815.         AddRES("RES", 0x0000); /* Flag Word */
  816.         AddRES("ZERO", 0x0001); /* Flag Word */
  817.         AddWORD("WORD", 0x0000); /* Flag Word */
  818.         AddWORD("BYTE", 0x0001); /* Flag Word */
  819.         AddWORD("TEXT", 0x0002); /* Flag Word */
  820.         AddInstTable(InstTable, "BITS", 0x0000, DecodeBITS);
  821. }
  822.  
  823. static void DeinitFields(void)
  824. {
  825.         DestroyInstTable(InstTable);
  826. }
  827.  
  828. /*---------------------------------------------------------------------------*/
  829.  
  830. static void MakeCode_CP1600(void)
  831. {
  832.         CodeLen = 0;
  833.         DontPrint = False;
  834.  
  835.         if (Memo("")) return;
  836.  
  837.         if (!LookupInstTable(InstTable, OpPart.str.p_str))
  838.                 WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
  839. }
  840.  
  841. static Boolean IsDef_CP1600(void)
  842. {
  843.         return False;
  844. }
  845.  
  846. static void SwitchFrom_CP1600(void)
  847. {
  848.         DeinitFields();
  849. }
  850.  
  851. static void SwitchTo_CP1600(void)
  852. {
  853.         const TFamilyDescr *pDescr;
  854.  
  855.         TurnWords = True;
  856.         /* SetIntConstMode(eIntConstModeIBM); */
  857.         NativeIntConstModeMask = (1ul << eIntFormatCOct) | (1ul << eIntFormatIBMXHex) | (1ul << eIntFormatDefRadix);
  858.         OtherIntConstModeMask = eIntFormatMaskC | eIntFormatMaskIntel | eIntFormatMaskMoto | eIntFormatMaskIBM;
  859.         SetIntConstModeByMask( NativeIntConstModeMask | (RelaxedMode ? OtherIntConstModeMask : 0));
  860.  
  861.         pDescr = FindFamilyByName("CP1600");
  862.         PCSymbol = "*";
  863.         HeaderID = pDescr->Id;
  864.         NOPCode = 0x0034;
  865.         DivideChars = ",";
  866.         HasAttrs = False;
  867.  
  868.         ValidSegs = (1 << SegCode);
  869.         Grans[SegCode] = 2;
  870.         ListGrans[SegCode] = 2;
  871.         SegInits[SegCode] = 0;
  872.         SegLimits[SegCode] = 0xffff;
  873.  
  874.         Bits = 16;
  875.         Mask = 0x0000;
  876.         PrefixedSDBD = False;
  877.  
  878.   onoff_packing_add(True);
  879.  
  880.         MakeCode = MakeCode_CP1600;
  881.         IsDef = IsDef_CP1600;
  882.         SwitchFrom = SwitchFrom_CP1600;
  883.         InitFields();
  884. }
  885.  
  886. void codecp1600_init(void)
  887. {
  888.         CPUCP1600 = AddCPU("CP-1600", SwitchTo_CP1600);
  889.  
  890.         AddCopyright("GI CP-1600-Generator (C) 2021 Haruo Asano");
  891. }
  892.