Subversion Repositories pentevo

Rev

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

  1. /* code16c5x.c */
  2. /*****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
  4. /*                                                                           */
  5. /* AS-Portierung                                                             */
  6. /*                                                                           */
  7. /* AS - Codegenerator fuer PIC16C5x                                          */
  8. /*                                                                           */
  9. /*****************************************************************************/
  10.  
  11. #include "stdinc.h"
  12.  
  13. #include <string.h>
  14.  
  15. #include "strutil.h"
  16. #include "chunks.h"
  17. #include "asmdef.h"
  18. #include "asmsub.h"
  19. #include "asmpars.h"
  20. #include "asmitree.h"
  21. #include "codepseudo.h"
  22. #include "fourpseudo.h"
  23. #include "codevars.h"
  24. #include "errmsg.h"
  25.  
  26. #include "code16c5x.h"
  27.  
  28. static CPUVar CPU16C54, CPU16C55, CPU16C56, CPU16C57;
  29.  
  30. /*-------------------------------------------------------------------------*/
  31.  
  32. static void DecodeFixed(Word Code)
  33. {
  34.   if (ChkArgCnt(0, 0))
  35.   {
  36.     CodeLen = 1;
  37.     WAsmCode[0] = Code;
  38.   }
  39. }
  40.  
  41. static void DecodeLit(Word Code)
  42. {
  43.   if (ChkArgCnt(1, 1))
  44.   {
  45.     Boolean OK;
  46.     Word AdrWord = EvalStrIntExpression(&ArgStr[1], Int8, &OK);
  47.     if (OK)
  48.     {
  49.       CodeLen = 1;
  50.       WAsmCode[0] = Code + (AdrWord & 0xff);
  51.     }
  52.   }
  53. }
  54.  
  55. static void DecodeAri(Word Code)
  56. {
  57.   Word DefaultDir = (Code >> 15) & 1, AdrWord;
  58.  
  59.   Code &= 0x7fff;
  60.   if (ChkArgCnt(1, 2))
  61.   {
  62.     tEvalResult EvalResult;
  63.  
  64.     AdrWord = EvalStrIntExpressionWithResult(&ArgStr[1], UInt5, &EvalResult);
  65.     if (EvalResult.OK)
  66.     {
  67.       ChkSpace(SegData, EvalResult.AddrSpaceMask);
  68.       WAsmCode[0] = Code + (AdrWord & 0x1f);
  69.       if (ArgCnt == 1)
  70.       {
  71.         CodeLen = 1;
  72.         WAsmCode[0] += DefaultDir << 5;
  73.       }
  74.       else if (!as_strcasecmp(ArgStr[2].str.p_str, "W"))
  75.         CodeLen = 1;
  76.       else if (!as_strcasecmp(ArgStr[2].str.p_str, "F"))
  77.       {
  78.         CodeLen = 1;
  79.         WAsmCode[0] += 0x20;
  80.       }
  81.       else
  82.       {
  83.         AdrWord = EvalStrIntExpressionWithResult(&ArgStr[2], UInt1, &EvalResult);
  84.         if (EvalResult.OK)
  85.         {
  86.           CodeLen = 1;
  87.           WAsmCode[0] += AdrWord << 5;
  88.         }
  89.       }
  90.     }
  91.   }
  92. }
  93.  
  94. static void DecodeBit(Word Code)
  95. {
  96.   if (ChkArgCnt(2, 2))
  97.   {
  98.     tEvalResult EvalResult;
  99.     Word AdrWord = EvalStrIntExpressionWithResult(&ArgStr[2], UInt3, &EvalResult);
  100.  
  101.     if (EvalResult.OK)
  102.     {
  103.       WAsmCode[0] = EvalStrIntExpressionWithResult(&ArgStr[1], UInt5, &EvalResult);
  104.       if (EvalResult.OK)
  105.       {
  106.         CodeLen = 1;
  107.         WAsmCode[0] += Code + (AdrWord << 5);
  108.         ChkSpace(SegData, EvalResult.AddrSpaceMask);
  109.       }
  110.     }
  111.   }
  112. }
  113.  
  114. static void DecodeF(Word Code)
  115. {
  116.   if (ChkArgCnt(1, 1))
  117.   {
  118.     tEvalResult EvalResult;
  119.     Word AdrWord = EvalStrIntExpressionWithResult(&ArgStr[1], UInt5, &EvalResult);
  120.  
  121.     if (EvalResult.OK)
  122.     {
  123.       CodeLen = 1;
  124.       WAsmCode[0] = Code + AdrWord;
  125.       ChkSpace(SegData, EvalResult.AddrSpaceMask);
  126.     }
  127.   }
  128. }
  129.  
  130. static void DecodeTRIS(Word Code)
  131. {
  132.   UNUSED(Code);
  133.  
  134.   if (ChkArgCnt(1, 1))
  135.   {
  136.     tEvalResult EvalResult;
  137.     Word AdrWord = EvalStrIntExpressionWithResult(&ArgStr[1], UInt3, &EvalResult);
  138.  
  139.     if (EvalResult.OK)
  140.      if (ChkRange(AdrWord, 5, 7))
  141.      {
  142.        CodeLen = 1;
  143.        WAsmCode[0] = 0x000 + AdrWord;
  144.        ChkSpace(SegData, EvalResult.AddrSpaceMask);
  145.      }
  146.   }
  147. }
  148.  
  149. static void DecodeCALL_GOTO(Word Code)
  150. {
  151.   if (ChkArgCnt(1, 1))
  152.   {
  153.     tEvalResult EvalResult;
  154.     Word AdrWord = EvalStrIntExpressionWithResult(&ArgStr[1], UInt16, &EvalResult);
  155.  
  156.     if (EvalResult.OK)
  157.     {
  158.       if (AdrWord > SegLimits[SegCode]) WrError(ErrNum_OverRange);
  159.       else if ((Code & 0x100) && ((AdrWord & 0x100) != 0)) WrError(ErrNum_NotFromThisAddress);
  160.       else
  161.       {
  162.         ChkSpace(SegCode, EvalResult.AddrSpaceMask);
  163.         if (((ProgCounter() ^ AdrWord) & 0x200) != 0)
  164.           WAsmCode[CodeLen++] = 0x4a3 + ((AdrWord & 0x200) >> 1); /* BCF/BSF 3,5 */
  165.         if (((ProgCounter() ^ AdrWord) & 0x400) != 0)
  166.           WAsmCode[CodeLen++] = 0x4c3 + ((AdrWord & 0x400) >> 2); /* BCF/BSF 3,6 */
  167.         WAsmCode[CodeLen++] = Code + (AdrWord & (Code & 0x100 ? 0xff : 0x1ff));
  168.       }
  169.     }
  170.   }
  171. }
  172.  
  173. static void DecodeSFR(Word Code)
  174. {
  175.   UNUSED(Code);
  176.  
  177.   CodeEquate(SegData, 0, 0x1f);
  178. }
  179.  
  180. static void DecodeDATA_16C5x(Word Code)
  181. {
  182.   UNUSED(Code);
  183.  
  184.   DecodeDATA(Int12, Int8);
  185. }
  186.  
  187. static void DecodeZERO(Word Code)
  188. {
  189.   Word Size;
  190.   Boolean ValOK;
  191.   tSymbolFlags Flags;
  192.  
  193.   UNUSED(Code);
  194.  
  195.   if (ChkArgCnt(1, 1))
  196.   {
  197.     Size = EvalStrIntExpressionWithFlags(&ArgStr[1], Int16, &ValOK, &Flags);
  198.     if (mFirstPassUnknown(Flags)) WrError(ErrNum_FirstPassCalc);
  199.     if (ValOK && !mFirstPassUnknown(Flags))
  200.     {
  201.       if (SetMaxCodeLen(Size << 1)) WrError(ErrNum_CodeOverflow);
  202.       else
  203.       {
  204.         CodeLen = Size;
  205.         memset(WAsmCode, 0, 2 * Size);
  206.       }
  207.     }
  208.   }
  209. }
  210.  
  211. /*-------------------------------------------------------------------------*/
  212.  
  213. static void AddFixed(const char *NName, Word NCode)
  214. {
  215.   AddInstTable(InstTable, NName, NCode, DecodeFixed);
  216. }
  217.  
  218. static void AddLit(const char *NName, Word NCode)
  219. {
  220.   AddInstTable(InstTable, NName, NCode, DecodeLit);
  221. }
  222.  
  223. static void AddAri(const char *NName, Word NCode, Word NDef)
  224. {
  225.   AddInstTable(InstTable, NName, NCode | (NDef << 15), DecodeAri);
  226. }
  227.  
  228. static void AddBit(const char *NName, Word NCode)
  229. {
  230.   AddInstTable(InstTable, NName, NCode, DecodeBit);
  231. }
  232.  
  233. static void AddF(const char *NName, Word NCode)
  234. {
  235.   AddInstTable(InstTable, NName, NCode, DecodeF);
  236. }
  237.  
  238. static void InitFields(void)
  239. {
  240.   InstTable = CreateInstTable(103);
  241.   AddInstTable(InstTable, "TRIS", 0, DecodeTRIS);
  242.   AddInstTable(InstTable, "CALL", 0x0900, DecodeCALL_GOTO);
  243.   AddInstTable(InstTable, "GOTO", 0x0a00, DecodeCALL_GOTO);
  244.   AddInstTable(InstTable, "SFR", 0, DecodeSFR);
  245.   AddInstTable(InstTable, "RES", 0, DecodeRES);
  246.   AddInstTable(InstTable, "DATA", 0, DecodeDATA_16C5x);
  247.   AddInstTable(InstTable, "ZERO", 0, DecodeZERO);
  248.  
  249.   AddFixed("CLRW"  , 0x040);
  250.   AddFixed("NOP"   , 0x000);
  251.   AddFixed("CLRWDT", 0x004);
  252.   AddFixed("OPTION", 0x002);
  253.   AddFixed("SLEEP" , 0x003);
  254.  
  255.   AddLit("ANDLW", 0xe00);
  256.   AddLit("IORLW", 0xd00);
  257.   AddLit("MOVLW", 0xc00);
  258.   AddLit("RETLW", 0x800);
  259.   AddLit("XORLW", 0xf00);
  260.  
  261.   AddAri("ADDWF" , 0x1c0, 0);
  262.   AddAri("ANDWF" , 0x140, 0);
  263.   AddAri("COMF"  , 0x240, 1);
  264.   AddAri("DECF"  , 0x0c0, 1);
  265.   AddAri("DECFSZ", 0x2c0, 1);
  266.   AddAri("INCF"  , 0x280, 1);
  267.   AddAri("INCFSZ", 0x3c0, 1);
  268.   AddAri("IORWF" , 0x100, 0);
  269.   AddAri("MOVF"  , 0x200, 0);
  270.   AddAri("RLF"   , 0x340, 1);
  271.   AddAri("RRF"   , 0x300, 1);
  272.   AddAri("SUBWF" , 0x080, 0);
  273.   AddAri("SWAPF" , 0x380, 1);
  274.   AddAri("XORWF" , 0x180, 0);
  275.  
  276.   AddBit("BCF"  , 0x400);
  277.   AddBit("BSF"  , 0x500);
  278.   AddBit("BTFSC", 0x600);
  279.   AddBit("BTFSS", 0x700);
  280.  
  281.   AddF("CLRF" , 0x060);
  282.   AddF("MOVWF", 0x020);
  283. }
  284.  
  285. static void DeinitFields(void)
  286. {
  287.   DestroyInstTable(InstTable);
  288. }
  289.  
  290. /*-------------------------------------------------------------------------*/
  291.  
  292. static void MakeCode_16C5X(void)
  293. {
  294.   CodeLen = 0;
  295.   DontPrint = False;
  296.  
  297.   /* zu ignorierendes */
  298.  
  299.   if (Memo(""))
  300.     return;
  301.  
  302.   if (!LookupInstTable(InstTable, OpPart.str.p_str))
  303.     WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
  304. }
  305.  
  306. static Boolean IsDef_16C5X(void)
  307. {
  308.   return Memo("SFR");
  309. }
  310.  
  311. static void SwitchFrom_16C5X(void)
  312. {
  313.   DeinitFields();
  314. }
  315.  
  316. static void SwitchTo_16C5X(void)
  317. {
  318.   TurnWords = False;
  319.   SetIntConstMode(eIntConstModeMoto);
  320.  
  321.   PCSymbol = "*";
  322.   HeaderID = 0x71;
  323.   NOPCode = 0x000;
  324.   DivideChars = ",";
  325.   HasAttrs = False;
  326.  
  327.   ValidSegs = (1 << SegCode) + (1 << SegData);
  328.   Grans[SegCode] = 2; ListGrans[SegCode] = 2; SegInits[SegCode] = 0;
  329.   if (MomCPU == CPU16C56)
  330.     SegLimits[SegCode] = 1023;
  331.   else if (MomCPU == CPU16C57)
  332.     SegLimits[SegCode] = 2047;
  333.   else
  334.     SegLimits[SegCode] = 511;
  335.   Grans[SegData] = 1; ListGrans[SegData] = 1; SegInits[SegCode] = 0;
  336.   SegLimits[SegData] = 0x1f;
  337.  
  338.   MakeCode = MakeCode_16C5X;
  339.   IsDef = IsDef_16C5X;
  340.   SwitchFrom = SwitchFrom_16C5X;
  341.   InitFields();
  342. }
  343.  
  344. void code16c5x_init(void)
  345. {
  346.   CPU16C54 = AddCPU("16C54", SwitchTo_16C5X);
  347.   CPU16C55 = AddCPU("16C55", SwitchTo_16C5X);
  348.   CPU16C56 = AddCPU("16C56", SwitchTo_16C5X);
  349.   CPU16C57 = AddCPU("16C57", SwitchTo_16C5X);
  350. }
  351.