Subversion Repositories pentevo

Rev

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

  1. /* code8x30x.c */
  2. /*****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
  4. /*                                                                           */
  5. /* AS-Portierung                                                             */
  6. /*                                                                           */
  7. /* Codegenerator Signetics 8X30x                                             */
  8. /*                                                                           */
  9. /*****************************************************************************/
  10.  
  11. #include "stdinc.h"
  12. #include <string.h>
  13. #include <ctype.h>
  14.  
  15. #include "nls.h"
  16. #include "chunks.h"
  17. #include "bpemu.h"
  18. #include "strutil.h"
  19.  
  20. #include "asmdef.h"
  21. #include "asmsub.h"
  22. #include "asmpars.h"
  23. #include "asmitree.h"
  24. #include "codevars.h"
  25. #include "errmsg.h"
  26.  
  27. #include "code8x30x.h"
  28.  
  29. /*****************************************************************************/
  30.  
  31. static CPUVar CPU8x300, CPU8x305;
  32.  
  33. /*-------------------------------------------------------------------------*/
  34.  
  35. static Boolean DecodeReg(const tStrComp *pArg, Word *Erg, ShortInt *ErgLen)
  36. {
  37.   Boolean OK;
  38.   Word Acc;
  39.   LongInt Adr;
  40.   char *z;
  41.   int Len = strlen(pArg->str.p_str);
  42.  
  43.   *ErgLen = -1;
  44.  
  45.   if (!as_strcasecmp(pArg->str.p_str, "AUX"))
  46.   {
  47.     *Erg = 0;
  48.     return True;
  49.   }
  50.  
  51.   if (!as_strcasecmp(pArg->str.p_str, "OVF"))
  52.   {
  53.     *Erg = 8;
  54.     return True;
  55.   }
  56.  
  57.   if (!as_strcasecmp(pArg->str.p_str, "IVL"))
  58.   {
  59.     *Erg = 7;
  60.     return True;
  61.   }
  62.  
  63.   if (!as_strcasecmp(pArg->str.p_str, "IVR"))
  64.   {
  65.     *Erg = 15;
  66.     return True;
  67.   }
  68.  
  69.   if ((as_toupper(*pArg->str.p_str) == 'R') && (Len > 1) && (Len < 4))
  70.   {
  71.     Acc = 0;
  72.     OK = True;
  73.     for (z = pArg->str.p_str + 1; *z != '\0'; z++)
  74.       if (OK)
  75.       {
  76.         if ((*z < '0') || (*z > '7'))
  77.           OK = False;
  78.         else
  79.           Acc = (Acc << 3) + (*z - '0');
  80.       }
  81.     if ((OK) && (Acc < 32))
  82.     {
  83.       if ((MomCPU == CPU8x300) && (Acc > 9) && (Acc < 15))
  84.       {
  85.         WrStrErrorPos(ErrNum_InvReg, pArg);
  86.         return False;
  87.       }
  88.       else *Erg = Acc;
  89.       return True;
  90.     }
  91.   }
  92.  
  93.   if ((Len == 4) && (as_strncasecmp(pArg->str.p_str + 1, "IV", 2) == 0) && (pArg->str.p_str[3] >= '0') && (pArg->str.p_str[3] <= '7'))
  94.   {
  95.     if (as_toupper(*pArg->str.p_str) == 'L')
  96.     {
  97.       *Erg = pArg->str.p_str[3]-'0' + 0x10;
  98.       return True;
  99.     }
  100.     else if (as_toupper(*pArg->str.p_str) == 'R')
  101.     {
  102.       *Erg = pArg->str.p_str[3] - '0' + 0x18;
  103.       return True;
  104.     }
  105.   }
  106.  
  107.   /* IV - Objekte */
  108.  
  109.   Adr = EvalStrIntExpression(pArg, UInt24, &OK);
  110.   if (OK)
  111.   {
  112.     *ErgLen = Adr & 7;
  113.     *Erg = 0x10 | ((Adr & 0x10) >> 1) | ((Adr & 0x700) >> 8);
  114.     return True;
  115.   }
  116.   else
  117.     return False;
  118. }
  119.  
  120. static char *HasDisp(char *Asc)
  121. {
  122.   int Lev;
  123.   char *z;
  124.   int l = strlen(Asc);
  125.  
  126.   if (Asc[l - 1] == ')')
  127.   {
  128.     z = Asc + l - 2;
  129.     Lev = 0;
  130.     while ((z >= Asc) && (Lev != -1))
  131.     {
  132.       switch (*z)
  133.       {
  134.         case '(':
  135.           Lev--;
  136.           break;
  137.         case ')':
  138.           Lev++;
  139.           break;
  140.       }
  141.       if (Lev != -1)
  142.         z--;
  143.     }
  144.     if (Lev != -1)
  145.     {
  146.       WrError(ErrNum_BrackErr);
  147.       return NULL;
  148.     }
  149.   }
  150.   else
  151.     z = NULL;
  152.  
  153.   return z;
  154. }
  155.  
  156. static Boolean GetLen(const tStrComp *pArg, Word *Erg, tSymbolFlags *pFlags)
  157. {
  158.   Boolean OK;
  159.  
  160.   *Erg = EvalStrIntExpressionWithFlags(pArg, UInt4, &OK, pFlags);
  161.   if (!OK)
  162.     return False;
  163.   if (mFirstPassUnknown(*pFlags))
  164.     *Erg = 8;
  165.   if (!ChkRange(*Erg, 1, 8))
  166.     return False;
  167.   *Erg &= 7;
  168.   return True;
  169. }
  170.  
  171. /*-------------------------------------------------------------------------*/
  172.  
  173. static void DecodeNOP(Word Code)     /* NOP = MOVE AUX,AUX */
  174. {
  175.   UNUSED(Code);
  176.  
  177.   if (ChkArgCnt(0, 0))
  178.   {
  179.     WAsmCode[0] = 0x0000;
  180.     CodeLen = 1;
  181.   }
  182. }
  183.  
  184. static void DecodeHALT(Word Code)      /* HALT = JMP * */
  185. {
  186.   UNUSED(Code);
  187.  
  188.   if (ChkArgCnt(0, 0))
  189.   {
  190.     WAsmCode[0] = 0xe000 | (EProgCounter() & 0x1fff);
  191.     CodeLen = 1;
  192.   }
  193. }
  194.  
  195. static void DecodeXML_XMR(Word Code)
  196. {
  197.   if (ChkArgCnt(1, 1)
  198.    && ChkMinCPU(CPU8x305))
  199.   {
  200.     Boolean OK;
  201.     Word Adr = EvalStrIntExpression(&ArgStr[1], Int8, &OK);
  202.     if (OK)
  203.     {
  204.       WAsmCode[0] = Code | (Adr & 0xff);
  205.       CodeLen = 1;
  206.     }
  207.   }
  208. }
  209.  
  210. static void DecodeSEL(Word Code)
  211. {
  212.   UNUSED(Code);
  213.  
  214.   if (ChkArgCnt(1, 1))
  215.   {
  216.     Boolean OK;
  217.     LongInt Op = EvalStrIntExpression(&ArgStr[1], UInt24, &OK);
  218.     if (OK)
  219.     {
  220.       WAsmCode[0] = 0xc700 | ((Op & 0x10) << 7) | ((Op >> 16) & 0xff);
  221.       CodeLen = 1;
  222.     }
  223.   }
  224. }
  225.  
  226. static void DecodeXMIT(Word Code)
  227. {
  228.   Word SrcReg, Rot;
  229.   ShortInt SrcLen;
  230.   Boolean OK;
  231.   tSymbolFlags Flags;
  232.   LongInt Adr;
  233.  
  234.   UNUSED(Code);
  235.  
  236.   if (ChkArgCnt(2, 3)
  237.    && DecodeReg(&ArgStr[2], &SrcReg, &SrcLen))
  238.   {
  239.     if (SrcReg < 16)
  240.     {
  241.       if (ChkArgCnt(2, 2))
  242.       {
  243.         Adr = EvalStrIntExpression(&ArgStr[1], Int8, &OK);
  244.         if (OK)
  245.         {
  246.           WAsmCode[0] = 0xc000 | (SrcReg << 8) | (Adr & 0xff);
  247.           CodeLen = 1;
  248.         }
  249.       }
  250.     }
  251.     else
  252.     {
  253.       if (ArgCnt == 2)
  254.       {
  255.         Rot = 0xffff; OK = True; Flags = eSymbolFlag_None;
  256.       }
  257.       else
  258.         OK = GetLen(&ArgStr[3], &Rot, &Flags);
  259.       if (OK)
  260.       {
  261.         if (Rot == 0xffff)
  262.           Rot = (SrcLen == -1) ? 0 : SrcLen;
  263.         if ((SrcLen != -1) && (Rot != SrcLen)) WrError(ErrNum_ConfOpSizes);
  264.         else
  265.         {
  266.           Adr = EvalStrIntExpression(&ArgStr[1], Int5, &OK);
  267.           if (OK)
  268.           {
  269.             WAsmCode[0] = 0xc000 | (SrcReg << 8) | (Rot << 5) | (Adr & 0x1f);
  270.             CodeLen = 1;
  271.           }
  272.         }
  273.       }
  274.     }
  275.   }
  276. }
  277.  
  278. static void DecodeAri(Word Code)
  279. {
  280.   Word SrcReg, DestReg, Rot;
  281.   ShortInt SrcLen, DestLen;
  282.   char *p;
  283.   Boolean OK;
  284.  
  285.   if (ChkArgCnt(2, 3)
  286.    && DecodeReg(&ArgStr[ArgCnt], &DestReg, &DestLen))
  287.   {
  288.     if (DestReg < 16)         /* Ziel Register */
  289.     {
  290.       if (ArgCnt == 2)        /* wenn nur zwei Operanden und Ziel Register... */
  291.       {
  292.         p = HasDisp(ArgStr[1].str.p_str); /* kann eine Rotation dabei sein */
  293.         if (p)
  294.         {                 /* jau! */
  295.           tStrComp RegArg, RotArg;
  296.  
  297.           StrCompSplitRef(&RegArg, &RotArg, &ArgStr[1], p);
  298.           StrCompShorten(&RotArg, 1);
  299.           Rot = EvalStrIntExpression(&RotArg, UInt3, &OK);
  300.           if (OK)
  301.           {
  302.             if (DecodeReg(&RegArg, &SrcReg, &SrcLen))
  303.             {
  304.               if (SrcReg >= 16) WrStrErrorPos(ErrNum_InvReg, &RegArg);
  305.               else
  306.               {
  307.                 WAsmCode[0] = (Code << 13) | (SrcReg << 8) | (Rot << 5) | DestReg;
  308.                 CodeLen = 1;
  309.               }
  310.             }
  311.           }
  312.         }
  313.         else                   /* noi! */
  314.         {
  315.           if (DecodeReg(&ArgStr[1], &SrcReg, &SrcLen))
  316.           {
  317.             WAsmCode[0] = (Code << 13) | (SrcReg << 8) | DestReg;
  318.             if ((SrcReg >= 16) && (SrcLen != -1)) WAsmCode[0] += SrcLen << 5;
  319.             CodeLen = 1;
  320.           }
  321.         }
  322.       }
  323.       else                     /* 3 Operanden --> Quelle ist I/O */
  324.       {
  325.         tSymbolFlags Flags;
  326.  
  327.         if (GetLen(&ArgStr[2], &Rot, &Flags))
  328.          if (DecodeReg(&ArgStr[1], &SrcReg, &SrcLen))
  329.          {
  330.            if (SrcReg < 16) WrStrErrorPos(ErrNum_InvReg, &ArgStr[1]);
  331.            else if ((SrcLen != -1) && (SrcLen != Rot)) WrError(ErrNum_ConfOpSizes);
  332.            else
  333.            {
  334.              WAsmCode[0] = (Code << 13) | (SrcReg << 8) | (Rot << 5) | DestReg;
  335.              CodeLen = 1;
  336.            }
  337.          }
  338.       }
  339.     }
  340.     else                       /* Ziel I/O */
  341.     {
  342.       if (ArgCnt == 2)           /* 2 Argumente: Laenge=Laenge Ziel */
  343.       {
  344.         Rot = DestLen; OK = True;
  345.       }
  346.       else                     /* 3 Argumente: Laenge=Laenge Ziel+Angabe */
  347.       {
  348.         tSymbolFlags Flags;
  349.  
  350.         OK = GetLen(&ArgStr[2], &Rot, &Flags);
  351.         if (OK)
  352.         {
  353.           if (mFirstPassUnknown(Flags)) Rot = DestLen;
  354.           if (DestLen == -1) DestLen = Rot;
  355.           OK = Rot == DestLen;
  356.           if (!OK) WrError(ErrNum_ConfOpSizes);
  357.         }
  358.       }
  359.       if (OK)
  360.        if (DecodeReg(&ArgStr[1], &SrcReg, &SrcLen))
  361.        {
  362.          if (Rot == 0xffff)
  363.            Rot = ((SrcLen == -1)) ? 0 : SrcLen;
  364.          if ((DestReg >= 16) && (SrcLen != -1) && (SrcLen != Rot)) WrError(ErrNum_ConfOpSizes);
  365.          else
  366.          {
  367.            WAsmCode[0] = (Code << 13) | (SrcReg << 8) | (Rot << 5) | DestReg;
  368.            CodeLen = 1;
  369.          }
  370.        }
  371.     }
  372.   }
  373. }
  374.  
  375. static void DecodeXEC(Word Code)
  376. {
  377.   char *p;
  378.   Word SrcReg, Rot;
  379.   ShortInt SrcLen;
  380.   Boolean OK;
  381.  
  382.   UNUSED(Code);
  383.  
  384.   if (ChkArgCnt(1, 2))
  385.   {
  386.     p = HasDisp(ArgStr[1].str.p_str);
  387.     if (!p) WrError(ErrNum_InvAddrMode);
  388.     else
  389.     {
  390.       tStrComp DispArg, RegArg;
  391.  
  392.       StrCompSplitRef(&DispArg, &RegArg, &ArgStr[1], p);
  393.       StrCompShorten(&RegArg, 1);
  394.       if (DecodeReg(&RegArg, &SrcReg, &SrcLen))
  395.       {
  396.         if (SrcReg < 16)
  397.         {
  398.           if (ChkArgCnt(1, 1))
  399.           {
  400.             WAsmCode[0] = EvalStrIntExpression(&DispArg, UInt8, &OK);
  401.             if (OK)
  402.             {
  403.               WAsmCode[0] |= 0x8000 | (SrcReg << 8);
  404.               CodeLen = 1;
  405.             }
  406.           }
  407.         }
  408.         else
  409.         {
  410.           tSymbolFlags Flags;
  411.  
  412.           if (ArgCnt == 1)
  413.           {
  414.             Rot = 0xffff; OK = True; Flags = eSymbolFlag_None;
  415.           }
  416.           else OK = GetLen(&ArgStr[2], &Rot, &Flags);
  417.           if (OK)
  418.           {
  419.             if (Rot == 0xffff)
  420.              Rot = (SrcLen == -1) ? 0 : SrcLen;
  421.             if ((SrcLen != -1) && (Rot != SrcLen)) WrError(ErrNum_ConfOpSizes);
  422.             else
  423.             {
  424.               WAsmCode[0] = EvalStrIntExpression(&DispArg, UInt5, &OK);
  425.               if (OK)
  426.               {
  427.                 WAsmCode[0] |= 0x8000 | (SrcReg << 8) | (Rot << 5);
  428.                 CodeLen = 1;
  429.               }
  430.             }
  431.           }
  432.         }
  433.       }
  434.     }
  435.   }
  436. }
  437.  
  438. static void DecodeJMP(Word Code)
  439. {
  440.   UNUSED(Code);
  441.  
  442.   if (ChkArgCnt(1, 1))
  443.   {
  444.     Boolean OK;
  445.  
  446.     WAsmCode[0] = EvalStrIntExpression(&ArgStr[1], UInt13, &OK);
  447.     if (OK)
  448.     {
  449.       WAsmCode[0] |= 0xe000;
  450.       CodeLen = 1;
  451.     }
  452.   }
  453.   return;
  454. }
  455.  
  456. static void DecodeNZT(Word Code)
  457. {
  458.   Word SrcReg, Adr, Rot;
  459.   ShortInt SrcLen;
  460.   Boolean OK;
  461.   tSymbolFlags Flags;
  462.  
  463.   UNUSED(Code);
  464.  
  465.   if (ChkArgCnt(2, 3)
  466.    && DecodeReg(&ArgStr[1], &SrcReg, &SrcLen))
  467.   {
  468.     if (SrcReg < 16)
  469.     {
  470.       if (ChkArgCnt(2, 2))
  471.       {
  472.         Adr = EvalStrIntExpressionWithFlags(&ArgStr[2], UInt13, &OK, &Flags);
  473.         if (OK && ChkSamePage(Adr, EProgCounter(), 8, Flags))
  474.         {
  475.           WAsmCode[0] = 0xa000 | (SrcReg << 8) | (Adr & 0xff);
  476.           CodeLen = 1;
  477.         }
  478.       }
  479.     }
  480.     else
  481.     {
  482.       if (ArgCnt == 2)
  483.       {
  484.         Rot = 0xffff; OK = True; Flags = eSymbolFlag_None;
  485.       }
  486.       else OK = GetLen(&ArgStr[2], &Rot, &Flags);
  487.       if (OK)
  488.       {
  489.         if (Rot == 0xffff)
  490.          Rot = (SrcLen == -1) ? 0 : SrcLen;
  491.         if ((SrcLen != -1) && (Rot != SrcLen)) WrError(ErrNum_ConfOpSizes);
  492.         else
  493.         {
  494.           Adr = EvalStrIntExpressionWithFlags(&ArgStr[ArgCnt], UInt13, &OK, &Flags);
  495.           if (OK && ChkSamePage(Adr, EProgCounter(), 5, Flags))
  496.           {
  497.             WAsmCode[0] = 0xa000 | (SrcReg << 8) | (Rot << 5) | (Adr & 0x1f);
  498.             CodeLen = 1;
  499.           }
  500.         }
  501.       }
  502.     }
  503.   }
  504. }
  505.  
  506. /* Symbol: 00AA0ORL */
  507.  
  508. static void DecodeLIV_RIV(Word Code)
  509. {
  510.   LongInt Adr, Ofs;
  511.   Word Len;
  512.   Boolean OK;
  513.   tSymbolFlags Flags;
  514.  
  515.   if (ChkArgCnt(3, 3))
  516.   {
  517.     Adr = EvalStrIntExpression(&ArgStr[1], UInt8, &OK);
  518.     if (OK)
  519.     {
  520.       Ofs = EvalStrIntExpression(&ArgStr[2], UInt3, &OK);
  521.       if (OK)
  522.        if (GetLen(&ArgStr[3], &Len, &Flags))
  523.        {
  524.          PushLocHandle(-1);
  525.          EnterIntSymbol(&LabPart, Code | (Adr << 16) | (Ofs << 8) | (Len & 7), SegNone, False);
  526.          PopLocHandle();
  527.        }
  528.     }
  529.   }
  530. }
  531.  
  532. /*-------------------------------------------------------------------------*/
  533.  
  534. static void AddAri(const char *NName, Word NCode)
  535. {
  536.   AddInstTable(InstTable, NName, NCode, DecodeAri);
  537. }
  538.  
  539. static void InitFields(void)
  540. {
  541.   InstTable = CreateInstTable(103);
  542.   AddInstTable(InstTable, "NOP", 0, DecodeNOP);
  543.   AddInstTable(InstTable, "HALT", 0, DecodeHALT);
  544.   AddInstTable(InstTable, "XML", 0xca00, DecodeXML_XMR);
  545.   AddInstTable(InstTable, "XMR", 0xcb00, DecodeXML_XMR);
  546.   AddInstTable(InstTable, "SEL", 0, DecodeSEL);
  547.   AddInstTable(InstTable, "XMIT", 0, DecodeXMIT);
  548.   AddInstTable(InstTable, "XEC", 0, DecodeXEC);
  549.   AddInstTable(InstTable, "JMP", 0, DecodeJMP);
  550.   AddInstTable(InstTable, "NZT", 0, DecodeNZT);
  551.   AddInstTable(InstTable, "LIV", 0, DecodeLIV_RIV);
  552.   AddInstTable(InstTable, "RIV", 0x10, DecodeLIV_RIV);
  553.  
  554.   AddAri("MOVE", 0); AddAri("ADD", 1); AddAri("AND", 2); AddAri("XOR", 3);
  555. }
  556.  
  557. static void DeinitFields(void)
  558. {
  559.   DestroyInstTable(InstTable);
  560. }
  561.  
  562. /*-------------------------------------------------------------------------*/
  563.  
  564. /*-------------------------------------------------------------------------*/
  565.  
  566. static void MakeCode_8x30X(void)
  567. {
  568.   CodeLen = 0; DontPrint = False;
  569.  
  570.   /* zu ignorierendes */
  571.  
  572.   if (Memo("")) return;
  573.  
  574.   /* Pseudoanweisungen */
  575.  
  576.   if (!LookupInstTable(InstTable, OpPart.str.p_str))
  577.     WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
  578. }
  579.  
  580. static Boolean IsDef_8x30X(void)
  581. {
  582.   return (Memo("LIV") || Memo("RIV"));
  583. }
  584.  
  585. static void SwitchFrom_8x30X(void)
  586. {
  587.   DeinitFields();
  588. }
  589.  
  590. static void SwitchTo_8x30X(void)
  591. {
  592.   TurnWords = False;
  593.   SetIntConstMode(eIntConstModeMoto);
  594.  
  595.   PCSymbol = "*";
  596.   HeaderID = 0x3a;
  597.   NOPCode = 0x0000;
  598.   DivideChars = ",";
  599.   HasAttrs = False;
  600.  
  601.   ValidSegs = 1 << SegCode;
  602.   Grans[SegCode] = 2;
  603.   ListGrans[SegCode] = 2;
  604.   SegInits[SegCode] = 0;
  605.   SegLimits[SegCode] = 0x1fff;
  606.  
  607.   MakeCode = MakeCode_8x30X;
  608.   IsDef = IsDef_8x30X;
  609.   SwitchFrom = SwitchFrom_8x30X;
  610.   InitFields();
  611. }
  612.  
  613. void code8x30x_init(void)
  614. {
  615.   CPU8x300 = AddCPU("8x300", SwitchTo_8x30X);
  616.   CPU8x305 = AddCPU("8x305", SwitchTo_8x30X);
  617. }
  618.