Subversion Repositories pentevo

Rev

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

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