Subversion Repositories pentevo

Rev

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

  1. /* codetms7.c */
  2. /*****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
  4. /*                                                                           */
  5. /* AS-Portierung                                                             */
  6. /*                                                                           */
  7. /* Codegenerator TMS7000-Familie                                             */
  8. /*                                                                           */
  9. /*****************************************************************************/
  10.  
  11. #include "stdinc.h"
  12. #include <ctype.h>
  13. #include <string.h>
  14.  
  15. #include "strutil.h"
  16. #include "bpemu.h"
  17. #include "nls.h"
  18. #include "asmdef.h"
  19. #include "asmsub.h"
  20. #include "asmpars.h"
  21. #include "asmitree.h"
  22. #include "codepseudo.h"
  23. #include "intpseudo.h"
  24. #include "codevars.h"
  25. #include "errmsg.h"
  26. #include "headids.h"
  27.  
  28. #include "codetms7.h"
  29.  
  30. #define ModNone (-1)
  31. #define ModAccA 0
  32. #define MModAccA (1 << ModAccA)       /* A */
  33. #define ModAccB 1
  34. #define MModAccB (1 << ModAccB)       /* B */
  35. #define ModReg 2
  36. #define MModReg (1 << ModReg)         /* Rn */
  37. #define ModPort 3
  38. #define MModPort (1 << ModPort)       /* Pn */
  39. #define ModAbs 4
  40. #define MModAbs (1 << ModAbs)         /* nnnn */
  41. #define ModBRel 5
  42. #define MModBRel (1 << ModBRel)       /* nnnn(B) */
  43. #define ModIReg 6
  44. #define MModIReg (1 << ModIReg)       /* *Rn */
  45. #define ModImm 7
  46. #define MModImm (1 << ModImm)         /* #nn */
  47. #define ModImmBRel 8
  48. #define MModImmBRel (1 << ModImmBRel) /* #nnnn(b) */
  49.  
  50.  
  51. static CPUVar CPU70C40,CPU70C20,CPU70C00,
  52.               CPU70CT40,CPU70CT20,
  53.               CPU70C82,CPU70C42,CPU70C02,
  54.               CPU70C48,CPU70C08;
  55.  
  56. static Byte OpSize;
  57. static ShortInt AdrType;
  58. static Byte AdrVals[2];
  59.  
  60. /*---------------------------------------------------------------------------*/
  61. /* helpers */
  62.  
  63. static void ChkAdr(Word Mask)
  64. {
  65.   if ((AdrType != -1) && ((Mask & (1L << AdrType)) == 0))
  66.   {
  67.     WrError(ErrNum_InvAddrMode); AdrType = ModNone; AdrCnt = 0;
  68.   }
  69. }
  70.  
  71. static void DecodeAdr(tStrComp *pArg, Word Mask)
  72. {
  73.   Integer HVal;
  74.   int Lev, l;
  75.   char *p;
  76.   Boolean OK;
  77.   tStrComp Expr;
  78.  
  79.   AdrType = ModNone; AdrCnt = 0;
  80.  
  81.   if (!as_strcasecmp(pArg->str.p_str, "A"))
  82.   {
  83.     if (Mask & MModAccA) AdrType = ModAccA;
  84.     else if (Mask & MModReg)
  85.     {
  86.       AdrCnt = 1; AdrVals[0] = 0; AdrType = ModReg;
  87.     }
  88.     else
  89.     {
  90.       AdrCnt = 2; AdrVals[0] = 0; AdrVals[1] = 0; AdrType = ModAbs;
  91.     }
  92.     ChkAdr(Mask); return;
  93.   }
  94.  
  95.   if (!as_strcasecmp(pArg->str.p_str, "B"))
  96.   {
  97.     if (Mask & MModAccB) AdrType = ModAccB;
  98.     else if (Mask & MModReg)
  99.     {
  100.       AdrCnt = 1; AdrVals[0] = 1; AdrType = ModReg;
  101.     }
  102.     else
  103.     {
  104.       AdrCnt = 2; AdrVals[0] = 0; AdrVals[1] = 1; AdrType = ModAbs;
  105.     }
  106.     ChkAdr(Mask); return;
  107.   }
  108.  
  109.   if ((*pArg->str.p_str == '#') || (*pArg->str.p_str == '%'))
  110.   {
  111.     tStrComp ImmComp;
  112.  
  113.     StrCompRefRight(&ImmComp, pArg, 1);
  114.     l = strlen(ImmComp.str.p_str);
  115.     if ((l >= 3) & (!as_strcasecmp(ImmComp.str.p_str + l - 3,"(B)")))
  116.     {
  117.       char Save;
  118.  
  119.       Save = ImmComp.str.p_str[l - 3];
  120.       ImmComp.str.p_str[l - 3] = '\0'; ImmComp.Pos.Len -= 3;
  121.       HVal = EvalStrIntExpression(&ImmComp, Int16, &OK);
  122.       ImmComp.str.p_str[l - 3] = Save;
  123.       if (OK)
  124.       {
  125.         AdrVals[0] = Hi(HVal); AdrVals[1] = Lo(HVal);
  126.         AdrType = ModImmBRel; AdrCnt = 2;
  127.       }
  128.     }
  129.     else
  130.     {
  131.       switch (OpSize)
  132.       {
  133.         case 0:
  134.           AdrVals[0] = EvalStrIntExpression(&ImmComp, Int8, &OK);
  135.           break;
  136.         case 1:
  137.           HVal = EvalStrIntExpression(&ImmComp, Int16, &OK);
  138.           AdrVals[0] = Hi(HVal);
  139.           AdrVals[1] = Lo(HVal);
  140.           break;
  141.       }
  142.       if (OK)
  143.       {
  144.         AdrCnt = 1 + OpSize;
  145.         AdrType = ModImm;
  146.       }
  147.     }
  148.     ChkAdr(Mask); return;
  149.   }
  150.  
  151.   if (*pArg->str.p_str == '*')
  152.   {
  153.     AdrVals[0] = EvalStrIntExpressionOffs(pArg, 1, Int8, &OK);
  154.     if (OK)
  155.     {
  156.       AdrCnt = 1;
  157.       AdrType = ModIReg;
  158.     }
  159.     ChkAdr(Mask); return;
  160.   }
  161.  
  162.   StrCompRefRight(&Expr, pArg, !!(*pArg->str.p_str == '@'));
  163.  
  164.   l = strlen(Expr.str.p_str);
  165.   if ((*Expr.str.p_str) && (Expr.str.p_str[l - 1] == ')'))
  166.   {
  167.     p = Expr.str.p_str + l - 2; Lev = 0;
  168.     while ((p >= Expr.str.p_str) && (Lev != -1))
  169.     {
  170.       switch (*p)
  171.       {
  172.         case '(': Lev--; break;
  173.         case ')': Lev++; break;
  174.       }
  175.       if (Lev != -1) p--;
  176.     }
  177.     if (p < Expr.str.p_str)
  178.     {
  179.       WrError(ErrNum_BrackErr);
  180.       p = NULL;
  181.     }
  182.   }
  183.   else
  184.     p = NULL;
  185.  
  186.   if (!p)
  187.   {
  188.     HVal = EvalStrIntExpression(&Expr, Int16, &OK);
  189.     if (OK)
  190.     {
  191.       if ((Mask & MModReg) && (!Hi(HVal)))
  192.       {
  193.         AdrVals[0] = Lo(HVal); AdrCnt = 1; AdrType = ModReg;
  194.       }
  195.       else if ((Mask & MModPort) && (Hi(HVal) == 0x01))
  196.       {
  197.         AdrVals[0] = Lo(HVal); AdrCnt = 1; AdrType = ModPort;
  198.       }
  199.       else
  200.       {
  201.         AdrVals[0] = Hi(HVal); AdrVals[1] = Lo(HVal); AdrCnt = 2;
  202.         AdrType = ModAbs;
  203.       }
  204.     }
  205.     ChkAdr(Mask); return;
  206.   }
  207.   else
  208.   {
  209.     tStrComp Left, Right;
  210.  
  211.     StrCompSplitRef(&Left, &Right, &Expr, p);
  212.     HVal = EvalStrIntExpression(&Left, Int16, &OK);
  213.     if (OK)
  214.     {
  215.       StrCompShorten(&Right, 1);
  216.       if (!as_strcasecmp(Right.str.p_str, "B"))
  217.       {
  218.         AdrVals[0] = Hi(HVal); AdrVals[1] = Lo(HVal); AdrCnt = 2;
  219.         AdrType = ModBRel;
  220.       }
  221.       else WrStrErrorPos(ErrNum_InvReg, &Right);
  222.     }
  223.     ChkAdr(Mask); return;
  224.   }
  225. }
  226.  
  227. static void PutCode(Word Code)
  228. {
  229.   if (Hi(Code))
  230.     BAsmCode[CodeLen++] = Hi(Code);
  231.   BAsmCode[CodeLen++] = Lo(Code);
  232. }
  233.  
  234. /*---------------------------------------------------------------------------*/
  235. /* decoders */
  236.  
  237. static void DecodeFixed(Word Index)
  238. {
  239.   if (ChkArgCnt(0, 0))
  240.     PutCode(Index);
  241. }
  242.  
  243. static void DecodeRel8(Word Index)
  244. {
  245.   if (ChkArgCnt(1, 1))
  246.   {
  247.     Boolean OK;
  248.     Integer AdrInt = EvalStrIntExpression(&ArgStr[1], UInt16, &OK) - (EProgCounter() + 2);
  249.  
  250.     if (OK)
  251.     {
  252.       if ((AdrInt > 127) || (AdrInt<-128)) WrError(ErrNum_JmpDistTooBig);
  253.       else
  254.       {
  255.         CodeLen = 2;
  256.         BAsmCode[0] = Index;
  257.         BAsmCode[1] = AdrInt & 0xff;
  258.       }
  259.     }
  260.   }
  261. }
  262.  
  263. static void DecodeALU1(Word Index)
  264. {
  265.   if (ChkArgCnt(2, 2))
  266.   {
  267.     DecodeAdr(&ArgStr[2], MModAccA | MModAccB | MModReg);
  268.     switch (AdrType)
  269.     {
  270.       case ModAccA:
  271.         DecodeAdr(&ArgStr[1], MModAccB | MModReg | MModImm);
  272.         switch (AdrType)
  273.         {
  274.           case ModAccB:
  275.             CodeLen = 1;
  276.             BAsmCode[0] = 0x60 | Index;
  277.             break;
  278.           case ModReg:
  279.             CodeLen = 2;
  280.             BAsmCode[0] = 0x10 | Index;
  281.             BAsmCode[1] = AdrVals[0];
  282.             break;
  283.           case ModImm:
  284.             CodeLen = 2;
  285.             BAsmCode[0] = 0x20 | Index;
  286.             BAsmCode[1] = AdrVals[0];
  287.             break;
  288.         }
  289.         break;
  290.       case ModAccB:
  291.         DecodeAdr(&ArgStr[1], MModReg | MModImm);
  292.         switch (AdrType)
  293.         {
  294.           case ModReg:
  295.             CodeLen = 2;
  296.             BAsmCode[0] = 0x30 | Index;
  297.             BAsmCode[1] = AdrVals[0];
  298.             break;
  299.           case ModImm:
  300.             CodeLen=2;
  301.             BAsmCode[0] = 0x50 | Index;
  302.             BAsmCode[1] = AdrVals[0];
  303.             break;
  304.         }
  305.         break;
  306.       case ModReg:
  307.         BAsmCode[2] = AdrVals[0];
  308.         DecodeAdr(&ArgStr[1], MModReg | MModImm);
  309.         switch (AdrType)
  310.         {
  311.           case ModReg:
  312.             CodeLen = 3;
  313.             BAsmCode[0] = 0x40 | Index;
  314.             BAsmCode[1] = AdrVals[0];
  315.             break;
  316.           case ModImm:
  317.             CodeLen = 3;
  318.             BAsmCode[0] = 0x70 | Index;
  319.             BAsmCode[1] = AdrVals[0];
  320.             break;
  321.         }
  322.         break;
  323.     }
  324.   }
  325. }
  326.  
  327. static void DecodeALU2(Word Index)
  328. {
  329.   Boolean IsP = ((Index & 0x8000) != 0),
  330.           IsRela = ((Index & 0x4000) != 0);
  331.  
  332.   Index &= ~0xc000;
  333.  
  334.   if (ChkArgCnt(IsRela ? 3 : 2, IsRela ? 3 : 2))
  335.   {
  336.     DecodeAdr(&ArgStr[2], MModPort | (IsP ? 0 : MModAccA | MModAccB | MModReg));
  337.     switch (AdrType)
  338.     {
  339.       case ModAccA:
  340.         DecodeAdr(&ArgStr[1], MModAccB | MModReg | MModImm);
  341.         switch (AdrType)
  342.         {
  343.           case ModAccB:
  344.             BAsmCode[0] = 0x60 | Index;
  345.             CodeLen = 1;
  346.             break;
  347.           case ModReg:
  348.             BAsmCode[0] = 0x10 | Index;
  349.             BAsmCode[1] = AdrVals[0];
  350.             CodeLen = 2;
  351.             break;
  352.           case ModImm:
  353.             BAsmCode[0] = 0x20 | Index;
  354.             BAsmCode[1] = AdrVals[0];
  355.             CodeLen = 2;
  356.             break;
  357.         }
  358.         break;
  359.       case ModAccB:
  360.         DecodeAdr(&ArgStr[1], MModReg | MModImm);
  361.         switch (AdrType)
  362.         {
  363.           case ModReg:
  364.             BAsmCode[0] = 0x30 | Index;
  365.             BAsmCode[1] = AdrVals[0];
  366.             CodeLen = 2;
  367.             break;
  368.           case ModImm:
  369.             BAsmCode[0] = 0x50 | Index;
  370.             BAsmCode[1] = AdrVals[0];
  371.             CodeLen = 2;
  372.             break;
  373.         }
  374.         break;
  375.       case ModReg:
  376.         BAsmCode[2] = AdrVals[0];
  377.         DecodeAdr(&ArgStr[1], MModReg | MModImm);
  378.         switch (AdrType)
  379.         {
  380.           case ModReg:
  381.             BAsmCode[0] = 0x40 | Index;
  382.             BAsmCode[1] = AdrVals[0];
  383.             CodeLen = 3;
  384.             break;
  385.           case ModImm:
  386.             BAsmCode[0] = 0x70 | Index;
  387.             BAsmCode[1] = AdrVals[0];
  388.             CodeLen = 3;
  389.         }
  390.         break;
  391.       case ModPort:
  392.         BAsmCode[1] = AdrVals[0];
  393.         DecodeAdr(&ArgStr[1], MModAccA | MModAccB | MModImm);
  394.         switch (AdrType)
  395.         {
  396.           case ModAccA:
  397.             BAsmCode[0] = 0x80 | Index;
  398.             CodeLen = 2;
  399.             break;
  400.           case ModAccB:
  401.             BAsmCode[0] = 0x90 | Index;
  402.             CodeLen = 2;
  403.             break;
  404.           case ModImm:
  405.             BAsmCode[0] = 0xa0 | Index;
  406.             BAsmCode[2] = BAsmCode[1];
  407.             BAsmCode[1] = AdrVals[0];
  408.             CodeLen = 3;
  409.         }
  410.         break;
  411.     }
  412.     if ((CodeLen != 0) && (IsRela))
  413.     {
  414.       Boolean OK;
  415.       tSymbolFlags Flags;
  416.       Integer AdrInt = EvalStrIntExpressionWithFlags(&ArgStr[3], Int16, &OK, &Flags) - (EProgCounter() + CodeLen + 1);
  417.  
  418.       if (!OK) CodeLen = 0;
  419.       else if (!mSymbolQuestionable(Flags) && ((AdrInt > 127) || (AdrInt < -128)))
  420.       {
  421.         WrError(ErrNum_JmpDistTooBig); CodeLen = 0;
  422.       }
  423.       else
  424.         BAsmCode[CodeLen++] = AdrInt & 0xff;
  425.     }
  426.   }
  427. }
  428.  
  429. static void DecodeJmp(Word Index)
  430. {
  431.   if (ChkArgCnt(1, 1))
  432.   {
  433.     DecodeAdr(&ArgStr[1], MModAbs | MModIReg | MModBRel);
  434.     switch (AdrType)
  435.     {
  436.       case ModAbs:
  437.         CodeLen = 3;
  438.         BAsmCode[0] = 0x80 | Index;
  439.         memcpy(BAsmCode + 1, AdrVals, 2);
  440.         break;
  441.       case ModIReg:
  442.         CodeLen = 2;
  443.         BAsmCode[0] = 0x90 | Index;
  444.         BAsmCode[1] = AdrVals[0];
  445.         break;
  446.       case ModBRel:
  447.         CodeLen = 3;
  448.         BAsmCode[0] = 0xa0 | Index;
  449.         memcpy(BAsmCode + 1, AdrVals, 2);
  450.         break;
  451.     }
  452.   }
  453. }
  454.  
  455. static void DecodeABRegCore(Word code)
  456. {
  457.   DecodeAdr(&ArgStr[1], MModAccA | MModAccB | MModReg);
  458.   switch (AdrType)
  459.   {
  460.     case ModAccA:
  461.       BAsmCode[0] = 0xb0 | code;
  462.       CodeLen = 1;
  463.       break;
  464.     case ModAccB:
  465.       BAsmCode[0] = 0xc0 | code;
  466.       CodeLen = 1;
  467.       break;
  468.     case ModReg:
  469.       BAsmCode[0] = 0xd0 | code;
  470.       BAsmCode[1] = AdrVals[0];
  471.       CodeLen = 2;
  472.       break;
  473.   }
  474. }
  475.  
  476. static void DecodeABReg(Word code)
  477. {
  478.   if (ChkArgCnt(1, 1))
  479.     DecodeABRegCore(code);
  480. }
  481.  
  482. static void DecodeDJNZ(Word code)
  483. {
  484.   if (ChkArgCnt(2, 2))
  485.   {
  486.     DecodeABRegCore(code);
  487.     if (CodeLen > 0)
  488.     {
  489.       Boolean OK;
  490.       tSymbolFlags Flags;
  491.       Integer AdrInt = EvalStrIntExpressionWithFlags(&ArgStr[2], UInt16, &OK, &Flags) - (EProgCounter() + CodeLen + 1);
  492.  
  493.       if (!OK)
  494.         CodeLen = 0;
  495.       else if (!mSymbolQuestionable(Flags) & ((AdrInt > 127) || (AdrInt < -128)))
  496.       {
  497.         WrError(ErrNum_JmpDistTooBig);
  498.         OK = False;
  499.       }
  500.       if (!OK)
  501.         CodeLen = 0;
  502.       else
  503.         BAsmCode[CodeLen++] = AdrInt & 0xff;
  504.     }
  505.   }
  506. }
  507.  
  508. static void DecodePUSH_POP(Word code)
  509. {
  510.   if (!ChkArgCnt(1, 1));
  511.   else if (!as_strcasecmp(ArgStr[1].str.p_str, "ST"))
  512.   {
  513.     BAsmCode[0] = (code & 1) ? 0x08 : 0x0e;
  514.     CodeLen = 1;
  515.   }
  516.   else
  517.     DecodeABRegCore(code);
  518. }
  519.  
  520. static void DecodeMOV(Word IsMOVP)
  521. {
  522.   if (ChkArgCnt(2, 2))
  523.   {
  524.     DecodeAdr(&ArgStr[2], MModPort| MModAccA| MModAccB |
  525.                         (IsMOVP ? 0: MModReg| MModAbs | MModIReg| MModBRel));
  526.     switch (AdrType)
  527.     {
  528.       case ModAccA:
  529.         DecodeAdr(&ArgStr[1], MModPort+
  530.                             (IsMOVP ? 0 : MModReg | MModAbs | MModIReg | MModBRel | MModAccB | MModImm));
  531.         switch (AdrType)
  532.         {
  533.           case ModReg:
  534.             BAsmCode[0] = 0x12;
  535.             BAsmCode[1] = AdrVals[0];
  536.             CodeLen = 2;
  537.             break;
  538.           case ModAbs:
  539.             BAsmCode[0] = 0x8a;
  540.             memcpy(BAsmCode + 1, AdrVals, 2);
  541.             CodeLen = 3;
  542.             break;
  543.           case ModIReg:
  544.             BAsmCode[0] = 0x9a;
  545.             BAsmCode[1] = AdrVals[0];
  546.             CodeLen = 2;
  547.             break;
  548.           case ModBRel:
  549.             BAsmCode[0] = 0xaa;
  550.             memcpy(BAsmCode + 1, AdrVals, 2);
  551.             CodeLen = 3;
  552.             break;
  553.           case ModAccB:
  554.             BAsmCode[0] = 0x62;
  555.             CodeLen = 1;
  556.             break;
  557.           case ModPort:
  558.             BAsmCode[0] = 0x80;
  559.             BAsmCode[1] = AdrVals[0];
  560.             CodeLen = 2;
  561.             break;
  562.           case ModImm:
  563.             BAsmCode[0] = 0x22;
  564.             BAsmCode[1] = AdrVals[0];
  565.             CodeLen = 2;
  566.             break;
  567.         }
  568.         break;
  569.       case ModAccB:
  570.         DecodeAdr(&ArgStr[1], MModPort | (IsMOVP ? 0 : MModAccA | MModReg | MModImm));
  571.         switch (AdrType)
  572.         {
  573.           case ModAccA:
  574.             BAsmCode[0] = 0xc0;
  575.             CodeLen = 1;
  576.             break;
  577.           case ModReg:
  578.             BAsmCode[0] = 0x32;
  579.             BAsmCode[1] = AdrVals[0];
  580.             CodeLen = 2;
  581.             break;
  582.           case ModPort:
  583.             BAsmCode[0] = 0x91;
  584.             BAsmCode[1] = AdrVals[0];
  585.             CodeLen = 2;
  586.             break;
  587.           case ModImm:
  588.             BAsmCode[0] = 0x52;
  589.             BAsmCode[1] = AdrVals[0];
  590.             CodeLen = 2;
  591.             break;
  592.         }
  593.         break;
  594.       case ModReg:
  595.         BAsmCode[1] = BAsmCode[2] = AdrVals[0];
  596.         DecodeAdr(&ArgStr[1], MModAccA | MModAccB | MModReg | MModPort | MModImm);
  597.         switch (AdrType)
  598.         {
  599.           case ModAccA:
  600.             BAsmCode[0] = 0xd0;
  601.             CodeLen = 2;
  602.             break;
  603.           case ModAccB:
  604.             BAsmCode[0] = 0xd1;
  605.             CodeLen = 2;
  606.             break;
  607.           case ModReg:
  608.             BAsmCode[0] = 0x42;
  609.             BAsmCode[1] = AdrVals[0];
  610.             CodeLen=3;
  611.             break;
  612.           case ModPort:
  613.             BAsmCode[0] = 0xa2;
  614.             BAsmCode[1] = AdrVals[0];
  615.             CodeLen = 3;
  616.             break;
  617.           case ModImm:
  618.             BAsmCode[0] = 0x72;
  619.             BAsmCode[1] = AdrVals[0];
  620.             CodeLen = 3;
  621.             break;
  622.         }
  623.         break;
  624.       case ModPort:
  625.         BAsmCode[1] = BAsmCode[2] = AdrVals[0];
  626.         DecodeAdr(&ArgStr[1], MModAccA | MModAccB | MModImm);
  627.         switch (AdrType)
  628.         {
  629.           case ModAccA:
  630.             BAsmCode[0] = 0x82;
  631.             CodeLen = 2;
  632.             break;
  633.           case ModAccB:
  634.             BAsmCode[0] = 0x92;
  635.             CodeLen = 2;
  636.             break;
  637.           case ModImm:
  638.             BAsmCode[0] = 0xa2;
  639.             BAsmCode[1] = AdrVals[0];
  640.             CodeLen = 3;
  641.             break;
  642.         }
  643.         break;
  644.       case ModAbs:
  645.         memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  646.         DecodeAdr(&ArgStr[1], MModAccA);
  647.         if (AdrType != ModNone)
  648.         {
  649.           BAsmCode[0] = 0x8b;
  650.           CodeLen = 3;
  651.         }
  652.         break;
  653.       case ModIReg:
  654.         BAsmCode[1] = AdrVals[0];
  655.         DecodeAdr(&ArgStr[1], MModAccA);
  656.         if (AdrType != ModNone)
  657.         {
  658.           BAsmCode[0] = 0x9b;
  659.           CodeLen = 2;
  660.         }
  661.         break;
  662.       case ModBRel:
  663.         memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  664.         DecodeAdr(&ArgStr[1], MModAccA);
  665.         if (AdrType != ModNone)
  666.         {
  667.           BAsmCode[0] = 0xab;
  668.           CodeLen = 3;
  669.         }
  670.         break;
  671.     }
  672.   }
  673. }
  674.  
  675. static void DecodeLDA(Word Index)
  676. {
  677.   UNUSED(Index);
  678.  
  679.   if (ChkArgCnt(1, 1))
  680.   {
  681.     DecodeAdr(&ArgStr[1], MModAbs | MModBRel | MModIReg);
  682.     switch (AdrType)
  683.     {
  684.       case ModAbs:
  685.         BAsmCode[0] = 0x8a;
  686.         memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  687.         CodeLen = 1 + AdrCnt;
  688.         break;
  689.       case ModBRel:
  690.         BAsmCode[0] = 0xaa;
  691.         memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  692.         CodeLen = 1 + AdrCnt;
  693.         break;
  694.       case ModIReg:
  695.         BAsmCode[0] = 0x9a;
  696.         BAsmCode[1] = AdrVals[0];
  697.         CodeLen = 2;
  698.         break;
  699.     }
  700.   }
  701. }
  702.  
  703. static void DecodeSTA(Word Index)
  704. {
  705.   UNUSED(Index);
  706.  
  707.   if (ChkArgCnt(1, 1))
  708.   {
  709.     DecodeAdr(&ArgStr[1], MModAbs | MModBRel | MModIReg);
  710.     switch (AdrType)
  711.     {
  712.       case ModAbs:
  713.         BAsmCode[0] = 0x8b;
  714.         memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  715.         CodeLen = 1 + AdrCnt;
  716.         break;
  717.       case ModBRel:
  718.         BAsmCode[0] = 0xab;
  719.         memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  720.         CodeLen = 1 + AdrCnt;
  721.         break;
  722.       case ModIReg:
  723.         BAsmCode[0] = 0x9b;
  724.         BAsmCode[1] = AdrVals[0];
  725.         CodeLen = 2;
  726.         break;
  727.     }
  728.   }
  729. }
  730.  
  731. static void DecodeMOVWD(Word Index)
  732. {
  733.   UNUSED(Index);
  734.  
  735.   OpSize = 1;
  736.   if (ChkArgCnt(2, 2))
  737.   {
  738.     DecodeAdr(&ArgStr[2], MModReg);
  739.     if (AdrType != ModNone)
  740.     {
  741.       Byte z = AdrVals[0];
  742.  
  743.       DecodeAdr(&ArgStr[1], MModReg | MModImm | MModImmBRel);
  744.       switch (AdrType)
  745.       {
  746.         case ModReg:
  747.           BAsmCode[0] = 0x98;
  748.           BAsmCode[1] = AdrVals[0];
  749.           BAsmCode[2] = z;
  750.           CodeLen = 3;
  751.           break;
  752.         case ModImm:
  753.           BAsmCode[0] = 0x88;
  754.           memcpy(BAsmCode + 1, AdrVals, 2);
  755.           BAsmCode[3] = z;
  756.           CodeLen = 4;
  757.           break;
  758.         case ModImmBRel:
  759.           BAsmCode[0] = 0xa8;
  760.           memcpy(BAsmCode + 1, AdrVals, 2);
  761.           BAsmCode[3] = z;
  762.           CodeLen = 4;
  763.           break;
  764.       }
  765.     }
  766.   }
  767. }
  768.  
  769. static void DecodeCMP(Word IsCMPA)
  770. {
  771.   if (ChkArgCnt(IsCMPA ? 1 : 2, IsCMPA ? 1 : 2))
  772.   {
  773.     if (IsCMPA)
  774.       AdrType = ModAccA;
  775.     else
  776.       DecodeAdr(&ArgStr[2], MModAccA | MModAccB | MModReg);
  777.     switch (AdrType)
  778.     {
  779.       case ModAccA:
  780.         DecodeAdr(&ArgStr[1], MModAbs | MModIReg | MModBRel | MModAccB | MModReg | MModImm);
  781.         switch (AdrType)
  782.         {
  783.           case ModAbs:
  784.             BAsmCode[0] = 0x8d;
  785.             memcpy(BAsmCode + 1,AdrVals, 2);
  786.             CodeLen = 3;
  787.             break;
  788.           case ModIReg:
  789.             BAsmCode[0] = 0x9d;
  790.             BAsmCode[1] = AdrVals[0];
  791.             CodeLen = 2;
  792.             break;
  793.           case ModBRel:
  794.             BAsmCode[0] = 0xad;
  795.             memcpy(BAsmCode + 1, AdrVals, 2);
  796.             CodeLen = 3;
  797.             break;
  798.           case ModAccB:
  799.             BAsmCode[0] = 0x6d;
  800.             CodeLen = 1;
  801.             break;
  802.           case ModReg:
  803.             BAsmCode[0] = 0x1d;
  804.             BAsmCode[1] = AdrVals[0];
  805.             CodeLen = 2;
  806.             break;
  807.           case ModImm:
  808.             BAsmCode[0] = 0x2d;
  809.             BAsmCode[1] = AdrVals[0];
  810.             CodeLen = 2;
  811.             break;
  812.         }
  813.         break;
  814.       case ModAccB:
  815.         DecodeAdr(&ArgStr[1], MModReg | MModImm);
  816.         switch (AdrType)
  817.         {
  818.           case ModReg:
  819.             BAsmCode[0] = 0x3d;
  820.             BAsmCode[1] = AdrVals[0];
  821.             CodeLen = 2;
  822.             break;
  823.           case ModImm:
  824.             BAsmCode[0] = 0x5d;
  825.             BAsmCode[1] = AdrVals[0];
  826.             CodeLen = 2;
  827.             break;
  828.         }
  829.         break;
  830.       case ModReg:
  831.         BAsmCode[2] = AdrVals[0];
  832.         DecodeAdr(&ArgStr[1], MModReg | MModImm);
  833.         switch (AdrType)
  834.         {
  835.           case ModReg:
  836.             BAsmCode[0] = 0x4d;
  837.             BAsmCode[1] = AdrVals[0];
  838.             CodeLen = 3;
  839.             break;
  840.           case ModImm:
  841.             BAsmCode[0] = 0x7d;
  842.             BAsmCode[1] = AdrVals[0];
  843.             CodeLen = 3;
  844.             break;
  845.         }
  846.         break;
  847.     }
  848.   }
  849. }
  850.  
  851. static void DecodeTRAP(Word Index)
  852. {
  853.   UNUSED(Index);
  854.  
  855.   if (ChkArgCnt(1, 1))
  856.   {
  857.     Boolean OK;
  858.     tSymbolFlags Flags;
  859.  
  860.     BAsmCode[0] = EvalStrIntExpressionWithFlags(&ArgStr[1], UInt5, &OK, &Flags);
  861.     if (mFirstPassUnknown(Flags))
  862.       BAsmCode[0] &= 15;
  863.     if (OK)
  864.     {
  865.       if (BAsmCode[0] > 23) WrError(ErrNum_OverRange);
  866.       else
  867.       {
  868.         BAsmCode[0] = 0xff - BAsmCode[0];
  869.         CodeLen = 1;
  870.       }
  871.     }
  872.   }
  873. }
  874.  
  875. static void DecodeTST(Word Index)
  876. {
  877.   UNUSED(Index);
  878.  
  879.   if (ChkArgCnt(1, 1))
  880.   {
  881.     DecodeAdr(&ArgStr[1], MModAccA | MModAccB);
  882.     switch (AdrType)
  883.     {
  884.       case ModAccA:
  885.         BAsmCode[0] = 0xb0;
  886.         CodeLen = 1;
  887.         break;
  888.       case ModAccB:
  889.         BAsmCode[0] = 0xc1;
  890.         CodeLen = 1;
  891.         break;
  892.     }
  893.   }
  894. }
  895.  
  896. /*---------------------------------------------------------------------------*/
  897. /* dynamic instruction table handling */
  898.  
  899. static void InitFixed(const char *NName, Word NCode)
  900. {
  901.   AddInstTable(InstTable, NName, NCode, DecodeFixed);
  902. }
  903.  
  904. static void InitRel8(const char *NName, Word NCode)
  905. {
  906.   AddInstTable(InstTable, NName, NCode, DecodeRel8);
  907. }
  908.  
  909. static void InitALU1(const char *NName, Word NCode)
  910. {
  911.   AddInstTable(InstTable, NName, NCode, DecodeALU1);
  912. }
  913.  
  914. static void InitALU2(const char *NName, Word NCode)
  915. {
  916.   AddInstTable(InstTable, NName, NCode, DecodeALU2);
  917. }
  918.  
  919. static void InitJmp(const char *NName, Word NCode)
  920. {
  921.   AddInstTable(InstTable, NName, NCode, DecodeJmp);
  922. }
  923.  
  924. static void InitABReg(const char *NName, Word NCode)
  925. {
  926.   AddInstTable(InstTable, NName, NCode, DecodeABReg);
  927. }
  928.  
  929. static void InitFields(void)
  930. {
  931.   InstTable = CreateInstTable(107);
  932.  
  933.   add_null_pseudo(InstTable);
  934.  
  935.   AddInstTable(InstTable, "MOV" , 0, DecodeMOV);
  936.   AddInstTable(InstTable, "MOVP", 1, DecodeMOV);
  937.   AddInstTable(InstTable, "LDA" , 0, DecodeLDA);
  938.   AddInstTable(InstTable, "STA" , 0, DecodeSTA);
  939.   AddInstTable(InstTable, "MOVW", 1, DecodeMOVWD);
  940.   AddInstTable(InstTable, "MOVD", 2, DecodeMOVWD);
  941.   AddInstTable(InstTable, "CMP" , 0, DecodeCMP);
  942.   AddInstTable(InstTable, "CMPA", 1, DecodeCMP);
  943.   AddInstTable(InstTable, "TRAP", 0, DecodeTRAP);
  944.   AddInstTable(InstTable, "TST" , 0, DecodeTST);
  945.  
  946.   InitFixed("CLRC" , 0x00b0); InitFixed("DINT" , 0x0006);
  947.   InitFixed("EINT" , 0x0005); InitFixed("IDLE" , 0x0001);
  948.   InitFixed("LDSP" , 0x000d); InitFixed("NOP"  , 0x0000);
  949.   InitFixed("RETI" , 0x000b); InitFixed("RTI"  , 0x000b);
  950.   InitFixed("RETS" , 0x000a); InitFixed("RTS"  , 0x000a);
  951.   InitFixed("SETC" , 0x0007); InitFixed("STSP" , 0x0009);
  952.   InitFixed("TSTA" , 0x00b0); InitFixed("TSTB" , 0x00c1);
  953.  
  954.   InitRel8("JMP", 0xe0); InitRel8("JC" , 0xe3); InitRel8("JEQ", 0xe2);
  955.   InitRel8("JHS", 0xe3); InitRel8("JL" , 0xe7); InitRel8("JN" , 0xe1);
  956.   InitRel8("JNC", 0xe7); InitRel8("JNE", 0xe6); InitRel8("JNZ", 0xe6);
  957.   InitRel8("JP" , 0xe4); InitRel8("JPZ", 0xe5); InitRel8("JZ" , 0xe2);
  958.   InitRel8("JLT", 0xe1); InitRel8("JGT", 0xe4); InitRel8("JGE", 0xe5);
  959.  
  960.   InitALU1("ADC",  9); InitALU1("ADD",  8);
  961.   InitALU1("DAC", 14); InitALU1("DSB", 15);
  962.   InitALU1("SBB", 11); InitALU1("SUB", 10);
  963.   InitALU1("MPY", 12);
  964.  
  965.   InitALU2("AND"  , 0x0003); InitALU2("BTJO" , 0x4006);
  966.   InitALU2("BTJZ" , 0x4007); InitALU2("OR"   , 0x0004); InitALU2("XOR" , 0x0005);
  967.   InitALU2("ANDP" , 0x8003); InitALU2("BTJOP", 0xc006);
  968.   InitALU2("BTJZP", 0xc007); InitALU2("ORP"  , 0x8004); InitALU2("XORP", 0x8005);
  969.  
  970.   InitJmp("BR"  ,12); InitJmp("CALL" ,14);
  971.  
  972.   InitABReg("CLR"  , 5); InitABReg("DEC"  , 2); InitABReg("DECD" ,11);
  973.   InitABReg("INC"  , 3); InitABReg("INV"  , 4); InitABReg("RL"   ,14);
  974.   InitABReg("RLC"  ,15); InitABReg("RR"   ,12); InitABReg("RRC"  ,13);
  975.   InitABReg("SWAP" , 7); InitABReg("XCHB" , 6);
  976.   AddInstTable(InstTable, "DJNZ" ,10, DecodeDJNZ);
  977.   AddInstTable(InstTable, "PUSH" , 8, DecodePUSH_POP);
  978.   AddInstTable(InstTable, "POP"  , 9, DecodePUSH_POP);
  979.  
  980.   AddIntelPseudo(InstTable, eIntPseudoFlag_BigEndian);
  981. }
  982.  
  983. static void DeinitFields(void)
  984. {
  985.   DestroyInstTable(InstTable);
  986. }
  987.  
  988. static void MakeCode_TMS7(void)
  989. {
  990.   OpSize = eSymbolSize8Bit;
  991.  
  992.   if (!LookupInstTable(InstTable, OpPart.str.p_str))
  993.     WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
  994. }
  995.  
  996. static Boolean IsDef_TMS7(void)
  997. {
  998.   return False;
  999. }
  1000.  
  1001. static void InternSymbol_TMS7(char *pAsc, TempResult *pErg)
  1002. {
  1003.   char *p_end, prefix;
  1004.   unsigned base;
  1005.   LargeInt Num;
  1006.  
  1007.   as_tempres_set_none(pErg);
  1008.   if ((strlen(pAsc) < 2) || ((as_toupper(*pAsc) != 'R') && (as_toupper(*pAsc) != 'P')))
  1009.     return;
  1010.   prefix = *pAsc++;
  1011.  
  1012.   if ((*pAsc == '0') && (strlen(pAsc) > 1))
  1013.   {
  1014.     base = 16;
  1015.     pAsc++;
  1016.   }
  1017.   else
  1018.     base = 10;
  1019.   Num = strtoul(pAsc, &p_end, base);
  1020.   if (*p_end || (Num < 0) || (Num > 255))
  1021.     return;
  1022.  
  1023.   if (as_toupper(prefix) == 'P')
  1024.     Num += 0x100;
  1025.   as_tempres_set_int(pErg, Num);
  1026. }
  1027.  
  1028. static void SwitchFrom_TMS7(void)
  1029. {
  1030.   DeinitFields();
  1031. }
  1032.  
  1033. static void SwitchTo_TMS7(void)
  1034. {
  1035.   const TFamilyDescr *p_descr = FindFamilyByName("TMS7000");
  1036.  
  1037.   TurnWords = False;
  1038.   SetIntConstMode(eIntConstModeIntel);
  1039.  
  1040.   PCSymbol = "$";
  1041.   HeaderID = p_descr->Id;
  1042.   NOPCode = 0x00;
  1043.   DivideChars = ",";
  1044.   HasAttrs = False;
  1045.  
  1046.   ValidSegs=1 << SegCode;
  1047.   Grans[SegCode] = 1; ListGrans[SegCode] = 1; SegInits[SegCode] = 0;
  1048.   SegLimits[SegCode] = 0xffff;
  1049.  
  1050.   MakeCode = MakeCode_TMS7; IsDef = IsDef_TMS7;
  1051.   SwitchFrom = SwitchFrom_TMS7; InternSymbol = InternSymbol_TMS7;
  1052.  
  1053.   InitFields();
  1054. }
  1055.  
  1056. void codetms7_init(void)
  1057. {
  1058.   CPU70C00  = AddCPU("TMS70C00", SwitchTo_TMS7);
  1059.   CPU70C20  = AddCPU("TMS70C20", SwitchTo_TMS7);
  1060.   CPU70C40  = AddCPU("TMS70C40", SwitchTo_TMS7);
  1061.   CPU70CT20 = AddCPU("TMS70CT20",SwitchTo_TMS7);
  1062.   CPU70CT40 = AddCPU("TMS70CT40",SwitchTo_TMS7);
  1063.   CPU70C02  = AddCPU("TMS70C02", SwitchTo_TMS7);
  1064.   CPU70C42  = AddCPU("TMS70C42", SwitchTo_TMS7);
  1065.   CPU70C82  = AddCPU("TMS70C82", SwitchTo_TMS7);
  1066.   CPU70C08  = AddCPU("TMS70C08", SwitchTo_TMS7);
  1067.   CPU70C48  = AddCPU("TMS70C48", SwitchTo_TMS7);
  1068. }
  1069.