Subversion Repositories pentevo

Rev

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

  1. /* code68rs08.c */
  2. /*****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
  4. /*                                                                           */
  5. /* AS-Portierung                                                             */
  6. /*                                                                           */
  7. /* Codegenerator 68RS08                                                      */
  8. /*                                                                           */
  9. /*****************************************************************************/
  10.  
  11. #include "stdinc.h"
  12.  
  13. #include <string.h>
  14. #include <ctype.h>
  15.  
  16. #include "bpemu.h"
  17. #include "strutil.h"
  18.  
  19. #include "asmdef.h"
  20. #include "asmpars.h"
  21. #include "asmsub.h"
  22. #include "asmitree.h"
  23. #include "codepseudo.h"
  24. #include "motpseudo.h"
  25. #include "intpseudo.h"
  26. #include "codevars.h"
  27. #include "errmsg.h"
  28.  
  29. #include "code68rs08.h"
  30.  
  31. typedef struct
  32. {
  33.   char *Name;
  34.   CPUVar MinCPU;
  35.   Byte Code;
  36. } BaseOrder;
  37.  
  38. typedef struct
  39. {
  40.   char *Name;
  41.   CPUVar MinCPU;
  42.   Byte Code;
  43.   Word Mask;
  44. } ALUOrder;
  45.  
  46. typedef struct
  47. {
  48.   char *Name;
  49.   CPUVar MinCPU;
  50.   Byte Code;
  51.   Byte DCode;
  52.   Word Mask;
  53. } RMWOrder;
  54.  
  55. enum
  56. {
  57.   ModNone = -1,
  58.   ModImm = 0,
  59.   ModDir = 1,
  60.   ModExt = 2,
  61.   ModSrt = 3,
  62.   ModTny = 4,
  63.   ModIX = 5,
  64.   ModX = 6
  65. };
  66.  
  67. #define MModImm (1 << ModImm)
  68. #define MModDir (1 << ModDir)
  69. #define MModExt (1 << ModExt)
  70. #define MModSrt (1 << ModSrt)
  71. #define MModTny (1 << ModTny)
  72. #define MModIX (1 << ModIX)
  73. #define MModX (1 << ModX)
  74.  
  75. static ShortInt AdrMode;
  76. static Byte AdrVals[2];
  77.  
  78. static IntType AdrIntType;
  79.  
  80. static CPUVar CPU68RS08;
  81.  
  82. static BaseOrder *FixedOrders;
  83. static BaseOrder *RelOrders;
  84. static RMWOrder *RMWOrders;
  85. static ALUOrder *ALUOrders;
  86.  
  87. /*--------------------------------------------------------------------------*/
  88. /* address parser */
  89.  
  90.  
  91. static unsigned ChkZero(char *s, Byte *pErg)
  92. {
  93.   if (*s == '<') /* short / tiny */
  94.   {
  95.     *pErg = 2;
  96.     return 1;
  97.   }
  98.   else if (*s == '>') /* direct */
  99.   {
  100.     *pErg = 1;
  101.     return 1;
  102.   }
  103.   else /* let the assembler make the choice */
  104.   {
  105.     *pErg = 0;
  106.     return 0;
  107.   }
  108. }
  109.  
  110. static void DecodeAdr(Byte Start, Byte Stop, Word Mask)
  111. {
  112.   Boolean OK;
  113.   tSymbolFlags Flags;
  114.   Word AdrWord;
  115.   Byte ZeroMode;
  116.   unsigned Offset;
  117.  
  118.   AdrMode = ModNone;
  119.   AdrCnt = 0;
  120.  
  121.   if (Stop - Start == 1)
  122.   {
  123.     if (*(ArgStr[Start].str.p_str) == 0 && (!as_strcasecmp(ArgStr[Stop].str.p_str, "X")))
  124.     {
  125.       AdrMode = ModIX;
  126.     }
  127.     else
  128.     {
  129.       WrStrErrorPos(ErrNum_InvReg, &ArgStr[Stop]);
  130.       goto chk;
  131.     }
  132.   }
  133.  
  134.   else if (Stop == Start)
  135.   {
  136.     /* X-indirekt */
  137.  
  138.     if (!as_strcasecmp(ArgStr[Start].str.p_str, "X"))
  139.     {
  140.       AdrMode = ModX;
  141.       goto chk;
  142.     }
  143.  
  144.     if (!as_strcasecmp(ArgStr[Start].str.p_str, "D[X]"))
  145.     {
  146.       AdrMode = ModIX;
  147.       goto chk;
  148.     }
  149.  
  150.     /* immediate */
  151.  
  152.     if (*ArgStr[Start].str.p_str == '#')
  153.     {
  154.       AdrVals[0] = EvalStrIntExpressionOffs(&ArgStr[Start], 1, Int8, &OK);
  155.       if (OK)
  156.       {
  157.         AdrCnt = 1;
  158.         AdrMode = ModImm;
  159.       }
  160.       goto chk;
  161.     }
  162.  
  163.     /* absolut */
  164.  
  165.     Offset = ChkZero(ArgStr[Start].str.p_str, &ZeroMode);
  166.     AdrWord = EvalStrIntExpressionOffsWithFlags(&ArgStr[Start], Offset, (ZeroMode == 2) ? UInt8 : AdrIntType, &OK, &Flags);
  167.  
  168.     if (OK)
  169.     {
  170.       if (((Mask & MModExt) == 0) || (ZeroMode == 2) || ((ZeroMode == 0) && (Hi(AdrWord) == 0)))
  171.       {
  172.         if (mFirstPassUnknown(Flags))
  173.           AdrWord &= 0xff;
  174.         if (Hi(AdrWord) != 0) WrError(ErrNum_NoShortAddr);
  175.         else
  176.         {
  177.           AdrCnt = 1;
  178.           AdrVals[0] = Lo(AdrWord);
  179.           AdrMode = ModDir;
  180.           if (ZeroMode == 0)
  181.           {
  182.             if ((Mask & MModTny) && (AdrVals[0] <= 0x0f))
  183.               AdrMode = ModTny;
  184.             if ((Mask & MModSrt) && (AdrVals[0] <= 0x1f))
  185.               AdrMode = ModSrt;
  186.           }
  187.           if (ZeroMode == 2)
  188.           {
  189.             if (Mask & MModTny)
  190.             {
  191.               if (AdrVals[0] <= 0x0f)
  192.                 AdrMode = ModTny;
  193.               else
  194.                 WrError(ErrNum_ConfOpSizes);
  195.               return;
  196.             }
  197.             else if (Mask & MModSrt)
  198.             {
  199.               if (AdrVals[0] <= 0x1f)
  200.                 AdrMode = ModSrt;
  201.               else
  202.                 WrError(ErrNum_ConfOpSizes);
  203.               return;
  204.             }
  205.             else
  206.             {
  207.               AdrMode = ModNone;
  208.               WrError(ErrNum_NoShortAddr);
  209.               return;
  210.             }
  211.           }
  212.         }
  213.       }
  214.       else
  215.       {
  216.         AdrVals[0] = Hi(AdrWord);
  217.         AdrVals[1] = Lo(AdrWord);
  218.         AdrCnt = 2;
  219.         AdrMode = ModExt;
  220.       }
  221.       goto chk;
  222.     }
  223.   }
  224.  
  225.   else
  226.    (void)ChkArgCnt(Start, Start + 1);
  227.  
  228. chk:
  229.   if ((AdrMode != ModNone) && (!(Mask & (1 << AdrMode))))
  230.   {
  231.     WrError(ErrNum_InvAddrMode);
  232.     AdrMode = ModNone;
  233.     AdrCnt = 0;
  234.   }
  235. }
  236.  
  237. /*--------------------------------------------------------------------------*/
  238. /* instruction parsers */
  239.  
  240. static void DecodeFixed(Word Index)
  241. {
  242.   BaseOrder *pOrder = FixedOrders + Index;
  243.  
  244.   if (ChkArgCnt(0, 0)
  245.    && ChkMinCPU(pOrder->MinCPU))
  246.   {
  247.     CodeLen = 1;
  248.     BAsmCode[0] = pOrder->Code;
  249.   }
  250. }
  251.  
  252. static void DecodeMOV(Word Index)
  253. {
  254.   UNUSED(Index);
  255.  
  256.   if (ChkArgCnt(2, 2))
  257.   {
  258.     DecodeAdr(1, 1, MModImm | MModDir | MModIX);
  259.     switch (AdrMode)
  260.     {
  261.       case ModImm:
  262.         BAsmCode[1] = AdrVals[0];
  263.         DecodeAdr(2, 2, MModDir | MModIX);
  264.         switch (AdrMode)
  265.         {
  266.           case ModDir:
  267.             BAsmCode[0] = 0x3e;
  268.             BAsmCode[2] = AdrVals[0];
  269.             CodeLen = 3;
  270.             break;
  271.           case ModIX:
  272.             BAsmCode[0] = 0x3e;
  273.             BAsmCode[2] = 0x0e;
  274.             CodeLen = 3;
  275.             break;
  276.         }
  277.         break;
  278.       case ModDir:
  279.         BAsmCode[1] = AdrVals[0];
  280.         DecodeAdr(2, 2, MModDir | MModIX);
  281.         switch (AdrMode)
  282.         {
  283.           case ModDir:
  284.             BAsmCode[0] = 0x4e;
  285.             BAsmCode[2] = AdrVals[0];
  286.             CodeLen = 3;
  287.             break;
  288.           case ModIX:
  289.             BAsmCode[0] = 0x4e;
  290.             BAsmCode[2] = 0x0e;
  291.             CodeLen = 3;
  292.             break;
  293.         }
  294.         break;
  295.       case ModIX:
  296.         DecodeAdr(2, 2, MModDir);
  297.         if (AdrMode == ModDir)
  298.         {
  299.           BAsmCode[0] = 0x4e;
  300.           BAsmCode[1] = 0x0e;
  301.           BAsmCode[2] = AdrVals[0];
  302.           CodeLen = 3;
  303.         }
  304.         break;
  305.     }
  306.   }
  307. }
  308.  
  309. static void DecodeRel(Word Index)
  310. {
  311.   BaseOrder *pOrder = RelOrders + Index;
  312.   Boolean OK;
  313.   tSymbolFlags Flags;
  314.   LongInt AdrInt;
  315.  
  316.   if (ChkArgCnt(1, 1)
  317.    && ChkMinCPU(pOrder->MinCPU))
  318.   {
  319.     AdrInt = EvalStrIntExpressionWithFlags(&ArgStr[1], AdrIntType, &OK, &Flags) - (EProgCounter() + 2);
  320.     if (OK)
  321.     {
  322.       if (!mSymbolQuestionable(Flags) && ((AdrInt < -128) || (AdrInt>127))) WrError(ErrNum_JmpDistTooBig);
  323.       else
  324.       {
  325.         CodeLen = 2;
  326.         BAsmCode[0] = pOrder->Code;
  327.         BAsmCode[1] = Lo(AdrInt);
  328.         if (BAsmCode[0] == 0x00) /* BRN pseudo op */
  329.         {
  330.           BAsmCode[0] = 0x30;
  331.           BAsmCode[1] = 0x00;
  332.         }
  333.       }
  334.     }
  335.   }
  336. }
  337.  
  338. static void DecodeCBEQx(Word Index)
  339. {
  340.   Boolean OK;
  341.   tSymbolFlags Flags;
  342.   LongInt AdrInt;
  343.  
  344.   UNUSED(Index);
  345.  
  346.   if (ChkArgCnt(2, 2))
  347.   {
  348.     DecodeAdr(1, 1, MModImm);
  349.     if (AdrMode == ModImm)
  350.     {
  351.       BAsmCode[1] = AdrVals[0];
  352.       AdrInt = EvalStrIntExpressionWithFlags(&ArgStr[2], AdrIntType, &OK, &Flags) - (EProgCounter() + 3);
  353.       if (OK)
  354.       {
  355.         if (!mSymbolQuestionable(Flags) && ((AdrInt < -128) || (AdrInt > 127))) WrError(ErrNum_JmpDistTooBig);
  356.         else
  357.         {
  358.           BAsmCode[0] = 0x41;
  359.           BAsmCode[2] = AdrInt & 0xff;
  360.           CodeLen = 3;
  361.         }
  362.       }
  363.     }
  364.   }
  365. }
  366.  
  367. static void DecodeCBEQ(Word Index)
  368. {
  369.   Boolean OK;
  370.   tSymbolFlags Flags;
  371.   LongInt AdrInt;
  372.  
  373.   UNUSED(Index);
  374.  
  375.   if (ArgCnt == 2)
  376.   {
  377.     DecodeAdr(1, 1, MModDir | MModX);
  378.     switch (AdrMode)
  379.     {
  380.       case ModDir:
  381.         BAsmCode[1] = AdrVals[0];
  382.         break;
  383.       case ModX:
  384.         BAsmCode[1] = 0x0f;
  385.         break;
  386.     }
  387.     if (AdrMode != ModNone)
  388.     {
  389.       BAsmCode[0] = 0x31;
  390.       AdrInt = EvalStrIntExpressionWithFlags(&ArgStr[2], AdrIntType, &OK, &Flags) - (EProgCounter() + 3);
  391.       if (OK)
  392.       {
  393.         if (!mSymbolQuestionable(Flags) && ((AdrInt < -128) || (AdrInt > 127))) WrError(ErrNum_JmpDistTooBig);
  394.         else
  395.         {
  396.           BAsmCode[2] = AdrInt & 0xff;
  397.           CodeLen = 3;
  398.         }
  399.       }
  400.     }
  401.   }
  402.   else if (ArgCnt == 3)
  403.   {
  404.     if ((*(ArgStr[1].str.p_str) != 0) || (as_strcasecmp(ArgStr[2].str.p_str, "X"))) WrStrErrorPos(ErrNum_InvReg, &ArgStr[2]);
  405.     else
  406.     {
  407.       BAsmCode[0] = 0x31; BAsmCode[1] = 0x0e;
  408.       AdrInt = EvalStrIntExpressionWithFlags(&ArgStr[3], AdrIntType, &OK, &Flags) - (EProgCounter() + 3);
  409.       if (OK)
  410.       {
  411.         if (!mSymbolQuestionable(Flags) && ((AdrInt < -128) || (AdrInt > 127))) WrError(ErrNum_JmpDistTooBig);
  412.         else
  413.         {
  414.           BAsmCode[2] = AdrInt & 0xff;
  415.           CodeLen = 3;
  416.         }
  417.       }
  418.     }
  419.   }
  420.   else
  421.     (void)ChkArgCnt(2, 3);
  422. }
  423.  
  424. static void DecodeDBNZx(Word Index)
  425. {
  426.   Boolean OK;
  427.   tSymbolFlags Flags;
  428.   LongInt AdrInt;
  429.  
  430.   if (ChkArgCnt(1, 1))
  431.   {
  432.     AdrInt = EvalStrIntExpressionWithFlags(&ArgStr[1], AdrIntType, &OK, &Flags) - (EProgCounter() + ((Index == 0) ? 3 : 2));
  433.     if (OK)
  434.     {
  435.       if (!mSymbolQuestionable(Flags) && ((AdrInt < -128) || (AdrInt > 127))) WrError(ErrNum_JmpDistTooBig);
  436.       else if (Index == 0)
  437.       {
  438.         BAsmCode[0] = 0x3b;
  439.         BAsmCode[1] = 0x0f;
  440.         BAsmCode[2] = AdrInt & 0xff;
  441.         CodeLen = 3;
  442.       }
  443.       else
  444.       {
  445.         BAsmCode[0] = 0x4b;
  446.         BAsmCode[1] = AdrInt & 0xff;
  447.         CodeLen = 2;
  448.       }
  449.     }
  450.   }
  451. }
  452.  
  453. static void DecodeDBNZ(Word Index)
  454. {
  455.   Boolean OK;
  456.   tSymbolFlags Flags;
  457.   LongInt AdrInt;
  458.   Byte Disp = 0;
  459.  
  460.   UNUSED(Index);
  461.  
  462.   if (ChkArgCnt(2, 3))
  463.   {
  464.     DecodeAdr(1, ArgCnt - 1, MModDir | MModIX);
  465.     switch (AdrMode)
  466.     {
  467.       case ModDir:
  468.         BAsmCode[0] = 0x3b;
  469.         BAsmCode[1] = AdrVals[0];
  470.         Disp = 3;
  471.         break;
  472.       case ModIX:
  473.         BAsmCode[0] = 0x3b;
  474.         BAsmCode[1] = 0x0e;
  475.         Disp = 3;
  476.         break;
  477.     }
  478.     if (AdrMode != ModNone)
  479.     {
  480.       AdrInt = EvalStrIntExpressionWithFlags(&ArgStr[ArgCnt], AdrIntType, &OK, &Flags) - (EProgCounter() + Disp);
  481.       if (OK)
  482.       {
  483.         if (!mSymbolQuestionable(Flags) && ((AdrInt < -128) || (AdrInt > 127))) WrError(ErrNum_JmpDistTooBig);
  484.         else
  485.         {
  486.           BAsmCode[Disp - 1] = AdrInt & 0xff;
  487.           CodeLen = Disp;
  488.         }
  489.       }
  490.     }
  491.   }
  492. }
  493.  
  494.  
  495. static void DecodeLDX(Word Index)
  496. {
  497.  
  498.   BAsmCode[0] = 0x4e;
  499.  
  500.   if (ChkArgCnt(1, 2))
  501.   {
  502.     DecodeAdr(1, ArgCnt, (Index == 0) ? (MModImm | MModDir | MModIX) : MModDir);
  503.     if (AdrMode != ModNone)
  504.     {
  505.       switch (AdrMode)
  506.       {
  507.         case ModImm:
  508.           BAsmCode[0] = 0x3e;
  509.           BAsmCode[1] = AdrVals[0];
  510.           BAsmCode[2] = 0x0f;
  511.           break;       
  512.         case ModDir:
  513.           if (Index == 0)
  514.           {
  515.             BAsmCode[1] = AdrVals[0];
  516.             BAsmCode[2] = 0x0f;
  517.           }
  518.           else
  519.           {
  520.             BAsmCode[1] = 0x0f;
  521.             BAsmCode[2] = AdrVals[0];
  522.           }
  523.           break;
  524.         case ModIX:
  525.           BAsmCode[1] = 0x0e;
  526.           BAsmCode[2] = 0x0e;
  527.           break;
  528.       }
  529.       CodeLen = 3;
  530.     }
  531.   }
  532. }
  533.  
  534. static void DecodeTST(Word Index)
  535. {
  536.  
  537.   BAsmCode[0] = 0x4e;
  538.  
  539.   if (Index == 1)
  540.   {
  541.     if (ChkArgCnt(0, 0))
  542.     {
  543.       BAsmCode[1] = 0x0f;
  544.       BAsmCode[2] = 0x0f;
  545.       CodeLen = 3;
  546.     }
  547.   }
  548.   else if (Index == 2)
  549.   {
  550.     BAsmCode[0] = 0xaa;
  551.     BAsmCode[1] = 0x00;
  552.     CodeLen = 2;
  553.   }
  554.   else
  555.   {
  556.     DecodeAdr(1, ArgCnt, MModDir | MModX | MModIX);
  557.     if (AdrMode != ModNone)
  558.     {
  559.       switch (AdrMode)
  560.       {
  561.         case ModDir:
  562.           BAsmCode[1] = AdrVals[0];
  563.           BAsmCode[2] = AdrVals[0];
  564.           break;
  565.         case ModIX:
  566.           BAsmCode[1] = 0x0e;
  567.           BAsmCode[2] = 0x0e;
  568.           break;
  569.         case ModX:
  570.           BAsmCode[1] = 0x0f;
  571.           BAsmCode[2] = 0x0f;
  572.           break;
  573.       }
  574.       CodeLen = 3;
  575.     }
  576.   }
  577. }
  578.  
  579. static void DecodeALU(Word Index)
  580. {
  581.   ALUOrder *pOrder = ALUOrders + Index;
  582.  
  583.   if (ChkMinCPU(pOrder->MinCPU))
  584.   {
  585.     DecodeAdr(1, ArgCnt, pOrder->Mask);
  586.     if (AdrMode != ModNone)
  587.     {
  588.       switch (AdrMode)
  589.       {
  590.         case ModImm:
  591.           BAsmCode[0] = 0xa0 | pOrder->Code;
  592.           memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  593.           CodeLen = 1 + AdrCnt;
  594.           break;
  595.         case ModDir:
  596.           BAsmCode[0] = 0xb0 | pOrder->Code;
  597.           memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  598.           CodeLen = 1 + AdrCnt;
  599.           break;
  600.         case ModIX:
  601.           BAsmCode[0] = 0xb0 | pOrder->Code;
  602.           BAsmCode[1] = 0x0e;
  603.           CodeLen = 2;
  604.           break;
  605.         case ModX:
  606.           BAsmCode[0] = 0xb0 | pOrder->Code;
  607.           BAsmCode[1] = 0x0f;
  608.           CodeLen = 2;
  609.           break;
  610.         case ModExt:
  611.           BAsmCode[0] = pOrder->Code;
  612.           memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  613.           CodeLen = 1 + AdrCnt;
  614.       }
  615.     }
  616.   }
  617. }
  618.  
  619. static void DecodeRMW(Word Index)
  620. {
  621.   RMWOrder *pOrder = RMWOrders + Index;
  622.  
  623.   if (ChkMinCPU(pOrder->MinCPU))
  624.   {
  625.     DecodeAdr(1, ArgCnt, pOrder->Mask);
  626.     if (AdrMode != ModNone)
  627.     {
  628.       switch (AdrMode)
  629.       {
  630.         case ModImm :
  631.           BAsmCode[0] = 0xa0 | pOrder->Code;
  632.           memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  633.           CodeLen = 1 + AdrCnt;
  634.           break;
  635.         case ModDir :
  636.           BAsmCode[0] = 0xb0 ^ pOrder->Code;
  637.           memcpy(BAsmCode + 1, AdrVals, AdrCnt);
  638.           CodeLen = 1+ AdrCnt;
  639.           break;
  640.         case ModTny :
  641.           BAsmCode[0] = AdrVals[0] | pOrder->DCode;
  642.           CodeLen = 1;
  643.           break;
  644.         case ModSrt :
  645.           BAsmCode[0] = AdrVals[0] | pOrder->DCode;
  646.           CodeLen = 1;
  647.           break;
  648.         case ModIX  :
  649.           BAsmCode[0] = 0x0e | pOrder->DCode;
  650.           CodeLen = 1;
  651.           break;
  652.         case ModX :
  653.           BAsmCode[0] = 0x0f | pOrder->DCode;
  654.           CodeLen = 1;
  655.           break;
  656.       }
  657.     }
  658.   }
  659. }
  660.  
  661. static void decode_bset_bclr_core(Word code, int arg_index)
  662. {
  663.   Boolean ok = True;
  664.  
  665.   if (!as_strcasecmp(ArgStr[arg_index].str.p_str, "D[X]")) BAsmCode[1] = 0x0e;
  666.   else if  (!as_strcasecmp(ArgStr[arg_index].str.p_str, "X")) BAsmCode[1] = 0x0f;
  667.   else BAsmCode[1] = EvalStrIntExpression(&ArgStr[2], Int8, &ok);
  668.  
  669.   if (ok)
  670.   {
  671.     CodeLen = 2;
  672.     BAsmCode[0] = 0x10 | code;
  673.   }
  674. }
  675.  
  676. static void decode_bset_bclr_1(Word code)
  677. {
  678.   if (ChkArgCnt(1, 1))
  679.     decode_bset_bclr_core(code, 1);
  680. }
  681.  
  682. static void decode_bset_bclr_2(Word code)
  683. {
  684.   if (ChkArgCnt(2, 2))
  685.   {
  686.     Boolean ok;
  687.  
  688.     code |= EvalStrIntExpression(&ArgStr[1], UInt3, &ok) << 1;
  689.     if (ok)
  690.       decode_bset_bclr_core(code, 2);
  691.   }
  692. }
  693.  
  694. static void decode_brset_brclr_core(Word code, int arg_index)
  695. {
  696.   Boolean ok = True;
  697.  
  698.   if (!as_strcasecmp(ArgStr[2].str.p_str, "D[X]"))
  699.     BAsmCode[1] = 0x0e;
  700.   else if (!as_strcasecmp(ArgStr[2].str.p_str, "X"))
  701.     BAsmCode[1] = 0x0f;
  702.   else
  703.     BAsmCode[1] = EvalStrIntExpression(&ArgStr[arg_index], Int8, &ok);
  704.  
  705.   if (ok)
  706.   {
  707.     tSymbolFlags flags;
  708.     LongInt address;
  709.  
  710.     address = EvalStrIntExpressionWithFlags(&ArgStr[arg_index + 1], AdrIntType, &ok, &flags) - (EProgCounter() + 3);
  711.     if (ok)
  712.     {
  713.       if (!mSymbolQuestionable(flags) && ((address < -128) || (address > 127))) WrError(ErrNum_JmpDistTooBig);
  714.       else
  715.       {
  716.         CodeLen = 3;
  717.         BAsmCode[0] = code;
  718.         BAsmCode[2] = Lo(address);
  719.       }
  720.     }
  721.   }
  722. }
  723.  
  724. static void decode_brset_brclr_2(Word code)
  725. {
  726.   if (ChkArgCnt(2, 2))
  727.     decode_brset_brclr_core(code, 1);
  728. }
  729.  
  730. static void decode_brset_brclr_3(Word code)
  731. {
  732.   if (ChkArgCnt(3, 3))
  733.   {
  734.     Boolean ok;
  735.  
  736.     code |= EvalStrIntExpression(&ArgStr[1], UInt3, &ok) << 1;
  737.     if (ok)
  738.       decode_brset_brclr_core(code, 2);
  739.   }
  740. }
  741.  
  742. /*--------------------------------------------------------------------------*/
  743. /* dynamic code table handling */
  744.  
  745. static void AddFixed(const char *NName, CPUVar NMin, Byte NCode)
  746. {
  747.   order_array_rsv_end(FixedOrders, BaseOrder);
  748.   FixedOrders[InstrZ].MinCPU = NMin;
  749.   FixedOrders[InstrZ].Code = NCode;
  750.   AddInstTable(InstTable, NName, InstrZ++, DecodeFixed);
  751. }
  752.  
  753. static void AddRel(const char *NName, CPUVar NMin, Byte NCode)
  754. {
  755.   order_array_rsv_end(RelOrders, BaseOrder);
  756.   RelOrders[InstrZ].MinCPU = NMin;
  757.   RelOrders[InstrZ].Code = NCode;
  758.   AddInstTable(InstTable, NName, InstrZ++, DecodeRel);
  759. }
  760.  
  761. static void AddALU(const char *NName, CPUVar NMin, Byte NCode, Word NMask)
  762. {
  763.   order_array_rsv_end(ALUOrders, ALUOrder);
  764.   ALUOrders[InstrZ].MinCPU = NMin;
  765.   ALUOrders[InstrZ].Code = NCode;
  766.   ALUOrders[InstrZ].Mask = NMask;
  767.   AddInstTable(InstTable, NName, InstrZ++, DecodeALU);
  768. }
  769.  
  770. static void AddRMW(const char *NName, CPUVar NMin, Byte NCode, Byte DCode, Word NMask)
  771. {
  772.   order_array_rsv_end(RMWOrders, RMWOrder);
  773.   RMWOrders[InstrZ].MinCPU = NMin;
  774.   RMWOrders[InstrZ].Code = NCode;
  775.   RMWOrders[InstrZ].DCode = DCode;
  776.   RMWOrders[InstrZ].Mask = NMask;
  777.   AddInstTable(InstTable, NName, InstrZ++, DecodeRMW);
  778. }
  779.  
  780. static void add_bset_bclr(const char *p_name, Word code)
  781. {
  782.   char name[10];
  783.   unsigned bit;
  784.  
  785.   AddInstTable(InstTable, p_name, code, decode_bset_bclr_2);
  786.   for (bit = 0; bit < 8; bit++)
  787.   {
  788.     as_snprintf(name, sizeof(name), "%s%c", p_name, bit + '0');
  789.     AddInstTable(InstTable, name, code | (bit << 1), decode_bset_bclr_1);
  790.   }
  791. }
  792.  
  793. static void add_brset_brclr(const char *p_name, Word code)
  794. {
  795.   char name[10];
  796.   unsigned bit;
  797.  
  798.   AddInstTable(InstTable, p_name, code, decode_brset_brclr_3);
  799.   for (bit = 0; bit < 8; bit++)
  800.   {
  801.     as_snprintf(name, sizeof(name), "%s%c", p_name, bit + '0');
  802.     AddInstTable(InstTable, name, code | (bit << 1), decode_brset_brclr_2);
  803.   }
  804. }
  805.  
  806. static void InitFields(void)
  807. {
  808.   InstTable = CreateInstTable(177);
  809.   SetDynamicInstTable(InstTable);
  810.  
  811.   add_null_pseudo(InstTable);
  812.  
  813.   InstrZ = 0;
  814.   AddFixed("SHA" , CPU68RS08, 0x45); AddFixed("SLA" , CPU68RS08, 0x42);
  815.   AddFixed("RTS" , CPU68RS08, 0xbe); AddFixed("TAX" , CPU68RS08, 0xef);
  816.   AddFixed("CLC" , CPU68RS08, 0x38); AddFixed("SEC" , CPU68RS08, 0x39);
  817.   AddFixed("NOP" , CPU68RS08, 0xac); AddFixed("TXA" , CPU68RS08, 0xcf);
  818.   AddFixed("COMA", CPU68RS08, 0x43); AddFixed("LSRA", CPU68RS08, 0x44);
  819.   AddFixed("RORA", CPU68RS08, 0x46); AddFixed("ASLA", CPU68RS08, 0x48);
  820.   AddFixed("LSLA", CPU68RS08, 0x48); AddFixed("ROLA", CPU68RS08, 0x49);
  821.   AddFixed("DECA", CPU68RS08, 0x4a); AddFixed("DECX", CPU68RS08, 0x5f);
  822.   AddFixed("INCA", CPU68RS08, 0x4c); AddFixed("INCX", CPU68RS08, 0x2f);
  823.   AddFixed("CLRA", CPU68RS08, 0x4f); AddFixed("CLRX", CPU68RS08, 0x8f);
  824.   AddFixed("STOP", CPU68RS08, 0xae); AddFixed("WAIT", CPU68RS08, 0xaf);
  825.   AddFixed("BGND", CPU68RS08, 0xbf);
  826.  
  827.   InstrZ = 0;
  828.   AddRel("BRA" , CPU68RS08, 0x30); AddRel("BRN" , CPU68RS08, 0x00);
  829.   AddRel("BCC" , CPU68RS08, 0x34); AddRel("BCS" , CPU68RS08, 0x35);
  830.   AddRel("BHS" , CPU68RS08, 0x34); AddRel("BLO" , CPU68RS08, 0x35);
  831.   AddRel("BNE" , CPU68RS08, 0x36); AddRel("BEQ" , CPU68RS08, 0x37);
  832.   AddRel("BSR" , CPU68RS08, 0xad);
  833.  
  834.   InstrZ = 0;
  835.   AddALU("ADC" , CPU68RS08, 0x09, MModImm | MModDir | MModIX  | MModX);
  836.   AddALU("AND" , CPU68RS08, 0x04, MModImm | MModDir | MModIX  | MModX);
  837.   AddALU("CMP" , CPU68RS08, 0x01, MModImm | MModDir | MModIX  | MModX);
  838.   AddALU("EOR" , CPU68RS08, 0x08, MModImm | MModDir | MModIX  | MModX);
  839.   AddALU("ORA" , CPU68RS08, 0x0a, MModImm | MModDir | MModIX  | MModX);
  840.   AddALU("SBC" , CPU68RS08, 0x02, MModImm | MModDir | MModIX  | MModX);
  841.   AddALU("JMP" , CPU68RS08, 0xbc, MModExt);
  842.   AddALU("JSR" , CPU68RS08, 0xbd, MModExt);
  843.  
  844.   InstrZ = 0;
  845.   AddRMW("ADD" , CPU68RS08, 0x0b, 0x60, MModImm | MModDir | MModTny           | MModIX | MModX );
  846.   AddRMW("SUB" , CPU68RS08, 0x00, 0x70, MModImm | MModDir | MModTny           | MModIX | MModX );
  847.   AddRMW("DEC" , CPU68RS08, 0x8a, 0x50,           MModDir | MModTny           | MModIX | MModX );
  848.   AddRMW("INC" , CPU68RS08, 0x8c, 0x20,           MModDir | MModTny           | MModIX | MModX );
  849.   AddRMW("CLR" , CPU68RS08, 0x8f, 0x80,           MModDir           | MModSrt | MModIX | MModX );
  850.   AddRMW("LDA" , CPU68RS08, 0x06, 0xc0, MModImm | MModDir           | MModSrt | MModIX | MModX );
  851.   AddRMW("STA" , CPU68RS08, 0x07, 0xe0,           MModDir           | MModSrt | MModIX | MModX );
  852.  
  853.  
  854.   AddInstTable(InstTable, "CBEQA", 1, DecodeCBEQx);
  855.  
  856.   AddInstTable(InstTable, "CBEQ" , 0, DecodeCBEQ);
  857.  
  858.   AddInstTable(InstTable, "DBNZA", 1, DecodeDBNZx);
  859.   AddInstTable(InstTable, "DBNZX", 0, DecodeDBNZx);
  860.  
  861.   AddInstTable(InstTable, "DBNZ" , 0, DecodeDBNZ);
  862.  
  863.   AddInstTable(InstTable, "MOV"  , 0, DecodeMOV);
  864.  
  865.   AddInstTable(InstTable, "TST"  , 0, DecodeTST);
  866.   AddInstTable(InstTable, "TSTX" , 1, DecodeTST);
  867.   AddInstTable(InstTable, "TSTA" , 2, DecodeTST);
  868.  
  869.   AddInstTable(InstTable, "LDX"  , 0, DecodeLDX);
  870.   AddInstTable(InstTable, "STX"  , 1, DecodeLDX);
  871.  
  872.   add_bset_bclr("BCLR" , 0x01);
  873.   add_bset_bclr("BSET" , 0x00);
  874.   add_brset_brclr("BRCLR", 0x01);
  875.   add_brset_brclr("BRSET", 0x00);
  876.  
  877.   add_moto8_pseudo(InstTable, e_moto_pseudo_flags_be);
  878.   AddMoto16Pseudo(InstTable, e_moto_pseudo_flags_be);
  879.   AddInstTable(InstTable, "DB", eIntPseudoFlag_BigEndian | eIntPseudoFlag_AllowInt | eIntPseudoFlag_AllowString | eIntPseudoFlag_MotoRep, DecodeIntelDB);
  880.   AddInstTable(InstTable, "DW", eIntPseudoFlag_BigEndian | eIntPseudoFlag_AllowInt | eIntPseudoFlag_AllowString | eIntPseudoFlag_MotoRep, DecodeIntelDW);
  881. }
  882.  
  883. static void DeinitFields(void)
  884. {
  885.   DestroyInstTable(InstTable);
  886.   order_array_free(FixedOrders);
  887.   order_array_free(RelOrders);
  888.   order_array_free(ALUOrders);
  889.   order_array_free(RMWOrders);
  890. }
  891.  
  892. /*--------------------------------------------------------------------------*/
  893. /* Main Functions */
  894.  
  895. static Boolean DecodeAttrPart_68rs08(void)
  896. {
  897.   if (strlen(AttrPart.str.p_str) > 1)
  898.   {
  899.     WrStrErrorPos(ErrNum_UndefAttr, &AttrPart);
  900.     return False;
  901.   }
  902.  
  903.   /* Deduce operand size.  No size is zero-length string -> '\0' */
  904.  
  905.   return DecodeMoto16AttrSize(*AttrPart.str.p_str, &AttrPartOpSize[0], False);
  906. }
  907.  
  908. static void MakeCode_68rs08(void)
  909. {
  910.   if (AttrPartOpSize[0] == eSymbolSizeUnknown)
  911.     AttrPartOpSize[0] = eSymbolSize8Bit;
  912.  
  913.   if (!LookupInstTable(InstTable, OpPart.str.p_str))
  914.     WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
  915. }
  916.  
  917. static Boolean IsDef_68rs08(void)
  918. {
  919.   return False;
  920. }
  921.  
  922. static void SwitchFrom_68rs08(void)
  923. {
  924.   DeinitFields();
  925. }
  926.  
  927. static void SwitchTo_68rs08(void)
  928. {
  929.   TurnWords = False;
  930.   SetIntConstMode(eIntConstModeMoto);
  931.  
  932.   PCSymbol = "*";
  933.   HeaderID = 0x5e;
  934.   NOPCode = 0xac;
  935.   DivideChars = ",";
  936.   HasAttrs = True;
  937.   AttrChars = ".";
  938.  
  939.   ValidSegs = (1 << SegCode);
  940.   Grans[SegCode] = 1; ListGrans[SegCode] = 1; SegInits[SegCode] = 0;
  941.   SegLimits[SegCode] = 0x3fff;
  942.   AdrIntType = UInt14;
  943.  
  944.   DecodeAttrPart = DecodeAttrPart_68rs08;
  945.   MakeCode = MakeCode_68rs08;
  946.   IsDef = IsDef_68rs08;
  947.   SwitchFrom = SwitchFrom_68rs08;
  948.   InitFields();
  949.   AddMoto16PseudoONOFF(False);
  950. }
  951.  
  952. void code68rs08_init(void)
  953. {
  954.   CPU68RS08 = AddCPU("68RS08", SwitchTo_68rs08);
  955.   AddCopyright("68RS08-Generator (C) 2006 Andreas Bolsch");
  956. }
  957.