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