Subversion Repositories pentevo

Rev

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

  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. /* Dynamic Code Table Handling                                               */
  919.  
  920. static void AddFixed(const char *NName, Word NMin, Word NCode)
  921. {
  922.   order_array_rsv_end(FixedOrders, FixedOrder);
  923.   FixedOrders[InstrZ].Code = NCode;
  924.   FixedOrders[InstrZ].CoreMask = NMin;
  925.   AddInstTable(InstTable, NName, InstrZ++, DecodeFixed);
  926. }
  927.  
  928. static void AddReg1(const char *NName, Word NMin, Word NCode)
  929. {
  930.   order_array_rsv_end(Reg1Orders, FixedOrder);
  931.   Reg1Orders[InstrZ].Code = NCode;
  932.   Reg1Orders[InstrZ].CoreMask = NMin;
  933.   AddInstTable(InstTable, NName, InstrZ++, DecodeReg1);
  934. }
  935.  
  936. static void AddReg2(const char *NName, Word NMin, Word NCode)
  937. {
  938.   order_array_rsv_end(Reg2Orders, FixedOrder);
  939.   Reg2Orders[InstrZ].Code = NCode;
  940.   Reg2Orders[InstrZ].CoreMask = NMin;
  941.   AddInstTable(InstTable, NName, InstrZ++, DecodeReg2);
  942. }
  943.  
  944. static void AddReg3(const char *NName, Word NCode)
  945. {
  946.   AddInstTable(InstTable, NName, NCode, DecodeReg3);
  947. }
  948.  
  949. static void AddImm(const char *NName, Word NCode)
  950. {
  951.   AddInstTable(InstTable, NName, NCode, DecodeImm);
  952. }
  953.  
  954. static void AddRel(const char *NName, Word NCode)
  955. {
  956.   AddInstTable(InstTable, NName, NCode, DecodeRel);
  957. }
  958.  
  959. static void AddBit(const char *NName, Word NCode)
  960. {
  961.   AddInstTable(InstTable, NName, NCode, DecodeBit);
  962. }
  963.  
  964. static void AddPBit(const char *NName, Word NCode)
  965. {
  966.   AddInstTable(InstTable, NName, NCode, DecodePBit);
  967. }
  968.  
  969. static void InitFields(void)
  970. {
  971.   InstTable = CreateInstTable(203);
  972.  
  973.   InstrZ = 0;
  974.   AddFixed("IJMP" , MinCoreMask(eCoreClassic) | (1 << eCoreMinTiny), 0x9409);
  975.   AddFixed("ICALL", MinCoreMask(eCoreClassic) | (1 << eCoreMinTiny), 0x9509);
  976.   AddFixed("RET"  , MinCoreMask(eCoreMinTiny), 0x9508); AddFixed("RETI"  , MinCoreMask(eCoreMinTiny), 0x9518);
  977.   AddFixed("SEC"  , MinCoreMask(eCoreMinTiny), 0x9408);
  978.   AddFixed("CLC"  , MinCoreMask(eCoreMinTiny), 0x9488); AddFixed("SEN"   , MinCoreMask(eCoreMinTiny), 0x9428);
  979.   AddFixed("CLN"  , MinCoreMask(eCoreMinTiny), 0x94a8); AddFixed("SEZ"   , MinCoreMask(eCoreMinTiny), 0x9418);
  980.   AddFixed("CLZ"  , MinCoreMask(eCoreMinTiny), 0x9498); AddFixed("SEI"   , MinCoreMask(eCoreMinTiny), 0x9478);
  981.   AddFixed("CLI"  , MinCoreMask(eCoreMinTiny), 0x94f8); AddFixed("SES"   , MinCoreMask(eCoreMinTiny), 0x9448);
  982.   AddFixed("CLS"  , MinCoreMask(eCoreMinTiny), 0x94c8); AddFixed("SEV"   , MinCoreMask(eCoreMinTiny), 0x9438);
  983.   AddFixed("CLV"  , MinCoreMask(eCoreMinTiny), 0x94b8); AddFixed("SET"   , MinCoreMask(eCoreMinTiny), 0x9468);
  984.   AddFixed("CLT"  , MinCoreMask(eCoreMinTiny), 0x94e8); AddFixed("SEH"   , MinCoreMask(eCoreMinTiny), 0x9458);
  985.   AddFixed("CLH"  , MinCoreMask(eCoreMinTiny), 0x94d8); AddFixed("NOP"   , MinCoreMask(eCoreMinTiny), 0x0000);
  986.   AddFixed("SLEEP", MinCoreMask(eCoreMinTiny), 0x9588); AddFixed("WDR"   , MinCoreMask(eCoreMinTiny), 0x95a8);
  987.   AddFixed("EIJMP", MinCoreMask(eCoreMega   ), 0x9419); AddFixed("EICALL", MinCoreMask(eCoreMega   ), 0x9519);
  988.   AddFixed("SPM"  , MinCoreMask(eCoreTiny   ), 0x95e8);
  989.   AddFixed("BREAK" , MinCoreMask(eCoreTiny   ) | (1 << eCoreMinTiny), 0x9598);
  990.  
  991.   InstrZ = 0;
  992.   AddReg1("COM"  , MinCoreMask(eCoreMinTiny), 0x9400); AddReg1("NEG"  , MinCoreMask(eCoreMinTiny), 0x9401);
  993.   AddReg1("INC"  , MinCoreMask(eCoreMinTiny), 0x9403); AddReg1("DEC"  , MinCoreMask(eCoreMinTiny), 0x940a);
  994.   AddReg1("PUSH" , MinCoreMask(eCoreClassic) | (1 << eCoreMinTiny), 0x920f);
  995.   AddReg1("POP"  , MinCoreMask(eCoreClassic) | (1 << eCoreMinTiny), 0x900f);
  996.   AddReg1("LSR"  , MinCoreMask(eCoreMinTiny), 0x9406); AddReg1("ROR"  , MinCoreMask(eCoreMinTiny), 0x9407);
  997.   AddReg1("ASR"  , MinCoreMask(eCoreMinTiny), 0x9405); AddReg1("SWAP" , MinCoreMask(eCoreMinTiny), 0x9402);
  998.  
  999.   InstrZ = 0;
  1000.   AddReg2("ADD"  , MinCoreMask(eCoreMinTiny), 0x0c00); AddReg2("ADC"  , MinCoreMask(eCoreMinTiny), 0x1c00);
  1001.   AddReg2("SUB"  , MinCoreMask(eCoreMinTiny), 0x1800); AddReg2("SBC"  , MinCoreMask(eCoreMinTiny), 0x0800);
  1002.   AddReg2("AND"  , MinCoreMask(eCoreMinTiny), 0x2000); AddReg2("OR"   , MinCoreMask(eCoreMinTiny), 0x2800);
  1003.   AddReg2("EOR"  , MinCoreMask(eCoreMinTiny), 0x2400); AddReg2("CPSE" , MinCoreMask(eCoreMinTiny), 0x1000);
  1004.   AddReg2("CP"   , MinCoreMask(eCoreMinTiny), 0x1400); AddReg2("CPC"  , MinCoreMask(eCoreMinTiny), 0x0400);
  1005.   AddReg2("MOV"  , MinCoreMask(eCoreMinTiny), 0x2c00); AddReg2("MUL"  , MinCoreMask(eCoreMega   ), 0x9c00);
  1006.  
  1007.   AddReg3("CLR"  , 0x2400); AddReg3("TST"  , 0x2000); AddReg3("LSL"  , 0x0c00);
  1008.   AddReg3("ROL"  , 0x1c00);
  1009.  
  1010.   AddImm("SUBI" , 0x5000); AddImm("SBCI" , 0x4000); AddImm("ANDI" , 0x7000);
  1011.   AddImm("ORI"  , 0x6000); AddImm("SBR"  , 0x6000); AddImm("CPI"  , 0x3000);
  1012.   AddImm("LDI"  , 0xe000);
  1013.  
  1014.   AddRel("BRCC" , 0xf400); AddRel("BRCS" , 0xf000); AddRel("BREQ" , 0xf001);
  1015.   AddRel("BRGE" , 0xf404); AddRel("BRSH" , 0xf400); AddRel("BRID" , 0xf407);
  1016.   AddRel("BRIE" , 0xf007); AddRel("BRLO" , 0xf000); AddRel("BRLT" , 0xf004);
  1017.   AddRel("BRMI" , 0xf002); AddRel("BRNE" , 0xf401); AddRel("BRHC" , 0xf405);
  1018.   AddRel("BRHS" , 0xf005); AddRel("BRPL" , 0xf402); AddRel("BRTC" , 0xf406);
  1019.   AddRel("BRTS" , 0xf006); AddRel("BRVC" , 0xf403); AddRel("BRVS" , 0xf003);
  1020.  
  1021.   AddBit("BLD"  , 0xf800); AddBit("BST"  , 0xfa00);
  1022.   AddBit("SBRC" , 0xfc00); AddBit("SBRS" , 0xfe00);
  1023.  
  1024.   AddPBit("CBI" , 0x9800); AddPBit("SBI" , 0x9a00);
  1025.   AddPBit("SBIC", 0x9900); AddPBit("SBIS", 0x9b00);
  1026.  
  1027.   AddInstTable(InstTable, "ADIW", 0x0000, DecodeADIW);
  1028.   AddInstTable(InstTable, "SBIW", 0x0100, DecodeADIW);
  1029.  
  1030.   AddInstTable(InstTable, "LD", 0x0000, DecodeLDST);
  1031.   AddInstTable(InstTable, "ST", 0x0200, DecodeLDST);
  1032.  
  1033.   AddInstTable(InstTable, "LDD", 0x0000, DecodeLDDSTD);
  1034.   AddInstTable(InstTable, "STD", 0x0200, DecodeLDDSTD);
  1035.  
  1036.   AddInstTable(InstTable, "IN" , 0x0000, DecodeINOUT);
  1037.   AddInstTable(InstTable, "OUT", 0x0800, DecodeINOUT);
  1038.  
  1039.   AddInstTable(InstTable, "LDS", 0x0000, DecodeLDSSTS);
  1040.   AddInstTable(InstTable, "STS", 0x0200, DecodeLDSSTS);
  1041.  
  1042.   AddInstTable(InstTable, "BCLR", 0x0080, DecodeBCLRSET);
  1043.   AddInstTable(InstTable, "BSET", 0x0000, DecodeBCLRSET);
  1044.  
  1045.   AddInstTable(InstTable, "CBR", 0, DecodeCBR);
  1046.   AddInstTable(InstTable, "SER", 0, DecodeSER);
  1047.  
  1048.   AddInstTable(InstTable, "BRBC", 0x0400, DecodeBRBSBC);
  1049.   AddInstTable(InstTable, "BRBS", 0x0000, DecodeBRBSBC);
  1050.  
  1051.   AddInstTable(InstTable, "JMP" , 0, DecodeJMPCALL);
  1052.   AddInstTable(InstTable, "CALL", 2, DecodeJMPCALL);
  1053.  
  1054.   AddInstTable(InstTable, "RJMP" , 0x0000, DecodeRJMPCALL);
  1055.   AddInstTable(InstTable, "RCALL", 0x1000, DecodeRJMPCALL);
  1056.  
  1057.   AddInstTable(InstTable, "PORT", 0, DecodePORT);
  1058.   AddInstTable(InstTable, "SFR" , 0, DecodeSFR);
  1059.   AddInstTable(InstTable, "RES" , 0, DecodeRES);
  1060.   AddInstTable(InstTable, "REG" , 0, CodeREG);
  1061.   AddInstTable(InstTable, "BIT" , 0, DecodeBIT);
  1062.  
  1063.   AddInstTable(InstTable, "MULS", 0, DecodeMULS);
  1064.  
  1065.   AddInstTable(InstTable, "MULSU" , 0x0300, DecodeMegaMUL);
  1066.   AddInstTable(InstTable, "FMUL"  , 0x0308, DecodeMegaMUL);
  1067.   AddInstTable(InstTable, "FMULS" , 0x0380, DecodeMegaMUL);
  1068.   AddInstTable(InstTable, "FMULSU", 0x0388, DecodeMegaMUL);
  1069.  
  1070.   AddInstTable(InstTable, "MOVW", 0, DecodeMOVW);
  1071.  
  1072.   AddInstTable(InstTable, "LPM" , 0, DecodeLPM);
  1073.   AddInstTable(InstTable, "ELPM", 0, DecodeELPM);
  1074. }
  1075.  
  1076. static void DeinitFields(void)
  1077. {
  1078.   DestroyInstTable(InstTable);
  1079.   order_array_free(FixedOrders);
  1080.   order_array_free(Reg1Orders);
  1081.   order_array_free(Reg2Orders);
  1082. }
  1083.  
  1084. /*---------------------------------------------------------------------------*/
  1085.  
  1086. static void MakeCode_AVR(void)
  1087. {
  1088.   CodeLen = 0; DontPrint = False;
  1089.  
  1090.   if (Memo("")) return;
  1091.  
  1092.   /* instructions that do not require word alignment in byte mode */
  1093.  
  1094.   if (Memo("DATA"))
  1095.   {
  1096.     DecodeDATA_AVR(0);
  1097.     return;
  1098.   }
  1099.  
  1100.   if (DecodeIntelPseudo(False))
  1101.     return;
  1102.  
  1103.   /* All other instructions must be on an even address in byte mode.
  1104.      In other words, they may not cross flash word boundaries: */
  1105.  
  1106.   if (!CodeSegSize)
  1107.   {
  1108.     if (Odd(EProgCounter()))
  1109.     {
  1110.       if (DoPadding)
  1111.         InsertPadding(1, False);
  1112.       else
  1113.         WrError(ErrNum_AddrNotAligned);
  1114.     }
  1115.   }
  1116.  
  1117.   if (!LookupInstTable(InstTable, OpPart.str.p_str))
  1118.     WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
  1119. }
  1120.  
  1121. static Boolean IsDef_AVR(void)
  1122. {
  1123.   return (Memo("PORT")
  1124.        || Memo("REG")
  1125.        || Memo("SFR")
  1126.        || Memo("BIT"));
  1127. }
  1128.  
  1129. /*!------------------------------------------------------------------------
  1130.  * \fn     InternSymbol_AVR(char *pArg, TempResult *pResult)
  1131.  * \brief  parse for built-in symbols
  1132.  * \param  pArg source argument
  1133.  * \param  pResult possible result
  1134.  * ------------------------------------------------------------------------ */
  1135.  
  1136. static void InternSymbol_AVR(char *pArg, TempResult *pResult)
  1137. {
  1138.   Word RegValue;
  1139.  
  1140.   if (DecodeRegCore(pArg, &RegValue))
  1141.   {
  1142.     pResult->Typ = TempReg;
  1143.     pResult->DataSize = eSymbolSize8Bit;
  1144.     pResult->Contents.RegDescr.Reg = RegValue;
  1145.     pResult->Contents.RegDescr.Dissect = DissectReg_AVR;
  1146.     pResult->Contents.RegDescr.compare = NULL;
  1147.   }
  1148. }
  1149.  
  1150. static Boolean ChkZeroArg(void)
  1151. {
  1152.   return (0 == ArgCnt);
  1153. }
  1154.  
  1155. static void SwitchTo_AVR(void *pUser)
  1156. {
  1157.   pCurrCPUProps = (const tCPUProps*)pUser;
  1158.  
  1159.   TurnWords = False;
  1160.   SetIntConstMode(eIntConstModeC);
  1161.   SetIsOccupiedFnc = ChkZeroArg;
  1162.  
  1163.   PCSymbol = "*";
  1164.   HeaderID = CodeSegSize ? 0x3b : 0x3d;
  1165.   NOPCode = 0x0000;
  1166.   DivideChars = ",";
  1167.   HasAttrs = False;
  1168.  
  1169.   ValidSegs = (1 << SegCode) | (1 << SegData) | (1 << SegIO);
  1170.   Grans[SegCode] = ListGrans[SegCode] = 1 << CodeSegSize; SegInits[SegCode] = 0;
  1171.   Grans[SegData] = 1; ListGrans[SegData] = 1; SegInits[SegData] = 32;
  1172.   Grans[SegIO  ] = 1; ListGrans[SegIO  ] = 1; SegInits[SegIO  ] = 0;  SegLimits[SegIO] = 0x3f;
  1173.   if (pCurrCPUProps->EESize)
  1174.   {
  1175.     ValidSegs |= (1 << SegEEData);
  1176.     SegLimits[SegEEData] = pCurrCPUProps->EESize;
  1177.     Grans[SegEEData] = 1; ListGrans[SegEEData] = 1; SegInits[SegEEData] = 0;
  1178.   }
  1179.  
  1180.   SegLimits[SegCode] = ((LongWord)pCurrCPUProps->FlashEndD16) << 4 | 0xf;
  1181.   if (!CodeSegSize)
  1182.   {
  1183.     SegLimits[SegCode] = (SegLimits[SegCode] << 1) + 1;
  1184.     AddONOFF(DoPaddingName, &DoPadding, DoPaddingName, False);
  1185.   }
  1186.   SegLimits[SegData] = (pCurrCPUProps->RegistersMapped ? RegBankSize : 0)
  1187.                      + pCurrCPUProps->IOAreaSize
  1188.                      + pCurrCPUProps->RAMSize
  1189.                      - 1;
  1190.  
  1191.   CodeAdrIntType = GetSmallestUIntType(SegLimits[SegCode]);
  1192.   DataAdrIntType = GetSmallestUIntType(SegLimits[SegData]);
  1193.  
  1194.   SignMask = (SegLimits[SegCode] + 1) >> 1;
  1195.   ORMask = ((LongInt) - 1) - SegLimits[SegCode];
  1196.  
  1197.   onoff_packing_add(False);
  1198.   AddONOFF("WRAPMODE", &WrapFlag, WrapFlagName, False);
  1199.   SetFlag(&WrapFlag, WrapFlagName, False);
  1200.  
  1201.   MakeCode = MakeCode_AVR;
  1202.   IsDef = IsDef_AVR;
  1203.   InternSymbol = InternSymbol_AVR;
  1204.   DissectReg = DissectReg_AVR;
  1205.   SwitchFrom = DeinitFields;
  1206.   DissectBit = DissectBit_AVR;
  1207.   InitFields();
  1208. }
  1209.  
  1210. static const tCPUProps CPUProps[] =
  1211. {
  1212.   { "AT90S1200"      ,  0x01f, 0x0000, 0x003f, IOAreaStdSize , True , eCore90S1200   },
  1213.   { "AT90S2313"      ,  0x03f, 0x0080, 0x007f, IOAreaStdSize , True , eCoreClassic   },
  1214.   { "AT90S2323"      ,  0x03f, 0x0080, 0x007f, IOAreaStdSize , True , eCoreClassic   },
  1215.   { "AT90S2333"      ,  0x03f, 0x0080, 0x007f, IOAreaStdSize , True , eCoreClassic   }, /* == ATtiny22 */
  1216.   { "AT90S2343"      ,  0x03f, 0x0080, 0x007f, IOAreaStdSize , True , eCoreClassic   },
  1217.   { "AT90S4414"      ,  0x07f, 0x0100, 0x00ff, IOAreaStdSize , True , eCoreClassic   },
  1218.   { "AT90S4433"      ,  0x07f, 0x0080, 0x00ff, IOAreaStdSize , True , eCoreClassic   },
  1219.   { "AT90S4434"      ,  0x07f, 0x0100, 0x00ff, IOAreaStdSize , True , eCoreClassic   },
  1220.   { "AT90S8515"      ,  0x0ff, 0x0200, 0x01ff, IOAreaStdSize , True , eCoreClassic   },
  1221.   { "AT90C8534"      ,  0x0ff, 0x0100, 0x01ff, IOAreaStdSize , True , eCoreClassic   },
  1222.   { "AT90S8535"      ,  0x0ff, 0x0200, 0x01ff, IOAreaStdSize , True , eCoreClassic   },
  1223.   { "AT90USB646"     ,  0x7ff, 0x1000, 0x07ff, IOAreaExtSize , True , eCoreMega      },
  1224.   { "AT90USB647"     ,  0x7ff, 0x1000, 0x07ff, IOAreaExtSize , True , eCoreMega      },
  1225.   { "AT90USB1286"    ,  0xfff, 0x2000, 0x0fff, IOAreaExtSize , True , eCoreMega      },
  1226.   { "AT90USB1287"    ,  0xfff, 0x2000, 0x0fff, IOAreaExtSize , True , eCoreMega      },
  1227.  
  1228.   { "AT43USB355"     ,  0x2ff, 0x0400, 0x0000, 0x2000-RegBankSize, True , eCoreClassic   }, /* allow USB registers @ 0x1fxx */
  1229.  
  1230.   { "ATTINY4"        ,  0x00f, 0x0020, 0x0000, IOAreaStdSize , False, eCoreMinTiny   },
  1231.   { "ATTINY5"        ,  0x00f, 0x0020, 0x0000, IOAreaStdSize , False, eCoreMinTiny   },
  1232.   { "ATTINY9"        ,  0x01f, 0x0020, 0x0000, IOAreaStdSize , False, eCoreMinTiny   },
  1233.   { "ATTINY10"       ,  0x01f, 0x0020, 0x0000, IOAreaStdSize , False, eCoreMinTiny   },
  1234.   { "ATTINY11"       ,  0x01f, 0x0000, 0x0000, IOAreaStdSize , True , eCore90S1200   },
  1235.   { "ATTINY12"       ,  0x01f, 0x0000, 0x003f, IOAreaStdSize , True , eCore90S1200   },
  1236.   { "ATTINY13"       ,  0x01f, 0x0040, 0x003f, IOAreaStdSize , True , eCoreTiny      },
  1237.   { "ATTINY13A"      ,  0x01f, 0x0040, 0x003f, IOAreaStdSize , True , eCoreTiny      },
  1238.   { "ATTINY15"       ,  0x01f, 0x0000, 0x003f, IOAreaStdSize , True , eCore90S1200   },
  1239.   { "ATTINY20"       ,  0x03f, 0x0080, 0x0000, IOAreaStdSize , False, eCoreMinTiny   },
  1240.   { "ATTINY24"       ,  0x03f, 0x0080, 0x007f, IOAreaStdSize , True , eCoreTiny      },
  1241.   { "ATTINY24A"      ,  0x03f, 0x0080, 0x007f, IOAreaStdSize , True , eCoreTiny      },
  1242.   { "ATTINY25"       ,  0x03f, 0x0080, 0x007f, IOAreaStdSize , True , eCoreTiny      },
  1243.   { "ATTINY26"       ,  0x03f, 0x0080, 0x007f, IOAreaStdSize , True , eCoreTiny      },
  1244.   { "ATTINY28"       ,  0x03f, 0x0000, 0x0000, IOAreaStdSize , True , eCore90S1200   },
  1245.   { "ATTINY40"       ,  0x07f, 0x0100, 0x0000, IOAreaStdSize , False, eCoreMinTiny   },
  1246.   { "ATTINY44"       ,  0x07f, 0x0100, 0x007f, IOAreaStdSize , True , eCoreTiny      },
  1247.   { "ATTINY44A"      ,  0x07f, 0x0100, 0x007f, IOAreaStdSize , True , eCoreTiny      },
  1248.   { "ATTINY45"       ,  0x07f, 0x0100, 0x00ff, IOAreaStdSize , True , eCoreTiny      },
  1249.   { "ATTINY48"       ,  0x07f, 0x0100, 0x003f, IOAreaExtSize , True , eCoreTiny      },
  1250.   { "ATTINY84"       ,  0x0ff, 0x0200, 0x007f, IOAreaStdSize , True , eCoreTiny      },
  1251.   { "ATTINY84A"      ,  0x0ff, 0x0200, 0x007f, IOAreaStdSize , True , eCoreTiny      },
  1252.   { "ATTINY85"       ,  0x0ff, 0x0200, 0x00ff, IOAreaStdSize , True , eCoreTiny      },
  1253.   { "ATTINY87"       ,  0x0ff, 0x0200, 0x01ff, IOAreaExtSize , True , eCoreTiny16K   },
  1254.   { "ATTINY88"       ,  0x0ff, 0x0200, 0x003f, IOAreaExtSize , True , eCoreTiny      },
  1255.   { "ATTINY102"      ,  0x01f, 0x0020, 0x0000, IOAreaStdSize , False, eCoreMinTiny   },
  1256.   { "ATTINY104"      ,  0x01f, 0x0020, 0x0000, IOAreaStdSize , False, eCoreMinTiny   },
  1257.   { "ATTINY167"      ,  0x1ff, 0x0200, 0x01ff, IOAreaExtSize , True , eCoreTiny16K   },
  1258.   { "ATTINY261"      ,  0x03f, 0x0080, 0x007f, IOAreaStdSize , True , eCoreTiny      },
  1259.   { "ATTINY261A"     ,  0x03f, 0x0080, 0x007f, IOAreaStdSize , True , eCoreTiny      },
  1260.   { "ATTINY43U"      ,  0x07f, 0x0100, 0x003f, IOAreaStdSize , True , eCoreTiny      },
  1261.   { "ATTINY441"      ,  0x07f, 0x0100, 0x00ff, IOAreaExtSize , True , eCoreTiny      },
  1262.   { "ATTINY461"      ,  0x07f, 0x0100, 0x00ff, IOAreaStdSize , True , eCoreTiny      },
  1263.   { "ATTINY461A"     ,  0x07f, 0x0100, 0x00ff, IOAreaStdSize , True , eCoreTiny      },
  1264.   { "ATTINY828"      ,  0x0ff, 0x0200, 0x00ff, IOAreaExtSize , True , eCoreTiny      },
  1265.   { "ATTINY841"      ,  0x0ff, 0x0200, 0x00ff, IOAreaExtSize , True , eCoreTiny      },
  1266.   { "ATTINY861"      ,  0x0ff, 0x0200, 0x01ff, IOAreaStdSize , True , eCoreTiny      },
  1267.   { "ATTINY861A"     ,  0x0ff, 0x0200, 0x01ff, IOAreaStdSize , True , eCoreTiny      },
  1268.   { "ATTINY1634"     ,  0x1ff, 0x0400, 0x00ff, IOAreaExtSize , True , eCoreTiny16K   },
  1269.   { "ATTINY2313"     ,  0x03f, 0x0080, 0x007f, IOAreaStdSize , True , eCoreTiny      },
  1270.   { "ATTINY2313A"    ,  0x03f, 0x0080, 0x007f, IOAreaStdSize , True , eCoreTiny      },
  1271.   { "ATTINY4313"     ,  0x07f, 0x0100, 0x00ff, IOAreaStdSize , True , eCoreTiny      },
  1272.  
  1273.   { "ATMEGA48"       ,  0x07f, 0x0200, 0x00ff, IOAreaExtSize , True , eCoreMega      },
  1274.  
  1275.   { "ATMEGA8"        ,  0x0ff, 0x0400, 0x01ff, IOAreaStdSize , True , eCoreMega      },
  1276.   { "ATMEGA8515"     ,  0x0ff, 0x0200, 0x01ff, IOAreaStdSize , True , eCoreMega      },
  1277.   { "ATMEGA8535"     ,  0x0ff, 0x0200, 0x01ff, IOAreaStdSize , True , eCoreMega      },
  1278.   { "ATMEGA88"       ,  0x0ff, 0x0200, 0x01ff, IOAreaExtSize , True , eCoreMega      },
  1279.   { "ATMEGA8U2"      ,  0x0ff, 0x0200, 0x01ff, IOAreaExtSize , True , eCoreMega      },
  1280.  
  1281.   { "ATMEGA16"       ,  0x1ff, 0x0400, 0x01ff, IOAreaStdSize , True , eCoreMega      },
  1282.   { "ATMEGA161"      ,  0x1ff, 0x0400, 0x01ff, IOAreaStdSize , True , eCoreMega      },
  1283.   { "ATMEGA162"      ,  0x1ff, 0x0400, 0x01ff, IOAreaExtSize , True , eCoreMega      },
  1284.   { "ATMEGA163"      ,  0x1ff, 0x0400, 0x01ff, IOAreaStdSize , True , eCoreMega      },
  1285.   { "ATMEGA164"      ,  0x1ff, 0x0400, 0x01ff, IOAreaExtSize , True , eCoreMega      },
  1286.   { "ATMEGA165"      ,  0x1ff, 0x0200, 0x01ff, IOAreaExtSize , True , eCoreMega      },
  1287.   { "ATMEGA168"      ,  0x1ff, 0x0400, 0x01ff, IOAreaExtSize , True , eCoreMega      },
  1288.   { "ATMEGA169"      ,  0x1ff, 0x0400, 0x01ff, IOAreaExtSize , True , eCoreMega      },
  1289.   { "ATMEGA16U2"     ,  0x1ff, 0x0200, 0x01ff, IOAreaExtSize , True , eCoreMega      },
  1290.   { "ATMEGA16U4"     ,  0x1ff, 0x0500, 0x01ff, IOAreaExtSize , True , eCoreMega      },
  1291.  
  1292.   { "ATMEGA32"       ,  0x3ff, 0x0800, 0x03ff, IOAreaStdSize , True , eCoreMega      },
  1293.   { "ATMEGA323"      ,  0x3ff, 0x0800, 0x03ff, IOAreaStdSize , True , eCoreMega      },
  1294.   { "ATMEGA324"      ,  0x3ff, 0x0800, 0x03ff, IOAreaExtSize , True , eCoreMega      },
  1295.   { "ATMEGA325"      ,  0x3ff, 0x0800, 0x03ff, IOAreaExtSize , True , eCoreMega      },
  1296.   { "ATMEGA3250"     ,  0x3ff, 0x0800, 0x03ff, IOAreaExtSize , True , eCoreMega      },
  1297.   { "ATMEGA328"      ,  0x3ff, 0x0800, 0x03ff, IOAreaExtSize , True , eCoreMega      },
  1298.   { "ATMEGA329"      ,  0x3ff, 0x0800, 0x03ff, IOAreaExtSize , True , eCoreMega      },
  1299.   { "ATMEGA3290"     ,  0x3ff, 0x0800, 0x03ff, IOAreaExtSize , True , eCoreMega      },
  1300.   { "ATMEGA32U2"     ,  0x3ff, 0x0400, 0x03ff, IOAreaExtSize , True , eCoreMega      },
  1301.   { "ATMEGA32U4"     ,  0x3ff, 0x0a00, 0x03ff, IOAreaExtSize , True , eCoreMega      },
  1302.   { "ATMEGA32U6"     ,  0x3ff, 0x0a00, 0x03ff, IOAreaExtSize , True , eCoreMega      },
  1303.  
  1304.   { "ATMEGA406"      ,  0x4ff, 0x0800, 0x01ff, IOAreaExtSize , True , eCoreMega      },
  1305.  
  1306.   { "ATMEGA64"       ,  0x7ff, 0x1000, 0x07ff, IOAreaExtSize , True , eCoreMega      },
  1307.   { "ATMEGA640"      ,  0x7ff, 0x2000, 0x0fff, IOAreaExt2Size, True , eCoreMega      },
  1308.   { "ATMEGA644"      ,  0x7ff, 0x1000, 0x07ff, IOAreaExtSize , True , eCoreMega      },
  1309.   { "ATMEGA644RFR2"  ,  0x7ff, 0x2000, 0x07ff, IOAreaExt2Size, True , eCoreMega      },
  1310.   { "ATMEGA645"      ,  0x7ff, 0x1000, 0x07ff, IOAreaExtSize , True , eCoreMega      },
  1311.   { "ATMEGA6450"     ,  0x7ff, 0x1000, 0x07ff, IOAreaExtSize , True , eCoreMega      },
  1312.   { "ATMEGA649"      ,  0x7ff, 0x1000, 0x07ff, IOAreaExtSize , True , eCoreMega      },
  1313.   { "ATMEGA6490"     ,  0x7ff, 0x1000, 0x07ff, IOAreaExtSize , True , eCoreMega      },
  1314.  
  1315.   { "ATMEGA103"      ,  0xfff, 0x1000, 0x0fff, IOAreaStdSize , True , eCoreMega      },
  1316.   { "ATMEGA128"      ,  0xfff, 0x1000, 0x0fff, IOAreaExtSize , True , eCoreMega      },
  1317.   { "ATMEGA1280"     ,  0xfff, 0x2000, 0x0fff, IOAreaExt2Size, True , eCoreMega      },
  1318.   { "ATMEGA1281"     ,  0xfff, 0x2000, 0x0fff, IOAreaExt2Size, True , eCoreMega      },
  1319.   { "ATMEGA1284"     ,  0xfff, 0x4000, 0x0fff, IOAreaExtSize , True , eCoreMega      },
  1320.   { "ATMEGA1284RFR2" ,  0xfff, 0x4000, 0x0fff, IOAreaExt2Size, True , eCoreMega      },
  1321.  
  1322.   { "ATMEGA2560"     , 0x1fff, 0x2000, 0x0fff, IOAreaExt2Size, True , eCoreMega      },
  1323.   { "ATMEGA2561"     , 0x1fff, 0x2000, 0x0fff, IOAreaExt2Size, True , eCoreMega      },
  1324.   { "ATMEGA2564RFR2" , 0x1fff, 0x8000, 0x1fff, IOAreaExt2Size, True , eCoreMega      },
  1325.   { NULL             ,    0x0, 0     , 0     , 0             , False, eCoreNone      },
  1326. };
  1327.  
  1328. void codeavr_init(void)
  1329. {
  1330.   const tCPUProps *pProp;
  1331.   static const tCPUArg AVRArgs[] =
  1332.   {
  1333.     { "CODESEGSIZE", 0, 1, 1, &CodeSegSize },
  1334.     { NULL         , 0, 0, 0, NULL         }
  1335.   };
  1336.  
  1337.   for (pProp = CPUProps; pProp->pName; pProp++)
  1338.     (void)AddCPUUserWithArgs(pProp->pName, SwitchTo_AVR, (void*)pProp, NULL, AVRArgs);
  1339. }
  1340.