Subversion Repositories pentevo

Rev

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

  1. /* codeavr.c */
  2. /*****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
  4. /*                                                                           */
  5. /* AS-Portierung                                                             */
  6. /*                                                                           */
  7. /* Codegenerator Atmel AVR                                                   */
  8. /*                                                                           */
  9. /*****************************************************************************/
  10.  
  11. #include "stdinc.h"
  12.  
  13. #include <ctype.h>
  14. #include <string.h>
  15.  
  16. #include "bpemu.h"
  17. #include "nls.h"
  18. #include "strutil.h"
  19. #include "asmdef.h"
  20. #include "asmsub.h"
  21. #include "asmpars.h"
  22. #include "asmallg.h"
  23. #include "onoff_common.h"
  24. #include "asmitree.h"
  25. #include "asmcode.h"
  26. #include "codepseudo.h"
  27. #include "intpseudo.h"
  28. #include "codevars.h"
  29. #include "errmsg.h"
  30. #include "onoff_common.h"
  31. #include "chartrans.h"
  32.  
  33. #include "codeavr.h"
  34.  
  35. #define RegBankSize 32
  36. #define IOAreaStdSize 64
  37. #define IOAreaExtSize (IOAreaStdSize + 160)
  38. #define IOAreaExt2Size (IOAreaExtSize + 256)
  39.  
  40. #define BitFlag_Data 0x800000ul
  41. #define BitFlag_IO 0x400000ul
  42.  
  43. typedef enum
  44. {
  45.   eCoreNone,
  46.   eCoreMinTiny,
  47.   eCore90S1200,
  48.   eCoreClassic, /* AT90Sxxxx */
  49.   eCoreTiny, /* ATtiny up to 8KB flash */
  50.   eCoreTiny16K,
  51.   eCoreMega
  52. } tCPUCore;
  53.  
  54. #define MinCoreMask(c) ((Word)(0xffffu << (c)))
  55.  
  56. typedef struct
  57. {
  58.   Word Code;
  59.   Word CoreMask;
  60. } FixedOrder;
  61.  
  62. /* Data types are a bit squeezed to make struct fit into fewer bytes:
  63.    lower four bits of FlashEnd are always 0xf and are not stored: */
  64.  
  65. typedef struct
  66. {
  67.   const char *pName;
  68.   Word FlashEndD16, RAMSize, EESize, IOAreaSize;
  69.   Boolean RegistersMapped;
  70.   Byte Core;
  71. } tCPUProps;
  72.  
  73. static FixedOrder *FixedOrders, *Reg1Orders, *Reg2Orders;
  74.  
  75. static Boolean WrapFlag;
  76. static LongInt ORMask, SignMask, CodeSegSize;
  77. static const tCPUProps *pCurrCPUProps;
  78.  
  79. static IntType CodeAdrIntType,
  80.                DataAdrIntType;
  81.  
  82. static const char WrapFlagName[] = "WRAPMODE";
  83.  
  84. /*---------------------------------------------------------------------------*/
  85.  
  86. static LongInt CutAdr(LongInt Adr)
  87. {
  88.   if ((Adr & SignMask) != 0)
  89.     return (Adr | ORMask);
  90.   else
  91.     return (Adr & SegLimits[SegCode]);
  92. }
  93.  
  94. static Boolean ChkMinCore(tCPUCore MinCore)
  95. {
  96.   if (pCurrCPUProps->Core < MinCore)
  97.   {
  98.     WrError(ErrNum_InstructionNotSupported);
  99.     return False;
  100.   }
  101.   return True;
  102. }
  103.  
  104. static Boolean ChkCoreMask(Word CoreMask)
  105. {
  106.   if ((1 << pCurrCPUProps->Core) & CoreMask)
  107.     return True;
  108.   WrError(ErrNum_InstructionNotSupported);
  109.   return False;
  110. }
  111.  
  112. static void DissectBit_AVR(char *pDest, size_t DestSize, LargeWord Inp)
  113. {
  114.   LongWord BitSpec = Inp;
  115.  
  116.   as_snprintf(pDest, DestSize, "0x%0*x(%c).%d",
  117.               (BitSpec & BitFlag_IO) ? 2 : 3,
  118.               (unsigned)((BitSpec >> 3) & 0xffff),
  119.               (BitSpec & BitFlag_Data) ? SegShorts[SegData]
  120.                                    : ((BitSpec & BitFlag_IO) ? SegShorts[SegIO] : SegShorts[SegNone]),
  121.               (int)(BitSpec & 7));
  122. }
  123.  
  124. /*---------------------------------------------------------------------------*/
  125. /* Argument Decoders                                                         */
  126.  
  127. /*!------------------------------------------------------------------------
  128.  * \fn     DecodeRegCore(const char *pArg, Word *pResult)
  129.  * \brief  check wether argument is CPU register
  130.  * \param  pArg source code argument
  131.  * \param  pResult register # if it's a register
  132.  * \return True if it's a register
  133.  * ------------------------------------------------------------------------ */
  134.  
  135. static Boolean DecodeRegCore(const char *pArg, Word *pResult)
  136. {
  137.   Boolean OK;
  138.   int l = strlen(pArg);
  139.  
  140.   if ((l < 2) || (l > 3) || (as_toupper(*pArg) != 'R'))
  141.     return False;
  142.  
  143.   *pResult = ConstLongInt(pArg + 1, &OK, 10);
  144.   return (OK
  145.        && ((*pResult >= 16) || (pCurrCPUProps->Core != eCoreMinTiny))
  146.        && (*pResult < 32));
  147. }
  148.  
  149. /*!------------------------------------------------------------------------
  150.  * \fn     DissectReg_AVR(char *pDest, size_t DestSize, tRegInt Value, tSymbolSize InpSize)
  151.  * \brief  dissect register symbols - AVR variant
  152.  * \param  pDest destination buffer
  153.  * \param  DestSize destination buffer size
  154.  * \param  Value numeric register value
  155.  * \param  InpSize register size
  156.  * ------------------------------------------------------------------------ */
  157.  
  158. static void DissectReg_AVR(char *pDest, size_t DestSize, tRegInt Value, tSymbolSize InpSize)
  159. {
  160.   switch (InpSize)
  161.   {
  162.     case eSymbolSize8Bit:
  163.       as_snprintf(pDest, DestSize, "R%u", (unsigned)Value);
  164.       break;
  165.     default:
  166.       as_snprintf(pDest, DestSize, "%d-%u", (int)InpSize, (unsigned)Value);
  167.   }
  168. }
  169.  
  170. /*!------------------------------------------------------------------------
  171.  * \fn     DecodeReg(const tStrComp *pArg, Word *pResult)
  172.  * \brief  check wether argument is CPU register, including register aliases
  173.  * \param  pArg source code argument
  174.  * \param  pResult register # if it's a register
  175.  * \return True if it's a register
  176.  * ------------------------------------------------------------------------ */
  177.  
  178. static Boolean DecodeReg(const tStrComp *pArg, Word *pResult)
  179. {
  180.   tRegDescr RegDescr;
  181.   tEvalResult EvalResult;
  182.   tRegEvalResult RegEvalResult;
  183.  
  184.   if (DecodeRegCore(pArg->str.p_str, pResult))
  185.     return True;
  186.  
  187.   RegEvalResult = EvalStrRegExpressionAsOperand(pArg, &RegDescr, &EvalResult, eSymbolSize8Bit, True);
  188.   *pResult = RegDescr.Reg;
  189.   return (RegEvalResult == eIsReg);
  190. }
  191.  
  192. static Boolean DecodeMem(char * Asc, Word *Erg)
  193. {
  194.   if (as_strcasecmp(Asc, "X") == 0) *Erg = 0x1c;
  195.   else if (as_strcasecmp(Asc, "X+") == 0) *Erg = 0x1d;
  196.   else if (as_strcasecmp(Asc, "-X") == 0) *Erg = 0x1e;
  197.   else if (as_strcasecmp(Asc, "Y" ) == 0) *Erg = 0x08;
  198.   else if (as_strcasecmp(Asc, "Y+") == 0) *Erg = 0x19;
  199.   else if (as_strcasecmp(Asc, "-Y") == 0) *Erg = 0x1a;
  200.   else if (as_strcasecmp(Asc, "Z" ) == 0) *Erg = 0x00;
  201.   else if (as_strcasecmp(Asc, "Z+") == 0) *Erg = 0x11;
  202.   else if (as_strcasecmp(Asc, "-Z") == 0) *Erg = 0x12;
  203.   else return False;
  204.   return True;
  205. }
  206.  
  207. static Boolean DecodeBitArg2(const tStrComp *pRegArg, const tStrComp *pBitArg, LongWord *pResult)
  208. {
  209.   tEvalResult EvalResult;
  210.   LongWord Addr;
  211.  
  212.   *pResult = EvalStrIntExpressionWithResult(pBitArg, UInt3, &EvalResult);
  213.   if (!EvalResult.OK)
  214.     return False;
  215.  
  216.   Addr = EvalStrIntExpressionWithResult(pRegArg, DataAdrIntType, &EvalResult);
  217.   if (!EvalResult.OK)
  218.     return False;
  219.  
  220.   if (EvalResult.AddrSpaceMask & (1 << SegIO))
  221.   {
  222.     if (!mFirstPassUnknown(EvalResult.Flags) && !ChkRange(Addr, 0, IOAreaStdSize - 1))
  223.       return False;
  224.     *pResult |= BitFlag_IO | (Addr & 0x3f) << 3;
  225.     return True;
  226.   }
  227.   else
  228.   {
  229.     ChkSpace(SegData, EvalResult.AddrSpaceMask);
  230.  
  231.     if (!mFirstPassUnknown(EvalResult.Flags) && !ChkRange(Addr, 0, SegLimits[SegData]))
  232.       return False;
  233.     *pResult |= ((EvalResult.AddrSpaceMask & (1 << SegData)) ? BitFlag_Data : 0) | (Addr & 0x1ff) << 3;
  234.     return True;
  235.   }
  236. }
  237.  
  238. static Boolean DecodeBitArg(int Start, int Stop, LongWord *pResult)
  239. {
  240.   if (Start == Stop)
  241.   {
  242.     char *pPos = QuotPos(ArgStr[Start].str.p_str, '.');
  243.     tEvalResult EvalResult;
  244.  
  245.     if (pPos)
  246.     {
  247.       tStrComp RegArg, BitArg;
  248.  
  249.       StrCompSplitRef(&RegArg, &BitArg, &ArgStr[Start], pPos);
  250.       return DecodeBitArg2(&RegArg, &BitArg, pResult);
  251.     }
  252.     *pResult = EvalStrIntExpressionWithResult(&ArgStr[Start], UInt16, &EvalResult);
  253.     if (EvalResult.OK)
  254.       ChkSpace(SegBData, EvalResult.AddrSpaceMask);
  255.     return EvalResult.OK;
  256.   }
  257.   else if (Stop == Start + 1)
  258.     return DecodeBitArg2(&ArgStr[Start], &ArgStr[Stop], pResult);
  259.   else
  260.   {
  261.     WrError(ErrNum_WrongArgCnt);
  262.     return False;
  263.   }
  264. }
  265.  
  266. static const LongWord
  267.        AllRegMask = 0xfffffffful,
  268.        UpperHalfRegMask = 0xffff0000ul,
  269.        Reg16_23Mask = 0x00ff0000ul,
  270.        EvenRegMask = 0x55555555ul,
  271.        UpperEightEvenRegMask = 0x55000000ul;
  272.  
  273. static Boolean DecodeArgReg(unsigned ArgIndex, Word *pReg, LongWord RegMask)
  274. {
  275.   Boolean Result;
  276.  
  277.   Result = DecodeReg(&ArgStr[ArgIndex], pReg);
  278.   if (Result && !((RegMask >> *pReg) & 1))
  279.   {
  280.     WrStrErrorPos(ErrNum_InvReg, &ArgStr[ArgIndex]);
  281.     return False;
  282.   }
  283.   return Result;
  284. }
  285.  
  286. /*!------------------------------------------------------------------------
  287.  * \fn     GetWordCodeAddress(tStrComp *pArg, tEvalResult *EvalResult)
  288.  * \brief  decode argument as code address and divide by two if in byte mode
  289.  * \param  pArg address argument
  290.  * \param  pEvalResult returns OK/failure
  291.  * \return (word) address
  292.  * ------------------------------------------------------------------------ */
  293.  
  294. static LongInt GetWordCodeAddress(tStrComp *pArg, tEvalResult *pEvalResult)
  295. {
  296.   LongInt Result;
  297.  
  298.   Result = EvalStrIntExpressionWithResult(pArg, CodeAdrIntType, pEvalResult);
  299.   if (pEvalResult->OK)
  300.   {
  301.     ChkSpace(SegCode, pEvalResult->AddrSpaceMask);
  302.     if (!CodeSegSize)
  303.     {
  304.       if (mFirstPassUnknown(pEvalResult->Flags))
  305.         Result &= ~1ul;
  306.       if (Result & 1)
  307.       {
  308.         WrStrErrorPos(ErrNum_NotAligned, pArg);
  309.         pEvalResult->OK = False;
  310.       }
  311.       else
  312.         Result >>= 1;
  313.     }
  314.   }
  315.   return Result;
  316. }
  317.  
  318. /*!------------------------------------------------------------------------
  319.  * \fn     GetNextCodeAddress(void)
  320.  * \brief  retrieve (word) address of next instruction
  321.  * \return (word) address
  322.  * ------------------------------------------------------------------------ */
  323.  
  324. static LongInt GetNextCodeAddress(void)
  325. {
  326.   LongInt Result = EProgCounter();
  327.  
  328.   if (!CodeSegSize)
  329.     Result >>= 1;
  330.   return Result + 1;
  331. }
  332.  
  333. /*---------------------------------------------------------------------------*/
  334. /* Individual Decoders                                                       */
  335.  
  336. /* Pseudo Instructions */
  337.  
  338. static void DecodePORT(Word Index)
  339. {
  340.   UNUSED(Index);
  341.  
  342.   CodeEquate(SegIO, 0, 0x3f);
  343. }
  344.  
  345. static void DecodeSFR(Word Index)
  346. {
  347.   LargeWord Start = (pCurrCPUProps->RegistersMapped ? RegBankSize : 0);
  348.   UNUSED(Index);
  349.  
  350.   CodeEquate(SegData, Start, Start + pCurrCPUProps->IOAreaSize);
  351. }
  352.  
  353. static void AppendCode(Word Code)
  354. {
  355.   if (CodeSegSize)
  356.     WAsmCode[CodeLen++] = Code;
  357.   else
  358.   {
  359.     BAsmCode[CodeLen++] = Lo(Code);
  360.     BAsmCode[CodeLen++] = Hi(Code);
  361.   }
  362. }
  363.  
  364. /* No Argument */
  365.  
  366. static void DecodeFixed(Word Index)
  367. {
  368.   const FixedOrder *pOrder = FixedOrders + Index;
  369.  
  370.   if (ChkArgCnt(0, 0) && ChkCoreMask(pOrder->CoreMask))
  371.     AppendCode(pOrder->Code);
  372. }
  373.  
  374. static void DecodeRES(Word Index)
  375. {
  376.   Boolean OK;
  377.   Integer Size;
  378.   tSymbolFlags Flags;
  379.  
  380.   UNUSED(Index);
  381.  
  382.   Size = EvalStrIntExpressionWithFlags(&ArgStr[1], Int16, &OK, &Flags);
  383.   if (mFirstPassUnknown(Flags)) WrError(ErrNum_FirstPassCalc);
  384.   if (OK && !mFirstPassUnknown(Flags))
  385.   {
  386.     DontPrint = True;
  387.     if (!Size) WrError(ErrNum_NullResMem);
  388.     CodeLen = Size;
  389.     BookKeeping();
  390.   }
  391. }
  392.  
  393. static Word WordAcc;
  394. static Boolean WordAccFull;
  395.  
  396. static void PlaceValue(Word Value, Boolean IsByte)
  397. {
  398.   if (ActPC != SegCode)
  399.   {
  400.     BAsmCode[CodeLen++] = Value;
  401.     WordAccFull = False;
  402.   }
  403.   else if (IsByte)
  404.   {
  405.     if (CodeSegSize)
  406.     {
  407.       Value &= 0xff;
  408.       if (WordAccFull)
  409.         AppendCode(WordAcc |= (Value << 8));
  410.       else
  411.         WordAcc = Value;
  412.       WordAccFull = !WordAccFull;
  413.     }
  414.     else
  415.     {
  416.       BAsmCode[CodeLen++] = Value;
  417.       WordAccFull = False;
  418.     }
  419.   }
  420.   else
  421.   {
  422.     if (CodeSegSize)
  423.       AppendCode(Value);
  424.     else
  425.     {
  426.       BAsmCode[CodeLen++] = Lo(Value);
  427.       BAsmCode[CodeLen++] = Hi(Value);
  428.     }
  429.     WordAccFull = False;
  430.   }
  431. }
  432.  
  433. static void DecodeDATA_AVR(Word Index)
  434. {
  435.   Integer Trans;
  436.   TempResult t;
  437.   LongInt MinV, MaxV;
  438.  
  439.   UNUSED(Index);
  440.  
  441.   as_tempres_ini(&t);
  442.   MaxV = ((ActPC == SegCode) && !Packing) ? 65535 : 255;
  443.   MinV = (-((MaxV + 1) >> 1));
  444.   WordAccFull = FALSE;
  445.   if (ChkArgCnt(1, ArgCntMax))
  446.   {
  447.     Boolean OK = True;
  448.     const tStrComp *pArg;
  449.  
  450.     forallargs(pArg, OK)
  451.     {
  452.       EvalStrExpression(pArg, &t);
  453.       if (mFirstPassUnknown(t.Flags) && (t.Typ == TempInt)) t.Contents.Int &= MaxV;
  454.       switch (t.Typ)
  455.       {
  456.         case TempString:
  457.         {
  458.           int z2;
  459.  
  460.           if (MultiCharToInt(&t, 2))
  461.             goto ToInt;
  462.  
  463.           if (as_chartrans_xlate_nonz_dynstr(CurrTransTable->p_table, &t.Contents.str, pArg))
  464.             OK = False;
  465.           else
  466.             for (z2 = 0; z2 < (int)t.Contents.str.len; z2++)
  467.             {
  468.               Trans = ((usint) t.Contents.str.p_str[z2]) & 0xff;
  469.               PlaceValue(Trans, True);
  470.             }
  471.           break;
  472.         }
  473.         ToInt:
  474.         case TempInt:
  475.           if (ChkRange(t.Contents.Int, MinV, MaxV))
  476.             PlaceValue(t.Contents.Int, Packing);
  477.           break;
  478.         case TempFloat:
  479.           WrStrErrorPos(ErrNum_StringOrIntButFloat, pArg);
  480.           /* fall-through */
  481.         default:
  482.           OK = False;
  483.       }
  484.     }
  485.     if (!OK)
  486.       CodeLen = 0;
  487.     else if (WordAccFull)
  488.     {
  489.       WrError(ErrNum_PaddingAdded);
  490.       AppendCode(WordAcc);
  491.     }
  492.   }
  493.   as_tempres_free(&t);
  494. }
  495.  
  496. /* one register 0..31 */
  497.  
  498. static void DecodeReg1(Word Index)
  499. {
  500.   const FixedOrder *pOrder = Reg1Orders + Index;
  501.   Word Reg;
  502.  
  503.   if (ChkArgCnt(1, 1)
  504.    && ChkCoreMask(pOrder->CoreMask)
  505.    && DecodeArgReg(1, &Reg, AllRegMask))
  506.     AppendCode(pOrder->Code | (Reg << 4));
  507. }
  508.  
  509. /* two registers 0..31 */
  510.  
  511. static void DecodeReg2(Word Index)
  512. {
  513.   const FixedOrder *pOrder = Reg2Orders + Index;
  514.   Word Reg1, Reg2;
  515.  
  516.   if (ChkArgCnt(2, 2)
  517.    && ChkCoreMask(pOrder->CoreMask)
  518.    && DecodeArgReg(1, &Reg1, AllRegMask)
  519.    && DecodeArgReg(2, &Reg2, AllRegMask))
  520.     AppendCode(pOrder->Code | (Reg2 & 15) | (Reg1 << 4) | ((Reg2 & 16) << 5));
  521. }
  522.  
  523. /* one register 0..31 with itself */
  524.  
  525. static void DecodeReg3(Word Code)
  526. {
  527.   Word Reg;
  528.  
  529.   if (ChkArgCnt(1, 1) && DecodeArgReg(1, &Reg, AllRegMask))
  530.     AppendCode(Code | (Reg & 15) | (Reg << 4) | ((Reg & 16) << 5));
  531. }
  532.  
  533. /* immediate with register */
  534.  
  535. static void DecodeImm(Word Code)
  536. {
  537.   Word Reg, Const;
  538.   Boolean OK;
  539.  
  540.   if (ChkArgCnt(2, 2) && DecodeArgReg(1, &Reg, UpperHalfRegMask))
  541.   {
  542.     Const = EvalStrIntExpression(&ArgStr[2], Int8, &OK);
  543.     if (OK)
  544.       AppendCode(Code | ((Const & 0xf0) << 4) | (Const & 0x0f) | ((Reg & 0x0f) << 4));
  545.   }
  546. }
  547.  
  548. static void DecodeADIW(Word Index)
  549. {
  550.   Word Reg, Const;
  551.   Boolean OK;
  552.  
  553.   if (ChkArgCnt(2, 2)
  554.    && ChkMinCore(eCoreClassic)
  555.    && DecodeArgReg(1, &Reg, UpperEightEvenRegMask))
  556.   {
  557.     Const = EvalStrIntExpression(&ArgStr[2], UInt6, &OK);
  558.     if (OK)
  559.       AppendCode(0x9600 | Index | ((Reg & 6) << 3) | (Const & 15) | ((Const & 0x30) << 2));
  560.   }
  561. }
  562.  
  563. /* transfer operations */
  564.  
  565. static void DecodeLDST(Word Index)
  566. {
  567.   int RegI, MemI;
  568.   Word Reg, Mem;
  569.  
  570.   if (ChkArgCnt(2, 2))
  571.   {
  572.     RegI = Index ? 2 : 1; /* ST */
  573.     MemI = 3 - RegI;
  574.     if (!DecodeArgReg(RegI, &Reg, AllRegMask));
  575.     else if (!DecodeMem(ArgStr[MemI].str.p_str, &Mem)) WrError(ErrNum_InvAddrMode);
  576.     else if ((pCurrCPUProps->Core == eCore90S1200) && (Mem != 0)) WrError(ErrNum_AddrMustBeAligned);
  577.     else
  578.     {
  579.       AppendCode(0x8000 | Index | (Reg << 4) | (Mem & 0x0f) | ((Mem & 0x10) << 8));
  580.       if (((Mem >= 0x1d) && (Mem <= 0x1e) && (Reg >= 26) && (Reg <= 27))  /* X+/-X with X */
  581.        || ((Mem >= 0x19) && (Mem <= 0x1a) && (Reg >= 28) && (Reg <= 29))  /* Y+/-Y with Y */
  582.        || ((Mem >= 0x11) && (Mem <= 0x12) && (Reg >= 30) && (Reg <= 31))) /* Z+/-Z with Z */
  583.         WrError(ErrNum_Unpredictable);
  584.     }
  585.   }
  586. }
  587.  
  588. static void DecodeLDDSTD(Word Index)
  589. {
  590.   int RegI, MemI;
  591.   Word Reg, Disp;
  592.   Boolean OK;
  593.  
  594.   if (ChkArgCnt(2, 2)
  595.    && ChkMinCore(eCoreClassic))
  596.   {
  597.     char RegChar;
  598.  
  599.     RegI = Index ? 2 : 1; /* STD */
  600.     MemI = 3 - RegI;
  601.     RegChar = *ArgStr[MemI].str.p_str;
  602.     OK = True;
  603.     if (as_toupper(RegChar) == 'Y') Index += 8;
  604.     else if (as_toupper(RegChar) == 'Z');
  605.     else OK = False;
  606.     if (!OK) WrError(ErrNum_InvAddrMode);
  607.     else if (DecodeArgReg(RegI, &Reg, AllRegMask))
  608.     {
  609.       *ArgStr[MemI].str.p_str = '0';
  610.       Disp = EvalStrIntExpression(&ArgStr[MemI], UInt6, &OK);
  611.       *ArgStr[MemI].str.p_str = RegChar;
  612.       if (OK)
  613.         AppendCode(0x8000 | Index | (Reg << 4) | (Disp & 7) | ((Disp & 0x18) << 7) | ((Disp & 0x20) << 8));
  614.     }
  615.   }
  616. }
  617.  
  618. static void DecodeINOUT(Word Index)
  619. {
  620.   int RegI, MemI;
  621.   Word Reg, Mem;
  622.  
  623.   if (ChkArgCnt(2, 2))
  624.   {
  625.     RegI = Index ? 2 : 1; /* OUT */
  626.     MemI = 3 - RegI;
  627.     if (DecodeArgReg(RegI, &Reg, AllRegMask))
  628.     {
  629.       tEvalResult EvalResult;
  630.  
  631.       Mem = EvalStrIntExpressionWithResult(&ArgStr[MemI], UInt6, &EvalResult);
  632.       if (EvalResult.OK)
  633.       {
  634.         ChkSpace(SegIO, EvalResult.AddrSpaceMask);
  635.         AppendCode(0xb000 | Index | (Reg << 4) | (Mem & 0x0f) | ((Mem & 0xf0) << 5));
  636.       }
  637.     }
  638.   }
  639. }
  640.  
  641. static void DecodeLDSSTS(Word Index)
  642. {
  643.   int RegI, MemI;
  644.   Word Reg;
  645.  
  646.   if (ChkArgCnt(2, 2)
  647.    && ChkCoreMask(MinCoreMask(eCoreClassic) | (1 << eCoreMinTiny)))
  648.   {
  649.     RegI = Index ? 2 : 1; /* STS */
  650.     MemI = 3 - RegI;
  651.     if (DecodeArgReg(RegI, &Reg, AllRegMask))
  652.     {
  653.       tEvalResult EvalResult;
  654.       Word Address = EvalStrIntExpressionWithResult(&ArgStr[MemI], UInt16, &EvalResult);
  655.       if (EvalResult.OK)
  656.       {
  657.         ChkSpace(SegData, EvalResult.AddrSpaceMask);
  658.         AppendCode(0x9000 | Index | (Reg << 4));
  659.         AppendCode(Address);
  660.       }
  661.     }
  662.   }
  663. }
  664.  
  665. /* bit operations */
  666.  
  667. static void DecodeBCLRSET(Word Index)
  668. {
  669.   Word Bit;
  670.   Boolean OK;
  671.  
  672.   if (ChkArgCnt(1, 1))
  673.   {
  674.     Bit = EvalStrIntExpression(&ArgStr[1], UInt3, &OK);
  675.     if (OK)
  676.       AppendCode(0x9408 | (Bit << 4) | Index);
  677.   }
  678. }
  679.  
  680. static void DecodeBit(Word Code)
  681. {
  682.   Word Reg, Bit;
  683.   Boolean OK;
  684.  
  685.   if (!ChkArgCnt(2, 2));
  686.   else if (DecodeArgReg(1, &Reg, AllRegMask))
  687.   {
  688.     Bit = EvalStrIntExpression(&ArgStr[2], UInt3, &OK);
  689.     if (OK)
  690.       AppendCode(Code | (Reg << 4) | Bit);
  691.   }
  692. }
  693.  
  694. static void DecodeCBR(Word Index)
  695. {
  696.   Word Reg, Mask;
  697.   Boolean OK;
  698.  
  699.   UNUSED(Index);
  700.  
  701.   if (ChkArgCnt(2, 2) && DecodeArgReg(1, &Reg, UpperHalfRegMask))
  702.   {
  703.     Mask = EvalStrIntExpression(&ArgStr[2], Int8, &OK) ^ 0xff;
  704.     if (OK)
  705.       AppendCode(0x7000 | ((Mask & 0xf0) << 4) | (Mask & 0x0f) | ((Reg & 0x0f) << 4));
  706.   }
  707. }
  708.  
  709. static void DecodeSER(Word Index)
  710. {
  711.   Word Reg;
  712.  
  713.   UNUSED(Index);
  714.  
  715.   if (ChkArgCnt(1, 1) && DecodeArgReg(1, &Reg, UpperHalfRegMask))
  716.     AppendCode(0xef0f | ((Reg & 0x0f) << 4));
  717. }
  718.  
  719. static void DecodePBit(Word Code)
  720. {
  721.   LongWord BitSpec;
  722.  
  723.   if (DecodeBitArg(1, ArgCnt, &BitSpec))
  724.   {
  725.     Word Bit = BitSpec & 7,
  726.          Adr = (BitSpec >> 3) & 0xffff;
  727.  
  728.     if (BitSpec & BitFlag_Data) WrError(ErrNum_WrongSegment);
  729.     if (ChkRange(Adr, 0, 31))
  730.       AppendCode(Code | Bit | (Adr << 3));
  731.   }
  732. }
  733.  
  734. /* branches */
  735.  
  736. static void DecodeRel(Word Code)
  737. {
  738.   LongInt AdrInt;
  739.   tEvalResult EvalResult;
  740.  
  741.   if (ChkArgCnt(1, 1))
  742.   {
  743.     AdrInt = GetWordCodeAddress(&ArgStr[1], &EvalResult) - GetNextCodeAddress();
  744.     if (EvalResult.OK)
  745.     {
  746.       if (WrapFlag) AdrInt = CutAdr(AdrInt);
  747.       if (!mSymbolQuestionable(EvalResult.Flags) && ((AdrInt < -64) || (AdrInt > 63))) WrError(ErrNum_JmpDistTooBig);
  748.       else
  749.         AppendCode(Code | ((AdrInt & 0x7f) << 3));
  750.     }
  751.   }
  752. }
  753.  
  754. static void DecodeBRBSBC(Word Index)
  755. {
  756.   Word Bit;
  757.   LongInt AdrInt;
  758.   tEvalResult EvalResult;
  759.  
  760.   if (ChkArgCnt(2, 2))
  761.   {
  762.     Bit = EvalStrIntExpressionWithResult(&ArgStr[1], UInt3, &EvalResult);
  763.     if (EvalResult.OK)
  764.     {
  765.       AdrInt = GetWordCodeAddress(&ArgStr[2], &EvalResult) - GetNextCodeAddress();
  766.       if (EvalResult.OK)
  767.       {
  768.         if (WrapFlag) AdrInt = CutAdr(AdrInt);
  769.         if (!mSymbolQuestionable(EvalResult.Flags) && ((AdrInt < -64) || (AdrInt > 63))) WrError(ErrNum_JmpDistTooBig);
  770.         else
  771.           AppendCode(0xf000 | Index | ((AdrInt & 0x7f) << 3) | Bit);
  772.       }
  773.     }
  774.   }
  775. }
  776.  
  777. static void DecodeJMPCALL(Word Index)
  778. {
  779.   LongInt AdrInt;
  780.   tEvalResult EvalResult;
  781.  
  782.   if (ChkArgCnt(1, 1)
  783.    && ChkMinCore(eCoreTiny16K))
  784.   {
  785.     AdrInt = GetWordCodeAddress(&ArgStr[1], &EvalResult);
  786.     if (EvalResult.OK)
  787.     {
  788.       AppendCode(0x940c | Index | ((AdrInt & 0x3e0000) >> 13) | ((AdrInt & 0x10000) >> 16));
  789.       AppendCode(AdrInt & 0xffff);
  790.     }
  791.   }
  792. }
  793.  
  794. static void DecodeRJMPCALL(Word Index)
  795. {
  796.   LongInt AdrInt;
  797.   tEvalResult EvalResult;
  798.  
  799.   if (ChkArgCnt(1, 1))
  800.   {
  801.     AdrInt = GetWordCodeAddress(&ArgStr[1], &EvalResult) - GetNextCodeAddress();
  802.     if (EvalResult.OK)
  803.     {
  804.       if (WrapFlag) AdrInt = CutAdr(AdrInt);
  805.       if (!mSymbolQuestionable(EvalResult.Flags) && ((AdrInt < -2048) || (AdrInt > 2047))) WrError(ErrNum_JmpDistTooBig);
  806.       else
  807.         AppendCode(0xc000 | Index | (AdrInt & 0xfff));
  808.     }
  809.   }
  810. }
  811.  
  812. static void DecodeMULS(Word Index)
  813. {
  814.   Word Reg1, Reg2;
  815.  
  816.   UNUSED(Index);
  817.  
  818.   if (ChkArgCnt(2, 2)
  819.    && ChkMinCore(eCoreMega)
  820.    && DecodeArgReg(1, &Reg1, UpperHalfRegMask)
  821.    && DecodeArgReg(2, &Reg2, UpperHalfRegMask))
  822.     AppendCode(0x0200 | ((Reg1 & 15) << 4) | (Reg2 & 15));
  823. }
  824.  
  825. static void DecodeMegaMUL(Word Index)
  826. {
  827.   Word Reg1, Reg2;
  828.  
  829.   if (ChkArgCnt(2, 2)
  830.    && ChkMinCore(eCoreMega)
  831.    && DecodeArgReg(1, &Reg1, Reg16_23Mask)
  832.    && DecodeArgReg(2, &Reg2, Reg16_23Mask))
  833.     AppendCode(Index | ((Reg1 & 7) << 4) | (Reg2 & 7));
  834. }
  835.  
  836. static void DecodeMOVW(Word Index)
  837. {
  838.   Word Reg1, Reg2;
  839.  
  840.   UNUSED(Index);
  841.  
  842.   if (ChkArgCnt(2, 2)
  843.    && ChkMinCore(eCoreTiny)
  844.    && DecodeArgReg(1, &Reg1, EvenRegMask)
  845.    && DecodeArgReg(2, &Reg2, EvenRegMask))
  846.     AppendCode(0x0100 | ((Reg1 >> 1) << 4) | (Reg2 >> 1));
  847. }
  848.  
  849. static void DecodeLPM(Word Index)
  850. {
  851.   Word Reg, Adr;
  852.  
  853.   UNUSED(Index);
  854.  
  855.   if (!ArgCnt)
  856.   {
  857.     if (ChkMinCore(eCoreClassic))
  858.       AppendCode(0x95c8);
  859.   }
  860.   else if (ArgCnt == 2)
  861.   {
  862.     if (!ChkMinCore(eCoreTiny));
  863.     else if (!DecodeArgReg(1, &Reg, AllRegMask));
  864.     else if (!DecodeMem(ArgStr[2].str.p_str, &Adr)) WrError(ErrNum_InvAddrMode);
  865.     else if ((Adr != 0x00) && (Adr != 0x11)) WrError(ErrNum_InvAddrMode);
  866.     else
  867.     {
  868.       if (((Reg == 30) || (Reg == 31)) && (Adr == 0x11)) WrError(ErrNum_Unpredictable);
  869.       AppendCode(0x9004 | (Reg << 4) | (Adr & 1));
  870.     }
  871.   }
  872.   else
  873.     (void)ChkArgCnt(2, 2);
  874. }
  875.  
  876. static void DecodeELPM(Word Index)
  877. {
  878.   Word Reg, Adr;
  879.  
  880.   UNUSED(Index);
  881.  
  882.   if (!ChkMinCore(eCoreMega));
  883.   else if (!ArgCnt)
  884.     AppendCode(0x95d8);
  885.   else if (!ChkArgCnt(2, 2));
  886.   else if (!DecodeArgReg(1, &Reg, AllRegMask));
  887.   else if (!DecodeMem(ArgStr[2].str.p_str, &Adr)) WrError(ErrNum_InvAddrMode);
  888.   else if ((Adr != 0x00) && (Adr != 0x11)) WrError(ErrNum_InvAddrMode);
  889.   else
  890.   {
  891.     if (((Reg == 30) || (Reg == 31)) && (Adr == 0x11)) WrError(ErrNum_Unpredictable);
  892.     AppendCode(0x9006 | (Reg << 4) | (Adr & 1));
  893.   }
  894. }
  895.  
  896. static void DecodeBIT(Word Code)
  897. {
  898.   LongWord BitSpec;
  899.  
  900.   UNUSED(Code);
  901.  
  902.   if (DecodeBitArg(1, ArgCnt, &BitSpec))
  903.   {
  904.     *ListLine = '=';
  905.     DissectBit_AVR(ListLine + 1, STRINGSIZE - 3, BitSpec);
  906.     PushLocHandle(-1);
  907.     EnterIntSymbol(&LabPart, BitSpec, SegBData, False);
  908.     PopLocHandle();
  909.     if (MakeUseList)
  910.     {
  911.       if (AddChunk(SegChunks + SegBData, BitSpec, 1, False))
  912.         WrError(ErrNum_Overlap);
  913.     }
  914.   }
  915. }
  916.  
  917. /*!------------------------------------------------------------------------
  918.  * \fn     make_pc_even(Word index)
  919.  * \brief  assure PC is even before assembling machine instructions
  920.  * ------------------------------------------------------------------------ */
  921.  
  922. static void make_pc_even(Word index)
  923. {
  924.   UNUSED(index);
  925.  
  926.   /* All other instructions must be on an even address in byte mode.
  927.      In other words, they may not cross flash word boundaries: */
  928.  
  929.   if (!CodeSegSize && Odd(EProgCounter()))
  930.   {
  931.     if (DoPadding)
  932.       InsertPadding(1, False);
  933.     else
  934.       WrError(ErrNum_AddrNotAligned);
  935.   }
  936. }
  937.  
  938. /*---------------------------------------------------------------------------*/
  939. /* Dynamic Code Table Handling                                               */
  940.  
  941. static void AddFixed(const char *NName, Word NMin, Word NCode)
  942. {
  943.   order_array_rsv_end(FixedOrders, FixedOrder);
  944.   FixedOrders[InstrZ].Code = NCode;
  945.   FixedOrders[InstrZ].CoreMask = NMin;
  946.   AddInstTable(InstTable, NName, InstrZ++, DecodeFixed);
  947. }
  948.  
  949. static void AddReg1(const char *NName, Word NMin, Word NCode)
  950. {
  951.   order_array_rsv_end(Reg1Orders, FixedOrder);
  952.   Reg1Orders[InstrZ].Code = NCode;
  953.   Reg1Orders[InstrZ].CoreMask = NMin;
  954.   AddInstTable(InstTable, NName, InstrZ++, DecodeReg1);
  955. }
  956.  
  957. static void AddReg2(const char *NName, Word NMin, Word NCode)
  958. {
  959.   order_array_rsv_end(Reg2Orders, FixedOrder);
  960.   Reg2Orders[InstrZ].Code = NCode;
  961.   Reg2Orders[InstrZ].CoreMask = NMin;
  962.   AddInstTable(InstTable, NName, InstrZ++, DecodeReg2);
  963. }
  964.  
  965. static void AddReg3(const char *NName, Word NCode)
  966. {
  967.   AddInstTable(InstTable, NName, NCode, DecodeReg3);
  968. }
  969.  
  970. static void AddImm(const char *NName, Word NCode)
  971. {
  972.   AddInstTable(InstTable, NName, NCode, DecodeImm);
  973. }
  974.  
  975. static void AddRel(const char *NName, Word NCode)
  976. {
  977.   AddInstTable(InstTable, NName, NCode, DecodeRel);
  978. }
  979.  
  980. static void AddBit(const char *NName, Word NCode)
  981. {
  982.   AddInstTable(InstTable, NName, NCode, DecodeBit);
  983. }
  984.  
  985. static void AddPBit(const char *NName, Word NCode)
  986. {
  987.   AddInstTable(InstTable, NName, NCode, DecodePBit);
  988. }
  989.  
  990. static void InitFields(void)
  991. {
  992.   InstTable = CreateInstTable(203);
  993.  
  994.   add_null_pseudo(InstTable);
  995.  
  996.   inst_table_set_prefix_proc(InstTable, make_pc_even, 0);
  997.  
  998.   InstrZ = 0;
  999.   AddFixed("IJMP" , MinCoreMask(eCoreClassic) | (1 << eCoreMinTiny), 0x9409);
  1000.   AddFixed("ICALL", MinCoreMask(eCoreClassic) | (1 << eCoreMinTiny), 0x9509);
  1001.   AddFixed("RET"  , MinCoreMask(eCoreMinTiny), 0x9508); AddFixed("RETI"  , MinCoreMask(eCoreMinTiny), 0x9518);
  1002.   AddFixed("SEC"  , MinCoreMask(eCoreMinTiny), 0x9408);
  1003.   AddFixed("CLC"  , MinCoreMask(eCoreMinTiny), 0x9488); AddFixed("SEN"   , MinCoreMask(eCoreMinTiny), 0x9428);
  1004.   AddFixed("CLN"  , MinCoreMask(eCoreMinTiny), 0x94a8); AddFixed("SEZ"   , MinCoreMask(eCoreMinTiny), 0x9418);
  1005.   AddFixed("CLZ"  , MinCoreMask(eCoreMinTiny), 0x9498); AddFixed("SEI"   , MinCoreMask(eCoreMinTiny), 0x9478);
  1006.   AddFixed("CLI"  , MinCoreMask(eCoreMinTiny), 0x94f8); AddFixed("SES"   , MinCoreMask(eCoreMinTiny), 0x9448);
  1007.   AddFixed("CLS"  , MinCoreMask(eCoreMinTiny), 0x94c8); AddFixed("SEV"   , MinCoreMask(eCoreMinTiny), 0x9438);
  1008.   AddFixed("CLV"  , MinCoreMask(eCoreMinTiny), 0x94b8); AddFixed("SET"   , MinCoreMask(eCoreMinTiny), 0x9468);
  1009.   AddFixed("CLT"  , MinCoreMask(eCoreMinTiny), 0x94e8); AddFixed("SEH"   , MinCoreMask(eCoreMinTiny), 0x9458);
  1010.   AddFixed("CLH"  , MinCoreMask(eCoreMinTiny), 0x94d8); AddFixed("NOP"   , MinCoreMask(eCoreMinTiny), 0x0000);
  1011.   AddFixed("SLEEP", MinCoreMask(eCoreMinTiny), 0x9588); AddFixed("WDR"   , MinCoreMask(eCoreMinTiny), 0x95a8);
  1012.   AddFixed("EIJMP", MinCoreMask(eCoreMega   ), 0x9419); AddFixed("EICALL", MinCoreMask(eCoreMega   ), 0x9519);
  1013.   AddFixed("SPM"  , MinCoreMask(eCoreTiny   ), 0x95e8);
  1014.   AddFixed("BREAK" , MinCoreMask(eCoreTiny   ) | (1 << eCoreMinTiny), 0x9598);
  1015.  
  1016.   InstrZ = 0;
  1017.   AddReg1("COM"  , MinCoreMask(eCoreMinTiny), 0x9400); AddReg1("NEG"  , MinCoreMask(eCoreMinTiny), 0x9401);
  1018.   AddReg1("INC"  , MinCoreMask(eCoreMinTiny), 0x9403); AddReg1("DEC"  , MinCoreMask(eCoreMinTiny), 0x940a);
  1019.   AddReg1("PUSH" , MinCoreMask(eCoreClassic) | (1 << eCoreMinTiny), 0x920f);
  1020.   AddReg1("POP"  , MinCoreMask(eCoreClassic) | (1 << eCoreMinTiny), 0x900f);
  1021.   AddReg1("LSR"  , MinCoreMask(eCoreMinTiny), 0x9406); AddReg1("ROR"  , MinCoreMask(eCoreMinTiny), 0x9407);
  1022.   AddReg1("ASR"  , MinCoreMask(eCoreMinTiny), 0x9405); AddReg1("SWAP" , MinCoreMask(eCoreMinTiny), 0x9402);
  1023.  
  1024.   InstrZ = 0;
  1025.   AddReg2("ADD"  , MinCoreMask(eCoreMinTiny), 0x0c00); AddReg2("ADC"  , MinCoreMask(eCoreMinTiny), 0x1c00);
  1026.   AddReg2("SUB"  , MinCoreMask(eCoreMinTiny), 0x1800); AddReg2("SBC"  , MinCoreMask(eCoreMinTiny), 0x0800);
  1027.   AddReg2("AND"  , MinCoreMask(eCoreMinTiny), 0x2000); AddReg2("OR"   , MinCoreMask(eCoreMinTiny), 0x2800);
  1028.   AddReg2("EOR"  , MinCoreMask(eCoreMinTiny), 0x2400); AddReg2("CPSE" , MinCoreMask(eCoreMinTiny), 0x1000);
  1029.   AddReg2("CP"   , MinCoreMask(eCoreMinTiny), 0x1400); AddReg2("CPC"  , MinCoreMask(eCoreMinTiny), 0x0400);
  1030.   AddReg2("MOV"  , MinCoreMask(eCoreMinTiny), 0x2c00); AddReg2("MUL"  , MinCoreMask(eCoreMega   ), 0x9c00);
  1031.  
  1032.   AddReg3("CLR"  , 0x2400); AddReg3("TST"  , 0x2000); AddReg3("LSL"  , 0x0c00);
  1033.   AddReg3("ROL"  , 0x1c00);
  1034.  
  1035.   AddImm("SUBI" , 0x5000); AddImm("SBCI" , 0x4000); AddImm("ANDI" , 0x7000);
  1036.   AddImm("ORI"  , 0x6000); AddImm("SBR"  , 0x6000); AddImm("CPI"  , 0x3000);
  1037.   AddImm("LDI"  , 0xe000);
  1038.  
  1039.   AddRel("BRCC" , 0xf400); AddRel("BRCS" , 0xf000); AddRel("BREQ" , 0xf001);
  1040.   AddRel("BRGE" , 0xf404); AddRel("BRSH" , 0xf400); AddRel("BRID" , 0xf407);
  1041.   AddRel("BRIE" , 0xf007); AddRel("BRLO" , 0xf000); AddRel("BRLT" , 0xf004);
  1042.   AddRel("BRMI" , 0xf002); AddRel("BRNE" , 0xf401); AddRel("BRHC" , 0xf405);
  1043.   AddRel("BRHS" , 0xf005); AddRel("BRPL" , 0xf402); AddRel("BRTC" , 0xf406);
  1044.   AddRel("BRTS" , 0xf006); AddRel("BRVC" , 0xf403); AddRel("BRVS" , 0xf003);
  1045.  
  1046.   AddBit("BLD"  , 0xf800); AddBit("BST"  , 0xfa00);
  1047.   AddBit("SBRC" , 0xfc00); AddBit("SBRS" , 0xfe00);
  1048.  
  1049.   AddPBit("CBI" , 0x9800); AddPBit("SBI" , 0x9a00);
  1050.   AddPBit("SBIC", 0x9900); AddPBit("SBIS", 0x9b00);
  1051.  
  1052.   AddInstTable(InstTable, "ADIW", 0x0000, DecodeADIW);
  1053.   AddInstTable(InstTable, "SBIW", 0x0100, DecodeADIW);
  1054.  
  1055.   AddInstTable(InstTable, "LD", 0x0000, DecodeLDST);
  1056.   AddInstTable(InstTable, "ST", 0x0200, DecodeLDST);
  1057.  
  1058.   AddInstTable(InstTable, "LDD", 0x0000, DecodeLDDSTD);
  1059.   AddInstTable(InstTable, "STD", 0x0200, DecodeLDDSTD);
  1060.  
  1061.   AddInstTable(InstTable, "IN" , 0x0000, DecodeINOUT);
  1062.   AddInstTable(InstTable, "OUT", 0x0800, DecodeINOUT);
  1063.  
  1064.   AddInstTable(InstTable, "LDS", 0x0000, DecodeLDSSTS);
  1065.   AddInstTable(InstTable, "STS", 0x0200, DecodeLDSSTS);
  1066.  
  1067.   AddInstTable(InstTable, "BCLR", 0x0080, DecodeBCLRSET);
  1068.   AddInstTable(InstTable, "BSET", 0x0000, DecodeBCLRSET);
  1069.  
  1070.   AddInstTable(InstTable, "CBR", 0, DecodeCBR);
  1071.   AddInstTable(InstTable, "SER", 0, DecodeSER);
  1072.  
  1073.   AddInstTable(InstTable, "BRBC", 0x0400, DecodeBRBSBC);
  1074.   AddInstTable(InstTable, "BRBS", 0x0000, DecodeBRBSBC);
  1075.  
  1076.   AddInstTable(InstTable, "JMP" , 0, DecodeJMPCALL);
  1077.   AddInstTable(InstTable, "CALL", 2, DecodeJMPCALL);
  1078.  
  1079.   AddInstTable(InstTable, "RJMP" , 0x0000, DecodeRJMPCALL);
  1080.   AddInstTable(InstTable, "RCALL", 0x1000, DecodeRJMPCALL);
  1081.  
  1082.   AddInstTable(InstTable, "MULS", 0, DecodeMULS);
  1083.  
  1084.   AddInstTable(InstTable, "MULSU" , 0x0300, DecodeMegaMUL);
  1085.   AddInstTable(InstTable, "FMUL"  , 0x0308, DecodeMegaMUL);
  1086.   AddInstTable(InstTable, "FMULS" , 0x0380, DecodeMegaMUL);
  1087.   AddInstTable(InstTable, "FMULSU", 0x0388, DecodeMegaMUL);
  1088.  
  1089.   AddInstTable(InstTable, "MOVW", 0, DecodeMOVW);
  1090.  
  1091.   AddInstTable(InstTable, "LPM" , 0, DecodeLPM);
  1092.   AddInstTable(InstTable, "ELPM", 0, DecodeELPM);
  1093.  
  1094.   inst_table_set_prefix_proc(InstTable, NULL, 0);
  1095.  
  1096.   /* instructions that do not require word alignment in byte mode */
  1097.  
  1098.   AddInstTable(InstTable, "PORT", 0, DecodePORT);
  1099.   AddInstTable(InstTable, "SFR" , 0, DecodeSFR);
  1100.   AddInstTable(InstTable, "RES" , 0, DecodeRES);
  1101.   AddInstTable(InstTable, "REG" , 0, CodeREG);
  1102.   AddInstTable(InstTable, "BIT" , 0, DecodeBIT);
  1103.   AddInstTable(InstTable, "DATA", 0, DecodeDATA_AVR);
  1104.   AddIntelPseudo(InstTable, eIntPseudoFlag_LittleEndian);
  1105. }
  1106.  
  1107. static void DeinitFields(void)
  1108. {
  1109.   DestroyInstTable(InstTable);
  1110.   order_array_free(FixedOrders);
  1111.   order_array_free(Reg1Orders);
  1112.   order_array_free(Reg2Orders);
  1113. }
  1114.  
  1115. /*---------------------------------------------------------------------------*/
  1116.  
  1117. static void MakeCode_AVR(void)
  1118. {
  1119.   if (!LookupInstTable(InstTable, OpPart.str.p_str))
  1120.     WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
  1121. }
  1122.  
  1123. static Boolean IsDef_AVR(void)
  1124. {
  1125.   return (Memo("PORT")
  1126.        || Memo("REG")
  1127.        || Memo("SFR")
  1128.        || Memo("BIT"));
  1129. }
  1130.  
  1131. /*!------------------------------------------------------------------------
  1132.  * \fn     InternSymbol_AVR(char *pArg, TempResult *pResult)
  1133.  * \brief  parse for built-in symbols
  1134.  * \param  pArg source argument
  1135.  * \param  pResult possible result
  1136.  * ------------------------------------------------------------------------ */
  1137.  
  1138. static void InternSymbol_AVR(char *pArg, TempResult *pResult)
  1139. {
  1140.   Word RegValue;
  1141.  
  1142.   if (DecodeRegCore(pArg, &RegValue))
  1143.   {
  1144.     pResult->Typ = TempReg;
  1145.     pResult->DataSize = eSymbolSize8Bit;
  1146.     pResult->Contents.RegDescr.Reg = RegValue;
  1147.     pResult->Contents.RegDescr.Dissect = DissectReg_AVR;
  1148.     pResult->Contents.RegDescr.compare = NULL;
  1149.   }
  1150. }
  1151.  
  1152. static Boolean ChkZeroArg(void)
  1153. {
  1154.   return (0 == ArgCnt);
  1155. }
  1156.  
  1157. static void SwitchTo_AVR(void *pUser)
  1158. {
  1159.   pCurrCPUProps = (const tCPUProps*)pUser;
  1160.  
  1161.   TurnWords = False;
  1162.   SetIntConstMode(eIntConstModeC);
  1163.   SetIsOccupiedFnc = ChkZeroArg;
  1164.  
  1165.   PCSymbol = "*";
  1166.   HeaderID = CodeSegSize ? 0x3b : 0x3d;
  1167.   NOPCode = 0x0000;
  1168.   DivideChars = ",";
  1169.   HasAttrs = False;
  1170.  
  1171.   ValidSegs = (1 << SegCode) | (1 << SegData) | (1 << SegIO);
  1172.   Grans[SegCode] = ListGrans[SegCode] = 1 << CodeSegSize; SegInits[SegCode] = 0;
  1173.   Grans[SegData] = 1; ListGrans[SegData] = 1; SegInits[SegData] = 32;
  1174.   Grans[SegIO  ] = 1; ListGrans[SegIO  ] = 1; SegInits[SegIO  ] = 0;  SegLimits[SegIO] = 0x3f;
  1175.   if (pCurrCPUProps->EESize)
  1176.   {
  1177.     ValidSegs |= (1 << SegEEData);
  1178.     SegLimits[SegEEData] = pCurrCPUProps->EESize;
  1179.     Grans[SegEEData] = 1; ListGrans[SegEEData] = 1; SegInits[SegEEData] = 0;
  1180.   }
  1181.  
  1182.   SegLimits[SegCode] = ((LongWord)pCurrCPUProps->FlashEndD16) << 4 | 0xf;
  1183.   if (!CodeSegSize)
  1184.   {
  1185.     SegLimits[SegCode] = (SegLimits[SegCode] << 1) + 1;
  1186.     AddONOFF(DoPaddingName, &DoPadding, DoPaddingName, False);
  1187.   }
  1188.   SegLimits[SegData] = (pCurrCPUProps->RegistersMapped ? RegBankSize : 0)
  1189.                      + pCurrCPUProps->IOAreaSize
  1190.                      + pCurrCPUProps->RAMSize
  1191.                      - 1;
  1192.  
  1193.   CodeAdrIntType = GetSmallestUIntType(SegLimits[SegCode]);
  1194.   DataAdrIntType = GetSmallestUIntType(SegLimits[SegData]);
  1195.  
  1196.   SignMask = (SegLimits[SegCode] + 1) >> 1;
  1197.   ORMask = ((LongInt) - 1) - SegLimits[SegCode];
  1198.  
  1199.   onoff_packing_add(False);
  1200.   AddONOFF("WRAPMODE", &WrapFlag, WrapFlagName, False);
  1201.   SetFlag(&WrapFlag, WrapFlagName, False);
  1202.  
  1203.   MakeCode = MakeCode_AVR;
  1204.   IsDef = IsDef_AVR;
  1205.   InternSymbol = InternSymbol_AVR;
  1206.   DissectReg = DissectReg_AVR;
  1207.   SwitchFrom = DeinitFields;
  1208.   DissectBit = DissectBit_AVR;
  1209.   InitFields();
  1210. }
  1211.  
  1212. static const tCPUProps CPUProps[] =
  1213. {
  1214.   { "AT90S1200"      ,  0x01f, 0x0000, 0x003f, IOAreaStdSize , True , eCore90S1200   },
  1215.   { "AT90S2313"      ,  0x03f, 0x0080, 0x007f, IOAreaStdSize , True , eCoreClassic   },
  1216.   { "AT90S2323"      ,  0x03f, 0x0080, 0x007f, IOAreaStdSize , True , eCoreClassic   },
  1217.   { "AT90S2333"      ,  0x03f, 0x0080, 0x007f, IOAreaStdSize , True , eCoreClassic   }, /* == ATtiny22 */
  1218.   { "AT90S2343"      ,  0x03f, 0x0080, 0x007f, IOAreaStdSize , True , eCoreClassic   },
  1219.   { "AT90S4414"      ,  0x07f, 0x0100, 0x00ff, IOAreaStdSize , True , eCoreClassic   },
  1220.   { "AT90S4433"      ,  0x07f, 0x0080, 0x00ff, IOAreaStdSize , True , eCoreClassic   },
  1221.   { "AT90S4434"      ,  0x07f, 0x0100, 0x00ff, IOAreaStdSize , True , eCoreClassic   },
  1222.   { "AT90S8515"      ,  0x0ff, 0x0200, 0x01ff, IOAreaStdSize , True , eCoreClassic   },
  1223.   { "AT90C8534"      ,  0x0ff, 0x0100, 0x01ff, IOAreaStdSize , True , eCoreClassic   },
  1224.   { "AT90S8535"      ,  0x0ff, 0x0200, 0x01ff, IOAreaStdSize , True , eCoreClassic   },
  1225.   { "AT90USB646"     ,  0x7ff, 0x1000, 0x07ff, IOAreaExtSize , True , eCoreMega      },
  1226.   { "AT90USB647"     ,  0x7ff, 0x1000, 0x07ff, IOAreaExtSize , True , eCoreMega      },
  1227.   { "AT90USB1286"    ,  0xfff, 0x2000, 0x0fff, IOAreaExtSize , True , eCoreMega      },
  1228.   { "AT90USB1287"    ,  0xfff, 0x2000, 0x0fff, IOAreaExtSize , True , eCoreMega      },
  1229.  
  1230.   { "AT43USB355"     ,  0x2ff, 0x0400, 0x0000, 0x2000-RegBankSize, True , eCoreClassic   }, /* allow USB registers @ 0x1fxx */
  1231.  
  1232.   { "ATTINY4"        ,  0x00f, 0x0020, 0x0000, IOAreaStdSize , False, eCoreMinTiny   },
  1233.   { "ATTINY5"        ,  0x00f, 0x0020, 0x0000, IOAreaStdSize , False, eCoreMinTiny   },
  1234.   { "ATTINY9"        ,  0x01f, 0x0020, 0x0000, IOAreaStdSize , False, eCoreMinTiny   },
  1235.   { "ATTINY10"       ,  0x01f, 0x0020, 0x0000, IOAreaStdSize , False, eCoreMinTiny   },
  1236.   { "ATTINY11"       ,  0x01f, 0x0000, 0x0000, IOAreaStdSize , True , eCore90S1200   },
  1237.   { "ATTINY12"       ,  0x01f, 0x0000, 0x003f, IOAreaStdSize , True , eCore90S1200   },
  1238.   { "ATTINY13"       ,  0x01f, 0x0040, 0x003f, IOAreaStdSize , True , eCoreTiny      },
  1239.   { "ATTINY13A"      ,  0x01f, 0x0040, 0x003f, IOAreaStdSize , True , eCoreTiny      },
  1240.   { "ATTINY15"       ,  0x01f, 0x0000, 0x003f, IOAreaStdSize , True , eCore90S1200   },
  1241.   { "ATTINY20"       ,  0x03f, 0x0080, 0x0000, IOAreaStdSize , False, eCoreMinTiny   },
  1242.   { "ATTINY24"       ,  0x03f, 0x0080, 0x007f, IOAreaStdSize , True , eCoreTiny      },
  1243.   { "ATTINY24A"      ,  0x03f, 0x0080, 0x007f, IOAreaStdSize , True , eCoreTiny      },
  1244.   { "ATTINY25"       ,  0x03f, 0x0080, 0x007f, IOAreaStdSize , True , eCoreTiny      },
  1245.   { "ATTINY26"       ,  0x03f, 0x0080, 0x007f, IOAreaStdSize , True , eCoreTiny      },
  1246.   { "ATTINY28"       ,  0x03f, 0x0000, 0x0000, IOAreaStdSize , True , eCore90S1200   },
  1247.   { "ATTINY40"       ,  0x07f, 0x0100, 0x0000, IOAreaStdSize , False, eCoreMinTiny   },
  1248.   { "ATTINY44"       ,  0x07f, 0x0100, 0x007f, IOAreaStdSize , True , eCoreTiny      },
  1249.   { "ATTINY44A"      ,  0x07f, 0x0100, 0x007f, IOAreaStdSize , True , eCoreTiny      },
  1250.   { "ATTINY45"       ,  0x07f, 0x0100, 0x00ff, IOAreaStdSize , True , eCoreTiny      },
  1251.   { "ATTINY48"       ,  0x07f, 0x0100, 0x003f, IOAreaExtSize , True , eCoreTiny      },
  1252.   { "ATTINY84"       ,  0x0ff, 0x0200, 0x007f, IOAreaStdSize , True , eCoreTiny      },
  1253.   { "ATTINY84A"      ,  0x0ff, 0x0200, 0x007f, IOAreaStdSize , True , eCoreTiny      },
  1254.   { "ATTINY85"       ,  0x0ff, 0x0200, 0x00ff, IOAreaStdSize , True , eCoreTiny      },
  1255.   { "ATTINY87"       ,  0x0ff, 0x0200, 0x01ff, IOAreaExtSize , True , eCoreTiny16K   },
  1256.   { "ATTINY88"       ,  0x0ff, 0x0200, 0x003f, IOAreaExtSize , True , eCoreTiny      },
  1257.   { "ATTINY102"      ,  0x01f, 0x0020, 0x0000, IOAreaStdSize , False, eCoreMinTiny   },
  1258.   { "ATTINY104"      ,  0x01f, 0x0020, 0x0000, IOAreaStdSize , False, eCoreMinTiny   },
  1259.   { "ATTINY167"      ,  0x1ff, 0x0200, 0x01ff, IOAreaExtSize , True , eCoreTiny16K   },
  1260.   { "ATTINY261"      ,  0x03f, 0x0080, 0x007f, IOAreaStdSize , True , eCoreTiny      },
  1261.   { "ATTINY261A"     ,  0x03f, 0x0080, 0x007f, IOAreaStdSize , True , eCoreTiny      },
  1262.   { "ATTINY43U"      ,  0x07f, 0x0100, 0x003f, IOAreaStdSize , True , eCoreTiny      },
  1263.   { "ATTINY441"      ,  0x07f, 0x0100, 0x00ff, IOAreaExtSize , True , eCoreTiny      },
  1264.   { "ATTINY461"      ,  0x07f, 0x0100, 0x00ff, IOAreaStdSize , True , eCoreTiny      },
  1265.   { "ATTINY461A"     ,  0x07f, 0x0100, 0x00ff, IOAreaStdSize , True , eCoreTiny      },
  1266.   { "ATTINY828"      ,  0x0ff, 0x0200, 0x00ff, IOAreaExtSize , True , eCoreTiny      },
  1267.   { "ATTINY841"      ,  0x0ff, 0x0200, 0x00ff, IOAreaExtSize , True , eCoreTiny      },
  1268.   { "ATTINY861"      ,  0x0ff, 0x0200, 0x01ff, IOAreaStdSize , True , eCoreTiny      },
  1269.   { "ATTINY861A"     ,  0x0ff, 0x0200, 0x01ff, IOAreaStdSize , True , eCoreTiny      },
  1270.   { "ATTINY1634"     ,  0x1ff, 0x0400, 0x00ff, IOAreaExtSize , True , eCoreTiny16K   },
  1271.   { "ATTINY2313"     ,  0x03f, 0x0080, 0x007f, IOAreaStdSize , True , eCoreTiny      },
  1272.   { "ATTINY2313A"    ,  0x03f, 0x0080, 0x007f, IOAreaStdSize , True , eCoreTiny      },
  1273.   { "ATTINY4313"     ,  0x07f, 0x0100, 0x00ff, IOAreaStdSize , True , eCoreTiny      },
  1274.  
  1275.   { "ATMEGA48"       ,  0x07f, 0x0200, 0x00ff, IOAreaExtSize , True , eCoreMega      },
  1276.  
  1277.   { "ATMEGA8"        ,  0x0ff, 0x0400, 0x01ff, IOAreaStdSize , True , eCoreMega      },
  1278.   { "ATMEGA8515"     ,  0x0ff, 0x0200, 0x01ff, IOAreaStdSize , True , eCoreMega      },
  1279.   { "ATMEGA8535"     ,  0x0ff, 0x0200, 0x01ff, IOAreaStdSize , True , eCoreMega      },
  1280.   { "ATMEGA88"       ,  0x0ff, 0x0200, 0x01ff, IOAreaExtSize , True , eCoreMega      },
  1281.   { "ATMEGA8U2"      ,  0x0ff, 0x0200, 0x01ff, IOAreaExtSize , True , eCoreMega      },
  1282.  
  1283.   { "ATMEGA16"       ,  0x1ff, 0x0400, 0x01ff, IOAreaStdSize , True , eCoreMega      },
  1284.   { "ATMEGA161"      ,  0x1ff, 0x0400, 0x01ff, IOAreaStdSize , True , eCoreMega      },
  1285.   { "ATMEGA162"      ,  0x1ff, 0x0400, 0x01ff, IOAreaExtSize , True , eCoreMega      },
  1286.   { "ATMEGA163"      ,  0x1ff, 0x0400, 0x01ff, IOAreaStdSize , True , eCoreMega      },
  1287.   { "ATMEGA164"      ,  0x1ff, 0x0400, 0x01ff, IOAreaExtSize , True , eCoreMega      },
  1288.   { "ATMEGA165"      ,  0x1ff, 0x0200, 0x01ff, IOAreaExtSize , True , eCoreMega      },
  1289.   { "ATMEGA168"      ,  0x1ff, 0x0400, 0x01ff, IOAreaExtSize , True , eCoreMega      },
  1290.   { "ATMEGA169"      ,  0x1ff, 0x0400, 0x01ff, IOAreaExtSize , True , eCoreMega      },
  1291.   { "ATMEGA16U2"     ,  0x1ff, 0x0200, 0x01ff, IOAreaExtSize , True , eCoreMega      },
  1292.   { "ATMEGA16U4"     ,  0x1ff, 0x0500, 0x01ff, IOAreaExtSize , True , eCoreMega      },
  1293.  
  1294.   { "ATMEGA32"       ,  0x3ff, 0x0800, 0x03ff, IOAreaStdSize , True , eCoreMega      },
  1295.   { "ATMEGA323"      ,  0x3ff, 0x0800, 0x03ff, IOAreaStdSize , True , eCoreMega      },
  1296.   { "ATMEGA324"      ,  0x3ff, 0x0800, 0x03ff, IOAreaExtSize , True , eCoreMega      },
  1297.   { "ATMEGA325"      ,  0x3ff, 0x0800, 0x03ff, IOAreaExtSize , True , eCoreMega      },
  1298.   { "ATMEGA3250"     ,  0x3ff, 0x0800, 0x03ff, IOAreaExtSize , True , eCoreMega      },
  1299.   { "ATMEGA328"      ,  0x3ff, 0x0800, 0x03ff, IOAreaExtSize , True , eCoreMega      },
  1300.   { "ATMEGA329"      ,  0x3ff, 0x0800, 0x03ff, IOAreaExtSize , True , eCoreMega      },
  1301.   { "ATMEGA3290"     ,  0x3ff, 0x0800, 0x03ff, IOAreaExtSize , True , eCoreMega      },
  1302.   { "ATMEGA32U2"     ,  0x3ff, 0x0400, 0x03ff, IOAreaExtSize , True , eCoreMega      },
  1303.   { "ATMEGA32U4"     ,  0x3ff, 0x0a00, 0x03ff, IOAreaExtSize , True , eCoreMega      },
  1304.   { "ATMEGA32U6"     ,  0x3ff, 0x0a00, 0x03ff, IOAreaExtSize , True , eCoreMega      },
  1305.  
  1306.   { "ATMEGA406"      ,  0x4ff, 0x0800, 0x01ff, IOAreaExtSize , True , eCoreMega      },
  1307.  
  1308.   { "ATMEGA64"       ,  0x7ff, 0x1000, 0x07ff, IOAreaExtSize , True , eCoreMega      },
  1309.   { "ATMEGA640"      ,  0x7ff, 0x2000, 0x0fff, IOAreaExt2Size, True , eCoreMega      },
  1310.   { "ATMEGA644"      ,  0x7ff, 0x1000, 0x07ff, IOAreaExtSize , True , eCoreMega      },
  1311.   { "ATMEGA644RFR2"  ,  0x7ff, 0x2000, 0x07ff, IOAreaExt2Size, True , eCoreMega      },
  1312.   { "ATMEGA645"      ,  0x7ff, 0x1000, 0x07ff, IOAreaExtSize , True , eCoreMega      },
  1313.   { "ATMEGA6450"     ,  0x7ff, 0x1000, 0x07ff, IOAreaExtSize , True , eCoreMega      },
  1314.   { "ATMEGA649"      ,  0x7ff, 0x1000, 0x07ff, IOAreaExtSize , True , eCoreMega      },
  1315.   { "ATMEGA6490"     ,  0x7ff, 0x1000, 0x07ff, IOAreaExtSize , True , eCoreMega      },
  1316.  
  1317.   { "ATMEGA103"      ,  0xfff, 0x1000, 0x0fff, IOAreaStdSize , True , eCoreMega      },
  1318.   { "ATMEGA128"      ,  0xfff, 0x1000, 0x0fff, IOAreaExtSize , True , eCoreMega      },
  1319.   { "ATMEGA1280"     ,  0xfff, 0x2000, 0x0fff, IOAreaExt2Size, True , eCoreMega      },
  1320.   { "ATMEGA1281"     ,  0xfff, 0x2000, 0x0fff, IOAreaExt2Size, True , eCoreMega      },
  1321.   { "ATMEGA1284"     ,  0xfff, 0x4000, 0x0fff, IOAreaExtSize , True , eCoreMega      },
  1322.   { "ATMEGA1284RFR2" ,  0xfff, 0x4000, 0x0fff, IOAreaExt2Size, True , eCoreMega      },
  1323.  
  1324.   { "ATMEGA2560"     , 0x1fff, 0x2000, 0x0fff, IOAreaExt2Size, True , eCoreMega      },
  1325.   { "ATMEGA2561"     , 0x1fff, 0x2000, 0x0fff, IOAreaExt2Size, True , eCoreMega      },
  1326.   { "ATMEGA2564RFR2" , 0x1fff, 0x8000, 0x1fff, IOAreaExt2Size, True , eCoreMega      },
  1327.   { NULL             ,    0x0, 0     , 0     , 0             , False, eCoreNone      },
  1328. };
  1329.  
  1330. void codeavr_init(void)
  1331. {
  1332.   const tCPUProps *pProp;
  1333.   static const tCPUArg AVRArgs[] =
  1334.   {
  1335.     { "CODESEGSIZE", 0, 1, 1, &CodeSegSize },
  1336.     { NULL         , 0, 0, 0, NULL         }
  1337.   };
  1338.  
  1339.   for (pProp = CPUProps; pProp->pName; pProp++)
  1340.     (void)AddCPUUserWithArgs(pProp->pName, SwitchTo_AVR, (void*)pProp, NULL, AVRArgs);
  1341. }
  1342.