Subversion Repositories pentevo

Rev

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

  1. /* code6805.c */
  2. /*****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
  4. /*                                                                           */
  5. /* AS-Portierung                                                             */
  6. /*                                                                           */
  7. /* Codegenerator 68(HC)05/08                                                 */
  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 "code6805.h"
  28.  
  29. typedef struct
  30. {
  31.   CPUVar MinCPU;
  32.   Byte Code;
  33. } BaseOrder;
  34.  
  35. typedef struct
  36. {
  37.   CPUVar MinCPU;
  38.   Byte Code;
  39.   Word Mask;
  40.   tSymbolSize Size;
  41. } ALUOrder;
  42.  
  43. typedef struct
  44. {
  45.   CPUVar MinCPU;
  46.   Byte Code;
  47.   Word Mask;
  48. } RMWOrder;
  49.  
  50. enum
  51. {
  52.   ModNone = -1,
  53.   ModImm = 0,
  54.   ModDir = 1,
  55.   ModExt = 2,
  56.   ModIx2 = 3,
  57.   ModIx1 = 4,
  58.   ModIx = 5,
  59.   ModSP2 = 6,
  60.   ModSP1 = 7,
  61.   ModIxP = 8
  62. };
  63.  
  64. #define MModImm (1 << ModImm)
  65. #define MModDir (1 << ModDir)
  66. #define MModExt (1 << ModExt)
  67. #define MModIx2 (1 << ModIx2)
  68. #define MModIx1 (1 << ModIx1)
  69. #define MModIx  (1 << ModIx)
  70. #define MModSP2 (1 << ModSP2)
  71. #define MModSP1 (1 << ModSP1)
  72. #define MModIxP (1 << ModIxP)
  73. #define MMod05 (MModImm | MModDir | MModExt | MModIx2 | MModIx1 | MModIx)
  74. #define MMod08 (MModSP2 | MModSP1 | MModIxP)
  75.  
  76. static ShortInt AdrMode;
  77. static tSymbolSize OpSize;
  78. static Byte AdrVals[2];
  79.  
  80. static IntType AdrIntType;
  81.  
  82. static CPUVar CPU6805, CPU68HC05, CPU68HC08, CPU68HCS08;
  83.  
  84. static BaseOrder *FixedOrders;
  85. static BaseOrder *RelOrders;
  86. static RMWOrder *RMWOrders;
  87. static ALUOrder *ALUOrders;
  88.  
  89. /*--------------------------------------------------------------------------*/
  90. /* address parser */
  91.  
  92.  
  93. static unsigned ChkZero(char *s, Byte *pErg)
  94. {
  95.   if (*s == '<')
  96.   {
  97.     *pErg = 2;
  98.     return 1;
  99.   }
  100.   else if (*s == '>')
  101.   {
  102.     *pErg = 1;
  103.     return 1;
  104.   }
  105.   else
  106.   {
  107.     *pErg = 0;
  108.     return 0;
  109.   }
  110. }
  111.  
  112. static void DecodeAdr(Byte Start, Byte Stop, Word Mask)
  113. {
  114.   Boolean OK;
  115.   tSymbolFlags Flags;
  116.   Word AdrWord, Mask08;
  117.   Byte ZeroMode;
  118.   unsigned Offset;
  119.   ShortInt tmode1, tmode2;
  120.  
  121.   AdrMode = ModNone;
  122.   AdrCnt = 0;
  123.  
  124.   Mask08 = Mask & MMod08;
  125.   if (MomCPU == CPU6805)
  126.     Mask &= MMod05;
  127.  
  128.   if (Stop - Start == 1)
  129.   {
  130.     if (!as_strcasecmp(ArgStr[Stop].str.p_str, "X"))
  131.     {
  132.       tmode1 = ModIx1;
  133.       tmode2 = ModIx2;
  134.     }
  135.     else if (!as_strcasecmp(ArgStr[Stop].str.p_str,"SP"))
  136.     {
  137.       tmode1 = ModSP1;
  138.       tmode2 = ModSP2;
  139.       if (MomCPU < CPU68HC08)
  140.       {
  141.         WrStrErrorPos(ErrNum_InvReg, &ArgStr[Stop]);
  142.         goto chk;
  143.       }
  144.     }
  145.     else
  146.     {
  147.       WrStrErrorPos(ErrNum_InvReg, &ArgStr[Stop]);
  148.       goto chk;
  149.     }
  150.  
  151.     Offset = ChkZero(ArgStr[Start].str.p_str, &ZeroMode);
  152.     AdrWord = EvalStrIntExpressionOffsWithFlags(&ArgStr[Start], Offset, (ZeroMode == 2) ? Int8 : Int16, &OK, &Flags);
  153.  
  154.     if (OK)
  155.     {
  156.       if ((ZeroMode == 0) && (AdrWord == 0) && (Mask & MModIx) && (tmode1 == ModIx1))
  157.         AdrMode = ModIx;
  158.  
  159.       else if (((Mask & (1 << tmode2)) == 0) || (ZeroMode == 2) || ((ZeroMode == 0) && (Hi(AdrWord) == 0)))
  160.       {
  161.         if (mFirstPassUnknown(Flags))
  162.           AdrWord &= 0xff;
  163.         if (Hi(AdrWord) != 0) WrError(ErrNum_NoShortAddr);
  164.         else
  165.         {
  166.           AdrCnt = 1;
  167.           AdrVals[0] = Lo(AdrWord);
  168.           AdrMode = tmode1;
  169.         }
  170.       }
  171.  
  172.       else
  173.       {
  174.         AdrVals[0] = Hi(AdrWord);
  175.         AdrVals[1] = Lo(AdrWord);
  176.         AdrCnt = 2;
  177.         AdrMode = tmode2;
  178.       }
  179.     }
  180.   }
  181.  
  182.   else if (Stop == Start)
  183.   {
  184.     /* Postinkrement */
  185.  
  186.     if (!as_strcasecmp(ArgStr[Start].str.p_str, "X+"))
  187.     {
  188.       AdrMode = ModIxP;
  189.       goto chk;
  190.     }
  191.  
  192.     /* X-indirekt */
  193.  
  194.     if (!as_strcasecmp(ArgStr[Start].str.p_str, "X"))
  195.     {
  196.       WrError(ErrNum_ConvIndX);
  197.       AdrMode = ModIx;
  198.       goto chk;
  199.     }
  200.  
  201.     /* immediate */
  202.  
  203.     if (*ArgStr[Start].str.p_str == '#')
  204.     {
  205.       switch (OpSize)
  206.       {
  207.         case eSymbolSizeUnknown:
  208.           WrError(ErrNum_UndefOpSizes);
  209.           break;
  210.         case eSymbolSize8Bit:
  211.           AdrVals[0] = EvalStrIntExpressionOffs(&ArgStr[Start], 1, Int8, &OK);
  212.           if (OK)
  213.           {
  214.             AdrCnt = 1;
  215.             AdrMode = ModImm;
  216.           }
  217.           break;
  218.         case eSymbolSize16Bit:
  219.           AdrWord = EvalStrIntExpressionOffs(&ArgStr[Start], 1, Int16, &OK);
  220.           if (OK)
  221.           {
  222.             AdrVals[0] = Hi(AdrWord);
  223.             AdrVals[1] = Lo(AdrWord);
  224.             AdrCnt = 2;
  225.             AdrMode = ModImm;
  226.           }
  227.           break;
  228.         default:
  229.           break;
  230.       }
  231.       goto chk;
  232.     }
  233.  
  234.     /* absolut */
  235.  
  236.     Offset = ChkZero(ArgStr[Start].str.p_str, &ZeroMode);
  237.     AdrWord = EvalStrIntExpressionOffsWithFlags(&ArgStr[Start], Offset, (ZeroMode == 2) ? UInt8 : AdrIntType, &OK, &Flags);
  238.  
  239.     if (OK)
  240.     {
  241.       if (((Mask & MModExt) == 0) || (ZeroMode == 2) || ((ZeroMode == 0) && (Hi(AdrWord) == 0)))
  242.       {
  243.         if (mFirstPassUnknown(Flags))
  244.           AdrWord &= 0xff;
  245.         if (Hi(AdrWord) != 0) WrError(ErrNum_NoShortAddr);
  246.         else
  247.         {
  248.           AdrCnt = 1;
  249.           AdrVals[0] = Lo(AdrWord);
  250.           AdrMode = ModDir;
  251.         }
  252.       }
  253.       else
  254.       {
  255.         AdrVals[0] = Hi(AdrWord);
  256.         AdrVals[1] = Lo(AdrWord);
  257.         AdrCnt = 2;
  258.         AdrMode = ModExt;
  259.       }
  260.       goto chk;
  261.     }
  262.   }
  263.  
  264.   else
  265.     (void)ChkArgCnt(Start, Start + 1);
  266.  
  267. chk:
  268.   if ((AdrMode != ModNone) && (!(Mask & (1 << AdrMode))))
  269.   {
  270.     if ((1 << AdrMode) & Mask08)
  271.       (void)ChkMinCPUExt(CPU68HC08, ErrNum_AddrModeNotSupported);
  272.     else
  273.       WrError(ErrNum_InvAddrMode);
  274.     AdrMode = ModNone;
  275.     AdrCnt = 0;
  276.   }
  277. }
  278.  
  279. /*--------------------------------------------------------------------------*/
  280. /* instruction parsers */
  281.  
  282. static void DecodeFixed(Word Index)
  283. {
  284.   const BaseOrder *pOrder = FixedOrders + Index;
  285.  
  286.   if (ChkArgCnt(0, 0)
  287.    && ChkMinCPU(pOrder->MinCPU))
  288.   {
  289.     CodeLen = 1;
  290.     BAsmCode[0] = pOrder->Code;
  291.   }
  292. }
  293.  
  294. static void DecodeMOV(Word Index)
  295. {
  296.   UNUSED(Index);
  297.  
  298.   if (ChkArgCnt(2, 2)
  299.    && ChkMinCPU(CPU68HC08))
  300.   {
  301.     OpSize = eSymbolSize8Bit;
  302.     DecodeAdr(1, 1, MModImm | MModDir | MModIxP);
  303.     switch (AdrMode)
  304.     {
  305.       case ModImm:
  306.         BAsmCode[1] = AdrVals[0];
  307.         DecodeAdr(2, 2, MModDir);
  308.         if (AdrMode == ModDir)
  309.         {
  310.           BAsmCode[0] = 0x6e;
  311.           BAsmCode[2] = AdrVals[0];
  312.           CodeLen = 3;
  313.         }
  314.         break;
  315.       case ModDir:
  316.         BAsmCode[1] = AdrVals[0];
  317.         DecodeAdr(2, 2, MModDir | MModIxP);
  318.         switch (AdrMode)
  319.         {
  320.           case ModDir:
  321.             BAsmCode[0] = 0x4e;
  322.             BAsmCode[2] = AdrVals[0];
  323.             CodeLen = 3;
  324.             break;
  325.           case ModIxP:
  326.             BAsmCode[0] = 0x5e;
  327.             CodeLen = 2;
  328.             break;
  329.         }
  330.         break;
  331.       case ModIxP:
  332.         DecodeAdr(2, 2, MModDir);
  333.         if (AdrMode == ModDir)
  334.         {
  335.           BAsmCode[0] = 0x7e;
  336.           BAsmCode[1] = AdrVals[0];
  337.           CodeLen = 2;
  338.         }
  339.         break;
  340.     }
  341.   }
  342. }
  343.  
  344. static void DecodeRel(Word Index)
  345. {
  346.   BaseOrder *pOrder = RelOrders + Index;
  347.   Boolean OK;
  348.   tSymbolFlags Flags;
  349.   LongInt AdrInt;
  350.  
  351.   if (ChkArgCnt(1, 1)
  352.    && ChkMinCPU(pOrder->MinCPU))
  353.   {
  354.     AdrInt = EvalStrIntExpressionWithFlags(&ArgStr[1], AdrIntType, &OK, &Flags) - (EProgCounter() + 2);
  355.     if (OK)
  356.     {
  357.       if (!mSymbolQuestionable(Flags) && ((AdrInt < -128) || (AdrInt > 127))) WrError(ErrNum_JmpDistTooBig);
  358.       else
  359.       {
  360.         CodeLen = 2;
  361.         BAsmCode[0] = pOrder->Code;
  362.         BAsmCode[1] = Lo(AdrInt);
  363.       }
  364.     }
  365.   }
  366. }
  367.  
  368. static void DecodeCBEQx(Word Index)
  369. {
  370.   Boolean OK;
  371.   tSymbolFlags Flags;
  372.   LongInt AdrInt;
  373.  
  374.   if (ChkArgCnt(2, 2)
  375.    && ChkMinCPU(CPU68HC08))
  376.   {
  377.     OpSize = eSymbolSize8Bit; DecodeAdr(1, 1, MModImm);
  378.     if (AdrMode == ModImm)
  379.     {
  380.       BAsmCode[1] = AdrVals[0];
  381.       AdrInt = EvalStrIntExpressionWithFlags(&ArgStr[2], AdrIntType, &OK, &Flags) - (EProgCounter() + 3);
  382.       if (OK)
  383.       {
  384.         if (!mSymbolQuestionable(Flags) && ((AdrInt < -128) || (AdrInt > 127))) WrError(ErrNum_JmpDistTooBig);
  385.         else
  386.         {
  387.           BAsmCode[0] = 0x41 | Index;
  388.           BAsmCode[2] = AdrInt & 0xff;
  389.           CodeLen = 3;
  390.         }
  391.       }
  392.     }
  393.   }
  394. }
  395.  
  396. static void DecodeCBEQ(Word Index)
  397. {
  398.   Boolean OK;
  399.   tSymbolFlags Flags;
  400.   LongInt AdrInt;
  401.   Byte Disp = 0;
  402.  
  403.   UNUSED(Index);
  404.  
  405.   if (!ChkMinCPU(CPU68HC08));
  406.   else if (ArgCnt == 2)
  407.   {
  408.     DecodeAdr(1, 1, MModDir | MModIxP);
  409.     switch (AdrMode)
  410.     {
  411.       case ModDir:
  412.         BAsmCode[0] = 0x31;
  413.         BAsmCode[1] = AdrVals[0];
  414.         Disp = 3;
  415.         break;
  416.       case ModIxP:
  417.         BAsmCode[0]=0x71;
  418.         Disp = 2;
  419.         break;
  420.     }
  421.     if (AdrMode != ModNone)
  422.     {
  423.       AdrInt = EvalStrIntExpressionWithFlags(&ArgStr[2], AdrIntType, &OK, &Flags) - (EProgCounter() + Disp);
  424.       if (OK)
  425.       {
  426.         if (!mSymbolQuestionable(Flags) && ((AdrInt < -128) || (AdrInt > 127))) WrError(ErrNum_JmpDistTooBig);
  427.         else
  428.         {
  429.           BAsmCode[Disp - 1] = AdrInt & 0xff;
  430.           CodeLen = Disp;
  431.         }
  432.       }
  433.     }
  434.   }
  435.   else if (ArgCnt == 3)
  436.   {
  437.     OK = True;
  438.     if (!as_strcasecmp(ArgStr[2].str.p_str, "X+")) Disp = 3;
  439.     else if (!as_strcasecmp(ArgStr[2].str.p_str,"SP"))
  440.     {
  441.       BAsmCode[0] = 0x9e;
  442.       Disp = 4;
  443.     }
  444.     else
  445.     {
  446.       WrStrErrorPos(ErrNum_InvReg, &ArgStr[2]);
  447.       OK = False;
  448.     }
  449.     if (OK)
  450.     {
  451.       BAsmCode[Disp - 3] = 0x61;
  452.       BAsmCode[Disp - 2] = EvalStrIntExpression(&ArgStr[1], UInt8, &OK);
  453.       if (OK)
  454.       {
  455.         AdrInt = EvalStrIntExpressionWithFlags(&ArgStr[3], AdrIntType, &OK, &Flags) - (EProgCounter() + Disp);
  456.         if (OK)
  457.         {
  458.           if (!mSymbolQuestionable(Flags) && ((AdrInt < -128) || (AdrInt > 127))) WrError(ErrNum_JmpDistTooBig);
  459.           else
  460.           {
  461.             BAsmCode[Disp - 1] = AdrInt & 0xff;
  462.             CodeLen = Disp;
  463.           }
  464.         }
  465.       }
  466.     }
  467.   }
  468.   else
  469.     (void)ChkArgCnt(2, 3);
  470. }
  471.  
  472. static void DecodeDBNZx(Word Index)
  473. {
  474.   Boolean OK;
  475.   tSymbolFlags Flags;
  476.   LongInt AdrInt;
  477.  
  478.   if (ChkArgCnt(1, 1)
  479.    && ChkMinCPU(CPU68HC08))
  480.   {
  481.     AdrInt = EvalStrIntExpressionWithFlags(&ArgStr[1], AdrIntType, &OK, &Flags) - (EProgCounter() + 2);
  482.     if (OK)
  483.     {
  484.       if (!mSymbolQuestionable(Flags) && ((AdrInt < -128) || (AdrInt > 127))) WrError(ErrNum_JmpDistTooBig);
  485.       else
  486.       {
  487.         BAsmCode[0] = 0x4b | Index;
  488.         BAsmCode[1] = AdrInt & 0xff;
  489.         CodeLen = 2;
  490.       }
  491.     }
  492.   }
  493. }
  494.  
  495. static void DecodeDBNZ(Word Index)
  496. {
  497.   Boolean OK;
  498.   tSymbolFlags Flags;
  499.   LongInt AdrInt;
  500.   Byte Disp = 0;
  501.  
  502.   UNUSED(Index);
  503.  
  504.   if (ChkArgCnt(2, 3)
  505.    && ChkMinCPU(CPU68HC08))
  506.   {
  507.     DecodeAdr(1, ArgCnt - 1, MModDir | MModIx | MModIx1 | MModSP1);
  508.     switch (AdrMode)
  509.     {
  510.       case ModDir:
  511.         BAsmCode[0] = 0x3b;
  512.         BAsmCode[1] = AdrVals[0];
  513.         Disp = 3;
  514.         break;
  515.       case ModIx:
  516.         BAsmCode[0] = 0x7b;
  517.         Disp = 2;
  518.         break;
  519.       case ModIx1:
  520.         BAsmCode[0] = 0x6b;
  521.         BAsmCode[1] = AdrVals[0];
  522.         Disp = 3;
  523.         break;
  524.       case ModSP1:
  525.         BAsmCode[0] = 0x9e;
  526.         BAsmCode[1] = 0x6b;
  527.         BAsmCode[2] = AdrVals[0];
  528.         Disp = 4;
  529.         break;
  530.     }
  531.     if (AdrMode != ModNone)
  532.     {
  533.       AdrInt = EvalStrIntExpressionWithFlags(&ArgStr[ArgCnt], AdrIntType, &OK, &Flags) - (EProgCounter() + Disp);
  534.       if (OK)
  535.       {
  536.         if (!mSymbolQuestionable(Flags) && ((AdrInt < -128) || (AdrInt > 127))) WrError(ErrNum_JmpDistTooBig);
  537.         else
  538.         {
  539.           BAsmCode[Disp - 1] = AdrInt & 0xff;
  540.           CodeLen = Disp;
  541.         }
  542.       }
  543.     }
  544.   }
  545. }
  546.  
  547. static void DecodeALU(Word Index)
  548. {
  549.   const ALUOrder *pOrder = ALUOrders + Index;
  550.  
  551.   if (ChkMinCPU(pOrder->MinCPU))
  552.   {
  553.     OpSize = pOrder->Size;
  554.     DecodeAdr(1, ArgCnt, pOrder->Mask);
  555.     if (AdrMode != ModNone)
  556.     {
  557.       switch (AdrMode)
  558.       {
  559.         case ModImm:
  560.           BAsmCode[0] = 0xa0 + pOrder->Code;
  561.           CodeLen = 1; /* leave for CPHX */
  562.           break;
  563.         case ModDir:
  564.           BAsmCode[0] = 0xb0 + pOrder->Code;
  565.           CodeLen = 1;
  566.           break;
  567.         case ModExt:
  568.           BAsmCode[0] = 0xc0 | pOrder->Code;
  569.           CodeLen = 1;
  570.           break;
  571.         case ModIx:
  572.           BAsmCode[0] = 0xf0 | pOrder->Code;
  573.           CodeLen = 1;
  574.           break;
  575.         case ModIx1:
  576.           BAsmCode[0] = 0xe0 | pOrder->Code;
  577.           CodeLen = 1;
  578.           break;
  579.         case ModIx2:
  580.           BAsmCode[0] = 0xd0 | pOrder->Code;
  581.           CodeLen = 1;
  582.           break;
  583.         case ModSP1:
  584.           BAsmCode[0] = 0x9e;
  585.           BAsmCode[1] = 0xe0| pOrder->Code;
  586.           CodeLen = 2;
  587.           break;
  588.         case ModSP2:
  589.           BAsmCode[0] = 0x9e;
  590.           BAsmCode[1] = 0xd0 | pOrder->Code;
  591.           CodeLen = 2;
  592.           break;
  593.       }
  594.       memcpy(BAsmCode + CodeLen, AdrVals, AdrCnt);
  595.       CodeLen += AdrCnt;
  596.     }
  597.   }
  598. }
  599.  
  600. static void DecodeCPHX(Word Index)
  601. {
  602.   UNUSED(Index);
  603.  
  604.   if (ChkMinCPU(CPU68HC08))
  605.   {
  606.     Word Mask = MModImm | MModDir;
  607.  
  608.     if (MomCPU >= CPU68HCS08)
  609.       Mask |= MModExt| MModSP1;
  610.     OpSize = eSymbolSize16Bit;
  611.     DecodeAdr(1, ArgCnt, Mask);
  612.     if (AdrMode != ModNone)
  613.     {
  614.       switch (AdrMode)
  615.       {
  616.         case ModImm:
  617.           BAsmCode[0] = 0x65;
  618.           CodeLen = 1;
  619.           break;
  620.         case ModDir:
  621.           BAsmCode[0] = 0x75;
  622.           CodeLen = 1;
  623.           break;
  624.         case ModExt:
  625.           BAsmCode[0] = 0x3e;
  626.           CodeLen = 1;
  627.           break;
  628.         case ModSP1:
  629.           BAsmCode[0] = 0x9e;
  630.           BAsmCode[1] = 0xf3;
  631.           CodeLen = 2;
  632.           break;
  633.       }
  634.       memcpy(BAsmCode + CodeLen, AdrVals, AdrCnt);
  635.       CodeLen += AdrCnt;
  636.     }
  637.   }
  638. }
  639.  
  640. static void DecodeSTHX(Word Index)
  641. {
  642.   UNUSED(Index);
  643.  
  644.   if (ChkMinCPU(CPU68HC08))
  645.   {
  646.     Word Mask = MModDir;
  647.  
  648.     if (MomCPU >= CPU68HCS08)
  649.       Mask |= MModExt| MModSP1;
  650.     DecodeAdr(1, ArgCnt, Mask);
  651.     if (AdrMode != ModNone)
  652.     {
  653.       switch (AdrMode)
  654.       {
  655.         case ModDir:
  656.           BAsmCode[0] = 0x35;
  657.           CodeLen = 1;
  658.           break;
  659.         case ModExt:
  660.           BAsmCode[0] = 0x96;
  661.           CodeLen = 1;
  662.           break;
  663.         case ModSP1:
  664.           BAsmCode[0] = 0x9e;
  665.           BAsmCode[1] = 0xff;
  666.           CodeLen = 2;
  667.           break;
  668.       }
  669.       memcpy(BAsmCode + CodeLen, AdrVals, AdrCnt);
  670.       CodeLen += AdrCnt;
  671.     }
  672.   }
  673. }
  674.  
  675. static void DecodeLDHX(Word Index)
  676. {
  677.   UNUSED(Index);
  678.  
  679.   if (ChkMinCPU(CPU68HC08))
  680.   {
  681.     Word Mask = MModImm | MModDir;
  682.  
  683.     if (MomCPU >= CPU68HCS08)
  684.       Mask |= MModExt| MModIx | MModIx1 | MModIx2 | MModSP1;
  685.     OpSize = eSymbolSize16Bit;
  686.     DecodeAdr(1, ArgCnt, Mask);
  687.     if (AdrMode != ModNone)
  688.     {
  689.       switch (AdrMode)
  690.       {
  691.         case ModImm:
  692.           BAsmCode[0] = 0x45;
  693.           CodeLen = 1;
  694.           break;
  695.         case ModDir:
  696.           BAsmCode[0] = 0x55;
  697.           CodeLen = 1;
  698.           break;
  699.         case ModExt:
  700.           BAsmCode[0] = 0x32;
  701.           CodeLen = 1;
  702.           break;
  703.         case ModIx  :
  704.           BAsmCode[0] = 0x9e;
  705.           BAsmCode[1] = 0xae;
  706.           CodeLen = 2;
  707.           break;
  708.         case ModIx1 :
  709.           BAsmCode[0] = 0x9e;
  710.           BAsmCode[1] = 0xce;
  711.           CodeLen = 2;
  712.           break;
  713.         case ModIx2 :
  714.           BAsmCode[0] = 0x9e;
  715.           BAsmCode[1] = 0xbe;
  716.           CodeLen = 2;
  717.           break;
  718.         case ModSP1:
  719.           BAsmCode[0] = 0x9e;
  720.           BAsmCode[1] = 0xfe;
  721.           CodeLen = 2;
  722.           break;
  723.       }
  724.       memcpy(BAsmCode + CodeLen, AdrVals, AdrCnt);
  725.       CodeLen += AdrCnt;
  726.     }
  727.   }
  728. }
  729.  
  730. static void DecodeAIx(Word Index)
  731. {
  732.   Boolean OK;
  733.  
  734.   if (!ChkArgCnt(1, 1));
  735.   else if (!ChkMinCPU(CPU68HC08));
  736.   else if (*ArgStr[1].str.p_str != '#') WrError(ErrNum_InvAddrMode);
  737.   else
  738.   {
  739.     BAsmCode[1] = EvalStrIntExpressionOffs(&ArgStr[1], 1, SInt8, &OK);
  740.     if (OK)
  741.     {
  742.       BAsmCode[0] = 0xa7 | Index;
  743.       CodeLen = 2;
  744.     }
  745.   }
  746. }
  747.  
  748. static void DecodeRMW(Word Index)
  749. {
  750.   const RMWOrder *pOrder = RMWOrders + Index;
  751.  
  752.   if (ChkMinCPU(pOrder->MinCPU))
  753.   {
  754.     DecodeAdr(1, ArgCnt, pOrder->Mask);
  755.     if (AdrMode != ModNone)
  756.     {
  757.       switch (AdrMode)
  758.       {
  759.         case ModDir :
  760.           BAsmCode[0] = 0x30 | pOrder->Code;
  761.           CodeLen = 1;
  762.           break;
  763.         case ModIx  :
  764.           BAsmCode[0] = 0x70 | pOrder->Code;
  765.           CodeLen = 1;
  766.           break;
  767.         case ModIx1 :
  768.           BAsmCode[0] = 0x60 | pOrder->Code;
  769.           CodeLen = 1;
  770.           break;
  771.         case ModSP1 :
  772.           BAsmCode[0] = 0x9e; BAsmCode[1] = 0x60 | pOrder->Code;
  773.           CodeLen = 2;
  774.           break;
  775.       }
  776.       memcpy(BAsmCode + CodeLen, AdrVals, AdrCnt);
  777.       CodeLen += AdrCnt;
  778.     }
  779.   }
  780. }
  781.  
  782. static void decode_bset_bclr_core(Word code, int arg_index)
  783. {
  784.   Boolean ok;
  785.  
  786.   BAsmCode[1] = EvalStrIntExpression(&ArgStr[arg_index], Int8, &ok);
  787.   if (ok)
  788.   {
  789.     BAsmCode[0] = 0x10 | code;
  790.     CodeLen = 2;
  791.   }
  792. }
  793.  
  794. static void decode_bset_bclr_1(Word code)
  795. {
  796.   if (ChkArgCnt(1, 1))
  797.     decode_bset_bclr_core(code, 1);
  798. }
  799.  
  800. static void decode_bset_bclr_2(Word code)
  801. {
  802.   if (ChkArgCnt(2, 2))
  803.   {
  804.     Boolean ok;
  805.  
  806.     code |= EvalStrIntExpression(&ArgStr[1], UInt3, &ok) << 1;
  807.     if (ok)
  808.       decode_bset_bclr_core(code, 2);
  809.   }
  810. }
  811.  
  812. static void decode_brset_brclr_core(Word code, int arg_index)
  813. {
  814.   Boolean ok;
  815.  
  816.   BAsmCode[1] = EvalStrIntExpression(&ArgStr[arg_index], Int8, &ok);
  817.   if (ok)
  818.   {
  819.     tSymbolFlags flags;
  820.     LongInt address;
  821.  
  822.     address = EvalStrIntExpressionWithFlags(&ArgStr[arg_index + 1], AdrIntType, &ok, &flags) - (EProgCounter() + 3);
  823.     if (ok)
  824.     {
  825.       if (!mSymbolQuestionable(flags) && ((address < -128) || (address > 127))) WrError(ErrNum_JmpDistTooBig);
  826.       else
  827.       {
  828.         CodeLen = 3;
  829.         BAsmCode[0] = code;
  830.         BAsmCode[2] = Lo(address);
  831.       }
  832.     }
  833.   }
  834. }
  835.  
  836. static void decode_brset_brclr_2(Word code)
  837. {
  838.   if (ChkArgCnt(2, 2))
  839.     decode_brset_brclr_core(code, 1);
  840. }
  841.  
  842. static void decode_brset_brclr_3(Word code)
  843. {
  844.   if (ChkArgCnt(3, 3))
  845.   {
  846.     Boolean ok;
  847.  
  848.     code |= EvalStrIntExpression(&ArgStr[1], UInt3, &ok) << 1;
  849.     if (ok)
  850.       decode_brset_brclr_core(code, 2);
  851.   }
  852. }
  853.  
  854. /*--------------------------------------------------------------------------*/
  855. /* dynamic code table handling */
  856.  
  857. static void AddFixed(const char *NName, CPUVar NMin, Byte NCode)
  858. {
  859.   order_array_rsv_end(FixedOrders, BaseOrder);
  860.   FixedOrders[InstrZ].MinCPU = NMin;
  861.   FixedOrders[InstrZ].Code = NCode;
  862.   AddInstTable(InstTable, NName, InstrZ++, DecodeFixed);
  863. }
  864.  
  865. static void AddRel(const char *NName, CPUVar NMin, Byte NCode)
  866. {
  867.   order_array_rsv_end(RelOrders, BaseOrder);
  868.   RelOrders[InstrZ].MinCPU = NMin;
  869.   RelOrders[InstrZ].Code = NCode;
  870.   AddInstTable(InstTable, NName, InstrZ++, DecodeRel);
  871. }
  872.  
  873. static void AddALU(const char *NName, CPUVar NMin, Byte NCode, Word NMask, tSymbolSize NSize)
  874. {
  875.   order_array_rsv_end(ALUOrders, ALUOrder);
  876.   ALUOrders[InstrZ].MinCPU = NMin;
  877.   ALUOrders[InstrZ].Code = NCode;
  878.   ALUOrders[InstrZ].Mask = NMask;
  879.   ALUOrders[InstrZ].Size = NSize;
  880.   AddInstTable(InstTable, NName, InstrZ++, DecodeALU);
  881. }
  882.  
  883. static void AddRMW(const char *NName, CPUVar NMin, Byte NCode ,Word NMask)
  884. {
  885.   order_array_rsv_end(RMWOrders, RMWOrder);
  886.   RMWOrders[InstrZ].MinCPU = NMin;
  887.   RMWOrders[InstrZ].Code = NCode;
  888.   RMWOrders[InstrZ].Mask = NMask;
  889.   AddInstTable(InstTable, NName, InstrZ++, DecodeRMW);
  890. }
  891.  
  892. static void add_bset_bclr(const char *p_name, Word code)
  893. {
  894.   char name[10];
  895.   unsigned bit;
  896.  
  897.   AddInstTable(InstTable, p_name, code, decode_bset_bclr_2);
  898.   for (bit = 0; bit < 8; bit++)
  899.   {
  900.     as_snprintf(name, sizeof(name), "%s%c", p_name, bit + '0');
  901.     AddInstTable(InstTable, name, code | (bit << 1), decode_bset_bclr_1);
  902.   }
  903. }
  904.  
  905. static void add_brset_brclr(const char *p_name, Word code)
  906. {
  907.   char name[10];
  908.   unsigned bit;
  909.  
  910.   AddInstTable(InstTable, p_name, code, decode_brset_brclr_3);
  911.   for (bit = 0; bit < 8; bit++)
  912.   {
  913.     as_snprintf(name, sizeof(name), "%s%c", p_name, bit + '0');
  914.     AddInstTable(InstTable, name, code | (bit << 1), decode_brset_brclr_2);
  915.   }
  916. }
  917.  
  918. static void InitFields(void)
  919. {
  920.   InstTable = CreateInstTable(247);
  921.   SetDynamicInstTable(InstTable);
  922.  
  923.   InstrZ = 0;
  924.   AddFixed("RTI" , CPU6805   , 0x80); AddFixed("RTS" , CPU6805   , 0x81);
  925.   AddFixed("SWI" , CPU6805   , 0x83); AddFixed("TAX" , CPU6805   , 0x97);
  926.   AddFixed("CLC" , CPU6805   , 0x98); AddFixed("SEC" , CPU6805   , 0x99);
  927.   AddFixed("CLI" , CPU6805   , 0x9a); AddFixed("SEI" , CPU6805   , 0x9b);
  928.   AddFixed("RSP" , CPU6805   , 0x9c); AddFixed("NOP" , CPU6805   , 0x9d);
  929.   AddFixed("TXA" , CPU6805   , 0x9f); AddFixed("NEGA", CPU6805   , 0x40);
  930.   AddFixed("NEGX", CPU6805   , 0x50); AddFixed("COMA", CPU6805   , 0x43);
  931.   AddFixed("COMX", CPU6805   , 0x53); AddFixed("LSRA", CPU6805   , 0x44);
  932.   AddFixed("LSRX", CPU6805   , 0x54); AddFixed("RORA", CPU6805   , 0x46);
  933.   AddFixed("RORX", CPU6805   , 0x56); AddFixed("ASRA", CPU6805   , 0x47);
  934.   AddFixed("ASRX", CPU6805   , 0x57); AddFixed("ASLA", CPU6805   , 0x48);
  935.   AddFixed("ASLX", CPU6805   , 0x58); AddFixed("LSLA", CPU6805   , 0x48);
  936.   AddFixed("LSLX", CPU6805   , 0x58); AddFixed("ROLA", CPU6805   , 0x49);
  937.   AddFixed("ROLX", CPU6805   , 0x59); AddFixed("DECA", CPU6805   , 0x4a);
  938.   AddFixed("DECX", CPU6805   , 0x5a); AddFixed("INCA", CPU6805   , 0x4c);
  939.   AddFixed("INCX", CPU6805   , 0x5c); AddFixed("TSTA", CPU6805   , 0x4d);
  940.   AddFixed("TSTX", CPU6805   , 0x5d); AddFixed("CLRA", CPU6805   , 0x4f);
  941.   AddFixed("CLRX", CPU6805   , 0x5f); AddFixed("CLRH", CPU68HC08 , 0x8c);
  942.   AddFixed("DAA" , CPU68HC08 , 0x72); AddFixed("DIV" , CPU68HC08 , 0x52);
  943.   AddFixed("MUL" , CPU68HC05 , 0x42); AddFixed("NSA" , CPU68HC08 , 0x62);
  944.   AddFixed("PSHA", CPU68HC08 , 0x87); AddFixed("PSHH", CPU68HC08 , 0x8b);
  945.   AddFixed("PSHX", CPU68HC08 , 0x89); AddFixed("PULA", CPU68HC08 , 0x86);
  946.   AddFixed("PULH", CPU68HC08 , 0x8a); AddFixed("PULX", CPU68HC08 , 0x88);
  947.   AddFixed("STOP", CPU68HC05 , 0x8e); AddFixed("TAP" , CPU68HC08 , 0x84);
  948.   AddFixed("TPA" , CPU68HC08 , 0x85); AddFixed("TSX" , CPU68HC08 , 0x95);
  949.   AddFixed("TXS" , CPU68HC08 , 0x94); AddFixed("WAIT", CPU68HC05 , 0x8f);
  950.   AddFixed("INX" , CPU6805   , 0x5c); AddFixed("BGND", CPU68HCS08, 0x82);
  951.  
  952.   AddInstTable(InstTable, "MOV", 0, DecodeMOV);
  953.  
  954.   InstrZ = 0;
  955.   AddRel("BRA" , CPU6805   , 0x20); AddRel("BRN" , CPU6805   , 0x21);
  956.   AddRel("BHI" , CPU6805   , 0x22); AddRel("BLS" , CPU6805   , 0x23);
  957.   AddRel("BCC" , CPU6805   , 0x24); AddRel("BCS" , CPU6805   , 0x25);
  958.   AddRel("BNE" , CPU6805   , 0x26); AddRel("BEQ" , CPU6805   , 0x27);
  959.   AddRel("BHCC", CPU6805   , 0x28); AddRel("BHCS", CPU6805   , 0x29);
  960.   AddRel("BPL" , CPU6805   , 0x2a); AddRel("BMI" , CPU6805   , 0x2b);
  961.   AddRel("BMC" , CPU6805   , 0x2c); AddRel("BMS" , CPU6805   , 0x2d);
  962.   AddRel("BIL" , CPU6805   , 0x2e); AddRel("BIH" , CPU6805   , 0x2f);
  963.   AddRel("BSR" , CPU6805   , 0xad); AddRel("BGE" , CPU68HC08 , 0x90);
  964.   AddRel("BGT" , CPU68HC08 , 0x92); AddRel("BHS" , CPU6805   , 0x24);
  965.   AddRel("BLE" , CPU68HC08 , 0x93); AddRel("BLO" , CPU6805   , 0x25);
  966.   AddRel("BLT" , CPU68HC08 , 0x91);
  967.  
  968.   AddInstTable(InstTable, "CBEQA", 0x00, DecodeCBEQx);
  969.   AddInstTable(InstTable, "CBEQX", 0x10, DecodeCBEQx);
  970.   AddInstTable(InstTable, "CBEQ", 0, DecodeCBEQ);
  971.   AddInstTable(InstTable, "DBNZA", 0x00, DecodeDBNZx);
  972.   AddInstTable(InstTable, "DBNZX", 0x10, DecodeDBNZx);
  973.   AddInstTable(InstTable, "DBNZ", 0, DecodeDBNZ);
  974.  
  975.   InstrZ = 0;
  976.   AddALU("SUB" , CPU6805   , 0x00, MModImm | MModDir | MModExt | MModIx | MModIx1 | MModIx2 | MModSP1 | MModSP2, eSymbolSize8Bit);
  977.   AddALU("CMP" , CPU6805   , 0x01, MModImm | MModDir | MModExt | MModIx | MModIx1 | MModIx2 | MModSP1 | MModSP2, eSymbolSize8Bit);
  978.   AddALU("SBC" , CPU6805   , 0x02, MModImm | MModDir | MModExt | MModIx | MModIx1 | MModIx2 | MModSP1 | MModSP2, eSymbolSize8Bit);
  979.   AddALU("CPX" , CPU6805   , 0x03, MModImm | MModDir | MModExt | MModIx | MModIx1 | MModIx2 | MModSP1 | MModSP2, eSymbolSize8Bit);
  980.   AddALU("AND" , CPU6805   , 0x04, MModImm | MModDir | MModExt | MModIx | MModIx1 | MModIx2 | MModSP1 | MModSP2, eSymbolSize8Bit);
  981.   AddALU("BIT" , CPU6805   , 0x05, MModImm | MModDir | MModExt | MModIx | MModIx1 | MModIx2 | MModSP1 | MModSP2, eSymbolSize8Bit);
  982.   AddALU("LDA" , CPU6805   , 0x06, MModImm | MModDir | MModExt | MModIx | MModIx1 | MModIx2 | MModSP1 | MModSP2, eSymbolSize8Bit);
  983.   AddALU("STA" , CPU6805   , 0x07,           MModDir | MModExt | MModIx | MModIx1 | MModIx2 | MModSP1 | MModSP2, eSymbolSize8Bit);
  984.   AddALU("EOR" , CPU6805   , 0x08, MModImm | MModDir | MModExt | MModIx | MModIx1 | MModIx2 | MModSP1 | MModSP2, eSymbolSize8Bit);
  985.   AddALU("ADC" , CPU6805   , 0x09, MModImm | MModDir | MModExt | MModIx | MModIx1 | MModIx2 | MModSP1 | MModSP2, eSymbolSize8Bit);
  986.   AddALU("ORA" , CPU6805   , 0x0a, MModImm | MModDir | MModExt | MModIx | MModIx1 | MModIx2 | MModSP1 | MModSP2, eSymbolSize8Bit);
  987.   AddALU("ADD" , CPU6805   , 0x0b, MModImm | MModDir | MModExt | MModIx | MModIx1 | MModIx2 | MModSP1 | MModSP2, eSymbolSize8Bit);
  988.   AddALU("JMP" , CPU6805   , 0x0c,           MModDir | MModExt | MModIx | MModIx1 | MModIx2                    , eSymbolSizeUnknown);
  989.   AddALU("JSR" , CPU6805   , 0x0d,           MModDir | MModExt | MModIx | MModIx1 | MModIx2                    , eSymbolSizeUnknown);
  990.   AddALU("LDX" , CPU6805   , 0x0e, MModImm | MModDir | MModExt | MModIx | MModIx1 | MModIx2 | MModSP1 | MModSP2, eSymbolSize8Bit);
  991.   AddALU("STX" , CPU6805   , 0x0f,           MModDir | MModExt | MModIx | MModIx1 | MModIx2 | MModSP1 | MModSP2, eSymbolSize8Bit);
  992.  
  993.   AddInstTable(InstTable, "CPHX", 0, DecodeCPHX);
  994.   AddInstTable(InstTable, "LDHX", 0, DecodeLDHX);
  995.   AddInstTable(InstTable, "STHX", 0, DecodeSTHX);
  996.  
  997.   AddInstTable(InstTable, "AIS", 0x00, DecodeAIx);
  998.   AddInstTable(InstTable, "AIX", 0x08, DecodeAIx);
  999.  
  1000.   InstrZ = 0;
  1001.   AddRMW("NEG", CPU6805, 0x00, MModDir |        MModIx | MModIx1 |         MModSP1        );
  1002.   AddRMW("COM", CPU6805, 0x03, MModDir |        MModIx | MModIx1 |         MModSP1        );
  1003.   AddRMW("LSR", CPU6805, 0x04, MModDir |        MModIx | MModIx1 |         MModSP1        );
  1004.   AddRMW("ROR", CPU6805, 0x06, MModDir |        MModIx | MModIx1 |         MModSP1        );
  1005.   AddRMW("ASR", CPU6805, 0x07, MModDir |        MModIx | MModIx1 |         MModSP1        );
  1006.   AddRMW("ASL", CPU6805, 0x08, MModDir |        MModIx | MModIx1 |         MModSP1        );
  1007.   AddRMW("LSL", CPU6805, 0x08, MModDir |        MModIx | MModIx1 |         MModSP1        );
  1008.   AddRMW("ROL", CPU6805, 0x09, MModDir |        MModIx | MModIx1 |         MModSP1        );
  1009.   AddRMW("DEC", CPU6805, 0x0a, MModDir |        MModIx | MModIx1 |         MModSP1        );
  1010.   AddRMW("INC", CPU6805, 0x0c, MModDir |        MModIx | MModIx1 |         MModSP1        );
  1011.   AddRMW("TST", CPU6805, 0x0d, MModDir |        MModIx | MModIx1 |         MModSP1        );
  1012.   AddRMW("CLR", CPU6805, 0x0f, MModDir |        MModIx | MModIx1 |         MModSP1        );
  1013.  
  1014.   add_bset_bclr("BCLR", 0x01);
  1015.   add_bset_bclr("BSET", 0x00);
  1016.   add_brset_brclr("BRCLR", 0x01);
  1017.   add_brset_brclr("BRSET", 0x00);
  1018.  
  1019.   init_moto8_pseudo(InstTable, e_moto_8_be | e_moto_8_db | e_moto_8_dw);
  1020. }
  1021.  
  1022. static void DeinitFields(void)
  1023. {
  1024.   DestroyInstTable(InstTable);
  1025.   order_array_free(FixedOrders);
  1026.   order_array_free(RelOrders);
  1027.   order_array_free(ALUOrders);
  1028.   order_array_free(RMWOrders);
  1029. }
  1030.  
  1031. /*--------------------------------------------------------------------------*/
  1032. /* Main Functions */
  1033.  
  1034. static Boolean DecodeAttrPart_6805(void)
  1035. {
  1036.   if (strlen(AttrPart.str.p_str) > 1)
  1037.   {
  1038.     WrStrErrorPos(ErrNum_UndefAttr, &AttrPart);
  1039.     return False;
  1040.   }
  1041.  
  1042.   /* deduce operand size - no size is zero-length string -> '\0' */
  1043.  
  1044.   return DecodeMoto16AttrSize(*AttrPart.str.p_str, &AttrPartOpSize[0], False);
  1045. }
  1046.  
  1047. static void MakeCode_6805(void)
  1048. {
  1049.   CodeLen = 0;
  1050.   DontPrint = False;
  1051.   OpSize = AttrPartOpSize[0];
  1052.  
  1053.   /* zu ignorierendes */
  1054.  
  1055.   if (Memo(""))
  1056.     return;
  1057.  
  1058.   /* Pseudoanweisungen */
  1059.  
  1060.   if (DecodeMoto16Pseudo(OpSize, True))
  1061.     return;
  1062.  
  1063.   if (!LookupInstTable(InstTable, OpPart.str.p_str))
  1064.     WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
  1065. }
  1066.  
  1067. static Boolean IsDef_6805(void)
  1068. {
  1069.   return False;
  1070. }
  1071.  
  1072. static void SwitchFrom_6805(void)
  1073. {
  1074.   DeinitFields();
  1075. }
  1076.  
  1077. static void SwitchTo_6805(void)
  1078. {
  1079.   TurnWords = False;
  1080.   SetIntConstMode(eIntConstModeMoto);
  1081.  
  1082.   PCSymbol = "*";
  1083.   HeaderID = 0x62;
  1084.   NOPCode = 0x9d;
  1085.   DivideChars = ",";
  1086.   HasAttrs = True;
  1087.   AttrChars = ".";
  1088.  
  1089.   ValidSegs = (1 << SegCode);
  1090.   Grans[SegCode] = 1;
  1091.   ListGrans[SegCode] = 1;
  1092.   SegInits[SegCode] = 0;
  1093.   SegLimits[SegCode] = (MomCPU >= CPU68HC08) ? 0xffff : 0x1fff;
  1094.   AdrIntType = (MomCPU >= CPU68HC08) ? UInt16 : UInt13;
  1095.  
  1096.   DecodeAttrPart = DecodeAttrPart_6805;
  1097.   MakeCode = MakeCode_6805;
  1098.   IsDef = IsDef_6805;
  1099.   SwitchFrom = SwitchFrom_6805;
  1100.   InitFields();
  1101.   AddMoto16PseudoONOFF(False);
  1102. }
  1103.  
  1104. void code6805_init(void)
  1105. {
  1106.   CPU6805    = AddCPU("6805",    SwitchTo_6805);
  1107.   CPU68HC05  = AddCPU("68HC05",  SwitchTo_6805);
  1108.   CPU68HC08  = AddCPU("68HC08",  SwitchTo_6805);
  1109.   CPU68HCS08 = AddCPU("68HCS08", SwitchTo_6805);
  1110. }
  1111.