Subversion Repositories pentevo

Rev

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

  1. /* code75xx.c */
  2. /*****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
  4. /*                                                                           */
  5. /* AS-Portierung                                                             */
  6. /*                                                                           */
  7. /* Codegenerator NEC 75xx                                                    */
  8. /*                                                                           */
  9. /*****************************************************************************/
  10.  
  11. #include "stdinc.h"
  12. #include <string.h>
  13. #include <ctype.h>
  14.  
  15. #include "nls.h"
  16. #include "strutil.h"
  17. #include "headids.h"
  18. #include "bpemu.h"
  19. #include "asmdef.h"
  20. #include "asmsub.h"
  21. #include "asmpars.h"
  22. #include "asmitree.h"
  23. #include "codepseudo.h"
  24. #include "intpseudo.h"
  25. #include "codevars.h"
  26. #include "errmsg.h"
  27.  
  28. #include "code75xx.h"
  29.  
  30. static CPUVar CPU7566, CPU7508;
  31. static IntType CodeIntType, DataIntType;
  32.  
  33. /*-------------------------------------------------------------------------*/
  34. /* code generation */
  35.  
  36. static void PutCode(Word Code)
  37. {
  38.   CodeLen = 0;
  39.   if (Hi(Code))
  40.     BAsmCode[CodeLen++] = Hi(Code);
  41.   BAsmCode[CodeLen++] = Lo(Code);
  42. }
  43.  
  44. static void DecodeFixed(Word Index)
  45. {
  46.   if (ChkArgCnt(0, 0))
  47.     PutCode(Index);
  48. }
  49.  
  50. static void DecodeImm4(Word Index)
  51. {
  52.   if (ChkArgCnt(1, 1))
  53.   {
  54.     tEvalResult EvalResult;
  55.     Word Value = EvalStrIntExpressionWithResult(&ArgStr[1], Int4, &EvalResult);
  56.  
  57.     if (EvalResult.OK)
  58.     {
  59.       PutCode(Index | (Value & 15));
  60.       if (Memo("OP"))
  61.         ChkSpace(SegIO, EvalResult.AddrSpaceMask);
  62.     }
  63.   }
  64. }
  65.  
  66. static void DecodeImm5(Word Index)
  67. {
  68.   if (ChkArgCnt(1, 1))
  69.   {
  70.     Boolean OK;
  71.     Word Value;
  72.  
  73.     Value = EvalStrIntExpression(&ArgStr[1], Int5, &OK);
  74.     if (OK)
  75.       PutCode(Index | (Value & 31));
  76.   }
  77. }
  78.  
  79. static void DecodeImm8(Word Index)
  80. {
  81.   if (ChkArgCnt(1, 1))
  82.   {
  83.     Boolean OK;
  84.     Word Value;
  85.  
  86.     Value = EvalStrIntExpression(&ArgStr[1], Int8, &OK);
  87.     if (OK)
  88.     {
  89.       PutCode(Index);
  90.       BAsmCode[CodeLen++] = Value;
  91.     }
  92.   }
  93. }
  94.  
  95. static void DecodeImm2(Word Index)
  96. {
  97.   if (ChkArgCnt(1, 1))
  98.   {
  99.     Boolean OK;
  100.     Word Value;
  101.  
  102.     Value = EvalStrIntExpression(&ArgStr[1], UInt2, &OK);
  103.     if (OK)
  104.       PutCode(Index | (Value & 3));
  105.   }
  106. }
  107.  
  108. static void DecodeImm3(Word Index)
  109. {
  110.   if (ChkArgCnt(1, 1))
  111.   {
  112.     tEvalResult EvalResult;
  113.     Word Value = EvalStrIntExpressionWithResult(&ArgStr[1], UInt3, &EvalResult);
  114.     if (EvalResult.OK)
  115.     {
  116.       PutCode(Index | (Value & 7));
  117.       if (Memo("OP"))
  118.         ChkSpace(SegIO, EvalResult.AddrSpaceMask);
  119.     }
  120.   }
  121. }
  122.  
  123. static void DecodePR(Word Index)
  124. {
  125.   if (!ChkArgCnt(1, 1));
  126.   else if (!as_strcasecmp(ArgStr[1].str.p_str, "HL-"))
  127.     PutCode(Index | 0x10);
  128.   else if (!as_strcasecmp(ArgStr[1].str.p_str, "HL+"))
  129.     PutCode(Index | 0x11);
  130.   else if (!as_strcasecmp(ArgStr[1].str.p_str, "HL"))
  131.     PutCode(Index | 0x12);
  132.   else if ((MomCPU == CPU7508) && (!as_strcasecmp(ArgStr[1].str.p_str, "DL")))
  133.     PutCode(Index | 0x00);
  134.   else if ((MomCPU == CPU7508) && (!as_strcasecmp(ArgStr[1].str.p_str, "DE")))
  135.     PutCode(Index | 0x01);
  136.   else
  137.     WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[1]);
  138. }
  139.  
  140. static void DecodeDataMem(Word Index)
  141. {
  142.   if (ChkArgCnt(1, 1))
  143.   {
  144.     tEvalResult EvalResult;
  145.     Word Value = EvalStrIntExpressionWithResult(&ArgStr[1], DataIntType, &EvalResult);
  146.     if (EvalResult.OK)
  147.     {
  148.       PutCode(Index);
  149.       BAsmCode[CodeLen++] = Value & SegLimits[SegData];
  150.       ChkSpace(SegData, EvalResult.AddrSpaceMask);
  151.     }
  152.   }
  153. }
  154.  
  155. static void DecodeAbs(Word Index)
  156. {
  157.   if (ChkArgCnt(1, 1))
  158.   {
  159.     tEvalResult EvalResult;
  160.     Word Address;
  161.     IntType Type = CodeIntType;
  162.     Word SegLimit = SegLimits[SegCode];
  163.  
  164.     /* CALL can only address first 2K on 7508! */
  165.  
  166.     if ((Memo("CALL")) && (MomCPU == CPU7508))
  167.     {
  168.       Type = UInt11;
  169.       SegLimit = 0x1fff;
  170.     }
  171.  
  172.     Address = EvalStrIntExpressionWithResult(&ArgStr[1], Type, &EvalResult);
  173.     if (EvalResult.OK)
  174.     {
  175.       PutCode(Index | (Address & SegLimit));
  176.       ChkSpace(SegCode, EvalResult.AddrSpaceMask);
  177.     }
  178.   }
  179. }
  180.  
  181. static void DecodeJCP(Word Index)
  182. {
  183.   if (ChkArgCnt(1, 1))
  184.   {
  185.     tEvalResult EvalResult;
  186.     Word Address = EvalStrIntExpressionWithResult(&ArgStr[1], CodeIntType, &EvalResult);
  187.  
  188.     if (EvalResult.OK && ChkSamePage(Address, EProgCounter() + 1, 6, EvalResult.Flags))
  189.     {
  190.       PutCode(Index | (Address & 0x3f));
  191.       ChkSpace(SegCode, EvalResult.AddrSpaceMask);
  192.     }
  193.   }
  194. }
  195.  
  196. static void DecodeCAL(Word Index)
  197. {
  198.   if (ChkArgCnt(1, 1))
  199.   {
  200.     tEvalResult EvalResult;
  201.     Word Address = EvalStrIntExpressionWithResult(&ArgStr[1], CodeIntType, &EvalResult);
  202.  
  203.     if (mFirstPassUnknown(EvalResult.Flags))
  204.       Address = (Address & 0x1c7) | 0x100;
  205.     if (EvalResult.OK)
  206.     {
  207.       if ((Address & 0x338) != 0x100) WrError(ErrNum_OverRange);
  208.       else
  209.         PutCode(Index | ((Address & 0x0c0) >> 3) | (Address & 7));
  210.       ChkSpace(SegCode, EvalResult.AddrSpaceMask);
  211.     }
  212.   }
  213. }
  214.  
  215. static void DecodeLHLT(Word Index)
  216. {
  217.   if (ChkArgCnt(1, 1))
  218.   {
  219.     tEvalResult EvalResult;
  220.     Word Address = EvalStrIntExpressionWithResult(&ArgStr[1], CodeIntType, &EvalResult);
  221.  
  222.     if (mFirstPassUnknown(EvalResult.Flags))
  223.       Address = (Address & 0x00cf) | 0x00c0;
  224.     if (EvalResult.OK)
  225.     {
  226.       if ((Address < 0xc0) || (Address > 0xcf)) WrError(ErrNum_OverRange);
  227.       else
  228.         PutCode(Index | (Address & 0xf));
  229.       ChkSpace(SegCode, EvalResult.AddrSpaceMask);
  230.     }
  231.   }
  232. }
  233.  
  234. static void DecodeCALT(Word Index)
  235. {
  236.   if (ChkArgCnt(1, 1))
  237.   {
  238.     tEvalResult EvalResult;
  239.     Word Address = EvalStrIntExpressionWithResult(&ArgStr[1], CodeIntType, &EvalResult);
  240.  
  241.     if (mFirstPassUnknown(EvalResult.Flags))
  242.       Address = (Address & 0x00ff) | 0x00c0;
  243.     if (EvalResult.OK)
  244.     {
  245.       if ((Address < 0xd0) || (Address > 0xff)) WrError(ErrNum_OverRange);
  246.       else
  247.         PutCode(Index | (Address & 0x3f));
  248.       ChkSpace(SegCode, EvalResult.AddrSpaceMask);
  249.     }
  250.   }
  251. }
  252.  
  253. static void DecodeLogPort(Word Index)
  254. {
  255.   if (ChkArgCnt(2, 2))
  256.   {
  257.     tEvalResult EvalResult;
  258.     Word Port, Mask;
  259.  
  260.     Port = EvalStrIntExpressionWithResult(&ArgStr[1], UInt4, &EvalResult);
  261.     if (EvalResult.OK)
  262.     {
  263.       ChkSpace(SegIO, EvalResult.AddrSpaceMask);
  264.       Mask = EvalStrIntExpressionWithResult(&ArgStr[2], UInt4, &EvalResult);
  265.       if (EvalResult.OK)
  266.         PutCode(Index | ((Mask & 15) << 4) | (Port & 15));
  267.     }
  268.   }
  269. }
  270.  
  271. /*-------------------------------------------------------------------------*/
  272. /* dynamische Codetabellenverwaltung */
  273.  
  274. static void AddFixed(const char *NewName, Word NewCode)
  275. {
  276.   AddInstTable(InstTable, NewName, NewCode, DecodeFixed);
  277. }
  278.  
  279. static void AddImm4(const char *NewName, Word NewCode)
  280. {
  281.   AddInstTable(InstTable, NewName, NewCode, DecodeImm4);
  282. }
  283.  
  284. static void AddImm2(const char *NewName, Word NewCode)
  285. {
  286.   AddInstTable(InstTable, NewName, NewCode, DecodeImm2);
  287. }
  288.  
  289. static void AddImm5(const char *NewName, Word NewCode)
  290. {
  291.   AddInstTable(InstTable, NewName, NewCode, DecodeImm5);
  292. }
  293.  
  294. static void AddImm8(const char *NewName, Word NewCode)
  295. {
  296.   AddInstTable(InstTable, NewName, NewCode, DecodeImm8);
  297. }
  298.  
  299. static void AddImm3(const char *NewName, Word NewCode)
  300. {
  301.   AddInstTable(InstTable, NewName, NewCode, DecodeImm3);
  302. }
  303.  
  304. static void AddPR(const char *NewName, Word NewCode)
  305. {
  306.   AddInstTable(InstTable, NewName, NewCode, DecodePR);
  307. }
  308.  
  309. static void AddDataMem(const char *NewName, Word NewCode)
  310. {
  311.   AddInstTable(InstTable, NewName, NewCode, DecodeDataMem);
  312. }
  313.  
  314. static void AddAbs(const char *NewName, Word NewCode)
  315. {
  316.   AddInstTable(InstTable, NewName, NewCode, DecodeAbs);
  317. }
  318.  
  319. static void InitFields(void)
  320. {
  321.   InstTable = CreateInstTable(103);
  322.   AddFixed("ST"    , 0x57);
  323.   AddFixed("XAL"   , 0x7b);
  324.   AddFixed("ASC"   , 0x7d);
  325.   AddFixed("ACSC"  , 0x7c);
  326.   AddFixed("EXL"   , 0x7e);
  327.   AddFixed("CMA"   , 0x7f);
  328.   AddFixed("RC"    , 0x78);
  329.   AddFixed("SC"    , 0x79);
  330.   AddFixed("ILS"   , 0x59);
  331.   AddFixed("DLS"   , 0x58);
  332.   AddFixed("RT"    , 0x53);
  333.   AddFixed("RTS"   , 0x5b);
  334.   AddFixed("TAMSP" , 0x3f31);
  335.   AddFixed("SKC"   , 0x5a);
  336.   AddFixed("SKAEM" , 0x5f);
  337.   AddFixed("TAMSIO", 0x3f3e);
  338.   AddFixed("TSIOAM", 0x3f3a);
  339.   AddFixed("SIO"   , 0x3f33);
  340.   AddFixed("TIMER" , 0x3f32);
  341.   AddFixed("TCNTAM", 0x3f3b);
  342.   AddFixed("IPL"   , 0x70);
  343.   AddFixed("OPL"   , 0x72);
  344.   AddFixed("HALT"  , 0x3f36);
  345.   AddFixed("STOP"  , 0x3f37);
  346.   AddFixed("NOP"  , 0x00);
  347.   if (MomCPU == CPU7566)
  348.   {
  349.     AddFixed("RPBL"  , 0x5c);
  350.     AddFixed("SPBL"  , 0x5d);
  351.   }
  352.   if (MomCPU == CPU7508)
  353.   {
  354.     AddFixed("LAMTL", 0x3f34);
  355.     AddFixed("TAD", 0x3eaa);
  356.     AddFixed("TAE", 0x3e8a);
  357.     AddFixed("TAH", 0x3eba);
  358.     AddFixed("TAL", 0x3e9a);
  359.     AddFixed("TDA", 0x3eab);
  360.     AddFixed("TEA", 0x3e8b);
  361.     AddFixed("THA", 0x3ebb);
  362.     AddFixed("TLA", 0x3e9b);
  363.     AddFixed("XAD", 0x4a);
  364.     AddFixed("XAE", 0x4b);
  365.     AddFixed("XAH", 0x7a);
  366.     AddFixed("ANL", 0x3fb2);
  367.     AddFixed("ORL", 0x3fb6);
  368.     AddFixed("RAR", 0x3fb3);
  369.     AddFixed("IES", 0x49);
  370.     AddFixed("DES", 0x48);
  371.     AddFixed("RTPSW", 0x43);
  372.     AddFixed("PSHDE", 0x3e8e);
  373.     AddFixed("PSHHL", 0x3e9e);
  374.     AddFixed("POPDE", 0x3e8f);
  375.     AddFixed("POPHL", 0x3e9f);
  376.     AddFixed("TSPAM", 0x3f35);
  377.     AddFixed("TAMMOD", 0x3f3f);
  378.     AddFixed("IP1", 0x71);
  379.     AddFixed("IP54", 0x3f38);
  380.     AddFixed("OP3", 0x73);
  381.     AddFixed("OP54", 0x3f3c);
  382.   }
  383.  
  384.   AddImm4("LAI", 0x10);
  385.   AddImm4("AISC", 0x00);
  386.   AddImm4("SKAEI", 0x3f60);
  387.   if (MomCPU == CPU7566)
  388.   {
  389.     AddImm4("STII", 0x40);
  390.   }
  391.   if (MomCPU == CPU7508)
  392.   {
  393.     AddImm4("LDI", 0x3e20);
  394.     AddImm4("LEI", 0x3e00);
  395.     AddImm4("LHI", 0x3e30);
  396.     AddImm4("LLI", 0x3e10);
  397.     AddImm4("JAM", 0x3f10);
  398.     AddImm4("SKDEI", 0x3e60);
  399.     AddImm4("SKEEI", 0x3e40);
  400.     AddImm4("SKHEI", 0x3e70);
  401.     AddImm4("SKLEI", 0x3e50);
  402.     AddImm4("OP", 0x3fe0);
  403.   }
  404.  
  405.   AddImm2("RMB", 0x68);
  406.   AddImm2("SMB", 0x6c);
  407.   AddImm2("SKABT", 0x74);
  408.   AddImm2("SKMBT", 0x64);
  409.   AddImm2("SKMBF", 0x60);
  410.   if (MomCPU == CPU7566)
  411.   {
  412.     AddImm2("SKI", 0x3d40);
  413.     AddImm2("LHI", 0x28);
  414.   }
  415.  
  416.   if (MomCPU == CPU7508)
  417.   {
  418.     AddImm3("EI", 0x3f90);
  419.     AddImm3("DI", 0x3f80);
  420.     AddImm3("SKI", 0x3f40);
  421.     AddImm3("IP", 0x3fc0);
  422.   }
  423.  
  424.   if (MomCPU == CPU7566)
  425.   {
  426.     AddImm5("LHLI", 0xc0);
  427.   }
  428.  
  429.   if (MomCPU == CPU7508)
  430.   {
  431.     AddImm8("LDEI", 0x4f);
  432.     AddImm8("LHLI", 0x4e);
  433.   }
  434.  
  435.   AddPR("LAM", 0x40);
  436.   AddPR("XAM", 0x44);
  437.  
  438.   AddDataMem("IDRS", 0x3d);
  439.   AddDataMem("DDRS", 0x3c);
  440.   if (MomCPU == CPU7508)
  441.   {
  442.     AddDataMem("LADR", 0x38);
  443.     AddDataMem("XADR", 0x39);
  444.     AddDataMem("XHDR", 0x3a);
  445.     AddDataMem("XLDR", 0x3b);
  446.   }
  447.  
  448.   AddAbs("JMP" , 0x2000);
  449.   AddAbs("CALL", 0x3000);
  450.   AddInstTable(InstTable, "JCP", 0x80, DecodeJCP);
  451.   if (MomCPU == CPU7566)
  452.   {
  453.     AddInstTable(InstTable, "CAL", 0xe0, DecodeCAL);
  454.   }
  455.   if (MomCPU == CPU7508)
  456.   {
  457.     AddInstTable(InstTable, "LHLT", 0xc0, DecodeLHLT);
  458.     AddInstTable(InstTable, "CALT", 0xc0, DecodeCALT);
  459.     AddInstTable(InstTable, "ANP", 0x4c00, DecodeLogPort);
  460.     AddInstTable(InstTable, "ORP", 0x4d00, DecodeLogPort);
  461.   }
  462. }
  463.  
  464. static void DeinitFields(void)
  465. {
  466.   DestroyInstTable(InstTable);
  467. }
  468.  
  469. /*-------------------------------------------------------------------------*/
  470.  
  471. static void MakeCode_75xx(void)
  472. {
  473.   CodeLen = 0; DontPrint = False;
  474.  
  475.   /* zu ignorierendes */
  476.  
  477.   if (Memo("")) return;
  478.  
  479.   /* Pseudoanweisungen */
  480.  
  481.   if (DecodeIntelPseudo(True)) return;
  482.  
  483.   if (!LookupInstTable(InstTable, OpPart.str.p_str))
  484.     WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
  485. }
  486.  
  487. static Boolean IsDef_75xx(void)
  488. {
  489.   return False;
  490. }
  491.  
  492. static void SwitchFrom_75xx(void)
  493. {
  494.   DeinitFields();
  495. }
  496.  
  497. static void SwitchTo_75xx(void)
  498. {
  499.   TurnWords = False;
  500.   SetIntConstMode(eIntConstModeIntel);
  501.  
  502.   PCSymbol = "PC"; HeaderID = FindFamilyByName("75xx")->Id; NOPCode = 0x00;
  503.   DivideChars = ","; HasAttrs = False;
  504.  
  505.   ValidSegs = (1 << SegCode) | (1 << SegData);
  506.   Grans[SegCode] = 1; ListGrans[SegCode] = 1; SegInits[SegCode] = 0;
  507.   Grans[SegData] = 1; ListGrans[SegData] = 1; SegInits[SegData] = 0;
  508.   if (MomCPU == CPU7508)
  509.   {
  510.     ValidSegs |= (1 << SegIO);
  511.     Grans[SegIO] = 1; ListGrans[SegIO] = 1; SegInits[SegIO] = 0; SegLimits[SegIO] = 15;
  512.  
  513.     SegLimits[SegData] = 0xff;
  514.     DataIntType = UInt8;
  515.     SegLimits[SegCode] = 0xfff;
  516.     CodeIntType = UInt12;
  517.   }
  518.   else
  519.   {
  520.     SegLimits[SegData] = 0x3f;
  521.     DataIntType = UInt6;
  522.     SegLimits[SegCode] = 0x3ff;
  523.     CodeIntType = UInt10;
  524.   }
  525.  
  526.   MakeCode = MakeCode_75xx; IsDef = IsDef_75xx;
  527.   SwitchFrom = SwitchFrom_75xx; InitFields();
  528. }
  529.  
  530. void code75xx_init(void)
  531. {
  532.   CPU7566 = AddCPU("7566", SwitchTo_75xx);
  533.   CPU7508 = AddCPU("7508", SwitchTo_75xx);
  534. }
  535.