Subversion Repositories pentevo

Rev

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

  1. /* code16c8x.c */
  2. /*****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
  4. /*                                                                           */
  5. /* AS-Portierung                                                             */
  6. /*                                                                           */
  7. /* AS-Codegenerator PIC16C8x                                                 */
  8. /*                                                                           */
  9. /*****************************************************************************/
  10.  
  11. #include "stdinc.h"
  12.  
  13. #include <string.h>
  14.  
  15. #include "chunks.h"
  16. #include "bpemu.h"
  17. #include "strutil.h"
  18. #include "asmdef.h"
  19. #include "asmsub.h"
  20. #include "asmpars.h"
  21. #include "asmitree.h"
  22. #include "headids.h"
  23. #include "codepseudo.h"
  24. #include "fourpseudo.h"
  25. #include "codevars.h"
  26. #include "errmsg.h"
  27.  
  28. #include "code16c8x.h"
  29.  
  30. /*---------------------------------------------------------------------------*/
  31.  
  32. #define AddCodeSpace 0x300
  33.  
  34. static CPUVar CPU16C64, CPU16C84, CPU16C873, CPU16C874, CPU16C876, CPU16C877;
  35.  
  36. /*--------------------------------------------------------------------------*/
  37. /* helper functions */
  38.  
  39. static Word EvalFExpression(tStrComp *pArg, tEvalResult *pEvalResult)
  40. {
  41.   LongInt h;
  42.  
  43.   h = EvalStrIntExpressionWithResult(pArg, UInt9, pEvalResult);
  44.   if (pEvalResult->OK)
  45.   {
  46.     ChkSpace(SegData, pEvalResult->AddrSpaceMask);
  47.     return (h & 0x7f);
  48.   }
  49.   else
  50.     return 0;
  51. }
  52.  
  53. /*--------------------------------------------------------------------------*/
  54. /* instruction decoders */
  55.  
  56. static void DecodeFixed(Word Code)
  57. {
  58.   if (ChkArgCnt(0, 0))
  59.   {
  60.     WAsmCode[CodeLen++] = Code;
  61.     if (Memo("OPTION"))
  62.       WrError(ErrNum_Obsolete);
  63.   }
  64. }
  65.  
  66. static void DecodeLit(Word Code)
  67. {
  68.   Word AdrWord;
  69.   Boolean OK;
  70.  
  71.   if (ChkArgCnt(1, 1))
  72.   {
  73.     AdrWord = EvalStrIntExpression(&ArgStr[1], Int8, &OK);
  74.     if (OK)
  75.       WAsmCode[CodeLen++] = Code | Lo(AdrWord);
  76.   }
  77. }
  78.  
  79. static void DecodeAri(Word Code)
  80. {
  81.   Word DefaultDir = (Code >> 8) & 0x80;
  82.   tEvalResult EvalResult;
  83.   Word AdrWord;
  84.  
  85.   Code &= 0x7fff;
  86.  
  87.   if (ChkArgCnt(1, 2))
  88.   {
  89.     AdrWord = EvalFExpression(&ArgStr[1], &EvalResult);
  90.     if (EvalResult.OK)
  91.     {
  92.       WAsmCode[0] = Code | AdrWord;
  93.       if (1 == ArgCnt)
  94.       {
  95.         WAsmCode[0] |= DefaultDir;
  96.         CodeLen = 1;
  97.       }
  98.       else if (!as_strcasecmp(ArgStr[2].str.p_str, "W"))
  99.         CodeLen = 1;
  100.       else if (!as_strcasecmp(ArgStr[2].str.p_str, "F"))
  101.       {
  102.          WAsmCode[0] |= 0x80;
  103.         CodeLen = 1;
  104.       }
  105.       else
  106.       {
  107.         AdrWord = EvalStrIntExpressionWithResult(&ArgStr[2], UInt1, &EvalResult);
  108.         if (EvalResult.OK)
  109.         {
  110.           WAsmCode[0] |= AdrWord << 7;
  111.           CodeLen = 1;
  112.         }
  113.       }
  114.     }
  115.   }
  116. }
  117.  
  118. static void DecodeBit(Word Code)
  119. {
  120.   if (ChkArgCnt(2, 2))
  121.   {
  122.     tEvalResult EvalResult;
  123.     Word AdrWord = EvalStrIntExpressionWithResult(&ArgStr[2], UInt3, &EvalResult);
  124.  
  125.     if (EvalResult.OK)
  126.     {
  127.       WAsmCode[0] = EvalFExpression(&ArgStr[1], &EvalResult);
  128.       if (EvalResult.OK)
  129.       {
  130.         WAsmCode[0] |= Code | (AdrWord << 7);
  131.         CodeLen = 1;
  132.       }
  133.     }
  134.   }
  135. }
  136.  
  137. static void DecodeF(Word Code)
  138. {
  139.   if (ChkArgCnt(1, 1))
  140.   {
  141.     tEvalResult EvalResult;
  142.     Word AdrWord = EvalFExpression(&ArgStr[1], &EvalResult);
  143.  
  144.     if (EvalResult.OK)
  145.       WAsmCode[CodeLen++] = Code | AdrWord;
  146.   }
  147. }
  148.  
  149. static void DecodeTRIS(Word Index)
  150. {
  151.   Word AdrWord;
  152.   tEvalResult EvalResult;
  153.  
  154.   UNUSED(Index);
  155.  
  156.   if (ChkArgCnt(1, 1))
  157.   {
  158.     AdrWord = EvalStrIntExpressionWithResult(&ArgStr[1], UInt3, &EvalResult);
  159.     if (mFirstPassUnknown(EvalResult.Flags))
  160.       AdrWord = 5;
  161.     if (EvalResult.OK)
  162.       if (ChkRange(AdrWord, 5, 6))
  163.       {
  164.         WAsmCode[CodeLen++] = 0x0060 | AdrWord;
  165.         ChkSpace(SegData, EvalResult.AddrSpaceMask);
  166.         WrError(ErrNum_Obsolete);
  167.       }
  168.   }
  169. }
  170.  
  171. static void DecodeJump(Word Index)
  172. {
  173.   if (ChkArgCnt(1, 1))
  174.   {
  175.     tEvalResult EvalResult;
  176.     Word AdrWord = EvalStrIntExpressionWithResult(&ArgStr[1], Int16, &EvalResult);
  177.     if (EvalResult.OK)
  178.     {
  179.       if (AdrWord > (SegLimits[SegCode] - AddCodeSpace)) WrError(ErrNum_OverRange);
  180.       else
  181.       {
  182.         Word XORVal, Mask, RegBit;
  183.  
  184.         ChkSpace(SegCode, EvalResult.AddrSpaceMask);
  185.  
  186.         XORVal = (ProgCounter() ^ AdrWord) & ~0x7ff;
  187.  
  188.         /* add BCF/BSF instruction for non-matching upper address bits
  189.            - we might need to extend this for the PICs with more than
  190.              8K of program space */
  191.  
  192.         for (RegBit = 3, Mask = 0x800; RegBit <= 4; RegBit++, Mask <<= 1)
  193.           if (XORVal & Mask)
  194.             WAsmCode[CodeLen++] = 0x100a
  195.                                 | (RegBit << 7)
  196.                                 | ((AdrWord & Mask) >> (RegBit - 2));
  197.  
  198.         WAsmCode[CodeLen++] = Index | (AdrWord & 0x7ff);
  199.       }
  200.     }
  201.   }
  202. }
  203.  
  204. static void DecodeSFR(Word Index)
  205. {
  206.   UNUSED(Index);
  207.  
  208.   CodeEquate(SegData, 0, 511);
  209. }
  210.  
  211. static void DecodeDATA_16C8x(Word Index)
  212. {
  213.   UNUSED(Index);
  214.  
  215.   DecodeDATA(Int14, Int8);
  216. }
  217.  
  218. static void DecodeZERO(Word Index)
  219. {
  220.   Word Size, Shift = (ActPC == SegCode) ? 1 : 0;
  221.   Boolean ValOK;
  222.   tSymbolFlags Flags;
  223.  
  224.   UNUSED(Index);
  225.  
  226.   if (ChkArgCnt(1, 1))
  227.   {
  228.     Size = EvalStrIntExpressionWithFlags(&ArgStr[1], Int16, &ValOK, &Flags);
  229.     if (mFirstPassUnknown(Flags)) WrError(ErrNum_FirstPassCalc);
  230.     if (ValOK && !mFirstPassUnknown(Flags))
  231.     {
  232.       if (SetMaxCodeLen(Size << Shift)) WrError(ErrNum_CodeOverflow);
  233.       else
  234.       {
  235.         CodeLen = Size;
  236.         memset(WAsmCode, 0, Size << Shift);
  237.       }
  238.     }
  239.   }
  240. }
  241.  
  242. static void DecodeBANKSEL(Word Index)
  243. {
  244.   Word Adr;
  245.   Boolean ValOK;
  246.  
  247.   UNUSED(Index);
  248.  
  249.   if (ChkArgCnt(1, 1))
  250.   {
  251.     Adr = EvalStrIntExpression(&ArgStr[1], UInt9, &ValOK);
  252.     if (ValOK)
  253.     {
  254.       WAsmCode[0] = 0x1283 | ((Adr &  0x80) << 3); /* BxF Status, 5 */
  255.       WAsmCode[1] = 0x1303 | ((Adr & 0x100) << 2); /* BxF Status, 6 */
  256.       CodeLen = 2;
  257.     }
  258.   }
  259. }
  260.  
  261. /*--------------------------------------------------------------------------*/
  262. /* dynamic code table handling */
  263.  
  264. static void AddFixed(const char *NName, Word NCode)
  265. {
  266.   AddInstTable(InstTable, NName, NCode, DecodeFixed);
  267. }
  268.  
  269. static void AddLit(const char *NName, Word NCode)
  270. {
  271.   AddInstTable(InstTable, NName, NCode, DecodeLit);
  272. }
  273.  
  274. static void AddAri(const char *NName, Word NCode, Word NDir)
  275. {
  276.   AddInstTable(InstTable, NName, NCode | (NDir << 15), DecodeAri);
  277. }
  278.  
  279. static void AddBit(const char *NName, Word NCode)
  280. {
  281.   AddInstTable(InstTable, NName, NCode, DecodeBit);
  282. }
  283.  
  284. static void AddF(const char *NName, Word NCode)
  285. {
  286.   AddInstTable(InstTable, NName, NCode, DecodeF);
  287. }
  288.  
  289. static void InitFields(void)
  290. {
  291.   InstTable = CreateInstTable(201);
  292.  
  293.   AddFixed("CLRW"  , 0x0100);
  294.   AddFixed("NOP"   , 0x0000);
  295.   AddFixed("CLRWDT", 0x0064);
  296.   AddFixed("OPTION", 0x0062);
  297.   AddFixed("SLEEP" , 0x0063);
  298.   AddFixed("RETFIE", 0x0009);
  299.   AddFixed("RETURN", 0x0008);
  300.  
  301.   AddLit("ADDLW", 0x3e00);
  302.   AddLit("ANDLW", 0x3900);
  303.   AddLit("IORLW", 0x3800);
  304.   AddLit("MOVLW", 0x3000);
  305.   AddLit("RETLW", 0x3400);
  306.   AddLit("SUBLW", 0x3c00);
  307.   AddLit("XORLW", 0x3a00);
  308.  
  309.   AddAri("ADDWF" , 0x0700, 0);
  310.   AddAri("ANDWF" , 0x0500, 0);
  311.   AddAri("COMF"  , 0x0900, 1);
  312.   AddAri("DECF"  , 0x0300, 1);
  313.   AddAri("DECFSZ", 0x0b00, 1);
  314.   AddAri("INCF"  , 0x0a00, 1);
  315.   AddAri("INCFSZ", 0x0f00, 1);
  316.   AddAri("IORWF" , 0x0400, 0);
  317.   AddAri("MOVF"  , 0x0800, 0);
  318.   AddAri("RLF"   , 0x0d00, 1);
  319.   AddAri("RRF"   , 0x0c00, 1);
  320.   AddAri("SUBWF" , 0x0200, 0);
  321.   AddAri("SWAPF" , 0x0e00, 1);
  322.   AddAri("XORWF" , 0x0600, 0);
  323.  
  324.   AddBit("BCF"  , 0x1000);
  325.   AddBit("BSF"  , 0x1400);
  326.   AddBit("BTFSC", 0x1800);
  327.   AddBit("BTFSS", 0x1c00);
  328.  
  329.   AddF("CLRF" , 0x0180);
  330.   AddF("MOVWF", 0x0080);
  331.  
  332.   AddInstTable(InstTable, "TRIS", 0, DecodeTRIS);
  333.   AddInstTable(InstTable, "GOTO", 0x2800, DecodeJump);
  334.   AddInstTable(InstTable, "CALL", 0x2000, DecodeJump);
  335.   AddInstTable(InstTable, "SFR" , 0, DecodeSFR);
  336.   AddInstTable(InstTable, "RES" , 0, DecodeRES);
  337.   AddInstTable(InstTable, "DATA", 0, DecodeDATA_16C8x);
  338.   AddInstTable(InstTable, "ZERO", 0, DecodeZERO);
  339.  
  340.   AddInstTable(InstTable, "BANKSEL", 0, DecodeBANKSEL);
  341. }
  342.  
  343. static void DeinitFields(void)
  344. {
  345.   DestroyInstTable(InstTable);
  346. }
  347.  
  348. /*--------------------------------------------------------------------------*/
  349.  
  350. static void MakeCode_16c8x(void)
  351. {
  352.   CodeLen = 0; DontPrint = False;
  353.  
  354.   /* zu ignorierendes */
  355.  
  356.   if (Memo("")) return;
  357.  
  358.   /* seek instruction */
  359.  
  360.   if (!LookupInstTable(InstTable, OpPart.str.p_str))
  361.     WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
  362. }
  363.  
  364. static Boolean IsDef_16c8x(void)
  365. {
  366.   return (Memo("SFR"));
  367. }
  368.  
  369. static Boolean ChkPC_16c8x(LargeWord Addr)
  370. {
  371.   if ((ActPC == SegCode) && (Addr > (LargeWord)SegLimits[SegCode]))
  372.     return ((Addr >= 0x2000) && (Addr <= 0x2007));
  373.   else
  374.     return (Addr <= (LargeWord)SegLimits[ActPC]);
  375. }
  376.  
  377. static void SwitchFrom_16c8x(void)
  378. {
  379.    DeinitFields();
  380. }
  381.  
  382. static void SwitchTo_16c8x(void)
  383. {
  384.   const TFamilyDescr *pDescr;
  385.  
  386.   TurnWords = False;
  387.   SetIntConstMode(eIntConstModeMoto);
  388.  
  389.   pDescr = FindFamilyByName("16C8x");
  390.   PCSymbol = "*";
  391.   HeaderID = pDescr->Id;
  392.   NOPCode = 0x0000;
  393.   DivideChars = ",";
  394.   HasAttrs = False;
  395.  
  396.   ValidSegs = (1 << SegCode) | (1 << SegData);
  397.   Grans[SegCode] = 2; ListGrans[SegCode] = 2; SegInits[SegCode] = 0;
  398.   if (MomCPU == CPU16C64)
  399.     SegLimits[SegCode] = 0x7ff;
  400.   else if (MomCPU == CPU16C873)
  401.     SegLimits[SegCode] = 0x0fff;
  402.   else if (MomCPU == CPU16C874)
  403.     SegLimits[SegCode] = 0x0fff;
  404.   else if (MomCPU == CPU16C876)
  405.     SegLimits[SegCode] = 0x1fff;
  406.   else if (MomCPU == CPU16C877)
  407.     SegLimits[SegCode] = 0x1fff;
  408.   else
  409.     SegLimits[SegCode] = 0x3ff;
  410.  
  411.   SegLimits[SegCode] += AddCodeSpace;
  412.   Grans[SegData] = 1; ListGrans[SegData] = 1; SegInits[SegData] = 0;
  413.   SegLimits[SegData] = 0x1ff;
  414.   Grans[SegEEData] = 1; ListGrans[SegEEData] = 1; SegInits[SegEEData] = 0;
  415.   if ((MomCPU == CPU16C877) || (MomCPU == CPU16C876))
  416.     SegLimits[SegEEData] = 0xff;
  417.   else if ((MomCPU == CPU16C874) || (MomCPU == CPU16C873))
  418.     SegLimits[SegEEData] = 0x7f;
  419.   else
  420.     SegLimits[SegEEData] = 0x3f;
  421.   ChkPC = ChkPC_16c8x;
  422.  
  423.   MakeCode = MakeCode_16c8x;
  424.   IsDef = IsDef_16c8x;
  425.   SwitchFrom = SwitchFrom_16c8x;
  426.   InitFields();
  427. }
  428.  
  429. void code16c8x_init(void)
  430. {
  431.   CPU16C64  = AddCPU("16C64",  SwitchTo_16c8x);
  432.   CPU16C84  = AddCPU("16C84",  SwitchTo_16c8x);
  433.   CPU16C873 = AddCPU("16C873", SwitchTo_16c8x);
  434.   CPU16C874 = AddCPU("16C874", SwitchTo_16c8x);
  435.   CPU16C876 = AddCPU("16C876", SwitchTo_16c8x);
  436.   CPU16C877 = AddCPU("16C877", SwitchTo_16c8x);
  437. }
  438.