Subversion Repositories pentevo

Rev

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

  1. /* codeko09.c */
  2. /*****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
  4. /*                                                                           */
  5. /* AS-Portierung                                                             */
  6. /*                                                                           */
  7. /* Code Generator Konami 052001                                              */
  8. /*                                                                           */
  9. /*****************************************************************************/
  10.  
  11. #include "stdinc.h"
  12. #include <ctype.h>
  13. #include <string.h>
  14. #include "bpemu.h"
  15. #include "strutil.h"
  16.  
  17. #include "asmdef.h"
  18. #include "asmsub.h"
  19. #include "asmpars.h"
  20. #include "asmitree.h"
  21. #include "codevars.h"
  22. #include "headids.h"
  23.  
  24. #include "codepseudo.h"
  25. #include "motpseudo.h"
  26. #include "intpseudo.h"
  27. #include "code6809.h"
  28. #include "codeko09.h"
  29.  
  30. typedef enum
  31. {
  32.   e_adr_mode_none = -1,
  33.   e_adr_mode_imm = 1,
  34.   e_adr_mode_ind = 2
  35. } adr_mode_t;
  36.  
  37. #define adr_mode_mask_imm (1 << e_adr_mode_imm)
  38. #define adr_mode_mask_ind (1 << e_adr_mode_ind)
  39. #define adr_mode_mask_no_imm (adr_mode_mask_ind)
  40. #define adr_mode_mask_all (adr_mode_mask_imm | adr_mode_mask_no_imm)
  41.  
  42. typedef struct
  43. {
  44.   adr_mode_t mode;
  45.   int cnt;
  46.   Byte vals[5];
  47. } adr_vals_t;
  48.  
  49. static const char reg_16_names[4] = { 'X','Y','U','S' };
  50. static LongInt DPRValue;
  51.  
  52. /*!------------------------------------------------------------------------
  53.  * \fn     decode_cpu_reg(const char *p_asc, Byte *p_ret)
  54.  * \brief  decode CPU register names for TFR/EXG
  55.  * \param  p_asc source argument
  56.  * \param  p_ret resulting encoded value
  57.  * \return True if known register
  58.  * ------------------------------------------------------------------------ */
  59.  
  60. static Boolean decode_cpu_reg(const char *p_asc, Byte *p_ret)
  61. {
  62. #define reg_cnt as_array_size(reg_names)
  63.   static const char reg_names[][2] =
  64.   {
  65.     "X", "Y", "U", "S", "A", "B"
  66.   };
  67.   static const Byte reg_vals[reg_cnt] =
  68.   {
  69.     2  , 3  , 5  , 4   , 0  , 1
  70.   };
  71.   size_t z;
  72.  
  73.   for (z = 0; z < reg_cnt; z++)
  74.     if (!as_strcasecmp(p_asc, reg_names[z]))
  75.     {
  76.       *p_ret = reg_vals[z];
  77.       return True;
  78.     }
  79.   return False;
  80. }
  81.  
  82. /*!------------------------------------------------------------------------
  83.  * \fn     DecodeAdr(int ArgStartIdx, int ArgEndIdx,
  84.                      tSymbolSize op_size, unsigned mode_mask, adr_vals_t *p_vals)
  85.  * \brief  decode/evaluate address expression
  86.  * \param  ArgStartIdx 1st argument of expression
  87.  * \param  ArgEndIdx last argument of expression
  88.  * \param  op_size operand size (8/16)
  89.  * \param  mode_mask bit mask of allowed modes
  90.  * \param  p_vals dest buffer
  91.  * \return encoded addressing mode
  92.  * ------------------------------------------------------------------------ */
  93.  
  94. static void reset_adr_vals(adr_vals_t *p_vals)
  95. {
  96.   p_vals->mode = e_adr_mode_none;
  97.   p_vals->cnt = 0;
  98. }
  99.  
  100. #define IDX_PCREG 7
  101.  
  102. static Boolean code_reg(const char *p_arg, Byte *p_ret)
  103. {
  104.   if (!as_strcasecmp(p_arg, "PCR") || !as_strcasecmp(p_arg, "PC"))
  105.   {
  106.     *p_ret = IDX_PCREG;
  107.     return True;
  108.   }
  109.  
  110.   if (strlen(p_arg) != 1)
  111.     return False;
  112.   else
  113.   {
  114.     static const char Regs[6] = "XY\aUS";
  115.     const char *p = strchr(Regs, as_toupper(*p_arg));
  116.  
  117.     if (!p)
  118.       return False;
  119.     *p_ret = p - Regs + 2;
  120.     return True;
  121.   }
  122. }
  123.  
  124. static unsigned ChkZero(const char *s, Byte *Erg)
  125. {
  126.   if (*s == '>')
  127.   {
  128.     *Erg = 1;
  129.     return 1;
  130.   }
  131.   else if (*s == '<')
  132.   {
  133.     *Erg = 2;
  134.     return 1;
  135.   }
  136.   else
  137.   {
  138.     *Erg = 0;
  139.     return 0;
  140.   }
  141. }
  142.  
  143. static Boolean MayShort(Integer Arg)
  144. {
  145.   return ((Arg >= -128) && (Arg < 127));
  146. }
  147.  
  148. static Boolean IsZeroOrEmpty(const tStrComp *pArg)
  149. {
  150.   Boolean OK;
  151.   LongInt Value;
  152.  
  153.   if (!*pArg->str.p_str)
  154.     return True;
  155.   Value = EvalStrIntExpression(pArg, Int32, &OK);
  156.   return OK && !Value;
  157. }
  158.  
  159. static adr_mode_t DecodeAdr(int ArgStartIdx, int ArgEndIdx,
  160.                             tSymbolSize op_size, unsigned mode_mask, adr_vals_t *p_vals)
  161. {
  162.   tStrComp *pStartArg, *pEndArg, IndirComps[2];
  163.   String temp;
  164.   Word AdrWord;
  165.   Boolean IndFlag, OK;
  166.   Byte EReg, ZeroMode;
  167.   char *p;
  168.   unsigned Offset;
  169.   Integer AdrInt;
  170.   int AdrArgCnt = ArgEndIdx - ArgStartIdx + 1, end_arg_len;
  171.   const unsigned OpcodeLen = 1;
  172.  
  173.   reset_adr_vals(p_vals);
  174.   pStartArg = &ArgStr[ArgStartIdx];
  175.   pEndArg = &ArgStr[ArgEndIdx];
  176.  
  177.   /* immediate */
  178.  
  179.   if ((*pStartArg->str.p_str == '#') && (AdrArgCnt == 1))
  180.   {
  181.     switch (op_size)
  182.     {
  183.       case eSymbolSize16Bit:
  184.         AdrWord = EvalStrIntExpressionOffs(pStartArg, 1, Int16, &OK);
  185.         if (OK)
  186.         {
  187.           p_vals->vals[0] = Hi(AdrWord);
  188.           p_vals->vals[1] = Lo(AdrWord);
  189.           p_vals->cnt = 2;
  190.         }
  191.         break;
  192.       case eSymbolSize8Bit:
  193.         p_vals->vals[0] = EvalStrIntExpressionOffs(pStartArg, 1, Int8, &OK);
  194.         if (OK)
  195.           p_vals->cnt = 1;
  196.         break;
  197.       default:
  198.         OK = False;
  199.         break;
  200.     }
  201.     if (OK)
  202.       p_vals->mode = e_adr_mode_imm;
  203.     goto chk_mode;
  204.   }
  205.  
  206.   /* indirekter Ausdruck ? */
  207.  
  208.   if ((*pStartArg->str.p_str == '[') && (pStartArg->str.p_str[strlen(pStartArg->str.p_str) - 1] == ']'))
  209.   {
  210.     tStrComp Arg, Remainder;
  211.  
  212.     IndFlag = True;
  213.     StrCompRefRight(&Arg, pStartArg, 1);
  214.     StrCompShorten(&Arg, 1);
  215.     AdrArgCnt = 0;
  216.     do
  217.     {
  218.       p = QuotPos(Arg.str.p_str, ',');
  219.       if (p)
  220.         StrCompSplitRef(&IndirComps[AdrArgCnt], &Remainder, &Arg, p);
  221.       else
  222.         IndirComps[AdrArgCnt] = Arg;
  223.       KillPrefBlanksStrCompRef(&IndirComps[AdrArgCnt]);
  224.       KillPostBlanksStrComp(&IndirComps[AdrArgCnt]);
  225.       AdrArgCnt++;
  226.       if (p)
  227.         Arg = Remainder;
  228.     }
  229.     while (p && (AdrArgCnt < 2));
  230.     pStartArg = &IndirComps[0];
  231.     pEndArg = &IndirComps[AdrArgCnt - 1];
  232.   }
  233.   else
  234.     IndFlag = False;
  235.  
  236.   /* Predekrement ? */
  237.  
  238.   end_arg_len = strlen(pEndArg->str.p_str);
  239.   if ((AdrArgCnt >= 1) && (AdrArgCnt <= 2) && (end_arg_len >= 2) && (*pEndArg->str.p_str == '-') && (code_reg(pEndArg->str.p_str + 1, &EReg)))
  240.   {
  241.     if ((AdrArgCnt == 2) && !IsZeroOrEmpty(pStartArg)) WrError(ErrNum_InvAddrMode);
  242.     else
  243.     {
  244.       p_vals->cnt = 1;
  245.       p_vals->vals[0] = 0x02 + (EReg << 4) + (Ord(IndFlag) << 3);
  246.       p_vals->mode = e_adr_mode_ind;
  247.     }
  248.     goto chk_mode;
  249.   }
  250.  
  251.   if ((AdrArgCnt >= 1) && (AdrArgCnt <= 2) && (end_arg_len >= 3) && (!strncmp(pEndArg->str.p_str, "--", 2)) && (code_reg(pEndArg->str.p_str + 2, &EReg)))
  252.   {
  253.     if ((AdrArgCnt == 2) && !IsZeroOrEmpty(pStartArg)) WrError(ErrNum_InvAddrMode);
  254.     else
  255.     {
  256.       p_vals->cnt = 1;
  257.       p_vals->vals[0] = 0x03 + (EReg << 4) + (Ord(IndFlag) << 3);
  258.       p_vals->mode = e_adr_mode_ind;
  259.     }
  260.     goto chk_mode;
  261.   }
  262.  
  263.   /* Postinkrement ? */
  264.  
  265.   if ((AdrArgCnt >= 1) && (AdrArgCnt <= 2) && (end_arg_len >= 2) && (pEndArg->str.p_str[end_arg_len - 1] == '+'))
  266.   {
  267.     memcpy(temp, pEndArg->str.p_str, end_arg_len - 1);
  268.     temp[end_arg_len - 1] = '\0';
  269.     if (code_reg(temp, &EReg))
  270.     {
  271.       if ((AdrArgCnt == 2) && !IsZeroOrEmpty(pStartArg)) WrError(ErrNum_InvAddrMode);
  272.       else
  273.       {
  274.         p_vals->cnt = 1;
  275.         p_vals->vals[0] = 0x00 + (EReg << 4) + (Ord(IndFlag) << 3);
  276.         p_vals->mode = e_adr_mode_ind;
  277.       }
  278.       goto chk_mode;
  279.     }
  280.   }
  281.  
  282.   if ((AdrArgCnt >= 1) && (AdrArgCnt <= 2) && (end_arg_len >= 3) && (!strncmp(pEndArg->str.p_str + end_arg_len - 2, "++", 2)))
  283.   {
  284.     memcpy(temp, pEndArg->str.p_str, end_arg_len - 2);
  285.     temp[end_arg_len - 2] = '\0';
  286.     if (code_reg(temp, &EReg))
  287.     {
  288.       if ((AdrArgCnt == 2) && !IsZeroOrEmpty(pStartArg)) WrError(ErrNum_InvAddrMode);
  289.       else
  290.       {
  291.         p_vals->cnt = 1;
  292.         p_vals->vals[0] = 0x01 + (EReg << 4) + (Ord(IndFlag) << 3);
  293.         p_vals->mode = e_adr_mode_ind;
  294.       }
  295.       goto chk_mode;
  296.     }
  297.   }
  298.  
  299.   /* 16-Bit-Register (mit Index) ? */
  300.  
  301.   if ((AdrArgCnt <= 2) && (AdrArgCnt >= 1) && (code_reg(pEndArg->str.p_str, &EReg)))
  302.   {
  303.     p_vals->vals[0] = (EReg << 4) + (Ord(IndFlag) << 3);
  304.  
  305.     /* nur 16-Bit-Register */
  306.  
  307.     if (AdrArgCnt == 1)
  308.     {
  309.       p_vals->cnt = 1;
  310.       p_vals->vals[0] |= 0x06;
  311.       p_vals->mode = e_adr_mode_ind;
  312.       goto chk_mode;
  313.     }
  314.  
  315.     /* mit Index */
  316.  
  317.     if (!as_strcasecmp(pStartArg->str.p_str, "A"))
  318.     {
  319.       p_vals->cnt = 1;
  320.       p_vals->vals[0] |= 0x80;
  321.       p_vals->mode = e_adr_mode_ind;
  322.       goto chk_mode;
  323.     }
  324.     if (!as_strcasecmp(pStartArg->str.p_str, "B"))
  325.     {
  326.       p_vals->cnt = 1;
  327.       p_vals->vals[0] |= 0x81;
  328.       p_vals->mode = e_adr_mode_ind;
  329.       goto chk_mode;
  330.     }
  331.     if (!as_strcasecmp(pStartArg->str.p_str, "D"))
  332.     {
  333.       p_vals->cnt = 1;
  334.       p_vals->vals[0] += 0x87;
  335.       p_vals->mode = e_adr_mode_ind;
  336.       goto chk_mode;
  337.     }
  338.  
  339.     /* Displacement auswerten */
  340.  
  341.     Offset = ChkZero(pStartArg->str.p_str, &ZeroMode);
  342.     if (EReg == IDX_PCREG)
  343.       AdrInt = EvalStrIntExpressionOffs(pStartArg, Offset, UInt16, &OK)
  344.              - (EProgCounter() + 2 + OpcodeLen);
  345.     else if (ZeroMode > 1)
  346.       AdrInt = EvalStrIntExpressionOffs(pStartArg, Offset, SInt8, &OK);
  347.     else
  348.       AdrInt = EvalStrIntExpressionOffs(pStartArg, Offset, SInt16, &OK);
  349.     if (!OK)
  350.       goto chk_mode;
  351.  
  352.     /* Displacement 0 ? */
  353.  
  354.     if ((ZeroMode == 0) && (AdrInt == 0))
  355.     {
  356.       p_vals->cnt = 1;
  357.       p_vals->vals[0] += 0x06;
  358.       p_vals->mode = e_adr_mode_ind;
  359.       goto chk_mode;
  360.     }
  361.  
  362.     /* 8-Bit-Displacement */
  363.  
  364.     else if ((ZeroMode == 2) || ((ZeroMode == 0) && (MayShort(AdrInt))))
  365.     {
  366.       if (!MayShort(AdrInt)) WrError(ErrNum_NoShortAddr);
  367.       else
  368.       {
  369.         p_vals->mode = e_adr_mode_ind;
  370.         p_vals->cnt = 2;
  371.         p_vals->vals[0] += 0x04;
  372.         p_vals->vals[1] = Lo(AdrInt);
  373.       }
  374.       goto chk_mode;
  375.     }
  376.  
  377.     /* 16-Bit-Displacement */
  378.  
  379.     else
  380.     {
  381.       p_vals->mode = e_adr_mode_ind;
  382.       p_vals->cnt = 3;
  383.       p_vals->vals[0] += 0x05;
  384.       if (EReg == IDX_PCREG)
  385.         AdrInt--;
  386.       p_vals->vals[1] = Hi(AdrInt);
  387.       p_vals->vals[2] = Lo(AdrInt);
  388.       goto chk_mode;
  389.     }
  390.   }
  391.  
  392.   /* absolute/direct */
  393.  
  394.   if (AdrArgCnt == 1)
  395.   {
  396.     tSymbolFlags Flags;
  397.  
  398.     Offset = ChkZero(pStartArg->str.p_str, &ZeroMode);
  399.     AdrInt = EvalStrIntExpressionOffsWithFlags(pStartArg, Offset, UInt16, &OK, &Flags);
  400.     if (mFirstPassUnknown(Flags) && (ZeroMode == 2))
  401.       AdrInt = (AdrInt & 0xff) | (DPRValue << 8);
  402.  
  403.     if (OK)
  404.     {
  405.       if ((ZeroMode == 2) || ((ZeroMode == 0) && (Hi(AdrInt) == DPRValue)))
  406.       {
  407.         if (Hi(AdrInt) != DPRValue) WrError(ErrNum_NoShortAddr);
  408.         else
  409.         {
  410.           p_vals->mode = e_adr_mode_ind;
  411.           p_vals->cnt = 2;
  412.           p_vals->vals[0] = 0xc4 | (Ord(IndFlag) << 3);
  413.           p_vals->vals[1] = Lo(AdrInt);
  414.         }
  415.       }
  416.  
  417.       else
  418.       {
  419.         p_vals->mode = e_adr_mode_ind;
  420.         p_vals->cnt = 3;
  421.         p_vals->vals[0] = 0x07 | (Ord(IndFlag) << 3);
  422.         p_vals->vals[1] = Hi(AdrInt);
  423.         p_vals->vals[2] = Lo(AdrInt);
  424.       }
  425.     }
  426.     goto chk_mode;
  427.   }
  428.  
  429.   if (p_vals->mode == e_adr_mode_none)
  430.     WrError(ErrNum_InvAddrMode);
  431.  
  432. chk_mode:
  433.   if ((p_vals->mode != e_adr_mode_none) && !((mode_mask >> p_vals->mode) & 1))
  434.   {
  435.     WrError(ErrNum_InvAddrMode);
  436.     reset_adr_vals(p_vals);
  437.   }
  438.   return p_vals->mode;
  439. }
  440.  
  441. /*!------------------------------------------------------------------------
  442.  * \fn     append_adr_vals(const adr_vals_t *p_vals)
  443.  * \brief  append encoded addressing mode to instruction
  444.  * \param  p_vals what to append
  445.  * ------------------------------------------------------------------------ */
  446.  
  447. static void append_adr_vals(const adr_vals_t *p_vals)
  448. {
  449.   memcpy(&BAsmCode[CodeLen], p_vals->vals, p_vals->cnt);
  450.   CodeLen += p_vals->cnt;
  451. }
  452.  
  453. /*-------------------------------------------------------------------------*/
  454.  
  455. /*!------------------------------------------------------------------------
  456.  * \fn     decode_inh(Word code)
  457.  * \brief  decode instructions without argument
  458.  * ------------------------------------------------------------------------ */
  459.  
  460. static void decode_inh(Word code)
  461. {
  462.   if (ChkArgCnt(0, 0))
  463.     BAsmCode[CodeLen++] = Lo(code);
  464. }
  465.  
  466. /*!------------------------------------------------------------------------
  467.  * \fn     decode_imm_8(Word code)
  468.  * \brief  decode instructions with 8 bit immediate argument
  469.  * ------------------------------------------------------------------------ */
  470.  
  471. static void decode_imm_8(Word code)
  472. {
  473.   if (ChkArgCnt(1, 1))
  474.   {
  475.     adr_vals_t adr_vals;
  476.  
  477.     switch (DecodeAdr(1, ArgCnt, eSymbolSize8Bit, adr_mode_mask_imm, &adr_vals))
  478.     {
  479.       case e_adr_mode_imm:
  480.         BAsmCode[CodeLen++] = code;
  481.         BAsmCode[CodeLen++] = adr_vals.vals[0];
  482.         break;
  483.       default:
  484.         break;
  485.     }
  486.   }
  487. }
  488.  
  489. /*!------------------------------------------------------------------------
  490.  * \fn     decode_idx(Word code)
  491.  * \brief  decode instructions with indexed argument
  492.  * ------------------------------------------------------------------------ */
  493.  
  494. static void decode_idx(Word code)
  495. {
  496.   if (ChkArgCnt(1, 2))
  497.   {
  498.     adr_vals_t adr_vals;
  499.  
  500.     switch (DecodeAdr(1, ArgCnt, eSymbolSizeUnknown, adr_mode_mask_ind, &adr_vals))
  501.     {
  502.       case e_adr_mode_ind:
  503.         BAsmCode[CodeLen++] = code;
  504.         append_adr_vals(&adr_vals);
  505.         break;
  506.       default:
  507.         break;
  508.     }
  509.   }
  510. }
  511.  
  512. /*!------------------------------------------------------------------------
  513.  * \fn     decode_ari(Word code)
  514.  * \brief  decode instructions with indexed or immediate argument
  515.  * ------------------------------------------------------------------------ */
  516.  
  517. static void decode_ari(Word code)
  518. {
  519.   if (ChkArgCnt(1, 2))
  520.   {
  521.     adr_vals_t adr_vals;
  522.  
  523.     switch (DecodeAdr(1, ArgCnt, (code & 0x8000) ? eSymbolSize16Bit : eSymbolSize8Bit, adr_mode_mask_all, &adr_vals))
  524.     {
  525.       case e_adr_mode_imm:
  526.         BAsmCode[CodeLen++] = Lo(code) + 0;
  527.         goto append;
  528.       case e_adr_mode_ind:
  529.         BAsmCode[CodeLen++] = Lo(code) + (Hi(code) & 0x7f);
  530.         goto append;
  531.       append:
  532.         append_adr_vals(&adr_vals);
  533.         break;
  534.       default:
  535.         break;
  536.     }
  537.   }
  538. }
  539.  
  540. /*!------------------------------------------------------------------------
  541.  * \fn     decode_branch_8_core(Word code)
  542.  * \brief  decode instructions with 8 bit displacement
  543.  * ------------------------------------------------------------------------ */
  544.  
  545. static void decode_branch_8_core(unsigned arg_index, Word code)
  546. {
  547.   tEvalResult eval_result;
  548.   LongInt dist = EvalStrIntExpressionWithResult(&ArgStr[arg_index], UInt16, &eval_result)
  549.                - (EProgCounter() + 2);
  550.   if (eval_result.OK)
  551.   {
  552.     if (!RangeCheck(dist, SInt8) && !mSymbolQuestionable(eval_result.Flags)) WrError(ErrNum_JmpDistTooBig);
  553.     else
  554.     {
  555.       BAsmCode[CodeLen++] = code;
  556.       BAsmCode[CodeLen++] = dist & 0xff;
  557.     }
  558.   }
  559. }
  560.  
  561. /*!------------------------------------------------------------------------
  562.  * \fn     decode_branch_8(Word code)
  563.  * \brief  decode instructions with 8 bit displacement
  564.  * ------------------------------------------------------------------------ */
  565.  
  566. static void decode_branch_8(Word code)
  567. {
  568.   if (ChkArgCnt(1, 1))
  569.     decode_branch_8_core(1, code);
  570. }
  571.  
  572. /*!------------------------------------------------------------------------
  573.  * \fn     decode_branch_16(Word code)
  574.  * \brief  decode instructions with 16 bit displacement
  575.  * ------------------------------------------------------------------------ */
  576.  
  577. static void decode_branch_16(Word code)
  578. {
  579.   if (ChkArgCnt(1, 1))
  580.   {
  581.     tEvalResult eval_result;
  582.     LongInt dist = EvalStrIntExpressionWithResult(&ArgStr[1], UInt16, &eval_result)
  583.                  - (EProgCounter() + 3);
  584.     if (eval_result.OK)
  585.     {
  586.       if (!RangeCheck(dist, SInt16) && !mSymbolQuestionable(eval_result.Flags)) WrError(ErrNum_JmpDistTooBig);
  587.       else
  588.       {
  589.         BAsmCode[CodeLen++] = code;
  590.         BAsmCode[CodeLen++] = (dist >> 8) & 0xff;
  591.         BAsmCode[CodeLen++] = dist & 0xff;
  592.       }
  593.     }
  594.   }
  595. }
  596.  
  597. /*!------------------------------------------------------------------------
  598.  * \fn     decode_div(Word code)
  599.  * \brief  decode DIV instruction
  600.  * \param  code machine code
  601.  * ------------------------------------------------------------------------ */
  602.  
  603. static void decode_div(Word code)
  604. {
  605.   if (!ChkArgCnt(2, 2));
  606.   else if (as_strcasecmp(ArgStr[1].str.p_str, "X")) WrStrErrorPos(ErrNum_InvReg, &ArgStr[1]);
  607.   else if (as_strcasecmp(ArgStr[2].str.p_str, "B")) WrStrErrorPos(ErrNum_InvReg, &ArgStr[2]);
  608.   else
  609.     BAsmCode[CodeLen++] = code;
  610. }
  611.  
  612. /*!------------------------------------------------------------------------
  613.  * \fn     decode_move(Word code)
  614.  * \brief  decode L(MOVE) instruction
  615.  * \param  code machine code
  616.  * ------------------------------------------------------------------------ */
  617.  
  618. static void decode_move(Word code)
  619. {
  620.   if (!ChkArgCnt(3, 3));
  621.   else if (as_strcasecmp(ArgStr[1].str.p_str, "Y")) WrStrErrorPos(ErrNum_InvReg, &ArgStr[1]);
  622.   else if (as_strcasecmp(ArgStr[2].str.p_str, "X")) WrStrErrorPos(ErrNum_InvReg, &ArgStr[2]);
  623.   else if (as_strcasecmp(ArgStr[3].str.p_str, "U")) WrStrErrorPos(ErrNum_InvReg, &ArgStr[3]);
  624.   else
  625.     BAsmCode[CodeLen++] = code;
  626. }
  627.  
  628. /*!------------------------------------------------------------------------
  629.  * \fn     decode_bset(Word code)
  630.  * \brief  decode BSETx instruction
  631.  * \param  code machine code
  632.  * ------------------------------------------------------------------------ */
  633.  
  634. static void decode_bset(Word code)
  635. {
  636.   if (!ChkArgCnt(2, 2));
  637.   else if (as_strcasecmp(ArgStr[1].str.p_str, "X")) WrStrErrorPos(ErrNum_InvReg, &ArgStr[1]);
  638.   else if (as_strcasecmp(ArgStr[2].str.p_str, "U")) WrStrErrorPos(ErrNum_InvReg, &ArgStr[2]);
  639.   else
  640.     BAsmCode[CodeLen++] = code;
  641. }
  642.  
  643. /*!------------------------------------------------------------------------
  644.  * \fn     decode_exg_tfr(Word code)
  645.  * \brief  decode EXG/TFR instruction
  646.  * \param  code machine code
  647.  * ------------------------------------------------------------------------ */
  648.  
  649. static void decode_exg_tfr(Word code)
  650. {
  651.   DecodeTFR_TFM_EXG_6809(code, False, decode_cpu_reg, True);
  652. }
  653.  
  654. /*!------------------------------------------------------------------------
  655.  * \fn     decode_dec(Word code)
  656.  * \brief  handle DEC instruction
  657.  * \param  code machine code
  658.  * ------------------------------------------------------------------------ */
  659.  
  660. static void decode_dec(Word code)
  661. {
  662.   switch (ArgCnt)
  663.   {
  664.     case 3:
  665.       if (as_strcasecmp(ArgStr[2].str.p_str, "JNZ")) WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[2]);
  666.       else if (!as_strcasecmp(ArgStr[1].str.p_str, "B"))
  667.         decode_branch_8_core(3, code);
  668.       else if (!as_strcasecmp(ArgStr[1].str.p_str, "X"))
  669.         decode_branch_8_core(3, code + 1);
  670.       else
  671.         WrStrErrorPos(ErrNum_InvReg, &ArgStr[1]);
  672.       break;
  673.     case 2:
  674.       decode_idx(0x8e);
  675.       break;
  676.     default:
  677.       (void)ChkArgCnt(2, 3);
  678.   }
  679. }
  680.  
  681. /*!------------------------------------------------------------------------
  682.  * \fn     init_fields(void)
  683.  * \brief  create hash table
  684.  * ------------------------------------------------------------------------ */
  685.  
  686. static void add_acc_idx(const char *p_name, Word code)
  687. {
  688.   char name[10];
  689.  
  690.   as_snprintf(name, sizeof(name), "%sA", p_name);
  691.   AddInstTable(InstTable, name , code + 0, decode_inh);
  692.   as_snprintf(name, sizeof(name), "%sB", p_name);
  693.   AddInstTable(InstTable, name , code + 1, decode_inh);
  694.   AddInstTable(InstTable, p_name, code + 2, decode_idx);
  695. }
  696.  
  697. static void add_acc_idx_16(const char *p_name, Word code)
  698. {
  699.   char name[10];
  700.  
  701.   as_snprintf(name, sizeof(name), "%sD", p_name);
  702.   AddInstTable(InstTable, name, code + 0, decode_inh);
  703.   as_snprintf(name, sizeof(name), "%sW", p_name);
  704.   AddInstTable(InstTable, name, code + 1, decode_idx);
  705. }
  706.  
  707. static void add_reg_16(const char *p_name, Word code, Word code_incr, InstProc proc)
  708. {
  709.   char name[10];
  710.   size_t z;
  711.  
  712.   for (z = 0; z < as_array_size(reg_16_names); z++)
  713.   {
  714.     as_snprintf(name, sizeof(name), "%s%c", p_name, reg_16_names[z]);
  715.     AddInstTable(InstTable, name, code + (z * code_incr), proc);
  716.   }
  717. }
  718.  
  719. static void add_reg_stack(const char *p_name, Word code, InstProc proc)
  720. {
  721.   char name[10];
  722.   size_t z;
  723.  
  724.   for (z = 2; z < as_array_size(reg_16_names); z++)
  725.   {
  726.     as_snprintf(name, sizeof(name), "%s%c", p_name, reg_16_names[z]);
  727.     AddInstTable(InstTable, name, code + (3 - z), proc);
  728.   }
  729. }
  730.  
  731. static void add_ari_8(const char *p_name, Word code)
  732. {
  733.   char name[10];
  734.  
  735.   as_snprintf(name, sizeof(name), "%sA", p_name);
  736.   AddInstTable(InstTable, name, 0x0200 | code, decode_ari);
  737.   as_snprintf(name, sizeof(name), "%sB", p_name);
  738.   AddInstTable(InstTable, name, 0x0200 | (code + 1), decode_ari);
  739. }
  740.  
  741. static void add_branch(const char *p_name, Word code)
  742. {
  743.   char name[10];
  744.  
  745.   AddInstTable(InstTable, p_name, code, decode_branch_8);
  746.   as_snprintf(name, sizeof(name), "L%s", p_name);
  747.   AddInstTable(InstTable, name, code + 8, decode_branch_16);
  748. }
  749.  
  750. static void init_fields(void)
  751. {
  752.   InstTable = CreateInstTable(207);
  753.   SetDynamicInstTable(InstTable);
  754.  
  755.   add_null_pseudo(InstTable);
  756.  
  757.   add_reg_16("LEA", 0x08, 1, decode_idx);
  758.   add_reg_stack("PSH", 0x0c, DecodeStack_6809);
  759.   add_reg_stack("PUL", 0x0e, DecodeStack_6809);
  760.   add_ari_8("LD"  , 0x10);
  761.   add_ari_8("ADD" , 0x14);
  762.   add_ari_8("ADC" , 0x18);
  763.   add_ari_8("SUB" , 0x1c);
  764.   add_ari_8("SBC" , 0x20);
  765.   add_ari_8("AND" , 0x24);
  766.   add_ari_8("BIT" , 0x28);
  767.   add_ari_8("EOR" , 0x2c);
  768.   add_ari_8("OR"  , 0x30);
  769.   add_ari_8("CMP" , 0x34);
  770.   AddInstTable(InstTable, "SETLINES", 0x0138, decode_ari);
  771.   AddInstTable(InstTable, "STA", 0x3a, decode_idx);
  772.   AddInstTable(InstTable, "STB", 0x3b, decode_idx);
  773.   AddInstTable(InstTable, "ANDCC", 0x3c, decode_imm_8);
  774.   AddInstTable(InstTable, "ORCC", 0x3d, decode_imm_8);
  775.   AddInstTable(InstTable, "EXG", 0x3e, decode_exg_tfr);
  776.   AddInstTable(InstTable, "TFR", 0x3f, decode_exg_tfr);
  777.   AddInstTable(InstTable, "LDD", 0x8140, decode_ari);
  778.   add_reg_16("LD", 0x8142, 2, decode_ari);
  779.   AddInstTable(InstTable, "CMPD", 0x814a, decode_ari);
  780.   add_reg_16("CMP", 0x814c, 2, decode_ari);
  781.   AddInstTable(InstTable, "ADDD", 0x8154, decode_ari);
  782.   AddInstTable(InstTable, "SUBD", 0x8156, decode_ari);
  783.   AddInstTable(InstTable, "STD", 0x58, decode_ari);
  784.         add_branch("BRA", 0x60);
  785.   add_branch("BHI", 0x61);
  786.   add_branch("BCC", 0x62);
  787.   add_branch("BNE", 0x63);
  788.   add_branch("BVC", 0x64);
  789.   add_branch("BPL", 0x65);
  790.   add_branch("BGE", 0x66);
  791.   add_branch("BGT", 0x67);
  792.   add_branch("BRN", 0x70);
  793.   add_branch("BLS", 0x71);
  794.   add_branch("BCS", 0x72);
  795.   add_branch("BEQ", 0x73);
  796.   add_branch("BVS", 0x74);
  797.   add_branch("BMI", 0x75);
  798.   add_branch("BLT", 0x76);
  799.   add_branch("BLE", 0x77);
  800.   add_reg_16("ST", 0x59, 1, decode_ari);
  801.   add_acc_idx("CLR" , 0x80);
  802.   add_acc_idx("COM" , 0x83);
  803.   add_acc_idx("NEG" , 0x86);
  804.   add_acc_idx("INC" , 0x89);
  805.   AddInstTable(InstTable, "DECA" , 0x8c + 0, decode_inh);
  806.   AddInstTable(InstTable, "DECB" , 0x8c + 1, decode_inh);
  807.   AddInstTable(InstTable, "RTS", 0x8f, decode_inh);
  808.   add_acc_idx("TST" , 0x90);
  809.   add_acc_idx("LSR" , 0x93);
  810.   add_acc_idx("ROR" , 0x96);
  811.   add_acc_idx("ASR" , 0x99);
  812.   add_acc_idx("ASL" , 0x9c);
  813.   AddInstTable(InstTable, "RTI", 0x9f, decode_inh);
  814.   add_acc_idx("ROL" , 0xa0);
  815.   AddInstTable(InstTable, "LSRW", 0xa3, decode_idx);
  816.   AddInstTable(InstTable, "RORW", 0xa4, decode_idx);
  817.   AddInstTable(InstTable, "ASRW", 0xa5, decode_idx);
  818.   AddInstTable(InstTable, "ASLW", 0xa6, decode_idx);
  819.   AddInstTable(InstTable, "ROLW", 0xa7, decode_idx);
  820.   AddInstTable(InstTable, "JMP", 0xa8, decode_idx);
  821.   AddInstTable(InstTable, "JSR", 0xa9, decode_idx);
  822.   AddInstTable(InstTable, "BSR" , 0xaa, decode_branch_8);
  823.   AddInstTable(InstTable, "LBSR" , 0xab, decode_branch_16);
  824.   AddInstTable(InstTable, "DEC" , 0xac, decode_dec);
  825.   AddInstTable(InstTable, "NOP" , NOPCode, decode_inh);
  826.   AddInstTable(InstTable, "ABX" , 0xb0, decode_inh);
  827.   AddInstTable(InstTable, "DAA" , 0xb1, decode_inh);
  828.   AddInstTable(InstTable, "SEX" , 0xb2, decode_inh);
  829.   AddInstTable(InstTable, "MUL" , 0xb3, decode_inh);
  830.   AddInstTable(InstTable, "LMUL", 0xb4, decode_inh);
  831.   AddInstTable(InstTable, "DIV" , 0xb5, decode_div);
  832.   AddInstTable(InstTable, "BMOVE", 0xb6, decode_move);
  833.   AddInstTable(InstTable, "MOVE", 0xb7, decode_move);
  834.   AddInstTable(InstTable, "LSRD", 0x01b8, decode_ari);
  835.   AddInstTable(InstTable, "RORD", 0x01ba, decode_ari);
  836.   AddInstTable(InstTable, "ASRD", 0x01bc, decode_ari);
  837.   AddInstTable(InstTable, "ASLD", 0x01be, decode_ari);
  838.   AddInstTable(InstTable, "ROLD", 0x01c0, decode_ari);
  839.   add_acc_idx_16("CLR", 0xc2);
  840.   add_acc_idx_16("NEG", 0xc4);
  841.   add_acc_idx_16("INC", 0xc6);
  842.   add_acc_idx_16("DEC", 0xc8);
  843.   add_acc_idx_16("TST", 0xca);
  844.   AddInstTable(InstTable, "ABSA" , 0xcc, decode_inh);
  845.   AddInstTable(InstTable, "ABSB" , 0xcd, decode_inh);
  846.   AddInstTable(InstTable, "ABSD" , 0xce, decode_inh);
  847.   AddInstTable(InstTable, "BSETA", 0xcf, decode_bset);
  848.   AddInstTable(InstTable, "BSETD", 0xd0, decode_bset);
  849.  
  850.   add_moto8_pseudo(InstTable, e_moto_pseudo_flags_be);
  851.   AddMoto16Pseudo(InstTable, e_moto_pseudo_flags_be);
  852.   AddInstTable(InstTable, "DB", eIntPseudoFlag_BigEndian | eIntPseudoFlag_AllowInt | eIntPseudoFlag_AllowString | eIntPseudoFlag_MotoRep, DecodeIntelDB);
  853.   AddInstTable(InstTable, "DW", eIntPseudoFlag_BigEndian | eIntPseudoFlag_AllowInt | eIntPseudoFlag_AllowString | eIntPseudoFlag_MotoRep, DecodeIntelDW);
  854. }
  855.  
  856. /*!------------------------------------------------------------------------
  857.  * \fn     deinit_fields(void)
  858.  * \brief  destroy hash table
  859.  * ------------------------------------------------------------------------ */
  860.  
  861. static void deinit_fields(void)
  862. {
  863.   DestroyInstTable(InstTable);
  864. }
  865.  
  866. /*!------------------------------------------------------------------------
  867.  * \fn     decode_attr_part_ko09(void)
  868.  * \brief  parse attribute part
  869.  * ------------------------------------------------------------------------ */
  870.  
  871. static Boolean decode_attr_part_ko09(void)
  872. {
  873.   if (strlen(AttrPart.str.p_str) > 1)
  874.   {
  875.     WrStrErrorPos(ErrNum_UndefAttr, &AttrPart);
  876.     return False;
  877.   }
  878.  
  879.   /* Deduce operand size.  No size is zero-length string -> '\0' */
  880.  
  881.   return DecodeMoto16AttrSize(*AttrPart.str.p_str, &AttrPartOpSize[0], False);
  882. }
  883.  
  884. /*!------------------------------------------------------------------------
  885.  * \fn     make_code_ko09(void)
  886.  * \brief  handle machine instructions
  887.  * ------------------------------------------------------------------------ */
  888.  
  889. static void make_code_ko09(void)
  890. {
  891.   if (AttrPartOpSize[0] == eSymbolSizeUnknown)
  892.     AttrPartOpSize[0] = eSymbolSize8Bit;
  893.  
  894.   if (!LookupInstTable(InstTable, OpPart.str.p_str))
  895.     WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
  896. }
  897.  
  898. /*!------------------------------------------------------------------------
  899.  * \fn     is_def_ko09(void)
  900.  * \brief  label part consumed by instruction?
  901.  * ------------------------------------------------------------------------ */
  902.  
  903. static Boolean is_def_ko09(void)
  904. {
  905.   return False;
  906. }
  907.  
  908. /*!------------------------------------------------------------------------
  909.  * \fn     switch_to_ko09(void)
  910.  * \brief  switch to target
  911.  * ------------------------------------------------------------------------ */
  912.  
  913. static void switch_to_ko09(void)
  914. {
  915.   const TFamilyDescr *p_descr = FindFamilyByName("052001");
  916.   static const ASSUMERec ASSUME09s[] =
  917.   {
  918.     { "DPR", &DPRValue, 0, 0xff, 0x100, NULL }
  919.   };
  920.  
  921.   TurnWords = False;
  922.   SetIntConstMode(eIntConstModeMoto);
  923.  
  924.   PCSymbol = "*";
  925.   HeaderID = p_descr->Id;
  926.   NOPCode = 0xae;
  927.   DivideChars = ",";
  928.   HasAttrs = True;
  929.   AttrChars = ".";
  930.  
  931.   ValidSegs = (1 << SegCode);
  932.   Grans[SegCode] = 1; ListGrans[SegCode] = 1; SegInits[SegCode] = 0;
  933.   SegLimits[SegCode] = 0xffff;
  934.  
  935.   DecodeAttrPart = decode_attr_part_ko09;
  936.   MakeCode = make_code_ko09;
  937.   IsDef = is_def_ko09;
  938.  
  939.   SwitchFrom = deinit_fields;
  940.   init_fields();
  941.   AddMoto16PseudoONOFF(False);
  942.  
  943.   pASSUMERecs = ASSUME09s;
  944.   ASSUMERecCnt = as_array_size(ASSUME09s);
  945. }
  946.  
  947. /*!------------------------------------------------------------------------
  948.  * \fn     codeko09_init(void)
  949.  * \brief  attach target
  950.  * ------------------------------------------------------------------------ */
  951.  
  952. void codeko09_init(void)
  953. {
  954.   (void)AddCPU("052001", switch_to_ko09);
  955. }
  956.