Subversion Repositories pentevo

Rev

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

  1. /* codest6.c */
  2. /*****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
  4. /*                                                                           */
  5. /* AS-Portierung                                                             */
  6. /*                                                                           */
  7. /* Codegenerator ST6-Familie                                                 */
  8. /*                                                                           */
  9. /*****************************************************************************/
  10.  
  11. #include "stdinc.h"
  12. #include <string.h>
  13.  
  14. #include "strutil.h"
  15. #include "bpemu.h"
  16. #include "asmdef.h"
  17. #include "asmsub.h"
  18. #include "asmpars.h"
  19. #include "asmitree.h"
  20. #include "assume.h"
  21. #include "asmstructs.h"
  22. #include "codepseudo.h"
  23. #include "motpseudo.h"
  24. #include "codevars.h"
  25. #include "errmsg.h"
  26. #include "intformat.h"
  27. #include "headids.h"
  28.  
  29. #include "codest6.h"
  30.  
  31. #define ModNone (-1)
  32. #define ModAcc 0
  33. #define MModAcc (1 << ModAcc)
  34. #define ModDir 1
  35. #define MModDir (1 << ModDir)
  36. #define ModInd 2
  37. #define MModInd (1 << ModInd)
  38.  
  39.  
  40. static Byte AdrMode;
  41. static ShortInt AdrType;
  42. static Byte AdrVal;
  43.  
  44. static LongInt WinAssume, PRPRVal;
  45.  
  46. typedef struct
  47. {
  48.   const char *pName;
  49.   IntType CodeAdrInt;
  50. } tCPUProps;
  51.  
  52. static as_assume_rec_t ASSUMEST6s[] =
  53. {
  54.   { "PRPR",    &PRPRVal  , 0, 0x03, 0x04, NULL },
  55.   { "ROMBASE", &WinAssume, 0, 0x3f, 0x40, NULL },
  56. };
  57. static const tCPUProps *pCurrCPUProps;
  58.  
  59. /*---------------------------------------------------------------------------------*/
  60. /* Helper Functions */
  61.  
  62. static void ResetAdr(void)
  63. {
  64.   AdrType = ModNone; AdrCnt = 0;
  65. }
  66.  
  67. static void DecodeAdr(const tStrComp *pArg, Byte Mask)
  68. {
  69.   Integer AdrInt;
  70.   tEvalResult EvalResult;
  71.  
  72.   ResetAdr();
  73.  
  74.   if ((!as_strcasecmp(pArg->str.p_str, "A")) && (Mask & MModAcc))
  75.   {
  76.     AdrType = ModAcc;
  77.     goto chk;
  78.   }
  79.  
  80.   if (!as_strcasecmp(pArg->str.p_str, "(X)"))
  81.   {
  82.     AdrType = ModInd;
  83.     AdrMode = 0;
  84.     goto chk;
  85.   }
  86.  
  87.   if (!as_strcasecmp(pArg->str.p_str, "(Y)"))
  88.   {
  89.     AdrType = ModInd;
  90.     AdrMode = 1;
  91.     goto chk;
  92.   }
  93.  
  94.   AdrInt = EvalStrIntExpressionWithResult(pArg, UInt16, &EvalResult);
  95.   if (EvalResult.OK)
  96.   {
  97.     if (EvalResult.AddrSpaceMask & (1 << SegCode))
  98.     {
  99.       AdrType = ModDir;
  100.       AdrVal = (AdrInt & 0x3f) + 0x40;
  101.       AdrCnt=1;
  102.       if (!mFirstPassUnknown(EvalResult.Flags))
  103.         if (WinAssume != (AdrInt >> 6)) WrError(ErrNum_InAccPage);
  104.     }
  105.     else
  106.     {
  107.       if (mFirstPassUnknown(EvalResult.Flags)) AdrInt = Lo(AdrInt);
  108.       if (AdrInt > 0xff) WrError(ErrNum_OverRange);
  109.       else
  110.       {
  111.         AdrType = ModDir;
  112.         AdrVal = AdrInt;
  113.         goto chk;
  114.       }
  115.     }
  116.   }
  117.  
  118. chk:
  119.   if ((AdrType != ModNone) && (!(Mask & (1 << AdrType))))
  120.   {
  121.     ResetAdr(); WrError(ErrNum_InvAddrMode);
  122.   }
  123. }
  124.  
  125. static Boolean IsReg(Byte Adr)
  126. {
  127.   return ((Adr & 0xfc) == 0x80);
  128. }
  129.  
  130. static Byte MirrBit(Byte inp)
  131. {
  132.   return (((inp & 1) << 2) + (inp & 2) + ((inp & 4) >> 2));
  133. }
  134.  
  135. /*--------------------------------------------------------------------------*/
  136. /* Bit Symbol Handling */
  137.  
  138. /*
  139.  * Compact representation of bits in symbol table:
  140.  * bits 0..2: bit position
  141.  * bits 3...10: register address in DATA/SFR space
  142.  */
  143.  
  144. /*!------------------------------------------------------------------------
  145.  * \fn     EvalBitPosition(const tStrComp *pArg, Boolean *pOK)
  146.  * \brief  evaluate bit position
  147.  * \param  bit position argument (with or without #)
  148.  * \param  pOK parsing OK?
  149.  * \return numeric bit position
  150.  * ------------------------------------------------------------------------ */
  151.  
  152. static LongWord EvalBitPosition(const tStrComp *pArg, Boolean *pOK)
  153. {
  154.   return EvalStrIntExpressionOffs(pArg, !!(*pArg->str.p_str == '#'), UInt3, pOK);
  155. }
  156.  
  157. /*!------------------------------------------------------------------------
  158.  * \fn     AssembleBitSymbol(Byte BitPos, Word Address)
  159.  * \brief  build the compact internal representation of a bit symbol
  160.  * \param  BitPos bit position in word
  161.  * \param  Address register address
  162.  * \return compact representation
  163.  * ------------------------------------------------------------------------ */
  164.  
  165. static LongWord AssembleBitSymbol(Byte BitPos, Word Address)
  166. {
  167.   return (BitPos & 7)
  168.        | (((LongWord)Address & 0xff) << 3);
  169. }
  170.  
  171. /*!------------------------------------------------------------------------
  172.  * \fn     DecodeBitArg2(LongWord *pResult, const tStrComp *pRegArg, const tStrComp *pBitArg)
  173.  * \brief  encode a bit symbol, address & bit position separated
  174.  * \param  pResult resulting encoded bit
  175.  * \param  pRegArg register argument
  176.  * \param  pBitArg bit argument
  177.  * \return True if success
  178.  * ------------------------------------------------------------------------ */
  179.  
  180. static Boolean DecodeBitArg2(LongWord *pResult, const tStrComp *pRegArg, const tStrComp *pBitArg)
  181. {
  182.   Boolean OK;
  183.   LongWord Addr;
  184.   Byte BitPos;
  185.  
  186.   BitPos = EvalBitPosition(pBitArg, &OK);
  187.   if (!OK)
  188.     return False;
  189.  
  190.   Addr = EvalStrIntExpression(pRegArg, UInt8, &OK);
  191.   if (!OK)
  192.     return False;
  193.  
  194.   *pResult = AssembleBitSymbol(BitPos, Addr);
  195.  
  196.   return True;
  197. }
  198.  
  199. /*!------------------------------------------------------------------------
  200.  * \fn     DecodeBitArg(LongWord *pResult, int Start, int Stop)
  201.  * \brief  encode a bit symbol from instruction argument(s)
  202.  * \param  pResult resulting encoded bit
  203.  * \param  Start first argument
  204.  * \param  Stop last argument
  205.  * \return True if success
  206.  * ------------------------------------------------------------------------ */
  207.  
  208. static Boolean DecodeBitArg(LongWord *pResult, int Start, int Stop)
  209. {
  210.   *pResult = 0;
  211.  
  212.   /* Just one argument -> parse as bit argument */
  213.  
  214.   if (Start == Stop)
  215.   {
  216.     tEvalResult EvalResult;
  217.  
  218.     *pResult = EvalStrIntExpressionWithResult(&ArgStr[Start], UInt11, &EvalResult);
  219.     if (EvalResult.OK)
  220.       ChkSpace(SegBData, EvalResult.AddrSpaceMask);
  221.     return EvalResult.OK;
  222.   }
  223.  
  224.   /* register & bit position are given as separate arguments */
  225.  
  226.   else if (Stop == Start + 1)
  227.     return DecodeBitArg2(pResult, &ArgStr[Stop], &ArgStr[Start]);
  228.  
  229.   /* other # of arguments not allowed */
  230.  
  231.   else
  232.   {
  233.     WrError(ErrNum_WrongArgCnt);
  234.     return False;
  235.   }
  236. }
  237.  
  238. /*!------------------------------------------------------------------------
  239.  * \fn     DissectBitSymbol(LongWord BitSymbol, Word *pAddress, Byte *pBitPos)
  240.  * \brief  transform compact represenation of bit (field) symbol into components
  241.  * \param  BitSymbol compact storage
  242.  * \param  pAddress (I/O) register address
  243.  * \param  pBitPos (start) bit position
  244.  * \return constant True
  245.  * ------------------------------------------------------------------------ */
  246.  
  247. static Boolean DissectBitSymbol(LongWord BitSymbol, Word *pAddress, Byte *pBitPos)
  248. {
  249.   *pAddress = (BitSymbol >> 3) & 0xffff;
  250.   *pBitPos = BitSymbol & 7;
  251.   return True;
  252. }
  253.  
  254. /*!------------------------------------------------------------------------
  255.  * \fn     DissectBit_ST6(char *pDest, size_t DestSize, LargeWord Inp)
  256.  * \brief  dissect compact storage of bit (field) into readable form for listing
  257.  * \param  pDest destination for ASCII representation
  258.  * \param  DestSize destination buffer size
  259.  * \param  Inp compact storage
  260.  * ------------------------------------------------------------------------ */
  261.  
  262. static void DissectBit_ST6(char *pDest, size_t DestSize, LargeWord Inp)
  263. {
  264.   Byte BitPos;
  265.   Word Address;
  266.  
  267.   DissectBitSymbol(Inp, &Address, &BitPos);
  268.  
  269.   as_snprintf(pDest, DestSize, "%02.*u%s.%u",
  270.               ListRadixBase, (unsigned)Address, GetIntConstIntelSuffix(ListRadixBase),
  271.               (unsigned)BitPos);
  272. }
  273.  
  274. /*!------------------------------------------------------------------------
  275.  * \fn     ExpandST6Bit(const tStrComp *pVarName, const struct sStructElem *pStructElem, LargeWord Base)
  276.  * \brief  expands bit definition when a structure is instantiated
  277.  * \param  pVarName desired symbol name
  278.  * \param  pStructElem element definition
  279.  * \param  Base base address of instantiated structure
  280.  * ------------------------------------------------------------------------ */
  281.  
  282. static void ExpandST6Bit(const tStrComp *pVarName, const struct sStructElem *pStructElem, LargeWord Base)
  283. {
  284.   LongWord Address = Base + pStructElem->Offset;
  285.  
  286.   if (pInnermostNamedStruct)
  287.   {
  288.     PStructElem pElem = CloneStructElem(pVarName, pStructElem);
  289.  
  290.     if (!pElem)
  291.       return;
  292.     pElem->Offset = Address;
  293.     AddStructElem(pInnermostNamedStruct->StructRec, pElem);
  294.   }
  295.   else
  296.   {
  297.     if (!ChkRange(Address, 0, 0xff)
  298.      || !ChkRange(pStructElem->BitPos, 0, 7))
  299.       return;
  300.  
  301.     PushLocHandle(-1);
  302.     EnterIntSymbol(pVarName, AssembleBitSymbol(pStructElem->BitPos, Address), SegBData, False);
  303.     PopLocHandle();
  304.     /* TODO: MakeUseList? */
  305.   }
  306. }
  307.  
  308. /*---------------------------------------------------------------------------------*/
  309. /* Instruction Decoders */
  310.  
  311. static void DecodeFixed(Word Code)
  312. {
  313.   if (ChkArgCnt(0, 0))
  314.   {
  315.     CodeLen = 1;
  316.     BAsmCode[0] = Code;
  317.   }
  318. }
  319.  
  320. static void DecodeLD(Word Code)
  321. {
  322.   UNUSED(Code);
  323.  
  324.   if (ChkArgCnt(2, 2))
  325.   {
  326.     DecodeAdr(&ArgStr[1], MModAcc | MModDir | MModInd);
  327.     switch (AdrType)
  328.     {
  329.       case ModAcc:
  330.         DecodeAdr(&ArgStr[2], MModDir | MModInd);
  331.         switch (AdrType)
  332.         {
  333.           case ModDir:
  334.             if (IsReg(AdrVal))
  335.             {
  336.               CodeLen = 1;
  337.               BAsmCode[0] = 0x35 + ((AdrVal & 3) << 6);
  338.             }
  339.             else
  340.             {
  341.               CodeLen = 2;
  342.               BAsmCode[0] = 0x1f;
  343.               BAsmCode[1] = AdrVal;
  344.             }
  345.             break;
  346.           case ModInd:
  347.             CodeLen = 1;
  348.             BAsmCode[0] = 0x07 + (AdrMode << 3);
  349.             break;
  350.         }
  351.         break;
  352.       case ModDir:
  353.         DecodeAdr(&ArgStr[2], MModAcc);
  354.         if (AdrType != ModNone)
  355.         {
  356.           if (IsReg(AdrVal))
  357.           {
  358.             CodeLen = 1;
  359.             BAsmCode[0] = 0x3d + ((AdrVal & 3) << 6);
  360.           }
  361.           else
  362.           {
  363.             CodeLen = 2;
  364.             BAsmCode[0] = 0x9f;
  365.             BAsmCode[1] = AdrVal;
  366.           }
  367.         }
  368.         break;
  369.       case ModInd:
  370.         DecodeAdr(&ArgStr[2], MModAcc);
  371.         if (AdrType != ModNone)
  372.         {
  373.           CodeLen = 1;
  374.           BAsmCode[0] = 0x87 + (AdrMode << 3);
  375.         }
  376.         break;
  377.     }
  378.   }
  379. }
  380.  
  381. static void DecodeLDI(Word Code)
  382. {
  383.   UNUSED(Code);
  384.  
  385.   if (ChkArgCnt(2, 2))
  386.   {
  387.     Boolean OK;
  388.  
  389.     Integer AdrInt = EvalStrIntExpression(&ArgStr[2], Int8, &OK);
  390.     if (OK)
  391.     {
  392.       DecodeAdr(&ArgStr[1], MModAcc | MModDir);
  393.       switch (AdrType)
  394.       {
  395.         case ModAcc:
  396.           CodeLen = 2;
  397.           BAsmCode[0] = 0x17;
  398.           BAsmCode[1] = Lo(AdrInt);
  399.           break;
  400.         case ModDir:
  401.           CodeLen = 3;
  402.           BAsmCode[0] = 0x0d;
  403.           BAsmCode[1] = AdrVal;
  404.           BAsmCode[2] = Lo(AdrInt);
  405.           break;
  406.       }
  407.     }
  408.   }
  409. }
  410.  
  411. static void DecodeRel(Word Code)
  412. {
  413.   if (ChkArgCnt(1, 1))
  414.   {
  415.     Boolean OK;
  416.     tSymbolFlags Flags;
  417.     Integer AdrInt = EvalStrIntExpressionWithFlags(&ArgStr[1], UInt16, &OK, &Flags) - (EProgCounter() + 1);
  418.  
  419.     if (OK)
  420.     {
  421.       if (!mSymbolQuestionable(Flags) && ((AdrInt < -16) || (AdrInt > 15))) WrError(ErrNum_JmpDistTooBig);
  422.       else
  423.       {
  424.         CodeLen = 1;
  425.         BAsmCode[0] = Code + ((AdrInt << 3) & 0xf8);
  426.       }
  427.     }
  428.   }
  429. }
  430.  
  431. static void DecodeJP_CALL(Word Code)
  432. {
  433.   if (ChkArgCnt(1, 1))
  434.   {
  435.     Boolean OK;
  436.     Word AdrInt;
  437.     tSymbolFlags Flags;
  438.  
  439.     AdrInt = EvalStrIntExpressionWithFlags(&ArgStr[1], pCurrCPUProps->CodeAdrInt, &OK, &Flags);
  440.     if (OK)
  441.     {
  442.       Word DestPage = AdrInt >> 11;
  443.  
  444.       /* CPU program space's page 1 (800h...0fffh) always accesses ROM space page 1.
  445.          CPU program space's page 0 (000h...7ffh) accesses 2K ROM space pages as defined by PRPR. */
  446.  
  447.       if (!mFirstPassUnknown(Flags) && (DestPage != 1))
  448.       {
  449.         Word SrcPage = EProgCounter() >> 11;
  450.  
  451.         /* Jump from page 1 is allowed to page defined by PRPR.
  452.            Jump from any other page is only allowed back to page 1 or within same page. */
  453.  
  454.         if (DestPage != ((SrcPage == 1) ? PRPRVal : SrcPage)) WrError(ErrNum_InAccPage);
  455.  
  456.         AdrInt &= 0x7ff;
  457.       }
  458.       CodeLen = 2;
  459.       BAsmCode[0] = Code + ((AdrInt & 0x00f) << 4);
  460.       BAsmCode[1] = AdrInt >> 4;
  461.     }
  462.   }
  463. }
  464.  
  465. static void DecodeALU(Word Code)
  466. {
  467.   if (ChkArgCnt(2, 2))
  468.   {
  469.     DecodeAdr(&ArgStr[1], MModAcc);
  470.     if (AdrType != ModNone)
  471.     {
  472.       DecodeAdr(&ArgStr[2], MModDir | MModInd);
  473.       switch (AdrType)
  474.       {
  475.         case ModDir:
  476.           CodeLen = 2;
  477.           BAsmCode[0] = Code + 0x18;
  478.           BAsmCode[1] = AdrVal;
  479.           break;
  480.         case ModInd:
  481.           CodeLen = 1;
  482.           BAsmCode[0] = Code + (AdrMode << 3);
  483.           break;
  484.       }
  485.     }
  486.   }
  487. }
  488.  
  489. static void DecodeALUImm(Word Code)
  490. {
  491.   if (ChkArgCnt(2, 2))
  492.   {
  493.     DecodeAdr(&ArgStr[1], MModAcc);
  494.     if (AdrType != ModNone)
  495.     {
  496.       Boolean OK;
  497.       BAsmCode[1] = EvalStrIntExpression(&ArgStr[2], Int8, &OK);
  498.       if (OK)
  499.       {
  500.         CodeLen = 2;
  501.         BAsmCode[0] = Code + 0x10;
  502.       }
  503.     }
  504.   }
  505. }
  506.  
  507. static void DecodeCLR(Word Code)
  508. {
  509.   UNUSED(Code);
  510.  
  511.   if (ChkArgCnt(1, 1))
  512.   {
  513.     DecodeAdr(&ArgStr[1], MModAcc | MModDir);
  514.     switch (AdrType)
  515.     {
  516.       case ModAcc:
  517.         CodeLen = 2;
  518.         BAsmCode[0] = 0xdf;
  519.         BAsmCode[1] = 0xff;
  520.         break;
  521.       case ModDir:
  522.         CodeLen = 3;
  523.         BAsmCode[0] = 0x0d;
  524.         BAsmCode[1] = AdrVal;
  525.         BAsmCode[2] = 0;
  526.         break;
  527.     }
  528.   }
  529. }
  530.  
  531. static void DecodeAcc(Word Code)
  532. {
  533.   if (ChkArgCnt(1, 1))
  534.   {
  535.     DecodeAdr(&ArgStr[1], MModAcc);
  536.     if (AdrType != ModNone)
  537.     {
  538.       BAsmCode[CodeLen++] = Lo(Code);
  539.       if (Hi(Code))
  540.         BAsmCode[CodeLen++] = Hi(Code);
  541.     }
  542.   }
  543. }
  544.  
  545. static void DecodeINC_DEC(Word Code)
  546. {
  547.   if (ChkArgCnt(1, 1))
  548.   {
  549.     DecodeAdr(&ArgStr[1], MModDir | MModInd);
  550.     switch (AdrType)
  551.     {
  552.       case ModDir:
  553.         if (IsReg(AdrVal))
  554.         {
  555.           CodeLen = 1;
  556.           BAsmCode[0] = Code + 0x15 + ((AdrVal & 3) << 6);
  557.         }
  558.         else
  559.         {
  560.           CodeLen = 2;
  561.           BAsmCode[0] = 0x7f + (Code << 4);
  562.           BAsmCode[1] = AdrVal;
  563.         }
  564.         break;
  565.       case ModInd:
  566.         CodeLen = 1;
  567.         BAsmCode[0] = 0x67 + (AdrMode << 3) + (Code << 4);
  568.         break;
  569.     }
  570.   }
  571. }
  572.  
  573. static void DecodeSET_RES(Word Code)
  574. {
  575.   LongWord PackedAddr;
  576.  
  577.   if (ChkArgCnt(1, 2)
  578.    && DecodeBitArg(&PackedAddr, 1, ArgCnt))
  579.   {
  580.     Word RegAddr;
  581.     Byte BitPos;
  582.  
  583.     DissectBitSymbol(PackedAddr, &RegAddr, &BitPos);
  584.     BAsmCode[0] = (MirrBit(BitPos) << 5) | Code;
  585.     BAsmCode[1] = RegAddr;
  586.     CodeLen = 2;
  587.   }
  588. }
  589.  
  590. static void DecodeJRR_JRS(Word Code)
  591. {
  592.   LongWord PackedAddr;
  593.  
  594.   if (ChkArgCnt(2, 3)
  595.    && DecodeBitArg(&PackedAddr, 1, ArgCnt - 1))
  596.   {
  597.     Word RegAddr;
  598.     Byte BitPos;
  599.     Boolean OK;
  600.     Integer AdrInt;
  601.     tSymbolFlags Flags;
  602.  
  603.     DissectBitSymbol(PackedAddr, &RegAddr, &BitPos);
  604.     BAsmCode[0] = (MirrBit(BitPos) << 5) | Code;
  605.     BAsmCode[1] = RegAddr;
  606.     AdrInt = EvalStrIntExpressionWithFlags(&ArgStr[ArgCnt], UInt16, &OK, &Flags) - (EProgCounter() + 3);
  607.     if (OK)
  608.     {
  609.       if (!mSymbolQuestionable(Flags) && ((AdrInt > 127) || (AdrInt < -128))) WrError(ErrNum_JmpDistTooBig);
  610.       else
  611.       {
  612.         CodeLen = 3;
  613.         BAsmCode[2] = Lo(AdrInt);
  614.       }
  615.     }
  616.   }
  617. }
  618.  
  619. static void DecodeSFR(Word Code)
  620. {
  621.   UNUSED(Code);
  622.   code_equate_type(SegData, UInt8);
  623. }
  624.  
  625. /*!------------------------------------------------------------------------
  626.  * \fn     DecodeASCII_ASCIZ(Word IsZ)
  627.  * \brief  handle ASCII/ASCIZ instructions
  628.  * \param  IsZ 1 if it's ASCIZ
  629.  * ------------------------------------------------------------------------ */
  630.  
  631. static void DecodeASCII_ASCIZ(Word IsZ)
  632. {
  633.   if (ChkArgCnt(1, ArgCntMax))
  634.   {
  635.     int l;
  636.     Boolean OK = True;
  637.     tStrComp *pArg;
  638.     TempResult t;
  639.  
  640.     as_tempres_ini(&t);
  641.     forallargs(pArg, OK)
  642.     {
  643.       EvalStrExpression(pArg, &t);
  644.       switch (t.Typ)
  645.       {
  646.         case TempString:
  647.         {
  648.           if (as_chartrans_xlate_nonz_dynstr(CurrTransTable->p_table, &t.Contents.str, pArg))
  649.             OK = False;
  650.           else
  651.           {
  652.             l = t.Contents.str.len;
  653.             if (SetMaxCodeLen(CodeLen + l + IsZ))
  654.             {
  655.               WrStrErrorPos(ErrNum_CodeOverflow, pArg); OK = False;
  656.             }
  657.             else
  658.             {
  659.               memcpy(BAsmCode + CodeLen, t.Contents.str.p_str, l);
  660.               CodeLen += l;
  661.               if (IsZ)
  662.                 BAsmCode[CodeLen++] = 0;
  663.             }
  664.           }
  665.           break;
  666.         }
  667.         case TempNone:
  668.           OK = False;
  669.           break;
  670.         default:
  671.           WrStrErrorPos(ErrNum_ExpectString, pArg);
  672.           OK = False;
  673.       }
  674.     }
  675.     as_tempres_free(&t);
  676.     if (!OK)
  677.       CodeLen = 0;
  678.   }
  679. }
  680.  
  681. /*!------------------------------------------------------------------------
  682.  * \fn     DecodeBIT(Word Code)
  683.  * \brief  decode BIT instruction
  684.  * ------------------------------------------------------------------------ */
  685.  
  686. static void DecodeBIT(Word Code)
  687. {
  688.   LongWord BitSpec;
  689.  
  690.   UNUSED(Code);
  691.  
  692.   /* if in structure definition, add special element to structure */
  693.  
  694.   if (ActPC == StructSeg)
  695.   {
  696.     Boolean OK;
  697.     Byte BitPos;
  698.     PStructElem pElement;
  699.  
  700.     if (!ChkArgCnt(2, 2))
  701.       return;
  702.     BitPos = EvalBitPosition(&ArgStr[2], &OK);
  703.     if (!OK)
  704.       return;
  705.     pElement = CreateStructElem(&LabPart);
  706.     if (!pElement)
  707.       return;
  708.     pElement->pRefElemName = as_strdup(ArgStr[1].str.p_str);
  709.     pElement->OpSize = eSymbolSize8Bit;
  710.     pElement->BitPos = BitPos;
  711.     pElement->ExpandFnc = ExpandST6Bit;
  712.     AddStructElem(pInnermostNamedStruct->StructRec, pElement);
  713.   }
  714.   else
  715.   {
  716.     if (DecodeBitArg(&BitSpec, 1, ArgCnt))
  717.     {
  718.       *ListLine = '=';
  719.       DissectBit_ST6(ListLine + 1, STRINGSIZE - 3, BitSpec);
  720.       PushLocHandle(-1);
  721.       EnterIntSymbol(&LabPart, BitSpec, SegBData, False);
  722.       PopLocHandle();
  723.       /* TODO: MakeUseList? */
  724.     }
  725.   }
  726. }
  727.  
  728. /*---------------------------------------------------------------------------------*/
  729. /* code table handling */
  730.  
  731. static void AddFixed(const char *NName, Byte NCode)
  732. {
  733.   AddInstTable(InstTable, NName, NCode, DecodeFixed);
  734. }
  735.  
  736. static void AddRel(const char *NName, Byte NCode)
  737. {
  738.   AddInstTable(InstTable, NName, NCode, DecodeRel);
  739. }
  740.  
  741. static void AddALU(const char *NName, const char *NNameImm, Byte NCode)
  742. {
  743.   AddInstTable(InstTable, NName, NCode, DecodeALU);
  744.   AddInstTable(InstTable, NNameImm, NCode, DecodeALUImm);
  745. }
  746.  
  747. static void AddAcc(const char *NName, Word NCode)
  748. {
  749.   AddInstTable(InstTable, NName, NCode, DecodeAcc);
  750. }
  751.  
  752. static void InitFields(void)
  753. {
  754.   InstTable = CreateInstTable(201);
  755.  
  756.   add_null_pseudo(InstTable);
  757.  
  758.   AddInstTable(InstTable, "LD", 0, DecodeLD);
  759.   AddInstTable(InstTable, "LDI", 0, DecodeLDI);
  760.   AddInstTable(InstTable, "JP", 0x09, DecodeJP_CALL);
  761.   AddInstTable(InstTable, "CALL", 0x01, DecodeJP_CALL);
  762.   AddInstTable(InstTable, "CLR", 0, DecodeCLR);
  763.   AddInstTable(InstTable, "INC", 0, DecodeINC_DEC);
  764.   AddInstTable(InstTable, "DEC", 8, DecodeINC_DEC);
  765.   AddInstTable(InstTable, "SET", 0x1b, DecodeSET_RES);
  766.   AddInstTable(InstTable, "RES", 0x0b, DecodeSET_RES);
  767.   AddInstTable(InstTable, "JRR", 0x03, DecodeJRR_JRS);
  768.   AddInstTable(InstTable, "JRS", 0x13, DecodeJRR_JRS);
  769.   AddInstTable(InstTable, "SFR", 0, DecodeSFR);
  770.   AddInstTable(InstTable, "ASCII", 0, DecodeASCII_ASCIZ);
  771.   AddInstTable(InstTable, "ASCIZ", 1, DecodeASCII_ASCIZ);
  772.   AddInstTable(InstTable, "BYTE", 0, DecodeMotoBYT);
  773.   AddInstTable(InstTable, "WORD", e_moto_pseudo_flags_le, DecodeMotoADR);
  774.   AddInstTable(InstTable, "BLOCK", e_moto_pseudo_flags_none, DecodeMotoDFS);
  775.   AddInstTable(InstTable, "BIT", 0, DecodeBIT);
  776.  
  777.   AddFixed("NOP" , 0x04);
  778.   AddFixed("RET" , 0xcd);
  779.   AddFixed("RETI", 0x4d);
  780.   AddFixed("STOP", 0x6d);
  781.   AddFixed("WAIT", 0xed);
  782.  
  783.   AddRel("JRZ" , 0x04);
  784.   AddRel("JRNZ", 0x00);
  785.   AddRel("JRC" , 0x06);
  786.   AddRel("JRNC", 0x02);
  787.  
  788.   AddALU("ADD" , "ADDI" , 0x47);
  789.   AddALU("AND" , "ANDI" , 0xa7);
  790.   AddALU("CP"  , "CPI"  , 0x27);
  791.   AddALU("SUB" , "SUBI" , 0xc7);
  792.  
  793.   AddAcc("COM", 0x002d);
  794.   AddAcc("RLC", 0x00ad);
  795.   AddAcc("SLA", 0xff5f);
  796. }
  797.  
  798. static void DeinitFields(void)
  799. {
  800.   DestroyInstTable(InstTable);
  801. }
  802.  
  803. /*!------------------------------------------------------------------------
  804.  * \fn     MakeCode_ST6(void)
  805.  * \brief  entry point to decode machine instructions
  806.  * ------------------------------------------------------------------------ */
  807.  
  808. static void MakeCode_ST6(void)
  809. {
  810.   if (!LookupInstTable(InstTable, OpPart.str.p_str))
  811.     WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
  812. }
  813.  
  814. /*!------------------------------------------------------------------------
  815.  * \fn     InitCode_ST6(void)
  816.  * \brief  per-pass initializations for ST6
  817.  * ------------------------------------------------------------------------ */
  818.  
  819. static void InitCode_ST6(void)
  820. {
  821.   WinAssume = 0x40;
  822.   PRPRVal = 0;
  823. }
  824.  
  825. /*!------------------------------------------------------------------------
  826.  * \fn     IsDef_ST6(void)
  827.  * \brief  does instruction consume label field?
  828.  * \return true if to be consumed
  829.  * ------------------------------------------------------------------------ */
  830.  
  831. static Boolean IsDef_ST6(void)
  832. {
  833.   return Memo("SFR") || Memo("BIT");
  834. }
  835.  
  836. /*!------------------------------------------------------------------------
  837.  * \fn     SwitchFrom_ST6(void)
  838.  * \brief  cleanup after switching away from target
  839.  * ------------------------------------------------------------------------ */
  840.  
  841. static void SwitchFrom_ST6(void)
  842. {
  843.   DeinitFields();
  844. }
  845.  
  846. static Boolean TrueFnc(void)
  847. {
  848.   return True;
  849. }
  850.  
  851. /*!------------------------------------------------------------------------
  852.  * \fn     InternSymbol_ST6(char *pArg, TempResult *pErg)
  853.  * \brief  check for built-in symbols
  854.  * \param  pAsc ASCII repr. of symbol
  855.  * \param  pErg result buffer
  856.  * ------------------------------------------------------------------------ */
  857.  
  858. static void InternSymbol_ST6(char *pArg, TempResult *pErg)
  859. {
  860.   int z;
  861. #define RegCnt 5
  862.   static const char RegNames[RegCnt + 1][2] = {"A", "V", "W", "X", "Y"};
  863.   static const Byte RegCodes[RegCnt + 1] = {0xff, 0x82, 0x83, 0x80, 0x81};
  864.  
  865.   for (z = 0; z < RegCnt; z++)
  866.     if (!as_strcasecmp(pArg, RegNames[z]))
  867.     {
  868.       as_tempres_set_int(pErg, RegCodes[z]);
  869.       pErg->AddrSpaceMask |= (1 << SegData);
  870.     }
  871. }
  872.  
  873. /*!------------------------------------------------------------------------
  874.  * \fn     SwitchTo_ST6(void)
  875.  * \brief  switch to target
  876.  * ------------------------------------------------------------------------ */
  877.  
  878. static void SwitchTo_ST6(void *pUser)
  879. {
  880.   const TFamilyDescr *p_descr = FindFamilyByName("ST6");
  881.   int ASSUMEOffset;
  882.  
  883.   pCurrCPUProps = (const tCPUProps*)pUser;
  884.   TurnWords = False;
  885.   SetIntConstMode(eIntConstModeIntel);
  886.   SetIsOccupiedFnc = TrueFnc;
  887.  
  888.   PCSymbol = "PC";
  889.   HeaderID = p_descr->Id;
  890.   NOPCode = 0x04;
  891.   DivideChars = ",";
  892.   HasAttrs = False;
  893.  
  894.   ValidSegs = (1 << SegCode) | (1 << SegData);
  895.   Grans[SegCode] = 1; ListGrans[SegCode] = 1; SegInits[SegCode] = 0;
  896.   SegLimits[SegCode] = IntTypeDefs[pCurrCPUProps->CodeAdrInt].Max;
  897.   Grans[SegData] = 1; ListGrans[SegData] = 1; SegInits[SegData] = 0;
  898.   SegLimits[SegData] = 0xff;
  899.  
  900.   ASSUMEOffset = (SegLimits[SegCode] > 0xfff) ? 0 : 1;
  901.   assume_set(ASSUMEST6s + ASSUMEOffset, as_array_size(ASSUMEST6s) - ASSUMEOffset);
  902.  
  903.   MakeCode = MakeCode_ST6;
  904.   IsDef = IsDef_ST6;
  905.   SwitchFrom = SwitchFrom_ST6;
  906.   DissectBit = DissectBit_ST6;
  907.   InternSymbol = InternSymbol_ST6;
  908.  
  909.   InitFields();
  910. }
  911.  
  912. /*!------------------------------------------------------------------------
  913.  * \fn     codest6_init(void)
  914.  * \brief  register ST6 target
  915.  * ------------------------------------------------------------------------ */
  916.  
  917. static const tCPUProps CPUProps[] =
  918. {
  919.   { "ST6200", UInt12 },
  920.   { "ST6201", UInt12 },
  921.   { "ST6203", UInt12 },
  922.   { "ST6208", UInt12 },
  923.   { "ST6209", UInt12 },
  924.   { "ST6210", UInt12 },
  925.   { "ST6215", UInt12 },
  926.   { "ST6218", UInt13 },
  927.   { "ST6220", UInt12 },
  928.   { "ST6225", UInt12 },
  929.   { "ST6228", UInt13 },
  930.   { "ST6230", UInt13 },
  931.   { "ST6232", UInt13 },
  932.   { "ST6235", UInt13 },
  933.   { "ST6240", UInt13 },
  934.   { "ST6242", UInt13 },
  935.   { "ST6245", UInt12 },
  936.   { "ST6246", UInt12 },
  937.   { "ST6252", UInt12 },
  938.   { "ST6253", UInt12 },
  939.   { "ST6255", UInt12 },
  940.   { "ST6260", UInt12 },
  941.   { "ST6262", UInt12 },
  942.   { "ST6263", UInt12 },
  943.   { "ST6265", UInt12 },
  944.   { "ST6280", UInt13 },
  945.   { "ST6285", UInt13 },
  946.   { NULL    , (IntType)0 },
  947. };
  948.  
  949. void codest6_init(void)
  950. {
  951.   const tCPUProps *pProp;
  952.  
  953.   for (pProp = CPUProps; pProp->pName; pProp++)
  954.     (void)AddCPUUser(pProp->pName, SwitchTo_ST6, (void*)pProp, NULL);
  955.  
  956.   AddInitPassProc(InitCode_ST6);
  957. }
  958.