Subversion Repositories pentevo

Rev

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

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