Subversion Repositories pentevo

Rev

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

  1. /* code6809.c */
  2. /*****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
  4. /*                                                                           */
  5. /* AS-Portierung                                                             */
  6. /*                                                                           */
  7. /* Code Generator 6809/6309                                                  */
  8. /*                                                                           */
  9. /*****************************************************************************/
  10.  
  11. #include "stdinc.h"
  12. #include <ctype.h>
  13. #include <string.h>
  14.  
  15. #include "nls.h"
  16. #include "strutil.h"
  17. #include "bpemu.h"
  18.  
  19. #include "asmdef.h"
  20. #include "asmpars.h"
  21. #include "asmsub.h"
  22. #include "asmallg.h"
  23. #include "asmitree.h"
  24. #include "codepseudo.h"
  25. #include "motpseudo.h"
  26. #include "codevars.h"
  27. #include "errmsg.h"
  28. #include "cmdarg.h"
  29.  
  30. #include "code6809.h"
  31.  
  32. #define plain_base_mode_sym_name "PLAINBASE"
  33. #define plain_base_mode_cmd_name "PLAINBASE"
  34.  
  35. typedef struct
  36. {
  37.   char *Name;
  38.   Word Code;
  39.   CPUVar MinCPU;
  40. } BaseOrder;
  41.  
  42. typedef struct
  43. {
  44.   char *Name;
  45.   Word Code;
  46.   Boolean Inv;
  47.   CPUVar MinCPU;
  48. } FlagOrder;
  49.  
  50. typedef struct
  51. {
  52.   char *Name;
  53.   Word Code8;
  54.   Word Code16;
  55.   CPUVar MinCPU;
  56. } RelOrder;
  57.  
  58. typedef struct
  59. {
  60.   char *Name;
  61.   Word Code;
  62.   tSymbolSize OpSize;
  63.   Boolean MayImm;
  64.   CPUVar MinCPU;
  65. } ALUOrder;
  66.  
  67. typedef enum
  68. {
  69.   e_adr_mode_none = -1,
  70.   e_adr_mode_imm = 1,
  71.   e_adr_mode_dir = 2,
  72.   e_adr_mode_ind = 3,
  73.   e_adr_mode_ext = 4
  74. } adr_mode_t;
  75.  
  76. #define adr_mode_mask_imm (1 << e_adr_mode_imm)
  77. #define adr_mode_mask_dir (1 << e_adr_mode_dir)
  78. #define adr_mode_mask_ind (1 << e_adr_mode_ind)
  79. #define adr_mode_mask_ext (1 << e_adr_mode_ext)
  80. #define adr_mode_mask_no_imm (adr_mode_mask_dir | adr_mode_mask_ind | adr_mode_mask_ext)
  81. #define adr_mode_mask_all (adr_mode_mask_imm | adr_mode_mask_no_imm)
  82.  
  83. typedef struct
  84. {
  85.   adr_mode_t mode;
  86.   int cnt;
  87.   Byte vals[5];
  88. } adr_vals_t;
  89.  
  90. #define StackRegCnt 12
  91. static char StackRegNames[StackRegCnt][4] =
  92. {
  93.   "CCR",  "A",  "B","DPR",  "X",  "Y","S/U", "PC", "CC", "DP",  "S",  "D"
  94. };
  95. static Byte StackRegMasks[StackRegCnt] =
  96. {
  97.   0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x01, 0x08, 0x40, 0x06
  98. };
  99.  
  100. static const char FlagChars[] = "CVZNIHFE";
  101.  
  102. static LongInt DPRValue;
  103.  
  104. static Boolean target_used,
  105.                plain_base_mode,
  106.                def_plain_base_mode,
  107.                def_plain_base_mode_set;
  108.  
  109. static BaseOrder  *FixedOrders;
  110. static RelOrder   *RelOrders;
  111. static ALUOrder   *ALUOrders;
  112. static BaseOrder *RMWOrders;
  113. static FlagOrder *FlagOrders;
  114. static BaseOrder *LEAOrders;
  115. static BaseOrder *ImmOrders;
  116.  
  117. static CPUVar CPU6809, CPU6309;
  118.  
  119. /*-------------------------------------------------------------------------*/
  120.  
  121. static Boolean CodeReg(char *ChIn, Byte *erg)
  122. {
  123.   static char Regs[5] = "XYUS", *p;
  124.  
  125.   if (strlen(ChIn) != 1)
  126.     return False;
  127.   else
  128.   {
  129.     p = strchr(Regs, as_toupper(*ChIn));
  130.     if (!p)
  131.       return False;
  132.     *erg = p - Regs;
  133.     return True;
  134.   }
  135. }
  136.  
  137. static unsigned ChkZero(const char *s, Byte *Erg)
  138. {
  139.   if (*s == '>')
  140.   {
  141.     *Erg = 1;
  142.     return 1;
  143.   }
  144.   else if (*s == '<')
  145.   {
  146.     if (1[s] == '<')
  147.     {
  148.       *Erg = 3;
  149.       return 2;
  150.     }
  151.     else
  152.     {
  153.       *Erg = 2;
  154.       return 1;
  155.     }
  156.   }
  157.   else
  158.   {
  159.     *Erg = 0;
  160.     return 0;
  161.   }
  162. }
  163.  
  164. static Boolean MayShort(Integer Arg)
  165. {
  166.   return ((Arg >= -128) && (Arg < 127));
  167. }
  168.  
  169. static Boolean IsZeroOrEmpty(const tStrComp *pArg)
  170. {
  171.   Boolean OK;
  172.   LongInt Value;
  173.  
  174.   if (!*pArg->str.p_str)
  175.     return True;
  176.   Value = EvalStrIntExpression(pArg, Int32, &OK);
  177.   return OK && !Value;
  178. }
  179.  
  180. static void reset_adr_vals(adr_vals_t *p_vals)
  181. {
  182.   p_vals->mode = e_adr_mode_none;
  183.   p_vals->cnt = 0;
  184. }
  185.  
  186. static Boolean check_plain_base_arg(int adr_arg_cnt, const tStrComp *p_start_arg)
  187. {
  188.   switch (adr_arg_cnt)
  189.   {
  190.     case 1:
  191.       if (!plain_base_mode)
  192.         WrStrErrorPos(ErrNum_WrongArgCnt, p_start_arg);
  193.       return plain_base_mode;
  194.     case 2:
  195.     {
  196.       Boolean ret = IsZeroOrEmpty(p_start_arg);
  197.       if (!ret)
  198.         WrStrErrorPos(ErrNum_InvAddrMode, p_start_arg);
  199.       return ret;
  200.     }
  201.     default:
  202.       WrError(ErrNum_WrongArgCnt);
  203.       return False;
  204.   }
  205. }
  206.  
  207. static adr_mode_t DecodeAdr(int ArgStartIdx, int ArgEndIdx,
  208.                             unsigned OpcodeLen, tSymbolSize op_size,
  209.                             unsigned mode_mask, adr_vals_t *p_vals)
  210. {
  211.   tStrComp *pStartArg, *pEndArg, IndirComps[2];
  212.   String temp;
  213.   LongInt AdrLong;
  214.   Word AdrWord;
  215.   Boolean IndFlag, OK;
  216.   Byte EReg, ZeroMode;
  217.   char *p;
  218.   unsigned Offset;
  219.   Integer AdrInt;
  220.   int AdrArgCnt = ArgEndIdx - ArgStartIdx + 1;
  221.   const Boolean allow_6309 = (MomCPU >= CPU6309);
  222.  
  223.   reset_adr_vals(p_vals);
  224.   pStartArg = &ArgStr[ArgStartIdx];
  225.   pEndArg = &ArgStr[ArgEndIdx];
  226.  
  227.   /* immediate */
  228.  
  229.   if ((*pStartArg->str.p_str == '#') && (AdrArgCnt == 1))
  230.   {
  231.     switch (op_size)
  232.     {
  233.       case eSymbolSize32Bit:
  234.         AdrLong = EvalStrIntExpressionOffs(pStartArg, 1, Int32, &OK);
  235.         if (OK)
  236.         {
  237.           p_vals->vals[0] = Lo(AdrLong >> 24);
  238.           p_vals->vals[1] = Lo(AdrLong >> 16);
  239.           p_vals->vals[2] = Lo(AdrLong >>  8);
  240.           p_vals->vals[3] = Lo(AdrLong);
  241.           p_vals->cnt = 4;
  242.         }
  243.         break;
  244.       case eSymbolSize16Bit:
  245.         AdrWord = EvalStrIntExpressionOffs(pStartArg, 1, Int16, &OK);
  246.         if (OK)
  247.         {
  248.           p_vals->vals[0] = Hi(AdrWord);
  249.           p_vals->vals[1] = Lo(AdrWord);
  250.           p_vals->cnt = 2;
  251.         }
  252.         break;
  253.       case eSymbolSize8Bit:
  254.         p_vals->vals[0] = EvalStrIntExpressionOffs(pStartArg, 1, Int8, &OK);
  255.         if (OK)
  256.           p_vals->cnt = 1;
  257.         break;
  258.       default:
  259.         OK = False;
  260.         break;
  261.     }
  262.     if (OK)
  263.       p_vals->mode = e_adr_mode_imm;
  264.     goto chk_mode;
  265.   }
  266.  
  267.   /* indirekter Ausdruck ? */
  268.  
  269.   if ((*pStartArg->str.p_str == '[') && (pStartArg->str.p_str[strlen(pStartArg->str.p_str) - 1] == ']'))
  270.   {
  271.     tStrComp Arg, Remainder;
  272.  
  273.     IndFlag = True;
  274.     StrCompRefRight(&Arg, pStartArg, 1);
  275.     StrCompShorten(&Arg, 1);
  276.     AdrArgCnt = 0;
  277.     do
  278.     {
  279.       p = QuotPos(Arg.str.p_str, ',');
  280.       if (p)
  281.         StrCompSplitRef(&IndirComps[AdrArgCnt], &Remainder, &Arg, p);
  282.       else
  283.         IndirComps[AdrArgCnt] = Arg;
  284.       KillPrefBlanksStrCompRef(&IndirComps[AdrArgCnt]);
  285.       KillPostBlanksStrComp(&IndirComps[AdrArgCnt]);
  286.       AdrArgCnt++;
  287.       if (p)
  288.         Arg = Remainder;
  289.     }
  290.     while (p && (AdrArgCnt < 2));
  291.     pStartArg = &IndirComps[0];
  292.     pEndArg = &IndirComps[AdrArgCnt - 1];
  293.   }
  294.   else
  295.     IndFlag = False;
  296.  
  297.   /* Predekrement ? */
  298.  
  299.   if ((AdrArgCnt >= 1) && (AdrArgCnt <= 2) && (strlen(pEndArg->str.p_str) == 2) && (*pEndArg->str.p_str == '-') && (CodeReg(pEndArg->str.p_str + 1, &EReg)))
  300.   {
  301.     if (check_plain_base_arg(AdrArgCnt, pStartArg))
  302.     {
  303.       p_vals->cnt = 1;
  304.       p_vals->vals[0] = 0x82 + (EReg << 5) + (Ord(IndFlag) << 4);
  305.       p_vals->mode = e_adr_mode_ind;
  306.     }
  307.     goto chk_mode;
  308.   }
  309.  
  310.   if ((AdrArgCnt >= 1) && (AdrArgCnt <= 2) && (strlen(pEndArg->str.p_str) == 3) && (!strncmp(pEndArg->str.p_str, "--", 2)) && (CodeReg(pEndArg->str.p_str + 2, &EReg)))
  311.   {
  312.     if (check_plain_base_arg(AdrArgCnt, pStartArg))
  313.     {
  314.       p_vals->cnt = 1;
  315.       p_vals->vals[0] = 0x83 + (EReg << 5) + (Ord(IndFlag) << 4);
  316.       p_vals->mode = e_adr_mode_ind;
  317.     }
  318.     goto chk_mode;
  319.   }
  320.  
  321.   if ((AdrArgCnt >= 1) && (AdrArgCnt <= 2) && (!as_strcasecmp(pEndArg->str.p_str, "--W")))
  322.   {
  323.     if (!check_plain_base_arg(AdrArgCnt, pStartArg));
  324.     else if (!allow_6309) WrError(ErrNum_AddrModeNotSupported);
  325.     else
  326.     {
  327.       p_vals->cnt = 1;
  328.       p_vals->vals[0] = 0xef + Ord(IndFlag);
  329.       p_vals->mode = e_adr_mode_ind;
  330.     }
  331.     goto chk_mode;
  332.   }
  333.  
  334.   /* Postinkrement ? */
  335.  
  336.   if ((AdrArgCnt >= 1) && (AdrArgCnt <= 2) && (strlen(pEndArg->str.p_str) == 2) && (pEndArg->str.p_str[1] == '+'))
  337.   {
  338.     temp[0] = *pEndArg->str.p_str;
  339.     temp[1] = '\0';
  340.     if (CodeReg(temp, &EReg))
  341.     {
  342.       if (check_plain_base_arg(AdrArgCnt, pStartArg))
  343.       {
  344.         p_vals->cnt = 1;
  345.         p_vals->vals[0] = 0x80 + (EReg << 5) + (Ord(IndFlag) << 4);
  346.         p_vals->mode = e_adr_mode_ind;
  347.       }
  348.       goto chk_mode;
  349.     }
  350.   }
  351.  
  352.   if ((AdrArgCnt >= 1) && (AdrArgCnt <= 2) && (strlen(pEndArg->str.p_str) == 3) && (!strncmp(pEndArg->str.p_str + 1, "++", 2)))
  353.   {
  354.     temp[0] = *pEndArg->str.p_str;
  355.     temp[1] = '\0';
  356.     if (CodeReg(temp, &EReg))
  357.     {
  358.       if (check_plain_base_arg(AdrArgCnt, pStartArg))
  359.       {
  360.         p_vals->cnt = 1;
  361.         p_vals->vals[0] = 0x81 + (EReg << 5) + (Ord(IndFlag) << 4);
  362.         p_vals->mode = e_adr_mode_ind;
  363.       }
  364.       goto chk_mode;
  365.     }
  366.   }
  367.  
  368.   if ((AdrArgCnt >= 1) && (AdrArgCnt <= 2) && (!as_strcasecmp(pEndArg->str.p_str, "W++")))
  369.   {
  370.     if (!check_plain_base_arg(AdrArgCnt, pStartArg));
  371.     else if (!allow_6309) WrError(ErrNum_AddrModeNotSupported);
  372.     else
  373.     {
  374.       p_vals->cnt = 1;
  375.       p_vals->vals[0] = 0xcf + Ord(IndFlag);
  376.       p_vals->mode = e_adr_mode_ind;
  377.     }
  378.     goto chk_mode;
  379.   }
  380.  
  381.   /* 16-Bit-Register (mit Index) ? */
  382.  
  383.   if ((AdrArgCnt <= 2) && (AdrArgCnt >= 1) && (CodeReg(pEndArg->str.p_str, &EReg)))
  384.   {
  385.     p_vals->vals[0] = (EReg << 5) + (Ord(IndFlag) << 4);
  386.  
  387.     /* nur 16-Bit-Register */
  388.  
  389.     if (AdrArgCnt == 1)
  390.     {
  391.       if (!plain_base_mode) WrStrErrorPos(ErrNum_WrongArgCnt, pEndArg);
  392.       else
  393.       {
  394.         p_vals->cnt = 1;
  395.         p_vals->vals[0] += 0x84;
  396.         p_vals->mode = e_adr_mode_ind;
  397.       }
  398.       goto chk_mode;
  399.     }
  400.  
  401.     /* mit Index */
  402.  
  403.     if (!as_strcasecmp(pStartArg->str.p_str, "A"))
  404.     {
  405.       p_vals->cnt = 1;
  406.       p_vals->vals[0] += 0x86;
  407.       p_vals->mode = e_adr_mode_ind;
  408.       goto chk_mode;
  409.     }
  410.     if (!as_strcasecmp(pStartArg->str.p_str, "B"))
  411.     {
  412.       p_vals->cnt = 1;
  413.       p_vals->vals[0] += 0x85;
  414.       p_vals->mode = e_adr_mode_ind;
  415.       goto chk_mode;
  416.     }
  417.     if (!as_strcasecmp(pStartArg->str.p_str, "D"))
  418.     {
  419.       p_vals->cnt = 1;
  420.       p_vals->vals[0] += 0x8b;
  421.       p_vals->mode = e_adr_mode_ind;
  422.       goto chk_mode;
  423.     }
  424.     if ((!as_strcasecmp(pStartArg->str.p_str, "E")) && allow_6309)
  425.     {
  426.       p_vals->cnt = 1;
  427.       p_vals->vals[0] += 0x87;
  428.       p_vals->mode = e_adr_mode_ind;
  429.       goto chk_mode;
  430.     }
  431.     if ((!as_strcasecmp(pStartArg->str.p_str, "F")) && allow_6309)
  432.     {
  433.       p_vals->cnt = 1;
  434.       p_vals->vals[0] += 0x8a;
  435.       p_vals->mode = e_adr_mode_ind;
  436.       goto chk_mode;
  437.     }
  438.     if ((!as_strcasecmp(pStartArg->str.p_str, "W")) && allow_6309)
  439.     {
  440.       p_vals->cnt = 1;
  441.       p_vals->vals[0] += 0x8e;
  442.       p_vals->mode = e_adr_mode_ind;
  443.       goto chk_mode;
  444.     }
  445.  
  446.     /* Displacement auswerten */
  447.  
  448.     Offset = ChkZero(pStartArg->str.p_str, &ZeroMode);
  449.     if (ZeroMode > 1)
  450.     {
  451.       tSymbolFlags Flags;
  452.  
  453.       AdrInt = EvalStrIntExpressionOffsWithFlags(pStartArg, Offset, Int8, &OK, &Flags);
  454.       if (mFirstPassUnknown(Flags) && (ZeroMode == 3))
  455.         AdrInt &= 0x0f;
  456.     }
  457.     else
  458.       AdrInt = EvalStrIntExpressionOffs(pStartArg, Offset, Int16, &OK);
  459.     if (!OK)
  460.       goto chk_mode;
  461.  
  462.     /* Displacement 0 ? */
  463.  
  464.     if ((ZeroMode == 0) && (AdrInt == 0))
  465.     {
  466.       p_vals->cnt = 1;
  467.       p_vals->vals[0] += 0x84;
  468.       p_vals->mode = e_adr_mode_ind;
  469.       goto chk_mode;
  470.     }
  471.  
  472.     /* 5-Bit-Displacement */
  473.  
  474.     else if ((ZeroMode == 3) || ((ZeroMode == 0) && (!IndFlag) && (AdrInt >= -16) && (AdrInt <= 15)))
  475.     {
  476.       if ((AdrInt < -16) || (AdrInt > 15)) WrError(ErrNum_NoShortAddr);
  477.       else if (IndFlag) WrError(ErrNum_InvAddrMode);
  478.       else
  479.       {
  480.         p_vals->mode = e_adr_mode_ind;
  481.         p_vals->cnt = 1;
  482.         p_vals->vals[0] += AdrInt & 0x1f;
  483.       }
  484.       goto chk_mode;
  485.     }
  486.  
  487.     /* 8-Bit-Displacement */
  488.  
  489.     else if ((ZeroMode == 2) || ((ZeroMode == 0) && (MayShort(AdrInt))))
  490.     {
  491.       if (!MayShort(AdrInt)) WrError(ErrNum_NoShortAddr);
  492.       else
  493.       {
  494.         p_vals->mode = e_adr_mode_ind;
  495.         p_vals->cnt = 2;
  496.         p_vals->vals[0] += 0x88;
  497.         p_vals->vals[1] = Lo(AdrInt);
  498.       }
  499.       goto chk_mode;
  500.     }
  501.  
  502.     /* 16-Bit-Displacement */
  503.  
  504.     else
  505.     {
  506.       p_vals->mode = e_adr_mode_ind;
  507.       p_vals->cnt = 3;
  508.       p_vals->vals[0] += 0x89;
  509.       p_vals->vals[1] = Hi(AdrInt);
  510.       p_vals->vals[2] = Lo(AdrInt);
  511.       goto chk_mode;
  512.     }
  513.   }
  514.  
  515.   if ((AdrArgCnt <= 2) && (AdrArgCnt >= 1) && allow_6309 && (!as_strcasecmp(pEndArg->str.p_str, "W")))
  516.   {
  517.     p_vals->vals[0] = 0x8f + Ord(IndFlag);
  518.  
  519.     /* nur W-Register */
  520.  
  521.     if (AdrArgCnt == 1)
  522.     {
  523.       if (!plain_base_mode) WrStrErrorPos(ErrNum_WrongArgCnt, pEndArg);
  524.       else
  525.       {
  526.         p_vals->cnt = 1;
  527.         p_vals->mode = e_adr_mode_ind;
  528.       }
  529.       goto chk_mode;
  530.     }
  531.  
  532.     /* Displacement auswerten */
  533.  
  534.     Offset = ChkZero(pStartArg->str.p_str, &ZeroMode);
  535.     AdrInt = EvalStrIntExpressionOffs(pStartArg, Offset, Int16, &OK);
  536.  
  537.     /* Displacement 0 ? */
  538.  
  539.     if ((ZeroMode == 0) && (AdrInt == 0))
  540.     {
  541.       p_vals->cnt = 1;
  542.       p_vals->mode = e_adr_mode_ind;
  543.       goto chk_mode;
  544.     }
  545.  
  546.     /* 16-Bit-Displacement */
  547.  
  548.     else
  549.     {
  550.       p_vals->mode = e_adr_mode_ind;
  551.       p_vals->cnt = 3;
  552.       p_vals->vals[0] += 0x20;
  553.       p_vals->vals[1] = Hi(AdrInt);
  554.       p_vals->vals[2] = Lo(AdrInt);
  555.       goto chk_mode;
  556.     }
  557.   }
  558.  
  559.   /* PC-relativ ? */
  560.  
  561.   if ((AdrArgCnt == 2) && (!as_strcasecmp(pEndArg->str.p_str, "PCR") || !as_strcasecmp(pEndArg->str.p_str, "PC")))
  562.   {
  563.     p_vals->vals[0] = Ord(IndFlag) << 4;
  564.     Offset = ChkZero(pStartArg->str.p_str, &ZeroMode);
  565.     AdrInt = EvalStrIntExpressionOffs(pStartArg, Offset, Int16, &OK);
  566.     if (OK)
  567.     {
  568.       AdrInt -= EProgCounter() + 2 + OpcodeLen;
  569.  
  570.       if (ZeroMode == 3) WrError(ErrNum_InvAddrMode);
  571.  
  572.       else if ((ZeroMode == 2) || ((ZeroMode == 0) && MayShort(AdrInt)))
  573.       {
  574.         if (!MayShort(AdrInt)) WrError(ErrNum_OverRange);
  575.         else
  576.         {
  577.           p_vals->cnt = 2;
  578.           p_vals->vals[0] += 0x8c;
  579.           p_vals->vals[1] = Lo(AdrInt);
  580.           p_vals->mode = e_adr_mode_ind;
  581.         }
  582.       }
  583.  
  584.       else
  585.       {
  586.         AdrInt--;
  587.         p_vals->cnt = 3;
  588.         p_vals->vals[0] += 0x8d;
  589.         p_vals->vals[1] = Hi(AdrInt);
  590.         p_vals->vals[2] = Lo(AdrInt);
  591.         p_vals->mode = e_adr_mode_ind;
  592.       }
  593.     }
  594.     goto chk_mode;
  595.   }
  596.  
  597.   if (AdrArgCnt == 1)
  598.   {
  599.     tSymbolFlags Flags;
  600.  
  601.     Offset = ChkZero(pStartArg->str.p_str, &ZeroMode);
  602.     AdrInt = EvalStrIntExpressionOffsWithFlags(pStartArg, Offset, Int16, &OK, &Flags);
  603.     if (mFirstPassUnknown(Flags) && (ZeroMode == 2))
  604.       AdrInt = (AdrInt & 0xff) | (DPRValue << 8);
  605.  
  606.     if (OK)
  607.     {
  608.       if (ZeroMode == 3) WrError(ErrNum_InvAddrMode);
  609.  
  610.       else if ((ZeroMode == 2) || ((ZeroMode == 0) && (Hi(AdrInt) == DPRValue) && (!IndFlag)))
  611.       {
  612.         if (IndFlag) WrError(ErrNum_NoIndir);
  613.         else if (Hi(AdrInt) != DPRValue) WrError(ErrNum_NoShortAddr);
  614.         else
  615.         {
  616.           p_vals->cnt = 1;
  617.           p_vals->mode = e_adr_mode_dir;
  618.           p_vals->vals[0] = Lo(AdrInt);
  619.         }
  620.       }
  621.  
  622.       else
  623.       {
  624.         if (IndFlag)
  625.         {
  626.           p_vals->mode = e_adr_mode_ind;
  627.           p_vals->cnt = 3;
  628.           p_vals->vals[0] = 0x9f;
  629.           p_vals->vals[1] = Hi(AdrInt);
  630.           p_vals->vals[2] = Lo(AdrInt);
  631.         }
  632.         else
  633.         {
  634.           p_vals->mode = e_adr_mode_ext;
  635.           p_vals->cnt = 2;
  636.           p_vals->vals[0] = Hi(AdrInt);
  637.           p_vals->vals[1] = Lo(AdrInt);
  638.         }
  639.       }
  640.     }
  641.     goto chk_mode;
  642.   }
  643.  
  644.   if (p_vals->mode == e_adr_mode_none)
  645.     WrError(ErrNum_InvAddrMode);
  646.  
  647. chk_mode:
  648.   if ((p_vals->mode != e_adr_mode_none) && !((mode_mask >> p_vals->mode) & 1))
  649.   {
  650.     WrError(ErrNum_InvAddrMode);
  651.     reset_adr_vals(p_vals);
  652.   }
  653.   return p_vals->mode;
  654. }
  655.  
  656. static Boolean CodeCPUReg(const char *Asc, Byte *Erg)
  657. {
  658. #define RegCnt (sizeof(RegNames) / sizeof(*RegNames))
  659.   static const char RegNames[][4] =
  660.   {
  661.     "D", "X", "Y", "U", "S", "SP", "PC", "W", "V", "A", "B", "CCR", "DPR", "CC", "DP", "Z", "E", "F"
  662.   };
  663.   static const Byte RegVals[RegCnt] =
  664.   {
  665.     0  , 1  , 2  , 3  , 4  , 4   , 5   , 6  , 7  , 8  , 9  , 10   , 11   , 10  , 11  , 13 , 14 , 15
  666.    };
  667.  
  668.   unsigned z;
  669.   String Asc_N;
  670.  
  671.   strmaxcpy(Asc_N, Asc, STRINGSIZE); NLS_UpString(Asc_N); Asc = Asc_N;
  672.  
  673.   for (z = 0; z < RegCnt; z++)
  674.     if (!strcmp(Asc, RegNames[z]))
  675.     {
  676.       if (((RegVals[z] & 6) == 6) && !ChkMinCPUExt(CPU6309, ErrNum_AddrModeNotSupported));
  677.       else
  678.       {
  679.         *Erg = RegVals[z];
  680.         return True;
  681.       }
  682.     }
  683.   return False;
  684. }
  685.  
  686. static void SplitIncDec(char *s, int *Erg)
  687. {
  688.   int l = strlen(s);
  689.  
  690.   if (l == 0)
  691.     *Erg = 0;
  692.   else if (s[l - 1] == '+')
  693.   {
  694.     s[l - 1] = '\0';
  695.     *Erg = 1;
  696.   }
  697.   else if (s[l - 1] == '-')
  698.   {
  699.     s[l - 1] = '\0';
  700.     *Erg = -1;
  701.   }
  702.   else
  703.     *Erg = 0;
  704. }
  705.  
  706. static Boolean SplitBit(tStrComp *pArg, int *Erg)
  707. {
  708.   char *p;
  709.   Boolean OK;
  710.   tStrComp BitArg;
  711.  
  712.   p = QuotPos(pArg->str.p_str, '.');
  713.   if (!p)
  714.   {
  715.     WrError(ErrNum_InvBitPos);
  716.     return False;
  717.   }
  718.   StrCompSplitRef(pArg, &BitArg, pArg, p);
  719.   *Erg = EvalStrIntExpression(&BitArg, UInt3, &OK);
  720.   if (!OK)
  721.     return False;
  722.   *p = '\0';
  723.   return True;
  724. }
  725.  
  726. static void append_adr_vals(const adr_vals_t *p_vals)
  727. {
  728.   memcpy(&BAsmCode[CodeLen], p_vals->vals, p_vals->cnt);
  729.   CodeLen += p_vals->cnt;
  730. }
  731.  
  732. /*-------------------------------------------------------------------------*/
  733.  
  734. /* Anweisungen ohne Argument */
  735.  
  736. static void DecodeFixed(Word Index)
  737. {
  738.   const BaseOrder *pOrder = FixedOrders + Index;
  739.  
  740.   if (!ChkArgCnt(0, 0));
  741.   else if (!ChkMinCPU(pOrder->MinCPU));
  742.   else if (Hi(pOrder->Code) == 0)
  743.   {
  744.     BAsmCode[0] = Lo(pOrder->Code);
  745.     CodeLen = 1;
  746.   }
  747.   else
  748.   {
  749.     BAsmCode[0] = Hi(pOrder->Code);
  750.     BAsmCode[1] = Lo(pOrder->Code);
  751.     CodeLen = 2;
  752.   }
  753. }
  754.  
  755. /* Specials... */
  756.  
  757. static void DecodeSWI(Word Code)
  758. {
  759.   UNUSED(Code);
  760.  
  761.   if (ArgCnt == 0)
  762.   {
  763.     BAsmCode[0] = 0x3f;
  764.     CodeLen = 1;
  765.   }
  766.   else if (ChkArgCnt(1, 1))
  767.   {
  768.     Boolean OK;
  769.     tSymbolFlags Flags;
  770.     Byte Num;
  771.  
  772.     Num = EvalStrIntExpressionWithFlags(&ArgStr[1], UInt2, &OK, &Flags);
  773.     if (OK && mFirstPassUnknown(Flags) && (Num < 2))
  774.       Num = 2;
  775.     if (OK && ChkRange(Num, 2, 3))
  776.     {
  777.       BAsmCode[0] = 0x10 | (Num & 1);
  778.       BAsmCode[1] = 0x3f;
  779.       CodeLen = 2;
  780.     }
  781.   }
  782. }
  783.  
  784. /* relative Spruenge */
  785.  
  786. static void DecodeRel(Word Index)
  787. {
  788.   Boolean LongFlag = (Index & 0x8000) || False;
  789.   const RelOrder *pOrder = RelOrders + (Index & 0x7fff);
  790.  
  791.   if (ChkArgCnt(1, 1))
  792.   {
  793.     Boolean ExtFlag = (LongFlag) && (Hi(pOrder->Code16) != 0), OK;
  794.     tSymbolFlags Flags;
  795.     Integer AdrInt = EvalStrIntExpressionWithFlags(&ArgStr[1], UInt16, &OK, &Flags);
  796.  
  797.     if (OK)
  798.     {
  799.       AdrInt -= EProgCounter() + 2 + Ord(LongFlag) + Ord(ExtFlag);
  800.       if (!mSymbolQuestionable(Flags) && !LongFlag && ((AdrInt < -128) || (AdrInt > 127))) WrError(ErrNum_JmpDistTooBig);
  801.       else
  802.       {
  803.         CodeLen = 1 + Ord(ExtFlag);
  804.         if (LongFlag)
  805.         {
  806.           if (ExtFlag)
  807.           {
  808.             BAsmCode[0] = Hi(pOrder->Code16);
  809.             BAsmCode[1] = Lo(pOrder->Code16);
  810.           }
  811.           else
  812.             BAsmCode[0] = Lo(pOrder->Code16);
  813.         }
  814.         else
  815.           BAsmCode[0] = Lo(pOrder->Code8);
  816.         if (LongFlag)
  817.         {
  818.           BAsmCode[CodeLen] = Hi(AdrInt);
  819.           BAsmCode[CodeLen + 1] = Lo(AdrInt);
  820.           CodeLen += 2;
  821.         }
  822.         else
  823.         {
  824.           BAsmCode[CodeLen] = Lo(AdrInt);
  825.           CodeLen++;
  826.         }
  827.       }
  828.     }
  829.   }
  830. }
  831.  
  832. /* ALU-Operationen */
  833.  
  834. static void DecodeALU(Word Index)
  835. {
  836.   const ALUOrder *pOrder = ALUOrders + Index;
  837.  
  838.   if (ChkArgCnt(1, 2)
  839.    && ChkMinCPU(pOrder->MinCPU))
  840.   {
  841.     adr_vals_t vals;
  842.  
  843.     if (DecodeAdr(1, ArgCnt, 1 + !!Hi(pOrder->Code), pOrder->OpSize, pOrder->MayImm ? adr_mode_mask_all : adr_mode_mask_no_imm, &vals) != e_adr_mode_none)
  844.     {
  845.       if (Hi(pOrder->Code))
  846.         BAsmCode[CodeLen++] = Hi(pOrder->Code);
  847.       BAsmCode[CodeLen++] = Lo(pOrder->Code) + ((vals.mode - 1) << 4);
  848.       append_adr_vals(&vals);
  849.     }
  850.   }
  851. }
  852.  
  853. static void DecodeLDQ(Word Index)
  854. {
  855.   UNUSED(Index);
  856.  
  857.   if (ChkArgCnt(1, 2)
  858.    && ChkMinCPU(CPU6309))
  859.   {
  860.     adr_vals_t vals;
  861.  
  862.     if (DecodeAdr(1, ArgCnt, 2, eSymbolSize32Bit, adr_mode_mask_all, &vals) == e_adr_mode_imm)
  863.     {
  864.       BAsmCode[CodeLen++] = 0xcd;
  865.       append_adr_vals(&vals);
  866.     }
  867.     else
  868.     {
  869.       BAsmCode[CodeLen++] = 0x10;
  870.       BAsmCode[CodeLen++] = 0xcc + ((vals.mode - 1) << 4);
  871.       append_adr_vals(&vals);
  872.     }
  873.   }
  874. }
  875.  
  876. /* Read-Modify-Write-Operationen */
  877.  
  878. static void DecodeRMW(Word Index)
  879. {
  880.   const BaseOrder *pOrder = RMWOrders + Index;
  881.  
  882.   if (ChkArgCnt(1, 2)
  883.    && ChkMinCPU(pOrder->MinCPU))
  884.   {
  885.     adr_vals_t vals;
  886.  
  887.     switch (DecodeAdr(1, ArgCnt, 1, eSymbolSizeUnknown, adr_mode_mask_no_imm, &vals))
  888.     {
  889.       case e_adr_mode_dir:
  890.         BAsmCode[CodeLen++] = pOrder->Code;
  891.         goto append;
  892.       case e_adr_mode_ind:
  893.         BAsmCode[CodeLen++] = pOrder->Code + 0x60;
  894.         goto append;
  895.       case e_adr_mode_ext:
  896.         BAsmCode[CodeLen++] = pOrder->Code + 0x70;
  897.         goto append;
  898.       append:
  899.         append_adr_vals(&vals);
  900.         break;
  901.       default:
  902.         return;
  903.     }
  904.   }
  905. }
  906.  
  907. /* Anweisungen mit Flag-Operand */
  908.  
  909. static void DecodeFlag(Word Index)
  910. {
  911.   const FlagOrder *pOrder = FlagOrders + Index;
  912.   Boolean OK;
  913.   const char *p;
  914.   int z2, z3;
  915.  
  916.   if (ChkArgCnt(1, ArgCntMax))
  917.   {
  918.     OK = True;
  919.     BAsmCode[1] = (pOrder->Inv) ? 0xff : 0x00;
  920.     for (z2 = 1; z2 <= ArgCnt; z2++)
  921.       if (OK)
  922.       {
  923.         p = (strlen(ArgStr[z2].str.p_str) == 1) ? strchr(FlagChars, as_toupper(*ArgStr[z2].str.p_str)) : NULL;
  924.         if (p)
  925.         {
  926.           z3 = p - FlagChars;
  927.           if (pOrder->Inv)
  928.             BAsmCode[1] &= (0xff ^ (1 << z3));
  929.           else
  930.             BAsmCode[1] |= (1 << z3);
  931.         }
  932.         else if (*ArgStr[z2].str.p_str != '#')
  933.         {
  934.           WrError(ErrNum_OnlyImmAddr);
  935.           OK = False;
  936.         }
  937.         else
  938.         {
  939.           BAsmCode[2] = EvalStrIntExpressionOffs(&ArgStr[z2], 1, Int8, &OK);
  940.           if (OK)
  941.           {
  942.             if (pOrder->Inv)
  943.               BAsmCode[1] &= BAsmCode[2];
  944.             else
  945.               BAsmCode[1] |= BAsmCode[2];
  946.           }
  947.         }
  948.       }
  949.     if (OK)
  950.     {
  951.       CodeLen = 2;
  952.       BAsmCode[0] = pOrder->Code;
  953.     }
  954.   }
  955. }
  956.  
  957. /* Bit-Befehle */
  958.  
  959. static void DecodeImm(Word Index)
  960. {
  961.   const BaseOrder *pOrder = ImmOrders + Index;
  962.  
  963.   if (!ChkArgCnt(2, 3));
  964.   else if (!ChkMinCPU(pOrder->MinCPU));
  965.   else if (*ArgStr[1].str.p_str != '#') WrError(ErrNum_OnlyImmAddr);
  966.   else
  967.   {
  968.     Boolean OK;
  969.  
  970.     BAsmCode[1] = EvalStrIntExpressionOffs(&ArgStr[1], 1, Int8, &OK);
  971.     if (OK)
  972.     {
  973.       adr_vals_t vals;
  974.  
  975.       switch (DecodeAdr(2, ArgCnt, 2, eSymbolSizeUnknown, adr_mode_mask_no_imm, &vals))
  976.       {
  977.         case e_adr_mode_dir:
  978.           BAsmCode[0] = pOrder->Code;
  979.           goto append;
  980.         case e_adr_mode_ext:
  981.           BAsmCode[0] = pOrder->Code + 0x70;
  982.           goto append;
  983.         case e_adr_mode_ind:
  984.           BAsmCode[0] = pOrder->Code + 0x60;
  985.           goto append;
  986.         append:
  987.           CodeLen = 2;
  988.           append_adr_vals(&vals);
  989.           break;
  990.         default:
  991.           return;
  992.       }
  993.     }
  994.   }
  995. }
  996.  
  997. static void DecodeBit(Word Code)
  998. {
  999.   int z2, z3;
  1000.  
  1001.   if (ChkArgCnt(2, 2)
  1002.    && ChkMinCPU(CPU6309)
  1003.    && SplitBit(&ArgStr[1], &z2) && SplitBit(&ArgStr[2], &z3))
  1004.   {
  1005.     if (!CodeCPUReg(ArgStr[1].str.p_str, BAsmCode + 2)) WrError(ErrNum_InvRegName);
  1006.     else if ((BAsmCode[2] < 8) || (BAsmCode[2] > 11)) WrError(ErrNum_InvRegName);
  1007.     else
  1008.     {
  1009.       adr_vals_t vals;
  1010.  
  1011.       if (DecodeAdr(2, 2, 3, eSymbolSizeUnknown, adr_mode_mask_dir, &vals) != e_adr_mode_none)
  1012.       {
  1013.         BAsmCode[2] -= 7;
  1014.         if (BAsmCode[2] == 3)
  1015.           BAsmCode[2] = 0;
  1016.         BAsmCode[0] = 0x11;
  1017.         BAsmCode[1] = 0x30 + Code;
  1018.         BAsmCode[2] = (BAsmCode[2] << 6) + (z3 << 3) + z2;
  1019.         BAsmCode[3] = vals.vals[0];
  1020.         CodeLen = 4;
  1021.       }
  1022.     }
  1023.   }
  1024. }
  1025.  
  1026. /* Register-Register-Operationen */
  1027.  
  1028. void DecodeTFR_TFM_EXG_6809(Word code, Boolean allow_inc_dec, reg_decoder_6809_t reg_decoder, Boolean reverse)
  1029. {
  1030.   if (ChkArgCnt(2, 2))
  1031.   {
  1032.     int Inc1, Inc2;
  1033.  
  1034.     SplitIncDec(ArgStr[1].str.p_str, &Inc1);
  1035.     SplitIncDec(ArgStr[2].str.p_str, &Inc2);
  1036.     if ((Inc1 != 0) || (Inc2 != 0))
  1037.     {
  1038.       if (!allow_inc_dec) WrError(ErrNum_InvAddrMode);
  1039.       else if (!reg_decoder(ArgStr[1].str.p_str, BAsmCode + 3) || (BAsmCode[3] > 4)) WrStrErrorPos(ErrNum_InvRegName, &ArgStr[1]);
  1040.       else if (!reg_decoder(ArgStr[2].str.p_str, BAsmCode + 2) || (BAsmCode[2] > 4)) WrStrErrorPos(ErrNum_InvRegName, &ArgStr[2]);
  1041.       else
  1042.       {
  1043.         BAsmCode[0] = 0x11;
  1044.         BAsmCode[1] = 0;
  1045.         if (reverse)
  1046.           BAsmCode[2] = (BAsmCode[2] << 4) | (BAsmCode[3] & 0x0f);
  1047.         else
  1048.           BAsmCode[2] |= BAsmCode[3] << 4;
  1049.         if ((Inc1 == 1) && (Inc2 == 1))
  1050.           BAsmCode[1] = 0x38;
  1051.         else if ((Inc1 == -1) && (Inc2 == -1))
  1052.           BAsmCode[1] = 0x39;
  1053.         else if ((Inc1 ==  1) && (Inc2 ==  0))
  1054.           BAsmCode[1] = 0x3a;
  1055.         else if ((Inc1 ==  0) && (Inc2 ==  1))
  1056.           BAsmCode[1] = 0x3b;
  1057.         if (BAsmCode[1] == 0) WrError(ErrNum_InvAddrMode);
  1058.         else
  1059.           CodeLen = 3;
  1060.       }
  1061.     }
  1062.     else if (Memo("TFM")) WrError(ErrNum_InvAddrMode);
  1063.     else if (!reg_decoder(ArgStr[1].str.p_str, BAsmCode + 2)) WrError(ErrNum_InvRegName);
  1064.     else if (!reg_decoder(ArgStr[2].str.p_str, BAsmCode + 1)) WrError(ErrNum_InvRegName);
  1065.     else if ((BAsmCode[1] != 13) && (BAsmCode[2] != 13) /* Z Register compatible to all other registers */
  1066.           && (((BAsmCode[1] ^ BAsmCode[2]) & 0x08) != 0)) WrError(ErrNum_ConfOpSizes);
  1067.     else
  1068.     {
  1069.       CodeLen = 2;
  1070.       BAsmCode[0] = code;
  1071.       if (reverse)
  1072.         BAsmCode[1] = (BAsmCode[1] << 4) | (BAsmCode[2] & 0x0f);
  1073.       else
  1074.         BAsmCode[1] |= BAsmCode[2] << 4;
  1075.     }
  1076.   }
  1077. }
  1078.  
  1079. static void DecodeTFR_TFM(Word code)
  1080. {
  1081.   DecodeTFR_TFM_EXG_6809(code, MomCPU == CPU6309, CodeCPUReg, False);
  1082. }
  1083.  
  1084. static void DecodeEXG(Word code)
  1085. {
  1086.   DecodeTFR_TFM_EXG_6809(code, False, CodeCPUReg, False);
  1087. }
  1088.  
  1089. static void DecodeALU2(Word Code)
  1090. {
  1091.   if (!ChkArgCnt(2, 2));
  1092.   else if (!CodeCPUReg(ArgStr[1].str.p_str, &BAsmCode[3])) WrError(ErrNum_InvRegName);
  1093.   else if (!CodeCPUReg(ArgStr[2].str.p_str, &BAsmCode[2])) WrError(ErrNum_InvRegName);
  1094.   else if ((BAsmCode[2] != 13) && (BAsmCode[3] != 13) /* Z Register compatible to all other registers */
  1095.         && (((BAsmCode[2] ^ BAsmCode[3]) & 0x08) != 0)) WrError(ErrNum_ConfOpSizes);
  1096.   else
  1097.   {
  1098.     CodeLen = 3;
  1099.     BAsmCode[0] = 0x10;
  1100.     BAsmCode[1] = 0x30 + Code;
  1101.     BAsmCode[2] += BAsmCode[3] << 4;
  1102.   }
  1103. }
  1104.  
  1105. /* Berechnung effektiver Adressen */
  1106.  
  1107. static void DecodeLEA(Word Index)
  1108. {
  1109.   const BaseOrder *pOrder = LEAOrders + Index;
  1110.  
  1111.   if (ChkArgCnt(1, 2))
  1112.   {
  1113.     adr_vals_t vals;
  1114.  
  1115.     if (DecodeAdr(1, ArgCnt, 1, eSymbolSizeUnknown, adr_mode_mask_ind, &vals) != e_adr_mode_none)
  1116.     {
  1117.       BAsmCode[CodeLen++] = pOrder->Code;
  1118.       append_adr_vals(&vals);
  1119.     }
  1120.   }
  1121. }
  1122.  
  1123. /* Push/Pull */
  1124.  
  1125. void DecodeStack_6809(Word code)
  1126. {
  1127.   Boolean OK = True, Extent = False;
  1128.   int z2, z3;
  1129.   Boolean has_w = !!Hi(code);
  1130.  
  1131.   BAsmCode[1] = 0;
  1132.  
  1133.   /* S oder U einsetzen, entsprechend Opcode */
  1134.  
  1135.   *StackRegNames[StackRegCnt - 2] = OpPart.str.p_str[strlen(OpPart.str.p_str) - 1] ^ ('S' ^ 'U');
  1136.   for (z2 = 1; z2 <= ArgCnt; z2++)
  1137.     if (OK)
  1138.     {
  1139.       if (!as_strcasecmp(ArgStr[z2].str.p_str, "W"))
  1140.       {
  1141.         if (!has_w)
  1142.           OK = False;
  1143.         else if (ArgCnt != 1)
  1144.         {
  1145.           WrError(ErrNum_InAccReg);
  1146.           OK = False;
  1147.         }
  1148.         else
  1149.           Extent = True;
  1150.       }
  1151.       else
  1152.       {
  1153.         for (z3 = 0; z3 < StackRegCnt; z3++)
  1154.           if (!as_strcasecmp(ArgStr[z2].str.p_str, StackRegNames[z3]))
  1155.           {
  1156.             BAsmCode[1] |= StackRegMasks[z3];
  1157.             break;
  1158.           }
  1159.         if (z3 >= StackRegCnt)
  1160.         {
  1161.           if (!as_strcasecmp(ArgStr[z2].str.p_str, "ALL"))
  1162.             BAsmCode[1] = 0xff;
  1163.           else if (*ArgStr[z2].str.p_str != '#') OK = False;
  1164.           else
  1165.           {
  1166.             BAsmCode[2] = EvalStrIntExpressionOffs(&ArgStr[z2], 1, Int8, &OK);
  1167.             if (OK)
  1168.               BAsmCode[1] |= BAsmCode[2];
  1169.           }
  1170.         }
  1171.       }
  1172.     }
  1173.   if (OK)
  1174.   {
  1175.     if (Extent)
  1176.     {
  1177.       CodeLen = 2;
  1178.       BAsmCode[0] = 0x10;
  1179.       BAsmCode[1] = Lo(code) + 4;
  1180.     }
  1181.     else
  1182.     {
  1183.       CodeLen = 2;
  1184.       BAsmCode[0] = code;
  1185.     }
  1186.   }
  1187.   else
  1188.     WrStrErrorPos(ErrNum_InvRegName, &ArgStr[z2 - 1]);
  1189. }
  1190.  
  1191. static void DecodeBITMD_LDMD(Word Code)
  1192. {
  1193.   if (!ChkArgCnt(1, 1));
  1194.   else if (!ChkMinCPU(CPU6309));
  1195.   else if (*ArgStr[1].str.p_str != '#') WrError(ErrNum_OnlyImmAddr);
  1196.   else
  1197.   {
  1198.     Boolean OK;
  1199.  
  1200.     BAsmCode[2] = EvalStrIntExpressionOffs(&ArgStr[1], 1,Int8, &OK);
  1201.     if (OK)
  1202.     {
  1203.       BAsmCode[0] = 0x11;
  1204.       BAsmCode[1] = Code;
  1205.       CodeLen = 3;
  1206.     }
  1207.   }
  1208. }
  1209.  
  1210. /*-------------------------------------------------------------------------*/
  1211. /* Erzeugung/Aufloesung Codetabellen */
  1212.  
  1213. static void AddFixed(const char *NName, Word NCode, CPUVar NCPU)
  1214. {
  1215.   order_array_rsv_end(FixedOrders, BaseOrder);
  1216.   FixedOrders[InstrZ].Code = NCode;
  1217.   FixedOrders[InstrZ].MinCPU = NCPU;
  1218.   AddInstTable(InstTable, NName, InstrZ++, DecodeFixed);
  1219. }
  1220.  
  1221. static void AddRel(const char *NName, Word NCode8, Word NCode16)
  1222. {
  1223.   char LongName[30];
  1224.  
  1225.   order_array_rsv_end(RelOrders, RelOrder);
  1226.   RelOrders[InstrZ].Code8 = NCode8;
  1227.   RelOrders[InstrZ].Code16 = NCode16;
  1228.   AddInstTable(InstTable, NName, InstrZ, DecodeRel);
  1229.   as_snprintf(LongName, sizeof(LongName), "L%s", NName);
  1230.   AddInstTable(InstTable, LongName, InstrZ | 0x8000, DecodeRel);
  1231.   InstrZ++;
  1232. }
  1233.  
  1234. static void AddALU(const char *NName, Word NCode, tSymbolSize NSize, Boolean NImm, CPUVar NCPU)
  1235. {
  1236.   order_array_rsv_end(ALUOrders, ALUOrder);
  1237.   ALUOrders[InstrZ].Code = NCode;
  1238.   ALUOrders[InstrZ].OpSize = NSize;
  1239.   ALUOrders[InstrZ].MayImm = NImm;
  1240.   ALUOrders[InstrZ].MinCPU = NCPU;
  1241.   AddInstTable(InstTable, NName, InstrZ++, DecodeALU);
  1242. }
  1243.  
  1244. static void AddALU2(const char *NName)
  1245. {
  1246.   char RName[30];
  1247.  
  1248.   AddInstTable(InstTable, NName, InstrZ, DecodeALU2);
  1249.   as_snprintf(RName, sizeof(RName), "%sR", NName);
  1250.   AddInstTable(InstTable, RName, InstrZ, DecodeALU2);
  1251.   InstrZ++;
  1252. }
  1253.  
  1254. static void AddRMW(const char *NName, Word NCode, CPUVar NCPU)
  1255. {
  1256.   order_array_rsv_end(RMWOrders, BaseOrder);
  1257.   RMWOrders[InstrZ].Code = NCode;
  1258.   RMWOrders[InstrZ].MinCPU = NCPU;
  1259.   AddInstTable(InstTable, NName, InstrZ++, DecodeRMW);
  1260. }
  1261.  
  1262. static void AddFlag(const char *NName, Word NCode, Boolean NInv, CPUVar NCPU)
  1263. {
  1264.   order_array_rsv_end(FlagOrders, FlagOrder);
  1265.   FlagOrders[InstrZ].Code = NCode;
  1266.   FlagOrders[InstrZ].Inv = NInv;
  1267.   FlagOrders[InstrZ].MinCPU = NCPU;
  1268.   AddInstTable(InstTable, NName, InstrZ++, DecodeFlag);
  1269. }
  1270.  
  1271. static void AddLEA(const char *NName, Word NCode, CPUVar NCPU)
  1272. {
  1273.   order_array_rsv_end(LEAOrders, BaseOrder);
  1274.   LEAOrders[InstrZ].Code = NCode;
  1275.   LEAOrders[InstrZ].MinCPU = NCPU;
  1276.   AddInstTable(InstTable, NName, InstrZ++, DecodeLEA);
  1277. }
  1278.  
  1279. static void AddImm(const char *NName, Word NCode, CPUVar NCPU)
  1280. {
  1281.   order_array_rsv_end(ImmOrders, BaseOrder);
  1282.   ImmOrders[InstrZ].Code = NCode;
  1283.   ImmOrders[InstrZ].MinCPU = NCPU;
  1284.   AddInstTable(InstTable, NName, InstrZ++, DecodeImm);
  1285. }
  1286.  
  1287. static void InitFields(void)
  1288. {
  1289.   InstTable = CreateInstTable(307);
  1290.   SetDynamicInstTable(InstTable);
  1291.  
  1292.   AddInstTable(InstTable, "SWI", 0, DecodeSWI);
  1293.   AddInstTable(InstTable, "LDQ", 0, DecodeLDQ);
  1294.   AddInstTable(InstTable, "TFR", 0x1f, DecodeTFR_TFM);
  1295.   AddInstTable(InstTable, "TFM", 0x1138, DecodeTFR_TFM);
  1296.   AddInstTable(InstTable, "EXG", 0x1e, DecodeEXG);
  1297.   AddInstTable(InstTable, "BITMD", 0x3c, DecodeBITMD_LDMD);
  1298.   AddInstTable(InstTable, "LDMD", 0x3d, DecodeBITMD_LDMD);
  1299.  
  1300.   InstrZ = 0;
  1301.   AddFixed("NOP"  , 0x0012, CPU6809); AddFixed("SYNC" , 0x0013, CPU6809);
  1302.   AddFixed("DAA"  , 0x0019, CPU6809); AddFixed("SEX"  , 0x001d, CPU6809);
  1303.   AddFixed("RTS"  , 0x0039, CPU6809); AddFixed("ABX"  , 0x003a, CPU6809);
  1304.   AddFixed("RTI"  , 0x003b, CPU6809); AddFixed("MUL"  , 0x003d, CPU6809);
  1305.   AddFixed("SWI2" , 0x103f, CPU6809); AddFixed("SWI3" , 0x113f, CPU6809);
  1306.   AddFixed("NEGA" , 0x0040, CPU6809); AddFixed("COMA" , 0x0043, CPU6809);
  1307.   AddFixed("LSRA" , 0x0044, CPU6809); AddFixed("RORA" , 0x0046, CPU6809);
  1308.   AddFixed("ASRA" , 0x0047, CPU6809); AddFixed("ASLA" , 0x0048, CPU6809);
  1309.   AddFixed("LSLA" , 0x0048, CPU6809); AddFixed("ROLA" , 0x0049, CPU6809);
  1310.   AddFixed("DECA" , 0x004a, CPU6809); AddFixed("INCA" , 0x004c, CPU6809);
  1311.   AddFixed("TSTA" , 0x004d, CPU6809); AddFixed("CLRA" , 0x004f, CPU6809);
  1312.   AddFixed("NEGB" , 0x0050, CPU6809); AddFixed("COMB" , 0x0053, CPU6809);
  1313.   AddFixed("LSRB" , 0x0054, CPU6809); AddFixed("RORB" , 0x0056, CPU6809);
  1314.   AddFixed("ASRB" , 0x0057, CPU6809); AddFixed("ASLB" , 0x0058, CPU6809);
  1315.   AddFixed("LSLB" , 0x0058, CPU6809); AddFixed("ROLB" , 0x0059, CPU6809);
  1316.   AddFixed("DECB" , 0x005a, CPU6809); AddFixed("INCB" , 0x005c, CPU6809);
  1317.   AddFixed("TSTB" , 0x005d, CPU6809); AddFixed("CLRB" , 0x005f, CPU6809);
  1318.   AddFixed("PSHSW", 0x1038, CPU6309); AddFixed("PULSW", 0x1039, CPU6309);
  1319.   AddFixed("PSHUW", 0x103a, CPU6309); AddFixed("PULUW", 0x103b, CPU6309);
  1320.   AddFixed("SEXW" , 0x0014, CPU6309); AddFixed("NEGD" , 0x1040, CPU6309);
  1321.   AddFixed("COMD" , 0x1043, CPU6309); AddFixed("LSRD" , 0x1044, CPU6309);
  1322.   AddFixed("RORD" , 0x1046, CPU6309); AddFixed("ASRD" , 0x1047, CPU6309);
  1323.   AddFixed("ASLD" , 0x1048, CPU6309); AddFixed("LSLD" , 0x1048, CPU6309);
  1324.   AddFixed("ROLD" , 0x1049, CPU6309); AddFixed("DECD" , 0x104a, CPU6309);
  1325.   AddFixed("INCD" , 0x104c, CPU6309); AddFixed("TSTD" , 0x104d, CPU6309);
  1326.   AddFixed("CLRD" , 0x104f, CPU6309); AddFixed("COMW" , 0x1053, CPU6309);
  1327.   AddFixed("LSRW" , 0x1054, CPU6309); AddFixed("RORW" , 0x1056, CPU6309);
  1328.   AddFixed("ROLW" , 0x1059, CPU6309); AddFixed("DECW" , 0x105a, CPU6309);
  1329.   AddFixed("INCW" , 0x105c, CPU6309); AddFixed("TSTW" , 0x105d, CPU6309);
  1330.   AddFixed("CLRW" , 0x105f, CPU6309); AddFixed("COME" , 0x1143, CPU6309);
  1331.   AddFixed("DECE" , 0x114a, CPU6309); AddFixed("INCE" , 0x114c, CPU6309);
  1332.   AddFixed("TSTE" , 0x114d, CPU6309); AddFixed("CLRE" , 0x114f, CPU6309);
  1333.   AddFixed("COMF" , 0x1153, CPU6309); AddFixed("DECF" , 0x115a, CPU6309);
  1334.   AddFixed("INCF" , 0x115c, CPU6309); AddFixed("TSTF" , 0x115d, CPU6309);
  1335.   AddFixed("CLRF" , 0x115f, CPU6309); AddFixed("CLRS" , 0x1fd4, CPU6309);
  1336.   AddFixed("CLRV" , 0x1fd7, CPU6309); AddFixed("CLRX" , 0x1fd1, CPU6309);
  1337.   AddFixed("CLRY" , 0x1fd2, CPU6309);
  1338.  
  1339.   InstrZ = 0;
  1340.   AddRel("BRA", 0x0020, 0x0016); AddRel("BRN", 0x0021, 0x1021);
  1341.   AddRel("BHI", 0x0022, 0x1022); AddRel("BLS", 0x0023, 0x1023);
  1342.   AddRel("BHS", 0x0024, 0x1024); AddRel("BCC", 0x0024, 0x1024);
  1343.   AddRel("BLO", 0x0025, 0x1025); AddRel("BCS", 0x0025, 0x1025);
  1344.   AddRel("BNE", 0x0026, 0x1026); AddRel("BEQ", 0x0027, 0x1027);
  1345.   AddRel("BVC", 0x0028, 0x1028); AddRel("BVS", 0x0029, 0x1029);
  1346.   AddRel("BPL", 0x002a, 0x102a); AddRel("BMI", 0x002b, 0x102b);
  1347.   AddRel("BGE", 0x002c, 0x102c); AddRel("BLT", 0x002d, 0x102d);
  1348.   AddRel("BGT", 0x002e, 0x102e); AddRel("BLE", 0x002f, 0x102f);
  1349.   AddRel("BSR", 0x008d, 0x0017);
  1350.  
  1351.   InstrZ = 0;
  1352.   AddALU("LDA" , 0x0086, eSymbolSize8Bit , True , CPU6809);
  1353.   AddALU("STA" , 0x0087, eSymbolSize8Bit , False, CPU6809);
  1354.   AddALU("CMPA", 0x0081, eSymbolSize8Bit , True , CPU6809);
  1355.   AddALU("ADDA", 0x008b, eSymbolSize8Bit , True , CPU6809);
  1356.   AddALU("ADCA", 0x0089, eSymbolSize8Bit , True , CPU6809);
  1357.   AddALU("SUBA", 0x0080, eSymbolSize8Bit , True , CPU6809);
  1358.   AddALU("SBCA", 0x0082, eSymbolSize8Bit , True , CPU6809);
  1359.   AddALU("ANDA", 0x0084, eSymbolSize8Bit , True , CPU6809);
  1360.   AddALU("ORA" , 0x008a, eSymbolSize8Bit , True , CPU6809);
  1361.   AddALU("EORA", 0x0088, eSymbolSize8Bit , True , CPU6809);
  1362.   AddALU("BITA", 0x0085, eSymbolSize8Bit , True , CPU6809);
  1363.  
  1364.   AddALU("LDB" , 0x00c6, eSymbolSize8Bit , True , CPU6809);
  1365.   AddALU("STB" , 0x00c7, eSymbolSize8Bit , False, CPU6809);
  1366.   AddALU("CMPB", 0x00c1, eSymbolSize8Bit , True , CPU6809);
  1367.   AddALU("ADDB", 0x00cb, eSymbolSize8Bit , True , CPU6809);
  1368.   AddALU("ADCB", 0x00c9, eSymbolSize8Bit , True , CPU6809);
  1369.   AddALU("SUBB", 0x00c0, eSymbolSize8Bit , True , CPU6809);
  1370.   AddALU("SBCB", 0x00c2, eSymbolSize8Bit , True , CPU6809);
  1371.   AddALU("ANDB", 0x00c4, eSymbolSize8Bit , True , CPU6809);
  1372.   AddALU("ORB" , 0x00ca, eSymbolSize8Bit , True , CPU6809);
  1373.   AddALU("EORB", 0x00c8, eSymbolSize8Bit , True , CPU6809);
  1374.   AddALU("BITB", 0x00c5, eSymbolSize8Bit , True , CPU6809);
  1375.  
  1376.   AddALU("LDD" , 0x00cc, eSymbolSize16Bit, True , CPU6809);
  1377.   AddALU("STD" , 0x00cd, eSymbolSize16Bit, False, CPU6809);
  1378.   AddALU("CMPD", 0x1083, eSymbolSize16Bit, True , CPU6809);
  1379.   AddALU("ADDD", 0x00c3, eSymbolSize16Bit, True , CPU6809);
  1380.   AddALU("ADCD", 0x1089, eSymbolSize16Bit, True , CPU6309);
  1381.   AddALU("SUBD", 0x0083, eSymbolSize16Bit, True , CPU6809);
  1382.   AddALU("SBCD", 0x1082, eSymbolSize16Bit, True , CPU6309);
  1383.   AddALU("MULD", 0x118f, eSymbolSize16Bit, True , CPU6309);
  1384.   AddALU("DIVD", 0x118d, eSymbolSize16Bit, True , CPU6309);
  1385.   AddALU("ANDD", 0x1084, eSymbolSize16Bit, True , CPU6309);
  1386.   AddALU("ORD" , 0x108a, eSymbolSize16Bit, True , CPU6309);
  1387.   AddALU("EORD", 0x1088, eSymbolSize16Bit, True , CPU6309);
  1388.   AddALU("BITD", 0x1085, eSymbolSize16Bit, True , CPU6309);
  1389.  
  1390.   AddALU("LDW" , 0x1086, eSymbolSize16Bit, True , CPU6309);
  1391.   AddALU("STW" , 0x1087, eSymbolSize16Bit, False, CPU6309);
  1392.   AddALU("CMPW", 0x1081, eSymbolSize16Bit, True , CPU6309);
  1393.   AddALU("ADDW", 0x108b, eSymbolSize16Bit, True , CPU6309);
  1394.   AddALU("SUBW", 0x1080, eSymbolSize16Bit, True , CPU6309);
  1395.  
  1396.   AddALU("STQ" , 0x10cd, eSymbolSize16Bit, True , CPU6309);
  1397.   AddALU("DIVQ", 0x118e, eSymbolSize16Bit, True , CPU6309);
  1398.  
  1399.   AddALU("LDE" , 0x1186, eSymbolSize8Bit , True , CPU6309);
  1400.   AddALU("STE" , 0x1187, eSymbolSize8Bit , False, CPU6309);
  1401.   AddALU("CMPE", 0x1181, eSymbolSize8Bit , True , CPU6309);
  1402.   AddALU("ADDE", 0x118b, eSymbolSize8Bit , True , CPU6309);
  1403.   AddALU("SUBE", 0x1180, eSymbolSize8Bit , True , CPU6309);
  1404.  
  1405.   AddALU("LDF" , 0x11c6, eSymbolSize8Bit , True , CPU6309);
  1406.   AddALU("STF" , 0x11c7, eSymbolSize8Bit , False, CPU6309);
  1407.   AddALU("CMPF", 0x11c1, eSymbolSize8Bit , True , CPU6309);
  1408.   AddALU("ADDF", 0x11cb, eSymbolSize8Bit , True , CPU6309);
  1409.   AddALU("SUBF", 0x11c0, eSymbolSize8Bit , True , CPU6309);
  1410.  
  1411.   AddALU("LDX" , 0x008e, eSymbolSize16Bit, True , CPU6809);
  1412.   AddALU("STX" , 0x008f, eSymbolSize16Bit, False, CPU6809);
  1413.   AddALU("CMPX", 0x008c, eSymbolSize16Bit, True , CPU6809);
  1414.  
  1415.   AddALU("LDY" , 0x108e, eSymbolSize16Bit, True , CPU6809);
  1416.   AddALU("STY" , 0x108f, eSymbolSize16Bit, False, CPU6809);
  1417.   AddALU("CMPY", 0x108c, eSymbolSize16Bit, True , CPU6809);
  1418.  
  1419.   AddALU("LDU" , 0x00ce, eSymbolSize16Bit, True , CPU6809);
  1420.   AddALU("STU" , 0x00cf, eSymbolSize16Bit, False, CPU6809);
  1421.   AddALU("CMPU", 0x1183, eSymbolSize16Bit, True , CPU6809);
  1422.  
  1423.   AddALU("LDS" , 0x10ce, eSymbolSize16Bit, True , CPU6809);
  1424.   AddALU("STS" , 0x10cf, eSymbolSize16Bit, False, CPU6809);
  1425.   AddALU("CMPS", 0x118c, eSymbolSize16Bit, True , CPU6809);
  1426.  
  1427.   AddALU("JSR" , 0x008d, eSymbolSize16Bit, False, CPU6809);
  1428.  
  1429.   InstrZ = 0;
  1430.   AddALU2("ADD"); AddALU2("ADC");
  1431.   AddALU2("SUB"); AddALU2("SBC");
  1432.   AddALU2("AND"); AddALU2("OR" );
  1433.   AddALU2("EOR"); AddALU2("CMP");
  1434.  
  1435.   InstrZ = 0;
  1436.   AddRMW("NEG", 0x00, CPU6809);
  1437.   AddRMW("COM", 0x03, CPU6809);
  1438.   AddRMW("LSR", 0x04, CPU6809);
  1439.   AddRMW("ROR", 0x06, CPU6809);
  1440.   AddRMW("ASR", 0x07, CPU6809);
  1441.   AddRMW("ASL", 0x08, CPU6809);
  1442.   AddRMW("LSL", 0x08, CPU6809);
  1443.   AddRMW("ROL", 0x09, CPU6809);
  1444.   AddRMW("DEC", 0x0a, CPU6809);
  1445.   AddRMW("INC", 0x0c, CPU6809);
  1446.   AddRMW("TST", 0x0d, CPU6809);
  1447.   AddRMW("JMP", 0x0e, CPU6809);
  1448.   AddRMW("CLR", 0x0f, CPU6809);
  1449.  
  1450.   InstrZ = 0;
  1451.   AddFlag("CWAI" , 0x3c, True , CPU6809);
  1452.   AddFlag("ANDCC", 0x1c, True , CPU6809);
  1453.   AddFlag("ORCC" , 0x1a, False, CPU6809);
  1454.  
  1455.   InstrZ = 0;
  1456.   AddLEA("LEAX", 0x30, CPU6809);
  1457.   AddLEA("LEAY", 0x31, CPU6809);
  1458.   AddLEA("LEAS", 0x32, CPU6809);
  1459.   AddLEA("LEAU", 0x33, CPU6809);
  1460.  
  1461.   InstrZ = 0;
  1462.   AddImm("AIM", 0x02, CPU6309);
  1463.   AddImm("OIM", 0x01, CPU6309);
  1464.   AddImm("EIM", 0x05, CPU6309);
  1465.   AddImm("TIM", 0x0b, CPU6309);
  1466.  
  1467.   AddInstTable(InstTable, "PSHS", 0x34 | ((MomCPU == CPU6309) ? 0x100 : 0), DecodeStack_6809);
  1468.   AddInstTable(InstTable, "PULS", 0x35 | ((MomCPU == CPU6309) ? 0x100 : 0), DecodeStack_6809);
  1469.   AddInstTable(InstTable, "PSHU", 0x36 | ((MomCPU == CPU6309) ? 0x100 : 0), DecodeStack_6809);
  1470.   AddInstTable(InstTable, "PULU", 0x37 | ((MomCPU == CPU6309) ? 0x100 : 0), DecodeStack_6809);
  1471.  
  1472.   InstrZ = 0;
  1473.   AddInstTable(InstTable, "BAND" , InstrZ++, DecodeBit);
  1474.   AddInstTable(InstTable, "BIAND", InstrZ++, DecodeBit);
  1475.   AddInstTable(InstTable, "BOR"  , InstrZ++, DecodeBit);
  1476.   AddInstTable(InstTable, "BIOR" , InstrZ++, DecodeBit);
  1477.   AddInstTable(InstTable, "BEOR" , InstrZ++, DecodeBit);
  1478.   AddInstTable(InstTable, "BIEOR", InstrZ++, DecodeBit);
  1479.   AddInstTable(InstTable, "LDBT" , InstrZ++, DecodeBit);
  1480.   AddInstTable(InstTable, "STBT" , InstrZ++, DecodeBit);
  1481.  
  1482.   init_moto8_pseudo(InstTable, e_moto_8_be | e_moto_8_db | e_moto_8_dw);
  1483. }
  1484.  
  1485. static void DeinitFields(void)
  1486. {
  1487.   DestroyInstTable(InstTable);
  1488.   order_array_free(FixedOrders);
  1489.   order_array_free(RelOrders);
  1490.   order_array_free(ALUOrders);
  1491.   order_array_free(RMWOrders);
  1492.   order_array_free(FlagOrders);
  1493.   order_array_free(LEAOrders);
  1494.   order_array_free(ImmOrders);
  1495. }
  1496.  
  1497. /*-------------------------------------------------------------------------*/
  1498.  
  1499. static Boolean DecodeAttrPart_6809(void)
  1500. {
  1501.   if (strlen(AttrPart.str.p_str) > 1)
  1502.   {
  1503.     WrStrErrorPos(ErrNum_UndefAttr, &AttrPart);
  1504.     return False;
  1505.   }
  1506.  
  1507.   /* deduce operand size No size is zero-length string -> '\0' */
  1508.  
  1509.   return DecodeMoto16AttrSize(*AttrPart.str.p_str, &AttrPartOpSize[0], False);
  1510. }
  1511.  
  1512. static void MakeCode_6809(void)
  1513. {
  1514.   tSymbolSize OpSize;
  1515.  
  1516.   CodeLen = 0;
  1517.   DontPrint = False;
  1518.   OpSize = (AttrPartOpSize[0] != eSymbolSizeUnknown) ? AttrPartOpSize[0] : eSymbolSize8Bit;
  1519.  
  1520.   /* zu ignorierendes */
  1521.  
  1522.   if (Memo(""))
  1523.     return;
  1524.  
  1525.   /* Pseudoanweisungen */
  1526.  
  1527.   if (DecodeMoto16Pseudo(OpSize, True))
  1528.     return;
  1529.  
  1530.   if (!LookupInstTable(InstTable, OpPart.str.p_str))
  1531.     WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
  1532. }
  1533.  
  1534. static void InitCode_6809(void)
  1535. {
  1536.   DPRValue = 0;
  1537.   target_used = False;
  1538. }
  1539.  
  1540. static Boolean IsDef_6809(void)
  1541. {
  1542.   return False;
  1543. }
  1544.  
  1545. static void SwitchTo_6809(void)
  1546. {
  1547. #define ASSUME09Count (sizeof(ASSUME09s) / sizeof(*ASSUME09s))
  1548.   static const ASSUMERec ASSUME09s[] =
  1549.   {
  1550.     { "DPR", &DPRValue, 0, 0xff, 0x100, NULL }
  1551.   };
  1552.  
  1553.   TurnWords = False;
  1554.   SetIntConstMode(eIntConstModeMoto);
  1555.  
  1556.   PCSymbol = "*";
  1557.   HeaderID = 0x63;
  1558.   NOPCode = 0x12;
  1559.   DivideChars = ",";
  1560.   HasAttrs = True;
  1561.   AttrChars = ".";
  1562.  
  1563.   ValidSegs = (1 << SegCode);
  1564.   Grans[SegCode] = 1; ListGrans[SegCode] = 1; SegInits[SegCode] = 0;
  1565.   SegLimits[SegCode] = 0xffff;
  1566.  
  1567.   DecodeAttrPart = DecodeAttrPart_6809;
  1568.   MakeCode = MakeCode_6809;
  1569.   IsDef = IsDef_6809;
  1570.  
  1571.   SwitchFrom = DeinitFields;
  1572.   InitFields();
  1573.   AddMoto16PseudoONOFF(False);
  1574.   if (!target_used)
  1575.     SetFlag(&plain_base_mode, plain_base_mode_sym_name, def_plain_base_mode_set ? def_plain_base_mode : False);
  1576.   AddONOFF(plain_base_mode_cmd_name, &plain_base_mode, plain_base_mode_sym_name, False);
  1577.   target_used = True;
  1578.  
  1579.   pASSUMERecs = ASSUME09s;
  1580.   ASSUMERecCnt = ASSUME09Count;
  1581. }
  1582.  
  1583. static as_cmd_result_t cmd_plain_base(Boolean negate, const char *p_arg)
  1584. {
  1585.   UNUSED(p_arg);
  1586.   def_plain_base_mode = !negate;
  1587.   def_plain_base_mode_set = True;
  1588.   return e_cmd_ok;
  1589. }
  1590.  
  1591. static const as_cmd_rec_t onoff_params[] =
  1592. {
  1593.   { plain_base_mode_cmd_name, cmd_plain_base }
  1594. };
  1595.  
  1596. void code6809_init(void)
  1597. {
  1598.   CPU6809 = AddCPU("6809", SwitchTo_6809);
  1599.   CPU6309 = AddCPU("6309", SwitchTo_6809);
  1600.  
  1601.   as_cmd_register(onoff_params, as_array_size(onoff_params));
  1602.   AddInitPassProc(InitCode_6809);
  1603. }
  1604.