Subversion Repositories pentevo

Rev

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

  1. /* code4500.c */
  2. /*****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
  4. /*                                                                           */
  5. /* AS-Portierung                                                             */
  6. /*                                                                           */
  7. /* Codegenerator MELPS-4500                                                  */
  8. /*                                                                           */
  9. /*****************************************************************************/
  10.  
  11. #include "stdinc.h"
  12.  
  13. #include <string.h>
  14.  
  15. #include "chunks.h"
  16. #include "asmdef.h"
  17. #include "asmsub.h"
  18. #include "asmpars.h"
  19. #include "asmitree.h"
  20. #include "codepseudo.h"
  21. #include "fourpseudo.h"
  22. #include "codevars.h"
  23. #include "errmsg.h"
  24.  
  25.  
  26. typedef struct
  27. {
  28.   Word Code;
  29.   IntType Max;
  30. } ConstOrder;
  31.  
  32.  
  33. static CPUVar CPU4500;
  34.  
  35. static ConstOrder *ConstOrders;
  36.  
  37. /*-------------------------------------------------------------------------*/
  38.  
  39. static void DecodeSFR(Word Code)
  40. {
  41.   UNUSED(Code);
  42.  
  43.   CodeEquate(SegData, 0, 415);
  44. }
  45.  
  46. static void DecodeDATA_4500(Word Code)
  47. {
  48.   UNUSED(Code);
  49.  
  50.   DecodeDATA(Int10, Int4);
  51. }
  52.  
  53. static void DecodeFixed(Word Code)
  54. {
  55.   if (ChkArgCnt(0, 0))
  56.   {
  57.     CodeLen = 1;
  58.     WAsmCode[0] = Code;
  59.   }
  60. }
  61.  
  62. static void DecodeConst(Word Index)
  63. {
  64.   const ConstOrder *pOrder = ConstOrders + Index;
  65.  
  66.   if (ChkArgCnt(1, 1))
  67.   {
  68.     Boolean OK;
  69.  
  70.     WAsmCode[0] = EvalStrIntExpression(&ArgStr[1], pOrder->Max, &OK);
  71.     if (OK)
  72.     {
  73.       CodeLen = 1;
  74.       WAsmCode[0] += pOrder->Code;
  75.     }
  76.   }
  77. }
  78.  
  79. static void DecodeSZD(Word Code)
  80. {
  81.   UNUSED(Code);
  82.  
  83.   if (ChkArgCnt(0, 0))
  84.   {
  85.     CodeLen = 2;
  86.     WAsmCode[0] = 0x024;
  87.     WAsmCode[1] = 0x02b;
  88.   }
  89. }
  90.  
  91. static void DecodeSEA(Word Code)
  92. {
  93.   UNUSED(Code);
  94.  
  95.   if (ChkArgCnt(1, 1))
  96.   {
  97.     Boolean OK;
  98.  
  99.     WAsmCode[1] = EvalStrIntExpression(&ArgStr[1], UInt4, &OK);
  100.     if (OK)
  101.     {
  102.       CodeLen = 2;
  103.       WAsmCode[1] += 0x070;
  104.       WAsmCode[0] = 0x025;
  105.     }
  106.   }
  107. }
  108.  
  109. static void DecodeB(Word Code)
  110. {
  111.   UNUSED(Code);
  112.  
  113.   if (ChkArgCnt(1, 1))
  114.   {
  115.     Word AdrWord;
  116.     Boolean OK;
  117.     tSymbolFlags Flags;
  118.  
  119.     AdrWord = EvalStrIntExpressionWithFlags(&ArgStr[1], UInt13, &OK, &Flags);
  120.     if (OK && ChkSamePage(EProgCounter(), AdrWord, 7, Flags))
  121.     {
  122.       CodeLen = 1;
  123.       WAsmCode[0] = 0x180 + (AdrWord & 0x7f);
  124.     }
  125.   }
  126. }
  127.  
  128. static void DecodeBL_BML(Word Code)
  129. {
  130.   if (ChkArgCnt(1, 2))
  131.   {
  132.     Boolean OK;
  133.     Word AdrWord;
  134.  
  135.     if (ArgCnt == 1)
  136.       AdrWord = EvalStrIntExpression(&ArgStr[1], UInt13, &OK);
  137.     else
  138.     {
  139.       AdrWord = EvalStrIntExpression(&ArgStr[1], UInt6, &OK) << 7;
  140.       if (OK)
  141.         AdrWord += EvalStrIntExpression(&ArgStr[2], UInt7, &OK);
  142.     }
  143.     if (OK)
  144.     {
  145.       CodeLen = 2;
  146.       WAsmCode[1] = 0x200 + (AdrWord & 0x7f) + ((AdrWord >> 12) << 7);
  147.       WAsmCode[0] = Code + ((AdrWord >> 7) & 0x1f);
  148.     }
  149.   }
  150. }
  151.  
  152. static void DecodeBLA_BMLA(Word Code)
  153. {
  154.   if (ChkArgCnt(1, 1))
  155.   {
  156.     Boolean OK;
  157.     Word AdrWord;
  158.  
  159.     AdrWord = EvalStrIntExpression(&ArgStr[1], UInt6, &OK);
  160.     if (OK)
  161.     {
  162.       CodeLen = 2;
  163.       WAsmCode[1] = 0x200 + (AdrWord & 0x0f) + ((AdrWord & 0x30) << 2);
  164.       WAsmCode[0] = Code;
  165.     }
  166.   }
  167. }
  168.  
  169. static void DecodeBM(Word Code)
  170. {
  171.   UNUSED(Code);
  172.  
  173.   if (ChkArgCnt(1, 1))
  174.   {
  175.     Boolean OK;
  176.     Word AdrWord;
  177.  
  178.     AdrWord = EvalStrIntExpression(&ArgStr[1], UInt13, &OK);
  179.     if (OK)
  180.     {
  181.       if ((AdrWord >> 7) != 2) WrError(ErrNum_NotFromThisAddress);
  182.       else
  183.       {
  184.         CodeLen = 1;
  185.         WAsmCode[0] = 0x100 + (AdrWord & 0x7f);
  186.       }
  187.     }
  188.   }
  189. }
  190.  
  191. static void DecodeLXY(Word Code)
  192. {
  193.   UNUSED(Code);
  194.  
  195.   if (ChkArgCnt(1, 2))
  196.   {
  197.     Boolean OK;
  198.     Word AdrWord;
  199.  
  200.     if (ArgCnt == 1)
  201.       AdrWord = EvalStrIntExpression(&ArgStr[1], Int8, &OK);
  202.     else
  203.     {
  204.       AdrWord = EvalStrIntExpression(&ArgStr[1], Int4, &OK) << 4;
  205.       if (OK)
  206.         AdrWord += EvalStrIntExpression(&ArgStr[2], Int4, &OK);
  207.     }
  208.     if (OK)
  209.     {
  210.       CodeLen = 1;
  211.       WAsmCode[0] = 0x300 + AdrWord;
  212.     }
  213.   }
  214. }
  215.  
  216. /*---------------------------------------------------------------------------*/
  217.  
  218. static void AddFixed(const char *NName, Word NCode)
  219. {
  220.   AddInstTable(InstTable, NName, NCode, DecodeFixed);
  221. }
  222.  
  223. static void AddConst(const char *NName, Word NCode, IntType NMax)
  224. {
  225.   order_array_rsv_end(ConstOrders, ConstOrder);
  226.   ConstOrders[InstrZ].Code = NCode;
  227.   ConstOrders[InstrZ].Max = NMax;
  228.   AddInstTable(InstTable, NName, InstrZ++, DecodeConst);
  229. }
  230.  
  231. static void InitFields(void)
  232. {
  233.   InstTable = CreateInstTable(307);
  234.   AddInstTable(InstTable, "SZD", 0, DecodeSZD);
  235.   AddInstTable(InstTable, "SEA", 0, DecodeSEA);
  236.   AddInstTable(InstTable, "B", 0, DecodeB);
  237.   AddInstTable(InstTable, "BL", 0x0e0, DecodeBL_BML);
  238.   AddInstTable(InstTable, "BML", 0x0c0, DecodeBL_BML);
  239.   AddInstTable(InstTable, "BLA", 0x010, DecodeBLA_BMLA);
  240.   AddInstTable(InstTable, "BMLA", 0x030, DecodeBLA_BMLA);
  241.   AddInstTable(InstTable, "BM", 0, DecodeBM);
  242.   AddInstTable(InstTable, "LXY", 0, DecodeLXY);
  243.  
  244.   AddInstTable(InstTable, "SFR", 0, DecodeSFR);
  245.   AddInstTable(InstTable, "RES", 0, DecodeRES);
  246.   AddInstTable(InstTable, "DATA", 0, DecodeDATA_4500);
  247.  
  248.   AddFixed("AM"   , 0x00a);  AddFixed("AMC"  , 0x00b);  AddFixed("AND"  , 0x018);
  249.   AddFixed("CLD"  , 0x011);  AddFixed("CMA"  , 0x01c);  AddFixed("DEY"  , 0x017);
  250.   AddFixed("DI"   , 0x004);  AddFixed("EI"   , 0x005);  AddFixed("IAP0" , 0x260);
  251.   AddFixed("IAP1" , 0x261);  AddFixed("IAP2" , 0x262);  AddFixed("IAP3" , 0x263);
  252.   AddFixed("IAP4" , 0x264);  AddFixed("INY"  , 0x013);  AddFixed("NOP"  , 0x000);
  253.   AddFixed("OR"   , 0x019);  AddFixed("OP0A" , 0x220);  AddFixed("OP1A" , 0x221);
  254.   AddFixed("POF"  , 0x002);  AddFixed("POF2" , 0x008);  AddFixed("RAR"  , 0x01d);
  255.   AddFixed("RC"   , 0x006);  AddFixed("RC3"  , 0x2ac);  AddFixed("RC4"  , 0x2ae);
  256.   AddFixed("RD"   , 0x014);  AddFixed("RT"   , 0x044);  AddFixed("RTI"  , 0x046);
  257.   AddFixed("RTS"  , 0x045);  AddFixed("SC"   , 0x007);  AddFixed("SC3"  , 0x2ad);
  258.   AddFixed("SC4"  , 0x2af);  AddFixed("SD"   , 0x015);  AddFixed("SEAM" , 0x026);
  259.   AddFixed("SNZ0" , 0x038);  AddFixed("SNZP" , 0x003);  AddFixed("SNZT1", 0x280);
  260.   AddFixed("SNZT2", 0x281);  AddFixed("SNZT3", 0x282);  AddFixed("SPCR" , 0x299);
  261.   AddFixed("STCR" , 0x298);  AddFixed("SZC"  , 0x02f);  AddFixed("T1R1" , 0x2ab);
  262.   AddFixed("T3AB" , 0x232);  AddFixed("TAB"  , 0x01e);  AddFixed("TAB3" , 0x272);
  263.   AddFixed("TABE" , 0x02a);  AddFixed("TAD"  , 0x051);  AddFixed("TAI1" , 0x253);
  264.   AddFixed("TAL1" , 0x24a);  AddFixed("TAMR" , 0x252);  AddFixed("TASP" , 0x050);
  265.   AddFixed("TAV1" , 0x054);  AddFixed("TAW1" , 0x24b);  AddFixed("TAW2" , 0x24c);
  266.   AddFixed("TAW3" , 0x24d);  AddFixed("TAX"  , 0x052);  AddFixed("TAY"  , 0x01f);
  267.   AddFixed("TAZ"  , 0x053);  AddFixed("TBA"  , 0x00e);  AddFixed("TC1A" , 0x2a8);
  268.   AddFixed("TC2A" , 0x2a9);  AddFixed("TDA"  , 0x029);  AddFixed("TEAB" , 0x01a);
  269.   AddFixed("TI1A" , 0x217);  AddFixed("TL1A" , 0x20a);  AddFixed("TL2A" , 0x20b);
  270.   AddFixed("TL3A" , 0x20c);  AddFixed("TLCA" , 0x20d);  AddFixed("TMRA" , 0x216);
  271.   AddFixed("TPTA" , 0x2a5);  AddFixed("TPAA" , 0x2aa);  AddFixed("TR1A" , 0x2a6);
  272.   AddFixed("TR1AB", 0x23f);  AddFixed("TV1A" , 0x03f);  AddFixed("TW1A" , 0x20e);
  273.   AddFixed("TW2A" , 0x20f);  AddFixed("TW3A" , 0x210);  AddFixed("TYA"  , 0x00c);
  274.   AddFixed("WRST" , 0x2a0);
  275.  
  276.   InstrZ = 0;
  277.   AddConst("A"   , 0x060, UInt4);  AddConst("LA"  , 0x070, UInt4);
  278.   AddConst("LZ"  , 0x048, UInt2);  AddConst("RB"  , 0x04c, UInt2);
  279.   AddConst("SB"  , 0x05c, UInt2);  AddConst("SZB" , 0x020, UInt2);
  280.   AddConst("TABP", 0x080, UInt6);  AddConst("TAM" , 0x2c0, UInt4);
  281.   AddConst("TMA" , 0x2b0, UInt4);  AddConst("XAM" , 0x2d0, UInt4);
  282.   AddConst("XAMD", 0x2f0, UInt4);  AddConst("XAMI", 0x2e0, UInt4);
  283. }
  284.  
  285. static void DeinitFields(void)
  286. {
  287.   DestroyInstTable(InstTable);
  288.  
  289.   order_array_free(ConstOrders);
  290. }
  291.  
  292. /*---------------------------------------------------------------------------*/
  293.  
  294. static void MakeCode_4500(void)
  295. {
  296.   CodeLen = 0;
  297.   DontPrint = False;
  298.  
  299.   /* zu ignorierendes */
  300.  
  301.   if (Memo(""))
  302.     return;
  303.  
  304.   if (!LookupInstTable(InstTable, OpPart.str.p_str))
  305.     WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
  306. }
  307.  
  308. static Boolean IsDef_4500(void)
  309. {
  310.   return (Memo("SFR"));
  311. }
  312.  
  313. static void SwitchFrom_4500(void)
  314. {
  315.   DeinitFields();
  316. }
  317.  
  318. static void SwitchTo_4500(void)
  319. {
  320.   TurnWords = False;
  321.   SetIntConstMode(eIntConstModeMoto);
  322.  
  323.   PCSymbol = "*";
  324.   HeaderID = 0x12;
  325.   NOPCode = 0x000;
  326.   DivideChars = ",";
  327.   HasAttrs = False;
  328.  
  329.   ValidSegs = (1 << SegCode) | (1 << SegData);
  330.   Grans[SegCode ] = 2; ListGrans[SegCode ] = 2; SegInits[SegCode ] = 0;
  331.   SegLimits[SegCode] = 0x1fff;
  332.   Grans[SegData ] = 1; ListGrans[SegData ] = 1; SegInits[SegData ] = 0;
  333.   SegLimits[SegData] = 415;
  334.  
  335.   MakeCode = MakeCode_4500;
  336.   IsDef = IsDef_4500;
  337.   SwitchFrom = SwitchFrom_4500;
  338.  
  339.   InitFields();
  340. }
  341.  
  342. void code4500_init(void)
  343. {
  344.   CPU4500 = AddCPU("MELPS4500", SwitchTo_4500);
  345. }
  346.