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