Subversion Repositories pentevo

Rev

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

  1. /* code6804.c */
  2. /*****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
  4. /*                                                                           */
  5. /* AS-Portierung                                                             */
  6. /*                                                                           */
  7. /* AS-Codegenerator Motorola/ST 6804                                         */
  8. /*                                                                           */
  9. /*****************************************************************************/
  10.  
  11. #include "stdinc.h"
  12.  
  13. #include <string.h>
  14.  
  15. #include "bpemu.h"
  16. #include "strutil.h"
  17. #include "asmdef.h"
  18. #include "asmsub.h"
  19. #include "asmpars.h"
  20. #include "asmitree.h"
  21. #include "codepseudo.h"
  22. #include "motpseudo.h"
  23. #include "codevars.h"
  24. #include "errmsg.h"
  25.  
  26. #include "code6804.h"
  27.  
  28. typedef struct
  29. {
  30.   char *Name;
  31.   LongInt Code;
  32. } BaseOrder;
  33.  
  34. enum
  35. {
  36.   ModNone = -1,
  37.   ModInd = 0,
  38.   ModDir = 1,
  39.   ModImm = 2
  40. };
  41.  
  42. #define MModInd (1 << ModInd)
  43. #define MModDir (1 << ModDir)
  44. #define MModImm (1 << ModImm)
  45.  
  46. static ShortInt AdrMode;
  47. static Byte AdrVal;
  48.  
  49. static CPUVar CPU6804;
  50.  
  51. static BaseOrder *FixedOrders;
  52.  
  53. /*--------------------------------------------------------------------------*/
  54.  
  55. static void DecodeAdr(const tStrComp *pArg, Boolean MayImm)
  56. {
  57.   Boolean OK;
  58.  
  59.   AdrMode = ModNone;
  60.  
  61.   if (!as_strcasecmp(pArg->str.p_str, "(X)"))
  62.   {
  63.     AdrMode = ModInd;
  64.     AdrVal = 0x00;
  65.     goto chk;
  66.   }
  67.   if (!as_strcasecmp(pArg->str.p_str, "(Y)"))
  68.   {
  69.     AdrMode = ModInd;
  70.     AdrVal = 0x10;
  71.     goto chk;
  72.   }
  73.  
  74.   if (*pArg->str.p_str == '#')
  75.   {
  76.     AdrVal = EvalStrIntExpressionOffs(pArg, 1, Int8, &OK);
  77.     if (OK)
  78.       AdrMode = ModImm;
  79.     goto chk;
  80.   }
  81.  
  82.   AdrVal = EvalStrIntExpression(pArg, Int8, &OK);
  83.   if (OK)
  84.     AdrMode = ModDir;
  85.  
  86. chk:
  87.   if ((AdrMode == ModImm) && (!MayImm))
  88.   {
  89.     WrError(ErrNum_InvAddrMode); AdrMode = ModNone;
  90.   }
  91. }
  92.  
  93. static Boolean IsShort(Byte Adr)
  94. {
  95.   return ((Adr & 0xfc) == 0x80);
  96. }
  97.  
  98. /*--------------------------------------------------------------------------*/
  99.  
  100. /* Anweisungen ohne Argument */
  101.  
  102. static void DecodeFixed(Word Index)
  103. {
  104.   const BaseOrder *pOrder = FixedOrders + Index;
  105.  
  106.   if (ChkArgCnt(0, 0))
  107.   {
  108.     if ((pOrder->Code >> 16) != 0)
  109.       CodeLen = 3;
  110.     else
  111.       CodeLen = 1 + Ord(Hi(pOrder->Code) != 0);
  112.     if (CodeLen == 3)
  113.       BAsmCode[0] = pOrder->Code >> 16;
  114.     if (CodeLen >= 2)
  115.       BAsmCode[CodeLen - 2] = Hi(pOrder->Code);
  116.     BAsmCode[CodeLen - 1] = Lo(pOrder->Code);
  117.   }
  118. }
  119.  
  120. /* relative/absolute Spruenge */
  121.  
  122. static void DecodeRel(Word Code)
  123. {
  124.   if (ChkArgCnt(1, 1))
  125.   {
  126.     tEvalResult EvalResult;
  127.     Integer AdrInt = EvalStrIntExpressionWithResult(&ArgStr[1], Int16, &EvalResult) - (EProgCounter() + 1);
  128.  
  129.     if (EvalResult.OK)
  130.     {
  131.       if (!mSymbolQuestionable(EvalResult.Flags) && ((AdrInt < -16) || (AdrInt > 15))) WrError(ErrNum_JmpDistTooBig);
  132.       else
  133.       {
  134.         CodeLen = 1;
  135.         BAsmCode[0] = Code + (AdrInt & 0x1f);
  136.         ChkSpace(SegCode, EvalResult.AddrSpaceMask);
  137.       }
  138.     }
  139.   }
  140. }
  141.  
  142. static void DecodeJSR_JMP(Word Code)
  143. {
  144.   if (ChkArgCnt(1, 1))
  145.   {
  146.     tEvalResult EvalResult;
  147.     Word AdrInt = EvalStrIntExpressionWithResult(&ArgStr[1], UInt12, &EvalResult);
  148.  
  149.     if (EvalResult.OK)
  150.     {
  151.       CodeLen = 2;
  152.       BAsmCode[1] = Lo(AdrInt);
  153.       BAsmCode[0] = Code + (Hi(AdrInt) & 15);
  154.       ChkSpace(SegCode, EvalResult.AddrSpaceMask);
  155.     }
  156.   }
  157. }
  158.  
  159. /* AKKU-Operationen */
  160.  
  161. static void DecodeALU(Word Code)
  162. {
  163.   if (ChkArgCnt(1, 1))
  164.   {
  165.     DecodeAdr(&ArgStr[1], True);
  166.     switch (AdrMode)
  167.     {
  168.       case ModInd:
  169.         CodeLen = 1;
  170.         BAsmCode[0] = 0xe0 + AdrVal + Code;
  171.         break;
  172.       case ModDir:
  173.         CodeLen = 2;
  174.         BAsmCode[0] = 0xf8 + Code;
  175.         BAsmCode[1] = AdrVal;
  176.         break;
  177.       case ModImm:
  178.         CodeLen = 2;
  179.         BAsmCode[0] = 0xe8 + Code;
  180.         BAsmCode[1] = AdrVal;
  181.         break;
  182.     }
  183.   }
  184. }
  185.  
  186. /* Datentransfer */
  187.  
  188. static void DecodeLDA_STA(Word Code)
  189. {
  190.   if (ChkArgCnt(1, 1))
  191.   {
  192.     DecodeAdr(&ArgStr[1], !Code);
  193.     switch (AdrMode)
  194.     {
  195.       case ModInd:
  196.         CodeLen = 1;
  197.         BAsmCode[0] = 0xe0 + Code + AdrVal;
  198.         break;
  199.       case ModDir:
  200.         if (IsShort(AdrVal))
  201.         {
  202.           CodeLen = 1;
  203.           BAsmCode[0] = 0xac + (Code << 4) + (AdrVal & 3);
  204.         }
  205.         else
  206.         {
  207.           CodeLen = 2;
  208.           BAsmCode[0] = 0xf8 + Code;
  209.           BAsmCode[1] = AdrVal;
  210.         }
  211.         break;
  212.       case ModImm:
  213.         CodeLen = 2;
  214.         BAsmCode[0] = 0xe8 + Code;
  215.         BAsmCode[1] = AdrVal;
  216.         break;
  217.     }
  218.   }
  219. }
  220.  
  221. static void DecodeLDXI_LDYI(Word Code)
  222. {
  223.   if (!ChkArgCnt(1, 1));
  224.   else if (*ArgStr[1].str.p_str != '#') WrError(ErrNum_InvAddrMode);
  225.   else
  226.   {
  227.     Boolean OK;
  228.  
  229.     BAsmCode[2] = EvalStrIntExpressionOffs(&ArgStr[1], 1, Int8, &OK);
  230.     if (OK)
  231.     {
  232.       CodeLen = 3;
  233.       BAsmCode[0] = 0xb0;
  234.       BAsmCode[1] = Code;
  235.     }
  236.   }
  237. }
  238.  
  239. static void DecodeMVI(Word Code)
  240. {
  241.   UNUSED(Code);
  242.  
  243.   if (!ChkArgCnt(2, 2));
  244.   else if (*ArgStr[2].str.p_str != '#') WrError(ErrNum_InvAddrMode);
  245.   else
  246.   {
  247.     tEvalResult EvalResult;
  248.  
  249.     BAsmCode[1] = EvalStrIntExpressionWithResult(&ArgStr[1], Int8, &EvalResult);
  250.     if (EvalResult.OK)
  251.     {
  252.       ChkSpace(SegData, EvalResult.AddrSpaceMask);
  253.       BAsmCode[2] = EvalStrIntExpressionOffsWithResult(&ArgStr[2], 1, Int8, &EvalResult);
  254.       if (EvalResult.OK)
  255.       {
  256.         BAsmCode[0] = 0xb0;
  257.         CodeLen = 3;
  258.       }
  259.     }
  260.   }
  261. }
  262.  
  263. /* Read/Modify/Write-Operationen */
  264.  
  265. static void DecodeINC_DEC(Word Code)
  266. {
  267.   if (ChkArgCnt(1, 1))
  268.   {
  269.     DecodeAdr(&ArgStr[1], False);
  270.     switch (AdrMode)
  271.     {
  272.       case ModInd:
  273.         CodeLen = 1;
  274.         BAsmCode[0] = 0xe6 + Code + AdrVal;
  275.         break;
  276.       case ModDir:
  277.         if (IsShort(AdrVal))
  278.         {
  279.           CodeLen = 1;
  280.           BAsmCode[0] = 0xa8 + (Code << 4) + (AdrVal & 3);
  281.         }
  282.         else
  283.         {
  284.           CodeLen = 2;
  285.           BAsmCode[0] = 0xfe + Code;
  286.           BAsmCode[1] = AdrVal;
  287.         }
  288.         break;
  289.     }
  290.   }
  291. }
  292.  
  293. /* Bitbefehle */
  294.  
  295. static void DecodeBSET_BCLR(Word Code)
  296. {
  297.   if (ChkArgCnt(2, 2))
  298.   {
  299.     tEvalResult EvalResult;
  300.     Byte Bit = EvalStrIntExpressionWithResult(&ArgStr[1], UInt3, &EvalResult);
  301.     if (EvalResult.OK)
  302.     {
  303.       BAsmCode[0] = Code + Bit;
  304.       BAsmCode[1] = EvalStrIntExpressionWithResult(&ArgStr[2], Int8, &EvalResult);
  305.       if (EvalResult.OK)
  306.       {
  307.         CodeLen = 2;
  308.         ChkSpace(SegData, EvalResult.AddrSpaceMask);
  309.       }
  310.     }
  311.   }
  312. }
  313.  
  314. static void DecodeBRSET_BRCLR(Word Code)
  315. {
  316.   if (ChkArgCnt(3, 3))
  317.   {
  318.     tEvalResult EvalResult;
  319.     Byte Bit = EvalStrIntExpressionWithResult(&ArgStr[1], UInt3, &EvalResult);
  320.  
  321.     if (EvalResult.OK)
  322.     {
  323.       BAsmCode[0] = Code + Bit;
  324.       BAsmCode[1] = EvalStrIntExpressionWithResult(&ArgStr[2], Int8, &EvalResult);
  325.       if (EvalResult.OK)
  326.       {
  327.         Integer AdrInt;
  328.  
  329.         ChkSpace(SegData, EvalResult.AddrSpaceMask);
  330.         AdrInt = EvalStrIntExpressionWithResult(&ArgStr[3], Int16, &EvalResult) - (EProgCounter() + 3);
  331.         if (EvalResult.OK)
  332.         {
  333.           if (!mSymbolQuestionable(EvalResult.Flags) && ((AdrInt < -128) || (AdrInt > 127))) WrError(ErrNum_JmpDistTooBig);
  334.           else
  335.           {
  336.             ChkSpace(SegCode, EvalResult.AddrSpaceMask);
  337.             BAsmCode[2] = AdrInt & 0xff;
  338.             CodeLen = 3;
  339.           }
  340.         }
  341.       }
  342.     }
  343.   }
  344. }
  345.  
  346. static void DecodeSFR(Word Code)
  347. {
  348.   UNUSED(Code);
  349.  
  350.   CodeEquate(SegData, 0, 0xff);
  351. }
  352.  
  353. /*--------------------------------------------------------------------------*/
  354.  
  355. static void AddFixed(const char *NName, LongInt NCode)
  356. {
  357.   order_array_rsv_end(FixedOrders, BaseOrder);
  358.   FixedOrders[InstrZ].Code = NCode;
  359.   AddInstTable(InstTable, NName, InstrZ++, DecodeFixed);
  360. }
  361.  
  362. static void AddRel(const char *NName, LongInt NCode)
  363. {
  364.   AddInstTable(InstTable, NName, NCode, DecodeRel);
  365. }
  366.  
  367. static void AddALU(const char *NName, LongInt NCode)
  368. {
  369.   AddInstTable(InstTable, NName, NCode, DecodeALU);
  370. }
  371.  
  372. static void InitFields(void)
  373. {
  374.   InstTable = CreateInstTable(203);
  375.   AddInstTable(InstTable, "JMP", 0x90, DecodeJSR_JMP);
  376.   AddInstTable(InstTable, "JSR", 0x80, DecodeJSR_JMP);
  377.   AddInstTable(InstTable, "LDA", 0, DecodeLDA_STA);
  378.   AddInstTable(InstTable, "STA", 1, DecodeLDA_STA);
  379.   AddInstTable(InstTable, "LDXI", 0x80, DecodeLDXI_LDYI);
  380.   AddInstTable(InstTable, "LDYI", 0x81, DecodeLDXI_LDYI);
  381.   AddInstTable(InstTable, "MVI", 0, DecodeMVI);
  382.   AddInstTable(InstTable, "INC", 0, DecodeINC_DEC);
  383.   AddInstTable(InstTable, "DEC", 1, DecodeINC_DEC);
  384.   AddInstTable(InstTable, "BSET", 0xd8, DecodeBSET_BCLR);
  385.   AddInstTable(InstTable, "BCLR", 0xd0, DecodeBSET_BCLR);
  386.   AddInstTable(InstTable, "BRSET", 0xc8, DecodeBRSET_BRCLR);
  387.   AddInstTable(InstTable, "BRCLR", 0xc0, DecodeBRSET_BRCLR);
  388.   AddInstTable(InstTable, "SFR", 0, DecodeSFR);
  389.  
  390.   InstrZ = 0;
  391.   AddFixed("CLRA", 0x00fbff);
  392.   AddFixed("CLRX", 0xb08000);
  393.   AddFixed("CLRY", 0xb08100);
  394.   AddFixed("COMA", 0x0000b4);
  395.   AddFixed("ROLA", 0x0000b5);
  396.   AddFixed("ASLA", 0x00faff);
  397.   AddFixed("INCA", 0x00feff);
  398.   AddFixed("INCX", 0x0000a8);
  399.   AddFixed("INCY", 0x0000a9);
  400.   AddFixed("DECA", 0x00ffff);
  401.   AddFixed("DECX", 0x0000b8);
  402.   AddFixed("DECY", 0x0000b9);
  403.   AddFixed("TAX" , 0x0000bc);
  404.   AddFixed("TAY" , 0x0000bd);
  405.   AddFixed("TXA" , 0x0000ac);
  406.   AddFixed("TYA" , 0x0000ad);
  407.   AddFixed("RTS" , 0x0000b3);
  408.   AddFixed("RTI" , 0x0000b2);
  409.   AddFixed("NOP" , 0x000020);
  410.  
  411.   AddRel("BCC", 0x40);
  412.   AddRel("BHS", 0x40);
  413.   AddRel("BCS", 0x60);
  414.   AddRel("BLO", 0x60);
  415.   AddRel("BNE", 0x00);
  416.   AddRel("BEQ", 0x20);
  417.  
  418.   AddALU("ADD", 0x02);
  419.   AddALU("SUB", 0x03);
  420.   AddALU("CMP", 0x04);
  421.   AddALU("AND", 0x05);
  422.  
  423.   init_moto8_pseudo(InstTable, e_moto_8_be | e_moto_8_db | e_moto_8_dw | e_moto_8_ds);
  424. }
  425.  
  426. static void DeinitFields(void)
  427. {
  428.   DestroyInstTable(InstTable);
  429.  
  430.   order_array_free(FixedOrders);
  431. }
  432.  
  433. /*--------------------------------------------------------------------------*/
  434.  
  435. static void MakeCode_6804(void)
  436. {
  437.   CodeLen = 0;
  438.   DontPrint = False;
  439.  
  440.   /* zu ignorierendes */
  441.  
  442.   if (Memo(""))
  443.     return;
  444.  
  445.   if (!LookupInstTable(InstTable, OpPart.str.p_str))
  446.     WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
  447. }
  448.  
  449. static Boolean IsDef_6804(void)
  450. {
  451.   return (Memo("SFR"));
  452. }
  453.  
  454. static void SwitchFrom_6804(void)
  455. {
  456.   DeinitFields();
  457. }
  458.  
  459. static void SwitchTo_6804(void)
  460. {
  461.   TurnWords = False;
  462.   SetIntConstMode(eIntConstModeMoto);
  463.  
  464.   PCSymbol = "PC";
  465.   HeaderID = 0x64;
  466.   NOPCode = 0x20;
  467.   DivideChars = ",";
  468.   HasAttrs = False;
  469.  
  470.   ValidSegs = (1 << SegCode) | (1 << SegData);
  471.   Grans[SegCode] = 1; ListGrans[SegCode] = 1; SegInits[SegCode] = 0;
  472.   SegLimits[SegCode] = 0xfff;
  473.   Grans[SegData] = 1; ListGrans[SegData] = 1; SegInits[SegData] = 0;
  474.   SegLimits[SegData] = 0xff;
  475.  
  476.   MakeCode = MakeCode_6804;
  477.   IsDef = IsDef_6804;
  478.   SwitchFrom = SwitchFrom_6804;
  479.   InitFields();
  480. }
  481.  
  482. void code6804_init(void)
  483. {
  484.   CPU6804 = AddCPU("6804", SwitchTo_6804);
  485. }
  486.