Subversion Repositories pentevo

Rev

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

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