Subversion Repositories pentevo

Rev

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

  1. /* codepdk.c */
  2. /*****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
  4. /*                                                                           */
  5. /* AS-Portierung                                                             */
  6. /*                                                                           */
  7. /* AS - Target Padauk MCUs                                                   */
  8. /*                                                                           */
  9. /*****************************************************************************/
  10.  
  11. #include "stdinc.h"
  12. #include <string.h>
  13. #include "bpemu.h"
  14. #include "strutil.h"
  15. #include "cpulist.h"
  16. #include "asmdef.h"
  17. #include "asmsub.h"
  18. #include "asmpars.h"
  19. #include "asmitree.h"
  20. #include "asmstructs.h"
  21. #include "codevars.h"
  22. #include "codepseudo.h"
  23. #include "fourpseudo.h"
  24. #include "codepdk.h"
  25.  
  26. typedef enum
  27. {
  28.   eCoreNone,
  29.   eCorePDK13,
  30.   eCorePDK14,
  31.   eCorePDK15,
  32.   eCorePDK16
  33. } tCPUCore;
  34.  
  35. enum
  36. {
  37.   eInstCapCOMP_AM_MA = 1 << 0,
  38.   eInstCapNADD_AM_MA = 1 << 1,
  39.   eInstCapMUL = 1 << 2,
  40.   eInstCapXOR_IOA = 1 << 3,
  41.   eInstCap_SWAPM = 1 << 4,
  42.   eInstCapNMOV_AM_MA = 1 << 5,
  43.   eInstCapPUSHW_POPW = 1 << 6,
  44.   eInstCapPMODE = 1 << 7
  45. };
  46.  
  47. typedef struct
  48. {
  49.   const char *pName;
  50.   Word FlashEndD16;
  51.   Byte RAMEnd, IOAreaEnd;
  52.   tCPUCore Core;
  53.   Word InstCaps;
  54. } tCPUProps;
  55.  
  56. typedef enum
  57. {
  58.   ModNone = 0,
  59.   ModMem = 1,
  60.   ModIO = 2,
  61.   ModImm = 3,
  62.   ModAcc = 4
  63. } tAdrMode;
  64.  
  65. #define MModMem (1 << ModMem)
  66. #define MModIO (1 << ModIO)
  67. #define MModImm (1 << ModImm)
  68. #define MModAcc (1 << ModAcc)
  69.  
  70. static const tCPUProps *pCurrCPUProps;
  71.  
  72. static IntType CodeAdrIntType,
  73.                CodeWordIntType,
  74.                DataAdrIntType,
  75.                DataBitAdrIntType,
  76.                IOAdrIntType;
  77. static Byte DataMemBits,
  78.             DataBitMemBits,
  79.             CodeMemBits,
  80.             IOMemBits;
  81. static Word AccInstOffs;
  82. static ShortInt OpSize;
  83.  
  84. /*!------------------------------------------------------------------------
  85.  * \fn     DecodeAdr(tStrComp *pArg, Word Mask, IntType MemIntType, Word *pResult)
  86.  * \brief  decode address expression
  87.  * \param  pArg string argument in source
  88.  * \param  Mask bit mask of allowed modes
  89.  * \param  MemIntType integer range for memory addresses
  90.  * \param  pResult resulting address for memory/IO
  91.  * \return decoded address mode or none
  92.  * ------------------------------------------------------------------------ */
  93.  
  94. static tAdrMode DecodeAdr(tStrComp *pArg, Word Mask, IntType MemIntType, Word *pResult)
  95. {
  96.   tAdrMode AdrMode = ModNone;
  97.   Boolean OK;
  98.   IntType AutoIntType;
  99.   LongInt AddrOrImm;
  100.   int ArgLen;
  101.   tEvalResult EvalResult;
  102.  
  103.   if (!as_strcasecmp(pArg->str.p_str, "A"))
  104.   {
  105.     AdrMode = ModAcc;
  106.     goto check;
  107.   }
  108.  
  109.   /* explicit memory: disp[addr], [addr], addr[idx] */
  110.  
  111.   ArgLen = strlen(pArg->str.p_str);
  112.   if ((ArgLen >= 2) && (pArg->str.p_str[ArgLen - 1] == ']'))
  113.   {
  114.     tStrComp Part1, Part2;
  115.     LongInt Num1, Num2;
  116.     Boolean EitherUnknown;
  117.     char *pSep;
  118.     tEvalResult EvalResult1, EvalResult2;
  119.  
  120.     StrCompShorten(pArg, 1);
  121.     pSep = RQuotPos(pArg->str.p_str, '[');
  122.     if (!pSep)
  123.     {
  124.       WrStrErrorPos(ErrNum_BrackErr, pArg);
  125.       goto check;
  126.     }
  127.  
  128.     StrCompSplitRef(&Part1, &Part2, pArg, pSep);
  129.     EitherUnknown = False;
  130.  
  131.     if (*Part1.str.p_str)
  132.     {
  133.       Num1 = EvalStrIntExpressionWithResult(&Part1, MemIntType, &EvalResult1);
  134.       if (!EvalResult1.OK)
  135.         goto check;
  136.       EitherUnknown = EitherUnknown || mFirstPassUnknown(EvalResult1.Flags);
  137.     }
  138.     else
  139.     {
  140.       EvalResult1.OK = False;
  141.       EvalResult1.Flags = eSymbolFlag_None;
  142.       EvalResult1.AddrSpaceMask = 0;
  143.       Num1 = 0;
  144.     }
  145.  
  146.     Num2 = EvalStrIntExpressionWithResult(&Part2, MemIntType, &EvalResult2);
  147.     if (!EvalResult2.OK)
  148.       goto check;
  149.     EitherUnknown = EitherUnknown || mFirstPassUnknown(EvalResult2.Flags);
  150.     Num1 += Num2;
  151.  
  152.     if (EitherUnknown)
  153.     {
  154.       Num1 &= SegLimits[SegData];
  155.       if (OpSize == eSymbolSize16Bit)
  156.         Num1 &= ~1;
  157.     }
  158.  
  159.     if ((OpSize == eSymbolSize16Bit) && (Num1 & 1)) WrStrErrorPos(ErrNum_NotAligned, pArg);
  160.     else if (ChkRange(Num1, 0, SegLimits[SegData]))
  161.     {
  162.       ChkSpace(SegData, EvalResult1.AddrSpaceMask | EvalResult2.AddrSpaceMask);
  163.       AdrMode = ModMem;
  164.       *pResult = Num1;
  165.     }
  166.     goto check;
  167.   }
  168.  
  169.   /* explicit I/O */
  170.  
  171.   if (!as_strncasecmp(pArg->str.p_str, "IO", 2) && IsIndirect(pArg->str.p_str + 2))
  172.   {
  173.     *pResult = EvalStrIntExpressionOffsWithResult(pArg, 2, IOAdrIntType, &EvalResult);
  174.     if (EvalResult.OK)
  175.     {
  176.       ChkSpace(SegIO, EvalResult.AddrSpaceMask);
  177.       AdrMode = ModIO;
  178.     }
  179.     goto check;
  180.   }
  181.  
  182.   /* explicit immediate */
  183.  
  184.   if (*pArg->str.p_str == '#')
  185.   {
  186.     *pResult = EvalStrIntExpressionOffs(pArg, 1, Int8, &OK) & 0xff;
  187.     if (OK)
  188.       AdrMode = ModImm;
  189.     goto check;
  190.   }
  191.  
  192.   /* OK, guess what is meant... */
  193.  
  194.   AutoIntType = Int8;
  195.   if (Lo(IntTypeDefs[IOAdrIntType].SignAndWidth) > Lo(IntTypeDefs[AutoIntType].SignAndWidth))
  196.     AutoIntType = IOAdrIntType;
  197.   if (Lo(IntTypeDefs[MemIntType].SignAndWidth) > Lo(IntTypeDefs[AutoIntType].SignAndWidth))
  198.     AutoIntType = MemIntType;
  199.  
  200.   AddrOrImm = EvalStrIntExpressionWithResult(pArg, AutoIntType, &EvalResult);
  201.   if (EvalResult.OK)
  202.   {
  203.     if (EvalResult.AddrSpaceMask == 1 << SegIO)
  204.     {
  205.       if (mFirstPassUnknown(EvalResult.Flags) && (AddrOrImm > (LongInt)SegLimits[SegIO]))
  206.         AddrOrImm &= SegLimits[SegIO];
  207.       if (AddrOrImm > (LongInt)SegLimits[SegIO])
  208.         WrStrErrorPos(ErrNum_OverRange, pArg);
  209.       else
  210.       {
  211.         AdrMode = ModIO;
  212.         *pResult = AddrOrImm;
  213.       }
  214.     }
  215.     else if (EvalResult.AddrSpaceMask == 1 << SegData)
  216.     {
  217.       if (mFirstPassUnknown(EvalResult.Flags) && (AddrOrImm > (LongInt)SegLimits[SegData]))
  218.         AddrOrImm &= SegLimits[SegData];
  219.       if (AddrOrImm > (LongInt)SegLimits[SegData])
  220.         WrStrErrorPos(ErrNum_OverRange, pArg);
  221.       else
  222.       {
  223.         AdrMode = ModMem;
  224.         *pResult = AddrOrImm;
  225.       }
  226.     }
  227.     else
  228.     {
  229.       if (mFirstPassUnknown(EvalResult.Flags) && ((AddrOrImm > 0xff) || (AddrOrImm < -128)))
  230.         AddrOrImm &= 0xff;
  231.       if (!ChkRange(AddrOrImm, -128, 255))
  232.         WrStrErrorPos(ErrNum_OverRange, pArg);
  233.       else
  234.       {
  235.         AdrMode = ModImm;
  236.         *pResult = AddrOrImm & 0xff;
  237.       }
  238.     }
  239.   }
  240.  
  241. check:
  242.   if ((AdrMode != ModNone) && (!(Mask & (1 << AdrMode))))
  243.   {
  244.     WrStrErrorPos(ErrNum_InvAddrMode, pArg);
  245.     AdrMode = ModNone;
  246.   }
  247.   return AdrMode;
  248. }
  249.  
  250. static Boolean CoreMask(Word Mask)
  251. {
  252.   return !!(Mask & (1 << pCurrCPUProps->Core));
  253. }
  254.  
  255. /*--------------------------------------------------------------------------*/
  256. /* Bit Symbol Handling */
  257.  
  258. /*
  259.  * Compact representation of bits in symbol table:
  260.  * bits 0..2: bit position
  261.  * bits 3...n: I/O or memory address
  262.  * bit 15: 1 for I/O, 0 for memory
  263.  */
  264.  
  265. /*!------------------------------------------------------------------------
  266.  * \fn     EvalBitPosition(const tStrComp *pArg, Boolean *pOK)
  267.  * \brief  evaluate bit position
  268.  * \param  bit position argument (with or without #)
  269.  * \param  pOK parsing OK?
  270.  * \return numeric bit position
  271.  * ------------------------------------------------------------------------ */
  272.  
  273. static LongWord EvalBitPosition(const tStrComp *pArg, Boolean *pOK)
  274. {
  275.   return EvalStrIntExpression(pArg, UInt3, pOK);
  276. }
  277.  
  278. /*!------------------------------------------------------------------------
  279.  * \fn     AssembleBitSymbol(Byte BitPos, Word Address, Boolean IsIO)
  280.  * \brief  build the compact internal representation of a bit symbol
  281.  * \param  BitPos bit position in word
  282.  * \param  Address register address
  283.  * \param  IsIO true for bit in I/O space
  284.  * \return compact representation
  285.  * ------------------------------------------------------------------------ */
  286.  
  287. static LongWord AssembleBitSymbol(Byte BitPos, Word Address, Boolean IsIO)
  288. {
  289.   return (BitPos & 7)
  290.        | (((LongWord)Address & 0x1ff) << 3)
  291.        | (IsIO ? 0x8000u : 0x0000);
  292. }
  293.  
  294. /*!------------------------------------------------------------------------
  295.  * \fn     DissectBitSymbol(LongWord BitSymbol, Word *pAddress, Byte *pBitPos, Boolean *pIO)
  296.  * \brief  transform compact representation of bit symbol into components
  297.  * \param  BitSymbol compact storage
  298.  * \param  pAddress I/O or memory address
  299.  * \param  pBitPos bit position
  300.  * \param  pIO 1 for I/O, 0 for memory address
  301.  * \return constant True
  302.  * ------------------------------------------------------------------------ */
  303.  
  304. static Boolean DissectBitSymbol(LongWord BitSymbol, Word *pAddress, Byte *pBitPos, Boolean *pIO)
  305. {
  306.   *pAddress = (BitSymbol >> 3) & 0x1ff;
  307.   *pBitPos = BitSymbol & 7;
  308.   *pIO = !!(BitSymbol & 0x8000u);
  309.   return True;
  310. }
  311.  
  312. /*!------------------------------------------------------------------------
  313.  * \fn     DecodeBitArg2(LongWord *pResult, tStrComp *pAddrArg, const tStrComp *pBitArg)
  314.  * \brief  encode a bit symbol, address & bit position separated
  315.  * \param  pResult resulting encoded bit
  316.  * \param  pAddrArg memory/IO address argument
  317.  * \param  pBitArg bit argument
  318.  * \return True if success
  319.  * ------------------------------------------------------------------------ */
  320.  
  321. static Boolean DecodeBitArg2(LongWord *pResult, tStrComp *pAddrArg, const tStrComp *pBitArg)
  322. {
  323.   Boolean OK;
  324.   Word Address;
  325.   Byte BitPos;
  326.   Boolean IsIO;
  327.  
  328.   BitPos = EvalBitPosition(pBitArg, &OK);
  329.   if (!OK)
  330.     return False;
  331.  
  332.   switch (DecodeAdr(pAddrArg, MModMem | MModIO, DataBitAdrIntType, &Address))
  333.   {
  334.     case ModMem:
  335.       IsIO = False;
  336.       break;
  337.     case ModIO:
  338.       IsIO = True;
  339.       break;
  340.     default:
  341.       return False;
  342.   }
  343.  
  344.   *pResult = AssembleBitSymbol(BitPos, Address, IsIO);
  345.  
  346.   return True;
  347. }
  348.  
  349. /*!------------------------------------------------------------------------
  350.  * \fn     DecodeBitArg(LongWord *pResult, int Start, int Stop)
  351.  * \brief  encode a bit symbol from instruction argument(s)
  352.  * \param  pResult resulting encoded bit
  353.  * \param  Start first argument
  354.  * \param  Stop last argument
  355.  * \return True if success
  356.  * ------------------------------------------------------------------------ */
  357.  
  358. static Boolean DecodeBitArg(LongWord *pResult, int Start, int Stop)
  359. {
  360.   *pResult = 0;
  361.  
  362.   /* Just one argument -> parse as bit argument */
  363.  
  364.   if (Start == Stop)
  365.   {
  366.     char *pSep = strchr(ArgStr[Start].str.p_str, '.');
  367.  
  368.     if (pSep)
  369.     {
  370.       tStrComp AddressComp, PosComp;
  371.  
  372.       StrCompSplitRef(&AddressComp, &PosComp, &ArgStr[Start], pSep);
  373.       return DecodeBitArg2(pResult, &AddressComp, &PosComp);
  374.     }
  375.     else
  376.     {
  377.       tEvalResult EvalResult;
  378.  
  379.       *pResult = EvalStrIntExpressionWithResult(&ArgStr[Start], UInt16, &EvalResult);
  380.       if (EvalResult.OK)
  381.         ChkSpace(SegBData, EvalResult.AddrSpaceMask);
  382.       return EvalResult.OK;
  383.     }
  384.   }
  385.  
  386.   /* register & bit position are given as separate arguments */
  387.  
  388.   else if (Stop == Start + 1)
  389.     return DecodeBitArg2(pResult, &ArgStr[Start], &ArgStr[Stop]);
  390.  
  391.   /* other # of arguments not allowed */
  392.  
  393.   else
  394.   {
  395.     WrError(ErrNum_WrongArgCnt);
  396.     return False;
  397.   }
  398. }
  399.  
  400. /*!------------------------------------------------------------------------
  401.  * \fn     DissectBit_Padauk(char *pDest, size_t DestSize, LargeWord Inp)
  402.  * \brief  dissect compact storage of bit (field) into readable form for listing
  403.  * \param  pDest destination for ASCII representation
  404.  * \param  DestSize destination buffer size
  405.  * \param  Inp compact storage
  406.  * ------------------------------------------------------------------------ */
  407.  
  408. static void DissectBit_Padauk(char *pDest, size_t DestSize, LargeWord Inp)
  409. {
  410.   Byte BitPos;
  411.   Word Address;
  412.   Boolean IsIO;
  413.  
  414.   DissectBitSymbol(Inp, &Address, &BitPos, &IsIO);
  415.  
  416.   if (IsIO)
  417.     as_snprintf(pDest, DestSize, "IO(0x%x).%u", (unsigned)Address, (unsigned)BitPos);
  418.   else
  419.     as_snprintf(pDest, DestSize, "[0x%x].%u", (unsigned)Address, (unsigned)BitPos);
  420. }
  421.  
  422. /*!------------------------------------------------------------------------
  423.  * \fn     ExpandBit_Padauk(const tStrComp *pVarName, const struct sStructElem *pStructElem, LargeWord Base)
  424.  * \brief  expands bit definition when a structure is instantiated
  425.  * \param  pVarName desired symbol name
  426.  * \param  pStructElem element definition
  427.  * \param  Base base address of instantiated structure
  428.  * ------------------------------------------------------------------------ */
  429.  
  430. static void ExpandBit_Padauk(const tStrComp *pVarName, const struct sStructElem *pStructElem, LargeWord Base)
  431. {
  432.   LongWord Address = Base + pStructElem->Offset;
  433.   Boolean IsIO = (ActPC == SegIO);
  434.  
  435.   if (!ChkRange(Address, 0, IntTypeDefs[IsIO ? IOAdrIntType : DataBitAdrIntType].Max)
  436.    || !ChkRange(pStructElem->BitPos, 0, 7))
  437.     return;
  438.  
  439.   PushLocHandle(-1);
  440.   EnterIntSymbol(pVarName, AssembleBitSymbol(pStructElem->BitPos, Address, IsIO), SegBData, False);
  441.   PopLocHandle();
  442.   /* TODO: MakeUseList? */
  443. }
  444.  
  445. /*!------------------------------------------------------------------------
  446.  * \fn     ImmCode(Word Code13)
  447.  * \brief  translate PDK13 arithmetic op code to actual code code for immediate src
  448.  * \param  Code13 PDK13 code
  449.  * \return Immediate Opcode
  450.  * ------------------------------------------------------------------------ */
  451.  
  452. static Word ImmCode(Word Code13)
  453. {
  454.   switch (pCurrCPUProps->Core)
  455.   {
  456.     case eCorePDK14:
  457.       return 0x20 | ((Code13 & 0x10) >> 1) | (Code13 & 7);
  458.     case eCorePDK15:
  459.       return 0x40 | Code13;
  460.     case eCorePDK16:
  461.       return 0x08 | Code13;
  462.     default:
  463.       return Code13;
  464.   }
  465. }
  466.  
  467. /*!------------------------------------------------------------------------
  468.  * \fn     AMCode(Word Code13, Boolean AccDest)
  469.  * \brief  translate PDK13 arithmetic op code to actual code code for Acc<->[M]
  470.  * \param  Code13 PDK13 code
  471.  * \param  AccDest: true if A<-M
  472.  * \return Opcode
  473.  * ------------------------------------------------------------------------ */
  474.  
  475. static Word AMCode(Word Code13, Boolean AccDest)
  476. {
  477.   switch (pCurrCPUProps->Core)
  478.   {
  479.     case eCorePDK16:
  480.       return (Code13 << 1) | (AccDest ? 1 : 0);
  481.     default:
  482.       return Code13 | (AccDest ? 8 : 0);
  483.   }
  484. }
  485.  
  486. /*!------------------------------------------------------------------------
  487.  * \fn     MCode(Word Code13)
  488.  * \brief  translate PDK13 arithmetic op code to actual code code for [M]
  489.  * \param  Code13 PDK13 code
  490.  * \return Opcode
  491.  * ------------------------------------------------------------------------ */
  492.  
  493. static Word MCode(Word Code13)
  494. {
  495.   switch (pCurrCPUProps->Core)
  496.   {
  497.     case eCorePDK16:
  498.       return 0x30 | Code13;
  499.     default:
  500.       return 0x20 | Code13;
  501.   }
  502. }
  503.  
  504. /*---------------------------------------------------------------------------*/
  505.  
  506. static void DecodeFixed(Word Code)
  507. {
  508.   if (ChkArgCnt(0, 0))
  509.     WAsmCode[CodeLen++] = Code;
  510. }
  511.  
  512. static void DecodeACC(Word Code)
  513. {
  514.   Word Address;
  515.  
  516.   if (ChkArgCnt(1, 1)
  517.    && DecodeAdr(&ArgStr[1], MModAcc, DataAdrIntType, &Address))
  518.     WAsmCode[CodeLen++] = Code;
  519. }
  520.  
  521. static void DecodeSWAP(Word Code)
  522. {
  523.   Word Address;
  524.  
  525.   if (ChkArgCnt(1, 1))
  526.     switch (DecodeAdr(&ArgStr[1], MModAcc | ((pCurrCPUProps->InstCaps & eInstCap_SWAPM) ? MModMem : 0), DataAdrIntType, &Address))
  527.     {
  528.       case ModAcc:
  529.         WAsmCode[CodeLen++] = Code;
  530.         break;
  531.       case ModMem:
  532.         WAsmCode[CodeLen++] = ((pCurrCPUProps->Core == eCorePDK16 ? 0x3e: 0x0a) << DataMemBits) | Address;
  533.         break;
  534.       default:
  535.         break;
  536.     }
  537. }
  538.  
  539. static void DecodeADDC_SUBC(Word Code)
  540. {
  541.   Word Address;
  542.  
  543.   switch (ArgCnt)
  544.   {
  545.     case 1:
  546.       switch (DecodeAdr(&ArgStr[1], MModAcc | MModMem, DataAdrIntType, &Address))
  547.       {
  548.         case ModAcc:
  549.           WAsmCode[CodeLen++] = (AccInstOffs + 0) | Code;
  550.           break;
  551.         case ModMem:
  552.           WAsmCode[CodeLen++] = (MCode(Code) << DataMemBits) | Address;
  553.           break;
  554.         default:
  555.           break;
  556.       }
  557.       break;
  558.     case 2:
  559.       if (!as_strcasecmp(ArgStr[1].str.p_str, "A"))
  560.       {
  561.         if (DecodeAdr(&ArgStr[2], MModMem, DataAdrIntType, &Address))
  562.           WAsmCode[CodeLen++] = (AMCode(0x12 + Code, True) << DataMemBits) | Address;
  563.       }
  564.       else if (!as_strcasecmp(ArgStr[2].str.p_str, "A"))
  565.       {
  566.         if (DecodeAdr(&ArgStr[1], MModMem, DataAdrIntType, &Address))
  567.           WAsmCode[CodeLen++] = (AMCode(0x12 + Code, False) << DataMemBits) | Address;
  568.       }
  569.       break;
  570.     default:
  571.       (void)ChkArgCnt(1, 2);
  572.   }
  573. }
  574.  
  575. static void DecodeACCOrM(Word Code)
  576. {
  577.   Word Address;
  578.  
  579.   if (ChkArgCnt(1, 1))
  580.     switch (DecodeAdr(&ArgStr[1], MModMem | MModAcc, DataAdrIntType, &Address))
  581.     {
  582.       case ModAcc:
  583.         WAsmCode[CodeLen++] = AccInstOffs + Code;
  584.         break;
  585.       case ModMem:
  586.         WAsmCode[CodeLen++] = (MCode(Code) << DataMemBits) | Address;
  587.         break;
  588.       default:
  589.         break;
  590.     }
  591. }
  592.  
  593. static void DecodeDELAY(Word Code)
  594. {
  595.   Word Address;
  596.  
  597.   if (ChkArgCnt(1, 1))
  598.     switch (DecodeAdr(&ArgStr[1], MModMem | MModAcc | MModImm, DataAdrIntType, &Address))
  599.     {
  600.       case ModAcc:
  601.         WAsmCode[CodeLen++] = AccInstOffs + Code;
  602.         break;
  603.       case ModMem:
  604.         WAsmCode[CodeLen++] = (MCode(Code) << DataMemBits) | Address;
  605.         break;
  606.       case ModImm:
  607.         WAsmCode[CodeLen++] = 0x0e00 | Address;
  608.         break;
  609.       default:
  610.         break;
  611.     }
  612. }
  613.  
  614. static void DecodeM(Word Code)
  615. {
  616.   Word Address;
  617.  
  618.   if (ChkArgCnt(1, 1)
  619.    && DecodeAdr(&ArgStr[1], MModMem, DataAdrIntType, &Address))
  620.     WAsmCode[CodeLen++] = (MCode(Code) << DataMemBits) | Address;
  621. }
  622.  
  623. static void DecodeRET(Word Code)
  624. {
  625.   Word Value;
  626.  
  627.   UNUSED(Code);
  628.  
  629.   switch (ArgCnt)
  630.   {
  631.     case 0:
  632.       WAsmCode[CodeLen++] = (AccInstOffs == 0x60) ? 0x7a : 0x3a;
  633.       break;
  634.     case 1:
  635.       if (DecodeAdr(&ArgStr[1], MModImm, DataAdrIntType, &Value))
  636.         WAsmCode[CodeLen++] = Code | Value;
  637.       break;
  638.     default:
  639.       (void)ChkArgCnt(0, 1);
  640.   }
  641. }
  642.  
  643. static void DecodeXOR(Word Code)
  644. {
  645.   Word DestAddress, SrcAddress,
  646.        OpCode = Lo(Code),
  647.        IOCode = Hi(Code);
  648.  
  649.   if (ChkArgCnt(2,2))
  650.     switch (DecodeAdr(&ArgStr[1], MModAcc | MModMem | ((pCurrCPUProps->InstCaps & eInstCapXOR_IOA) ? MModIO : 0), DataAdrIntType, &DestAddress))
  651.     {
  652.       case ModAcc:
  653.         switch (DecodeAdr(&ArgStr[2], MModMem | MModImm | ((pCurrCPUProps->Core >= eCorePDK16) ? MModIO : 0), DataAdrIntType, &SrcAddress))
  654.         {
  655.           case ModMem:
  656.             WAsmCode[CodeLen++] = (AMCode(OpCode, True) << DataMemBits) | SrcAddress;
  657.             break;
  658.           case ModImm:
  659.             WAsmCode[CodeLen++] = (ImmCode(OpCode) << 8) | SrcAddress;
  660.             break;
  661.           case ModIO:
  662.             WAsmCode[CodeLen++] = ((IOCode + 1) << IOMemBits) | SrcAddress;
  663.             break;
  664.           default:
  665.             break;
  666.         }
  667.         break;
  668.       case ModMem:
  669.         if (DecodeAdr(&ArgStr[2], MModAcc, DataAdrIntType, &SrcAddress))
  670.           WAsmCode[CodeLen++] = (AMCode(OpCode, False) << DataMemBits) | DestAddress;
  671.         break;
  672.       case ModIO:
  673.         if (DecodeAdr(&ArgStr[2], MModAcc, DataAdrIntType, &SrcAddress))
  674.           WAsmCode[CodeLen++] = (IOCode << IOMemBits) | DestAddress;
  675.         break;
  676.       default:
  677.         break;
  678.     }
  679. }
  680.  
  681. static void DecodeAccToM(Word Code)
  682. {
  683.   Word DestAddress, SrcAddress;
  684.  
  685.   if (ChkArgCnt(2, 2))
  686.     switch (DecodeAdr(&ArgStr[1], MModAcc | MModMem, DataAdrIntType, &DestAddress))
  687.     {
  688.       case ModAcc:
  689.         switch (DecodeAdr(&ArgStr[2], MModMem | MModImm, DataAdrIntType, &SrcAddress))
  690.         {
  691.           case ModMem:
  692.             WAsmCode[CodeLen++] = (AMCode(Code, True) << DataMemBits) | SrcAddress;
  693.             break;
  694.           case ModImm:
  695.             WAsmCode[CodeLen++] = (ImmCode(Code) << 8) | SrcAddress;
  696.             break;
  697.           default:
  698.             break;
  699.         }
  700.         break;
  701.       case ModMem:
  702.         if (DecodeAdr(&ArgStr[2], MModAcc, DataAdrIntType, &SrcAddress))
  703.           WAsmCode[CodeLen++] = (AMCode(Code, False) << DataMemBits) | DestAddress;
  704.         break;
  705.       default:
  706.         break;
  707.     }
  708. }
  709.  
  710. static void DecodeCOMP_NADD_NMOV(Word Code)
  711. {
  712.   Word DestAddress, SrcAddress;
  713.  
  714.   UNUSED(Code);
  715.  
  716.   if (ChkArgCnt(2, 2))
  717.     switch (DecodeAdr(&ArgStr[1], MModAcc | MModMem, DataAdrIntType, &DestAddress))
  718.     {
  719.       case ModAcc:
  720.         if (DecodeAdr(&ArgStr[2], MModMem, DataAdrIntType, &SrcAddress))
  721.           WAsmCode[CodeLen++] = (((Code << 1) + 0) << DataMemBits) | SrcAddress;
  722.         break;
  723.       case ModMem:
  724.         if (DecodeAdr(&ArgStr[2], MModAcc, DataAdrIntType, &SrcAddress))
  725.           WAsmCode[CodeLen++] = (((Code << 1) + 1) << DataMemBits) | DestAddress;
  726.         break;
  727.       default:
  728.         break;
  729.     }
  730. }
  731.  
  732. static void DecodeMOV(Word Code)
  733. {
  734.   Word DestAddress, SrcAddress,
  735.        OpCode = Lo(Code),
  736.        IOCode = Hi(Code) & 15;
  737.  
  738.   if (ChkArgCnt(2,2))
  739.     switch (DecodeAdr(&ArgStr[1], MModAcc | MModMem | MModIO, DataAdrIntType, &DestAddress))
  740.     {
  741.       case ModAcc:
  742.         switch (DecodeAdr(&ArgStr[2], MModMem | MModImm | MModIO, DataAdrIntType, &SrcAddress))
  743.         {
  744.           case ModMem:
  745.             WAsmCode[CodeLen++] = (AMCode(OpCode, True) << DataMemBits) | SrcAddress;
  746.             break;
  747.           case ModImm:
  748.             WAsmCode[CodeLen++] = (ImmCode(OpCode) << 8) | SrcAddress;
  749.             break;
  750.           case ModIO:
  751.             WAsmCode[CodeLen++] = ((IOCode + 1) << IOMemBits) | SrcAddress;
  752.             break;
  753.           default:
  754.             break;
  755.         }
  756.         break;
  757.       case ModMem:
  758.         if (DecodeAdr(&ArgStr[2], MModAcc, DataAdrIntType, &SrcAddress))
  759.           WAsmCode[CodeLen++] = (AMCode(OpCode, False) << DataMemBits) | DestAddress;
  760.         break;
  761.       case ModIO:
  762.         if (DecodeAdr(&ArgStr[2], MModAcc, DataAdrIntType, &SrcAddress))
  763.           WAsmCode[CodeLen++] = (IOCode << IOMemBits) | DestAddress;
  764.         break;
  765.       default:
  766.         break;
  767.     }
  768. }
  769.  
  770. static void DecodeGOTO_CALL(Word Code)
  771. {
  772.   if (ChkArgCnt(1, 1))
  773.   {
  774.     tEvalResult EvalResult;
  775.     Word Address = EvalStrIntExpressionWithResult(&ArgStr[1], CodeAdrIntType, &EvalResult);
  776.  
  777.     if (EvalResult.OK)
  778.     {
  779.       ChkSpace(SegCode, EvalResult.AddrSpaceMask);
  780.       WAsmCode[CodeLen++] = (Code << CodeMemBits) | Address;
  781.     }
  782.   }
  783. }
  784.  
  785. static void DecodeCnEQSN(Word Code)
  786. {
  787.   Word SrcAddress, DestAddress;
  788.  
  789.   if (ChkArgCnt(2, 2))
  790.    switch (DecodeAdr(&ArgStr[1], MModAcc | ((pCurrCPUProps->Core >= eCorePDK16) ? MModMem : 0), DataAdrIntType, &DestAddress))
  791.    {
  792.      case ModAcc:
  793.        switch (DecodeAdr(&ArgStr[2], MModMem | MModImm, DataAdrIntType, &SrcAddress))
  794.        {
  795.          case ModMem:
  796.            WAsmCode[CodeLen++] = (Code << DataMemBits) | SrcAddress;
  797.            break;
  798.          case ModImm:
  799.            WAsmCode[CodeLen++] = (ImmCode(0x12 + (Code & 1)) << 8) | SrcAddress;
  800.            break;
  801.          default:
  802.            break;
  803.        }
  804.        break;
  805.      case ModMem:
  806.        if (DecodeAdr(&ArgStr[2], MModAcc, DataAdrIntType, &SrcAddress))
  807.          WAsmCode[CodeLen++] = ((Code ^ 1) << DataMemBits) | DestAddress;
  808.        break;
  809.      default:
  810.        break;
  811.    }
  812. }
  813.  
  814. static void DecodeEvenAddr(tStrComp *pArg, Word Code1, Word Code2)
  815. {
  816.   Word Address;
  817.  
  818.   OpSize = eSymbolSize16Bit;
  819.  
  820.   if (DecodeAdr(pArg, MModMem, (pCurrCPUProps->Core == eCorePDK13) ? UInt5 : DataAdrIntType, &Address))
  821.     WAsmCode[CodeLen++] = (Code1 << ((pCurrCPUProps->Core == eCorePDK13) ? 5 : DataMemBits)) | Code2 | Address;
  822. }
  823.  
  824. static void DecodeSTT16_LDT16(Word Code)
  825. {
  826.   if (ChkArgCnt(1, 1))
  827.     DecodeEvenAddr(&ArgStr[1], Hi(Code), Lo(Code));
  828. }
  829.  
  830. static void DecodeLDTAB(Word Code)
  831. {
  832.   if (ChkArgCnt(1, 1))
  833.     DecodeEvenAddr(&ArgStr[1], 0x05, Code);
  834. }
  835.  
  836. static void DecodeIDXM(Word Code)
  837. {
  838.   if (ChkArgCnt(2, 2))
  839.   {
  840.     if (!as_strcasecmp(ArgStr[1].str.p_str, "A"))
  841.       DecodeEvenAddr(&ArgStr[2], Code, 1);
  842.     else if (!as_strcasecmp(ArgStr[2].str.p_str, "A"))
  843.       DecodeEvenAddr(&ArgStr[1], Code, 0);
  844.   }
  845. }
  846.  
  847. static void DecodeBitOp(Word Code)
  848. {
  849.   LongWord BitSpec;
  850.   Word OpCode = Lo(Code);
  851.  
  852.   if (DecodeBitArg(&BitSpec, 1, ArgCnt))
  853.   {
  854.     Word Address;
  855.     Byte BitPos;
  856.     Boolean IsIO;
  857.  
  858.     DissectBitSymbol(BitSpec, &Address, &BitPos, &IsIO);
  859.     if (IsIO)
  860.     {
  861.       if (pCurrCPUProps->Core == eCorePDK16)
  862.         WAsmCode[CodeLen++] = 0x2000 | (OpCode << (3 + IOMemBits)) | (BitPos << IOMemBits) | Address;
  863.       else
  864.         WAsmCode[CodeLen++] = (3 << (5 + IOMemBits)) | (OpCode << (3 + IOMemBits)) | (BitPos << IOMemBits) | Address;
  865.     }
  866.     else if (pCurrCPUProps->Core == eCorePDK13)
  867.       WAsmCode[CodeLen++] = (Code & 0xff00u) | ((OpCode & 2) << (4 - 1 + DataBitMemBits)) | (BitPos << (1 + DataBitMemBits)) | ((Code & 1) << DataBitMemBits) | Address;
  868.     else
  869.       WAsmCode[CodeLen++] = (Code & 0xff00u) | (OpCode << (3 + DataBitMemBits)) | (BitPos << DataBitMemBits) | Address;
  870.   }
  871. }
  872.  
  873. static void DecodeBitOpIO(Word Code)
  874. {
  875.   LongWord BitSpec;
  876.  
  877.   if (DecodeBitArg(&BitSpec, 1, ArgCnt))
  878.   {
  879.     Word Address;
  880.     Byte BitPos;
  881.     Boolean IsIO;
  882.  
  883.     DissectBitSymbol(BitSpec, &Address, &BitPos, &IsIO);
  884.     if (IsIO)
  885.       WAsmCode[CodeLen++] = (Code << (3 + IOMemBits)) | (BitPos << IOMemBits) | Address;
  886.     else
  887.       WrError(ErrNum_InvAddrMode);
  888.   }
  889. }
  890.  
  891. static void DecodeConstU5(Word Code)
  892. {
  893.   if (ChkArgCnt(1, 1))
  894.   {
  895.     Boolean OK;
  896.     Word Num = EvalStrIntExpressionOffs(&ArgStr[1], !!(*ArgStr[1].str.p_str == '#'), UInt5, &OK);
  897.  
  898.     if (OK)
  899.       WAsmCode[CodeLen++] = Code | (Num & 0x1f);
  900.   }
  901. }
  902.  
  903. static void DecodeConstU4(Word Code)
  904. {
  905.   if (ChkArgCnt(1, 1))
  906.   {
  907.     Boolean OK;
  908.     Word Num = EvalStrIntExpressionOffs(&ArgStr[1], !!(*ArgStr[1].str.p_str == '#'), UInt4, &OK);
  909.  
  910.     if (OK)
  911.       WAsmCode[CodeLen++] = Code | (Num & 0x0f);
  912.   }
  913. }
  914.  
  915. static void DecodeBIT(Word Code)
  916. {
  917.   UNUSED(Code);
  918.  
  919.   /* if in structure definition, add special element to structure */
  920.  
  921.   if (ActPC == StructSeg)
  922.   {
  923.     Boolean OK;
  924.     Byte BitPos;
  925.     PStructElem pElement;
  926.     tStrComp BitComp, *pBitComp, AddrComp, *pAddrComp;
  927.  
  928.     switch (ArgCnt)
  929.     {
  930.       case 1:
  931.       {
  932.         char *pSep = strchr(ArgStr[1].str.p_str, '.');
  933.         if (!pSep)
  934.           goto fail;
  935.         StrCompSplitRef(&AddrComp, &BitComp, &ArgStr[1], pSep);
  936.         pBitComp = &BitComp;
  937.         pAddrComp = &AddrComp;
  938.         break;
  939.       }
  940.       case 2:
  941.         pAddrComp = &ArgStr[1];
  942.         pBitComp = &ArgStr[2];
  943.         break;
  944.       default:
  945.       fail:
  946.         WrError(ErrNum_WrongArgCnt);
  947.         return;
  948.     }
  949.  
  950.     BitPos = EvalBitPosition(pBitComp, &OK);
  951.     if (!OK)
  952.       return;
  953.     pElement = CreateStructElem(&LabPart);
  954.     pElement->pRefElemName = as_strdup(pAddrComp->str.p_str);
  955.     pElement->OpSize = eSymbolSize8Bit;
  956.     pElement->BitPos = BitPos;
  957.     pElement->ExpandFnc = ExpandBit_Padauk;
  958.     AddStructElem(pInnermostNamedStruct->StructRec, pElement);
  959.   }
  960.   else
  961.   {
  962.     LongWord BitSpec;
  963.  
  964.     if (DecodeBitArg(&BitSpec, 1, ArgCnt))
  965.     {
  966.       *ListLine = '=';
  967.       DissectBit_Padauk(ListLine + 1, STRINGSIZE - 3, BitSpec);
  968.       PushLocHandle(-1);
  969.       EnterIntSymbol(&LabPart, BitSpec, SegBData, False);
  970.       PopLocHandle();
  971.       /* TODO: MakeUseList? */
  972.     }
  973.   }
  974. }
  975.  
  976. static void DecodeDATA_Padauk(Word Code)
  977. {
  978.   UNUSED(Code);
  979.  
  980.   DecodeDATA(CodeWordIntType, DataAdrIntType);
  981. }
  982.  
  983. static void DecodeSFR(Word Code)
  984. {
  985.   UNUSED(Code);
  986.  
  987.   CodeEquate(SegIO, 0, SegLimits[SegIO]);
  988. }
  989.  
  990. /*---------------------------------------------------------------------------*/
  991.  
  992. static void InitFields(void)
  993. {
  994.   Word Base, MovIOCode, RETCode, SWAPCCode, BitOpCode, XORIOCode, STT16_LDT16Code, IDXMCode, CEQSNCode, CNEQSNCode;
  995.   InstTable = CreateInstTable(203);
  996.  
  997.   switch (pCurrCPUProps->Core)
  998.   {
  999.     case eCorePDK13:
  1000.       MovIOCode = 0x0400;
  1001.       RETCode = 0x0100;
  1002.       SWAPCCode = 0;
  1003.       BitOpCode = 0x0200;
  1004.       XORIOCode = 0x0300;
  1005.       STT16_LDT16Code = 0x0600;
  1006.       IDXMCode = 7;
  1007.       CEQSNCode = 0x2e;
  1008.       CNEQSNCode = 0x2f;
  1009.       break;
  1010.     case eCorePDK14:
  1011.       MovIOCode = 0x0600;
  1012.       RETCode = 0x0200;
  1013.       SWAPCCode = 2;
  1014.       BitOpCode = 0x2000;
  1015.       XORIOCode = 0x0300;
  1016.       STT16_LDT16Code = 0x0600;
  1017.       IDXMCode = 7;
  1018.       CEQSNCode = 0x2e;
  1019.       CNEQSNCode = 0x2f;
  1020.       break;
  1021.     case eCorePDK15:
  1022.       MovIOCode = 0x0200;
  1023.       RETCode = 0x0200;
  1024.       SWAPCCode = 0x17;
  1025.       BitOpCode = 0x4000;
  1026.       XORIOCode = 0x0100;
  1027.       STT16_LDT16Code = 0x0600;
  1028.       IDXMCode = 7;
  1029.       CEQSNCode = 0x2e;
  1030.       CNEQSNCode = 0x2f;
  1031.       break;
  1032.     case eCorePDK16:
  1033.       MovIOCode = 0x0200;
  1034.       RETCode = 0x0f00;
  1035.       SWAPCCode = 0x17;
  1036.       BitOpCode = 0x8000;
  1037.       XORIOCode = 0x4000;
  1038.       STT16_LDT16Code = 0x0100;
  1039.       IDXMCode = 4;
  1040.       CNEQSNCode = 0x0b;
  1041.       CEQSNCode = 0x1c;
  1042.       break;
  1043.     default:
  1044.       WrError(ErrNum_InternalError);
  1045.       exit(255);
  1046.   }
  1047.  
  1048.   AddInstTable(InstTable, "NOP", NOPCode, DecodeFixed);
  1049.   if (pCurrCPUProps->Core <= eCorePDK14)
  1050.   {
  1051.     AddInstTable(InstTable, "LDSPTL", 0x0006, DecodeFixed);
  1052.     AddInstTable(InstTable, "LDSPTH", 0x0007, DecodeFixed);
  1053.   }
  1054.   else
  1055.   {
  1056.     AddInstTable(InstTable, "LDTABL", 0, DecodeLDTAB);
  1057.     AddInstTable(InstTable, "LDTABH", 1, DecodeLDTAB);
  1058.   }
  1059.   Base = (AccInstOffs == 0x60) ? 0x70 : 0x30;
  1060.   AddInstTable(InstTable, "WDRESET", Base + 0x00, DecodeFixed);
  1061.   AddInstTable(InstTable, "PUSHAF" , Base + 0x02, DecodeFixed);
  1062.   AddInstTable(InstTable, "POPAF"  , Base + 0x03, DecodeFixed);
  1063.   AddInstTable(InstTable, "RESET"  , Base + 0x05, DecodeFixed);
  1064.   AddInstTable(InstTable, "STOPSYS", Base + 0x06, DecodeFixed);
  1065.   AddInstTable(InstTable, "STOPEXE", Base + 0x07, DecodeFixed);
  1066.   AddInstTable(InstTable, "ENGINT" , Base + 0x08, DecodeFixed);
  1067.   AddInstTable(InstTable, "DISGINT", Base + 0x09, DecodeFixed);
  1068.   AddInstTable(InstTable, "RETI"   , Base + 0x0b, DecodeFixed);
  1069.   if (pCurrCPUProps->InstCaps & eInstCapMUL)
  1070.     AddInstTable(InstTable, "MUL"    , Base + 0x0c, DecodeFixed);
  1071.  
  1072.   AddInstTable(InstTable, "RET"    , RETCode, DecodeRET);
  1073.  
  1074.   AddInstTable(InstTable, "ADDC", 0, DecodeADDC_SUBC);
  1075.   AddInstTable(InstTable, "SUBC", 1, DecodeADDC_SUBC);
  1076.   AddInstTable(InstTable, "IZSN", 2, DecodeACCOrM);
  1077.   AddInstTable(InstTable, "DZSN", 3, DecodeACCOrM);
  1078.   AddInstTable(InstTable, "NOT" , 8, DecodeACCOrM);
  1079.   AddInstTable(InstTable, "NEG" , 9, DecodeACCOrM);
  1080.   AddInstTable(InstTable, "SR"  ,10, DecodeACCOrM);
  1081.   AddInstTable(InstTable, "SL"  ,11, DecodeACCOrM);
  1082.   AddInstTable(InstTable, "SRC" ,12, DecodeACCOrM);
  1083.   AddInstTable(InstTable, "SLC" ,13, DecodeACCOrM);
  1084.   if (pCurrCPUProps->Core >= eCorePDK16)
  1085.     AddInstTable(InstTable, "DELAY", 15, DecodeDELAY);
  1086.  
  1087.   AddInstTable(InstTable, "PCADD", AccInstOffs +  7, DecodeACC);
  1088.   AddInstTable(InstTable, "SWAP",  AccInstOffs + 14, DecodeSWAP);
  1089.  
  1090.   AddInstTable(InstTable, "INC"  , 4, DecodeM);
  1091.   AddInstTable(InstTable, "DEC"  , 5, DecodeM);
  1092.   AddInstTable(InstTable, "CLEAR", 6, DecodeM);
  1093.   AddInstTable(InstTable, "XCH"  , 7, DecodeM);
  1094.  
  1095.   if (pCurrCPUProps->InstCaps & eInstCapNADD_AM_MA)
  1096.     AddInstTable(InstTable, "COMP", pCurrCPUProps->Core >= eCorePDK16 ? 0x0f : 0x06, DecodeCOMP_NADD_NMOV);
  1097.   if (pCurrCPUProps->InstCaps & eInstCapCOMP_AM_MA)
  1098.     AddInstTable(InstTable, "NADD", pCurrCPUProps->Core >= eCorePDK16 ? 0x0d : 0x07, DecodeCOMP_NADD_NMOV);
  1099.   if (pCurrCPUProps->InstCaps & eInstCapNMOV_AM_MA)
  1100.     AddInstTable(InstTable, "NMOV", pCurrCPUProps->Core >= eCorePDK16 ? 0x0c : 0x04, DecodeCOMP_NADD_NMOV);
  1101.   AddInstTable(InstTable, "ADD", 0x10, DecodeAccToM);
  1102.   AddInstTable(InstTable, "SUB", 0x11, DecodeAccToM);
  1103.   AddInstTable(InstTable, "AND", 0x14, DecodeAccToM);
  1104.   AddInstTable(InstTable, "OR" , 0x15, DecodeAccToM);
  1105.   AddInstTable(InstTable, "XOR", XORIOCode | 0x16, DecodeXOR);
  1106.   AddInstTable(InstTable, "MOV", MovIOCode | 0x17, DecodeMOV);
  1107.   AddInstTable(InstTable, "CEQSN", CEQSNCode, DecodeCnEQSN);
  1108.   if (pCurrCPUProps->Core >= eCorePDK14)
  1109.     AddInstTable(InstTable, "CNEQSN", CNEQSNCode | 1, DecodeCnEQSN);
  1110.  
  1111.   AddInstTable(InstTable, "STT16", STT16_LDT16Code | 0, DecodeSTT16_LDT16);
  1112.   AddInstTable(InstTable, "LDT16", STT16_LDT16Code | 1, DecodeSTT16_LDT16);
  1113.   if (pCurrCPUProps->InstCaps & eInstCapPUSHW_POPW)
  1114.   {
  1115.     AddInstTable(InstTable, "POPW", 0x0200, DecodeSTT16_LDT16);
  1116.     AddInstTable(InstTable, "PUSHW", 0x0201, DecodeSTT16_LDT16);
  1117.   }
  1118.   if (pCurrCPUProps->Core >= eCorePDK16)
  1119.   {
  1120.     AddInstTable(InstTable, "IGOTO", 0x0300, DecodeSTT16_LDT16);
  1121.     AddInstTable(InstTable, "ICALL", 0x0301, DecodeSTT16_LDT16);
  1122.   }
  1123.   AddInstTable(InstTable, "IDXM" , IDXMCode, DecodeIDXM);
  1124.  
  1125.   AddInstTable(InstTable, "GOTO", 6, DecodeGOTO_CALL);
  1126.   AddInstTable(InstTable, "CALL", 7, DecodeGOTO_CALL);
  1127.  
  1128.   AddInstTable(InstTable, "T0SN", BitOpCode | 0, DecodeBitOp);
  1129.   AddInstTable(InstTable, "T1SN", BitOpCode | 1, DecodeBitOp);
  1130.   AddInstTable(InstTable, "SET0", BitOpCode | 2, DecodeBitOp);
  1131.   AddInstTable(InstTable, "SET1", BitOpCode | 3, DecodeBitOp);
  1132.   if (pCurrCPUProps->Core >= eCorePDK16)
  1133.   {
  1134.     AddInstTable(InstTable, "TOG", 0x14, DecodeBitOpIO);
  1135.     AddInstTable(InstTable, "WAIT0", 0x15, DecodeBitOpIO);
  1136.     AddInstTable(InstTable, "WAIT1", 0x16, DecodeBitOpIO);
  1137.   }
  1138.   if (SWAPCCode)
  1139.     AddInstTable(InstTable, "SWAPC", SWAPCCode, DecodeBitOpIO);
  1140.  
  1141.   if (pCurrCPUProps->InstCaps & eInstCapPMODE)
  1142.     AddInstTable(InstTable, "PMODE", 0x0040, DecodeConstU5);
  1143.   if (pCurrCPUProps->InstCaps & eInstCapPUSHW_POPW)
  1144.   {
  1145.     AddInstTable(InstTable, "POPWPC" , 0x0060, DecodeConstU4);
  1146.     AddInstTable(InstTable, "PUSHWPC", 0x0070, DecodeConstU4);
  1147.   }
  1148.  
  1149.   AddInstTable(InstTable, "BIT", 0, DecodeBIT);
  1150.   AddInstTable(InstTable, "DATA", 0, DecodeDATA_Padauk);
  1151.   AddInstTable(InstTable, "SFR", 0, DecodeSFR);
  1152.   AddInstTable(InstTable, "RES", 0, DecodeRES);
  1153. }
  1154.  
  1155. static void DeinitFields(void)
  1156. {
  1157.   DestroyInstTable(InstTable);
  1158. }
  1159.  
  1160. /*---------------------------------------------------------------------------*/
  1161.  
  1162. static void MakeCode_Padauk(void)
  1163. {
  1164.   CodeLen = 0;
  1165.   DontPrint = False;
  1166.   OpSize = eSymbolSize8Bit;
  1167.  
  1168.   if (Memo("")) return;
  1169.  
  1170.   if (!LookupInstTable(InstTable, OpPart.str.p_str))
  1171.     WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
  1172. }
  1173.  
  1174. static Boolean IsDef_Padauk(void)
  1175. {
  1176.   return Memo("BIT")
  1177.       || Memo("SFR");
  1178. }
  1179.  
  1180. static void SwitchFrom_Padauk(void)
  1181. {
  1182.   DeinitFields();
  1183. }
  1184.  
  1185. static void SwitchTo_Padauk(void *pUser)
  1186. {
  1187.   static const char CommentLeadIn[] = { ';', '\0', '/', '/', '\0', '\0' };
  1188.  
  1189.   pCurrCPUProps = (const tCPUProps*)pUser;
  1190.  
  1191.   TurnWords = False;
  1192.   SetIntConstMode(eIntConstModeC);
  1193.  
  1194.   PCSymbol = "*";
  1195.   HeaderID = 0x3b;
  1196.   NOPCode = 0x0000;
  1197.   DivideChars = ",";
  1198.   pCommentLeadIn = CommentLeadIn;
  1199.   HasAttrs = False;
  1200.  
  1201.   ValidSegs = (1 << SegCode) | (1 << SegData) | (1 << SegIO);
  1202.   Grans[SegCode] = 2; ListGrans[SegCode] = 2; SegInits[SegCode] = 0;
  1203.   Grans[SegData] = 1; ListGrans[SegData] = 1; SegInits[SegData] = 0; SegLimits[SegData] = pCurrCPUProps->RAMEnd;
  1204.   Grans[SegIO  ] = 1; ListGrans[SegIO  ] = 1; SegInits[SegIO  ] = 0;  SegLimits[SegIO] = pCurrCPUProps->IOAreaEnd;
  1205.  
  1206.   SegLimits[SegCode] = ((LongWord)pCurrCPUProps->FlashEndD16) << 4 | 0xf;
  1207.   CodeAdrIntType = GetSmallestUIntType(SegLimits[SegCode]);
  1208.   CodeWordIntType = GetUIntTypeByBits(13 + (pCurrCPUProps->Core - eCorePDK13));
  1209.   DataAdrIntType = GetSmallestUIntType(SegLimits[SegData]);
  1210.   DataBitAdrIntType = (pCurrCPUProps->Core == eCorePDK13) ? UInt4 : DataAdrIntType;
  1211.   IOAdrIntType   = GetSmallestUIntType(SegLimits[SegIO  ]);
  1212.  
  1213. #if 0
  1214.   fprintf(stderr, "Data 0x%lx DataBit 0x%lx Code 0x%lx IO 0x%lx\n",
  1215.           IntTypeDefs[DataAdrIntType].Max,
  1216.           IntTypeDefs[DataBitAdrIntType].Max,
  1217.           IntTypeDefs[CodeAdrIntType].Max,
  1218.           IntTypeDefs[IOAdrIntType].Max);
  1219. #endif
  1220.  
  1221.   switch (pCurrCPUProps->Core)
  1222.   {
  1223.     case eCorePDK13:
  1224.       DataBitAdrIntType = UInt4;
  1225.       IOMemBits = 5;
  1226.       break;
  1227.     case eCorePDK14:
  1228.       DataBitAdrIntType = UInt6;
  1229.       IOMemBits = 6;
  1230.       break;
  1231.     case eCorePDK15:
  1232.       DataBitAdrIntType = UInt7;
  1233.       IOMemBits = 7;
  1234.       break;
  1235.     case eCorePDK16:
  1236.       DataBitAdrIntType = UInt9;
  1237.       IOMemBits = 6;
  1238.       break;
  1239.     default:
  1240.       break;
  1241.   }
  1242.   DataBitMemBits = Lo(IntTypeDefs[DataBitAdrIntType].SignAndWidth);
  1243.  
  1244.   DataMemBits = 6 + (pCurrCPUProps->Core - eCorePDK13);
  1245.   CodeMemBits = 10 + (pCurrCPUProps->Core - eCorePDK13);
  1246.  
  1247.   AccInstOffs = CoreMask((1 << eCorePDK14) | (1 << eCorePDK15)) ? 0x0060 : 0x0010;
  1248.  
  1249.   MakeCode = MakeCode_Padauk;
  1250.   IsDef = IsDef_Padauk;
  1251.   SwitchFrom = SwitchFrom_Padauk;
  1252.   DissectBit = DissectBit_Padauk;
  1253.   InitFields();
  1254. }
  1255.  
  1256. static const tCPUProps CPUProps[] =
  1257. {
  1258.   { "PMC150"  , 0x3f, 0x3f, 0x1f, eCorePDK13,                                                         eInstCapXOR_IOA                                                                            },
  1259.   { "PMS150"  , 0x3f, 0x3f, 0x1f, eCorePDK13,                                                         eInstCapXOR_IOA                                                                            },
  1260.   { "PFS154"  , 0x7f, 0x7f, 0x3f, eCorePDK14,                                                         eInstCapXOR_IOA                                                                            },
  1261.   { "PMC131"  , 0x5f, 0x57, 0x3f, eCorePDK14, eInstCapCOMP_AM_MA | eInstCapMUL | eInstCapNADD_AM_MA                                                                                              },
  1262.   { "PMS130"  , 0x5f, 0x57, 0x3f, eCorePDK14, eInstCapCOMP_AM_MA | eInstCapMUL | eInstCapNADD_AM_MA                                                                                              },
  1263.   { "PMS131"  , 0x5f, 0x57, 0x3f, eCorePDK14, eInstCapCOMP_AM_MA | eInstCapMUL | eInstCapNADD_AM_MA                                                                                              },
  1264.   { "PMS132"  , 0x7f, 0x7f, 0x3f, eCorePDK14, eInstCapCOMP_AM_MA | eInstCapMUL | eInstCapNADD_AM_MA | eInstCapXOR_IOA                                                                            },
  1265.   { "PMS132B" , 0x7f, 0x7f, 0x3f, eCorePDK14, eInstCapCOMP_AM_MA | eInstCapMUL | eInstCapNADD_AM_MA | eInstCapXOR_IOA                                                                            },
  1266.   { "PMS152"  , 0x4f, 0x4f, 0x3f, eCorePDK14, eInstCapCOMP_AM_MA               | eInstCapNADD_AM_MA | eInstCapXOR_IOA                                                                            },
  1267.   { "PMS154B" , 0x7f, 0x7f, 0x3f, eCorePDK14, eInstCapCOMP_AM_MA               | eInstCapNADD_AM_MA | eInstCapXOR_IOA                                                                            },
  1268.   { "PMS154C" , 0x7f, 0x7f, 0x3f, eCorePDK14, eInstCapCOMP_AM_MA               | eInstCapNADD_AM_MA | eInstCapXOR_IOA                                                                            },
  1269.   { "PFS173"  , 0xbf, 0xff, 0x7f, eCorePDK15, eInstCapCOMP_AM_MA               | eInstCapNADD_AM_MA                                                                                              },
  1270.   { "PMS133"  , 0xbf, 0xff, 0x7f, eCorePDK15, eInstCapCOMP_AM_MA | eInstCapMUL | eInstCapNADD_AM_MA | eInstCapXOR_IOA | eInstCapNMOV_AM_MA | eInstCap_SWAPM                                      },
  1271.   { "PMS134"  , 0xff, 0xff, 0x7f, eCorePDK15, eInstCapCOMP_AM_MA | eInstCapMUL | eInstCapNADD_AM_MA | eInstCapXOR_IOA | eInstCapNMOV_AM_MA | eInstCap_SWAPM                                      },
  1272.   { "DF69"    , 0xff, 0xcf, 0x3f, eCorePDK16, eInstCapCOMP_AM_MA | eInstCapMUL | eInstCapNADD_AM_MA | eInstCapXOR_IOA | eInstCapNMOV_AM_MA | eInstCap_SWAPM | eInstCapPUSHW_POPW | eInstCapPMODE },
  1273.   { "MCS11"   , 0xff, 0xcf, 0x3f, eCorePDK16, eInstCapCOMP_AM_MA | eInstCapMUL | eInstCapNADD_AM_MA | eInstCapXOR_IOA | eInstCapNMOV_AM_MA | eInstCap_SWAPM | eInstCapPUSHW_POPW | eInstCapPMODE },
  1274.   { "PMC232"  , 0x7f, 0x9f, 0x3f, eCorePDK16, eInstCapCOMP_AM_MA               | eInstCapNADD_AM_MA | eInstCapXOR_IOA | eInstCapNMOV_AM_MA | eInstCap_SWAPM                                      },
  1275.   { "PMC234"  , 0xff, 0xcf, 0x3f, eCorePDK16, eInstCapCOMP_AM_MA               | eInstCapNADD_AM_MA | eInstCapXOR_IOA | eInstCapNMOV_AM_MA | eInstCap_SWAPM                                      },
  1276.   { "PMC251"  , 0x3f, 0x3f, 0x3f, eCorePDK16, eInstCapCOMP_AM_MA               | eInstCapNADD_AM_MA | eInstCapXOR_IOA | eInstCapNMOV_AM_MA | eInstCap_SWAPM                                      },
  1277.   { "PMC271"  , 0x3f, 0x3f, 0x3f, eCorePDK16, eInstCapCOMP_AM_MA               | eInstCapNADD_AM_MA | eInstCapXOR_IOA | eInstCapNMOV_AM_MA | eInstCap_SWAPM                                      },
  1278.   { "PMC884"  , 0xff, 0xff, 0x3f, eCorePDK16, eInstCapCOMP_AM_MA | eInstCapMUL | eInstCapNADD_AM_MA | eInstCapXOR_IOA | eInstCapNMOV_AM_MA | eInstCap_SWAPM | eInstCapPUSHW_POPW | eInstCapPMODE },
  1279.   { "PMS232"  , 0x7f, 0x9f, 0x3f, eCorePDK16, eInstCapCOMP_AM_MA               | eInstCapNADD_AM_MA | eInstCapXOR_IOA | eInstCapNMOV_AM_MA | eInstCap_SWAPM                                      },
  1280.   { "PMS234"  , 0xff, 0xcf, 0x3f, eCorePDK16, eInstCapCOMP_AM_MA               | eInstCapNADD_AM_MA | eInstCapXOR_IOA | eInstCapNMOV_AM_MA | eInstCap_SWAPM                                      },
  1281.   { "PMS271"  , 0x3f, 0x3f, 0x3f, eCorePDK16, eInstCapCOMP_AM_MA               | eInstCapNADD_AM_MA | eInstCapXOR_IOA | eInstCapNMOV_AM_MA | eInstCap_SWAPM                                      },
  1282.   { NULL      , 0x00, 0x00, 0x00, eCoreNone , 0 }
  1283. };
  1284.  
  1285. void codepdk_init(void)
  1286. {
  1287.   const tCPUProps *pProp;
  1288.  
  1289.   for (pProp = CPUProps; pProp->pName; pProp++)
  1290.     (void)AddCPUUser(pProp->pName, SwitchTo_Padauk, (void*)pProp, NULL);
  1291. }
  1292.