Subversion Repositories pentevo

Rev

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

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