OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [opcodes/] [m68hc11-dis.c] - Diff between revs 578 and 1765

Only display areas with differences | Details | Blame | View Log

Rev 578 Rev 1765
/* m68hc11-dis.c -- Motorola 68HC11 & 68HC12 disassembly
/* m68hc11-dis.c -- Motorola 68HC11 & 68HC12 disassembly
   Copyright 1999, 2000 Free Software Foundation, Inc.
   Copyright 1999, 2000 Free Software Foundation, Inc.
   Written by Stephane Carrez (stcarrez@worldnet.fr)
   Written by Stephane Carrez (stcarrez@worldnet.fr)
 
 
This program is free software; you can redistribute it and/or modify
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
(at your option) any later version.
 
 
This program is distributed in the hope that it will be useful,
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
GNU General Public License for more details.
 
 
You should have received a copy of the GNU General Public License
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 
#include <stdio.h>
#include <stdio.h>
 
 
#include "ansidecl.h"
#include "ansidecl.h"
#include "opcode/m68hc11.h"
#include "opcode/m68hc11.h"
#include "dis-asm.h"
#include "dis-asm.h"
 
 
static const char *const reg_name[] = {
static const char *const reg_name[] = {
  "X", "Y", "SP", "PC"
  "X", "Y", "SP", "PC"
};
};
 
 
static const char *const reg_src_table[] = {
static const char *const reg_src_table[] = {
  "A", "B", "CCR", "TMP3", "D", "X", "Y", "SP"
  "A", "B", "CCR", "TMP3", "D", "X", "Y", "SP"
};
};
 
 
static const char *const reg_dst_table[] = {
static const char *const reg_dst_table[] = {
  "A", "B", "CCR", "TMP2", "D", "X", "Y", "SP"
  "A", "B", "CCR", "TMP2", "D", "X", "Y", "SP"
};
};
 
 
#define OP_PAGE_MASK (M6811_OP_PAGE2|M6811_OP_PAGE3|M6811_OP_PAGE4)
#define OP_PAGE_MASK (M6811_OP_PAGE2|M6811_OP_PAGE3|M6811_OP_PAGE4)
 
 
static int
static int
read_memory (memaddr, buffer, size, info)
read_memory (memaddr, buffer, size, info)
     bfd_vma memaddr;
     bfd_vma memaddr;
     bfd_byte *buffer;
     bfd_byte *buffer;
     int size;
     int size;
     struct disassemble_info *info;
     struct disassemble_info *info;
{
{
  int status;
  int status;
 
 
  /* Get first byte.  Only one at a time because we don't know the
  /* Get first byte.  Only one at a time because we don't know the
     size of the insn.  */
     size of the insn.  */
  status = (*info->read_memory_func) (memaddr, buffer, size, info);
  status = (*info->read_memory_func) (memaddr, buffer, size, info);
  if (status != 0)
  if (status != 0)
    {
    {
      (*info->memory_error_func) (status, memaddr, info);
      (*info->memory_error_func) (status, memaddr, info);
      return -1;
      return -1;
    }
    }
  return 0;
  return 0;
}
}
 
 
 
 
/* Read the 68HC12 indexed operand byte and print the corresponding mode.
/* Read the 68HC12 indexed operand byte and print the corresponding mode.
   Returns the number of bytes read or -1 if failure.  */
   Returns the number of bytes read or -1 if failure.  */
static int
static int
print_indexed_operand (memaddr, info, mov_insn)
print_indexed_operand (memaddr, info, mov_insn)
     bfd_vma memaddr;
     bfd_vma memaddr;
     struct disassemble_info *info;
     struct disassemble_info *info;
     int mov_insn;
     int mov_insn;
{
{
  bfd_byte buffer[4];
  bfd_byte buffer[4];
  int reg;
  int reg;
  int status;
  int status;
  short sval;
  short sval;
  int pos = 1;
  int pos = 1;
 
 
  status = read_memory (memaddr, &buffer[0], 1, info);
  status = read_memory (memaddr, &buffer[0], 1, info);
  if (status != 0)
  if (status != 0)
    {
    {
      return status;
      return status;
    }
    }
 
 
  /* n,r with 5-bits signed constant.  */
  /* n,r with 5-bits signed constant.  */
  if ((buffer[0] & 0x20) == 0)
  if ((buffer[0] & 0x20) == 0)
    {
    {
      reg = (buffer[0] >> 6) & 3;
      reg = (buffer[0] >> 6) & 3;
      sval = (buffer[0] & 0x1f);
      sval = (buffer[0] & 0x1f);
      if (sval & 0x10)
      if (sval & 0x10)
        sval |= 0xfff0;
        sval |= 0xfff0;
      (*info->fprintf_func) (info->stream, "%d,%s",
      (*info->fprintf_func) (info->stream, "%d,%s",
                             (int) sval, reg_name[reg]);
                             (int) sval, reg_name[reg]);
    }
    }
 
 
  /* Auto pre/post increment/decrement.  */
  /* Auto pre/post increment/decrement.  */
  else if ((buffer[0] & 0xc0) != 0xc0)
  else if ((buffer[0] & 0xc0) != 0xc0)
    {
    {
      const char *mode;
      const char *mode;
 
 
      reg = (buffer[0] >> 6) & 3;
      reg = (buffer[0] >> 6) & 3;
      sval = (buffer[0] & 0x0f);
      sval = (buffer[0] & 0x0f);
      if (sval & 0x8)
      if (sval & 0x8)
        {
        {
          sval |= 0xfff0;
          sval |= 0xfff0;
          sval = -sval;
          sval = -sval;
          mode = "-";
          mode = "-";
        }
        }
      else
      else
        {
        {
          sval = sval + 1;
          sval = sval + 1;
          mode = "+";
          mode = "+";
        }
        }
      (*info->fprintf_func) (info->stream, "%d,%s%s%s",
      (*info->fprintf_func) (info->stream, "%d,%s%s%s",
                             (int) sval,
                             (int) sval,
                             (buffer[0] & 0x10 ? "" : mode),
                             (buffer[0] & 0x10 ? "" : mode),
                             reg_name[reg], (buffer[0] & 0x10 ? mode : ""));
                             reg_name[reg], (buffer[0] & 0x10 ? mode : ""));
    }
    }
 
 
  /* [n,r] 16-bits offset indexed indirect.  */
  /* [n,r] 16-bits offset indexed indirect.  */
  else if ((buffer[0] & 0x07) == 3)
  else if ((buffer[0] & 0x07) == 3)
    {
    {
      if (mov_insn)
      if (mov_insn)
        {
        {
          (*info->fprintf_func) (info->stream, "<invalid op: 0x%x>",
          (*info->fprintf_func) (info->stream, "<invalid op: 0x%x>",
                                 buffer[0] & 0x0ff);
                                 buffer[0] & 0x0ff);
          return 0;
          return 0;
        }
        }
      reg = (buffer[0] >> 3) & 0x03;
      reg = (buffer[0] >> 3) & 0x03;
      status = read_memory (memaddr + pos, &buffer[0], 2, info);
      status = read_memory (memaddr + pos, &buffer[0], 2, info);
      if (status != 0)
      if (status != 0)
        {
        {
          return status;
          return status;
        }
        }
 
 
      pos += 2;
      pos += 2;
      sval = ((buffer[0] << 8) | (buffer[1] & 0x0FF));
      sval = ((buffer[0] << 8) | (buffer[1] & 0x0FF));
      (*info->fprintf_func) (info->stream, "[%u,%s]",
      (*info->fprintf_func) (info->stream, "[%u,%s]",
                             sval & 0x0ffff, reg_name[reg]);
                             sval & 0x0ffff, reg_name[reg]);
    }
    }
  else if ((buffer[0] & 0x4) == 0)
  else if ((buffer[0] & 0x4) == 0)
    {
    {
      if (mov_insn)
      if (mov_insn)
        {
        {
          (*info->fprintf_func) (info->stream, "<invalid op: 0x%x>",
          (*info->fprintf_func) (info->stream, "<invalid op: 0x%x>",
                                 buffer[0] & 0x0ff);
                                 buffer[0] & 0x0ff);
          return 0;
          return 0;
        }
        }
      reg = (buffer[0] >> 3) & 0x03;
      reg = (buffer[0] >> 3) & 0x03;
      status = read_memory (memaddr + pos,
      status = read_memory (memaddr + pos,
                            &buffer[1], (buffer[0] & 0x2 ? 2 : 1), info);
                            &buffer[1], (buffer[0] & 0x2 ? 2 : 1), info);
      if (status != 0)
      if (status != 0)
        {
        {
          return status;
          return status;
        }
        }
      if (buffer[0] & 2)
      if (buffer[0] & 2)
        {
        {
          sval = ((buffer[1] << 8) | (buffer[2] & 0x0FF));
          sval = ((buffer[1] << 8) | (buffer[2] & 0x0FF));
          sval &= 0x0FFFF;
          sval &= 0x0FFFF;
          pos += 2;
          pos += 2;
        }
        }
      else
      else
        {
        {
          sval = buffer[1] & 0x00ff;
          sval = buffer[1] & 0x00ff;
          if (buffer[0] & 0x01)
          if (buffer[0] & 0x01)
            sval |= 0xff00;
            sval |= 0xff00;
          pos++;
          pos++;
        }
        }
      (*info->fprintf_func) (info->stream, "%d,%s",
      (*info->fprintf_func) (info->stream, "%d,%s",
                             (int) sval, reg_name[reg]);
                             (int) sval, reg_name[reg]);
    }
    }
  else
  else
    {
    {
      reg = (buffer[0] >> 3) & 0x03;
      reg = (buffer[0] >> 3) & 0x03;
      switch (buffer[0] & 3)
      switch (buffer[0] & 3)
        {
        {
        case 0:
        case 0:
          (*info->fprintf_func) (info->stream, "A,%s", reg_name[reg]);
          (*info->fprintf_func) (info->stream, "A,%s", reg_name[reg]);
          break;
          break;
        case 1:
        case 1:
          (*info->fprintf_func) (info->stream, "B,%s", reg_name[reg]);
          (*info->fprintf_func) (info->stream, "B,%s", reg_name[reg]);
          break;
          break;
        case 2:
        case 2:
          (*info->fprintf_func) (info->stream, "D,%s", reg_name[reg]);
          (*info->fprintf_func) (info->stream, "D,%s", reg_name[reg]);
          break;
          break;
        case 3:
        case 3:
        default:
        default:
          (*info->fprintf_func) (info->stream, "[D,%s]", reg_name[reg]);
          (*info->fprintf_func) (info->stream, "[D,%s]", reg_name[reg]);
          break;
          break;
        }
        }
    }
    }
 
 
  return pos;
  return pos;
}
}
 
 
/* Disassemble one instruction at address 'memaddr'.  Returns the number
/* Disassemble one instruction at address 'memaddr'.  Returns the number
   of bytes used by that instruction.  */
   of bytes used by that instruction.  */
static int
static int
print_insn (memaddr, info, arch)
print_insn (memaddr, info, arch)
     bfd_vma memaddr;
     bfd_vma memaddr;
     struct disassemble_info *info;
     struct disassemble_info *info;
     int arch;
     int arch;
{
{
  int status;
  int status;
  bfd_byte buffer[4];
  bfd_byte buffer[4];
  unsigned char code;
  unsigned char code;
  long format, pos, i;
  long format, pos, i;
  short sval;
  short sval;
  const struct m68hc11_opcode *opcode;
  const struct m68hc11_opcode *opcode;
 
 
  /* Get first byte.  Only one at a time because we don't know the
  /* Get first byte.  Only one at a time because we don't know the
     size of the insn.  */
     size of the insn.  */
  status = read_memory (memaddr, buffer, 1, info);
  status = read_memory (memaddr, buffer, 1, info);
  if (status != 0)
  if (status != 0)
    {
    {
      return status;
      return status;
    }
    }
 
 
  format = 0;
  format = 0;
  code = buffer[0];
  code = buffer[0];
  pos = 0;
  pos = 0;
 
 
  /* Look for page2,3,4 opcodes.  */
  /* Look for page2,3,4 opcodes.  */
  if (code == M6811_OPCODE_PAGE2)
  if (code == M6811_OPCODE_PAGE2)
    {
    {
      pos++;
      pos++;
      format = M6811_OP_PAGE2;
      format = M6811_OP_PAGE2;
    }
    }
  else if (code == M6811_OPCODE_PAGE3 && arch == cpu6811)
  else if (code == M6811_OPCODE_PAGE3 && arch == cpu6811)
    {
    {
      pos++;
      pos++;
      format = M6811_OP_PAGE3;
      format = M6811_OP_PAGE3;
    }
    }
  else if (code == M6811_OPCODE_PAGE4 && arch == cpu6811)
  else if (code == M6811_OPCODE_PAGE4 && arch == cpu6811)
    {
    {
      pos++;
      pos++;
      format = M6811_OP_PAGE4;
      format = M6811_OP_PAGE4;
    }
    }
 
 
  /* We are in page2,3,4; get the real opcode.  */
  /* We are in page2,3,4; get the real opcode.  */
  if (pos == 1)
  if (pos == 1)
    {
    {
      status = read_memory (memaddr + pos, &buffer[1], 1, info);
      status = read_memory (memaddr + pos, &buffer[1], 1, info);
      if (status != 0)
      if (status != 0)
        {
        {
          return status;
          return status;
        }
        }
      code = buffer[1];
      code = buffer[1];
    }
    }
 
 
 
 
  /* Look first for a 68HC12 alias.  All of them are 2-bytes long and
  /* Look first for a 68HC12 alias.  All of them are 2-bytes long and
     in page 1.  There is no operand to print.  We read the second byte
     in page 1.  There is no operand to print.  We read the second byte
     only when we have a possible match.  */
     only when we have a possible match.  */
  if ((arch & cpu6812) && format == 0)
  if ((arch & cpu6812) && format == 0)
    {
    {
      int must_read = 1;
      int must_read = 1;
 
 
      /* Walk the alias table to find a code1+code2 match.  */
      /* Walk the alias table to find a code1+code2 match.  */
      for (i = 0; i < m68hc12_num_alias; i++)
      for (i = 0; i < m68hc12_num_alias; i++)
        {
        {
          if (m68hc12_alias[i].code1 == code)
          if (m68hc12_alias[i].code1 == code)
            {
            {
              if (must_read)
              if (must_read)
                {
                {
                  status = read_memory (memaddr + pos + 1,
                  status = read_memory (memaddr + pos + 1,
                                        &buffer[1], 1, info);
                                        &buffer[1], 1, info);
                  if (status != 0)
                  if (status != 0)
                    break;
                    break;
 
 
                  must_read = 1;
                  must_read = 1;
                }
                }
              if (m68hc12_alias[i].code2 == (unsigned char) buffer[1])
              if (m68hc12_alias[i].code2 == (unsigned char) buffer[1])
                {
                {
                  (*info->fprintf_func) (info->stream, "%s",
                  (*info->fprintf_func) (info->stream, "%s",
                                         m68hc12_alias[i].name);
                                         m68hc12_alias[i].name);
                  return 2;
                  return 2;
                }
                }
            }
            }
        }
        }
    }
    }
 
 
  pos++;
  pos++;
 
 
  /* Scan the opcode table until we find the opcode
  /* Scan the opcode table until we find the opcode
     with the corresponding page.  */
     with the corresponding page.  */
  opcode = m68hc11_opcodes;
  opcode = m68hc11_opcodes;
  for (i = 0; i < m68hc11_num_opcodes; i++, opcode++)
  for (i = 0; i < m68hc11_num_opcodes; i++, opcode++)
    {
    {
      int offset;
      int offset;
 
 
      if ((opcode->arch & arch) == 0)
      if ((opcode->arch & arch) == 0)
        continue;
        continue;
      if (opcode->opcode != code)
      if (opcode->opcode != code)
        continue;
        continue;
      if ((opcode->format & OP_PAGE_MASK) != format)
      if ((opcode->format & OP_PAGE_MASK) != format)
        continue;
        continue;
 
 
      if (opcode->format & M6812_OP_REG)
      if (opcode->format & M6812_OP_REG)
        {
        {
          int j;
          int j;
          int is_jump;
          int is_jump;
 
 
          if (opcode->format & M6811_OP_JUMP_REL)
          if (opcode->format & M6811_OP_JUMP_REL)
            is_jump = 1;
            is_jump = 1;
          else
          else
            is_jump = 0;
            is_jump = 0;
 
 
          status = read_memory (memaddr + pos, &buffer[0], 1, info);
          status = read_memory (memaddr + pos, &buffer[0], 1, info);
          if (status != 0)
          if (status != 0)
            {
            {
              return status;
              return status;
            }
            }
          for (j = 0; i + j < m68hc11_num_opcodes; j++)
          for (j = 0; i + j < m68hc11_num_opcodes; j++)
            {
            {
              if ((opcode[j].arch & arch) == 0)
              if ((opcode[j].arch & arch) == 0)
                continue;
                continue;
              if (opcode[j].opcode != code)
              if (opcode[j].opcode != code)
                continue;
                continue;
              if (is_jump)
              if (is_jump)
                {
                {
                  if (!(opcode[j].format & M6811_OP_JUMP_REL))
                  if (!(opcode[j].format & M6811_OP_JUMP_REL))
                    continue;
                    continue;
 
 
                  if ((opcode[j].format & M6812_OP_IBCC_MARKER)
                  if ((opcode[j].format & M6812_OP_IBCC_MARKER)
                      && (buffer[0] & 0xc0) != 0x80)
                      && (buffer[0] & 0xc0) != 0x80)
                    continue;
                    continue;
                  if ((opcode[j].format & M6812_OP_TBCC_MARKER)
                  if ((opcode[j].format & M6812_OP_TBCC_MARKER)
                      && (buffer[0] & 0xc0) != 0x40)
                      && (buffer[0] & 0xc0) != 0x40)
                    continue;
                    continue;
                  if ((opcode[j].format & M6812_OP_DBCC_MARKER)
                  if ((opcode[j].format & M6812_OP_DBCC_MARKER)
                      && (buffer[0] & 0xc0) != 0)
                      && (buffer[0] & 0xc0) != 0)
                    continue;
                    continue;
                  if ((opcode[j].format & M6812_OP_EQ_MARKER)
                  if ((opcode[j].format & M6812_OP_EQ_MARKER)
                      && (buffer[0] & 0x20) == 0)
                      && (buffer[0] & 0x20) == 0)
                    break;
                    break;
                  if (!(opcode[j].format & M6812_OP_EQ_MARKER)
                  if (!(opcode[j].format & M6812_OP_EQ_MARKER)
                      && (buffer[0] & 0x20) != 0)
                      && (buffer[0] & 0x20) != 0)
                    break;
                    break;
                  continue;
                  continue;
                }
                }
              if (opcode[j].format & M6812_OP_EXG_MARKER && buffer[0] & 0x80)
              if (opcode[j].format & M6812_OP_EXG_MARKER && buffer[0] & 0x80)
                break;
                break;
              if ((opcode[j].format & M6812_OP_SEX_MARKER)
              if ((opcode[j].format & M6812_OP_SEX_MARKER)
                  && (((buffer[0] & 0x07) >= 3 && (buffer[0] & 7) <= 7))
                  && (((buffer[0] & 0x07) >= 3 && (buffer[0] & 7) <= 7))
                  && ((buffer[0] & 0x0f0) <= 0x20))
                  && ((buffer[0] & 0x0f0) <= 0x20))
                break;
                break;
              if (opcode[j].format & M6812_OP_TFR_MARKER
              if (opcode[j].format & M6812_OP_TFR_MARKER
                  && !(buffer[0] & 0x80))
                  && !(buffer[0] & 0x80))
                break;
                break;
            }
            }
          if (i + j < m68hc11_num_opcodes)
          if (i + j < m68hc11_num_opcodes)
            opcode = &opcode[j];
            opcode = &opcode[j];
        }
        }
 
 
      /* We have found the opcode.  Extract the operand and print it.  */
      /* We have found the opcode.  Extract the operand and print it.  */
      (*info->fprintf_func) (info->stream, "%s", opcode->name);
      (*info->fprintf_func) (info->stream, "%s", opcode->name);
 
 
      format = opcode->format;
      format = opcode->format;
      if (format & (M6811_OP_MASK | M6811_OP_BITMASK
      if (format & (M6811_OP_MASK | M6811_OP_BITMASK
                    | M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
                    | M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
        {
        {
          (*info->fprintf_func) (info->stream, "\t");
          (*info->fprintf_func) (info->stream, "\t");
        }
        }
 
 
      /* The movb and movw must be handled in a special way...  */
      /* The movb and movw must be handled in a special way...  */
      offset = 0;
      offset = 0;
      if (format & (M6812_OP_IDX_P2 | M6812_OP_IND16_P2))
      if (format & (M6812_OP_IDX_P2 | M6812_OP_IND16_P2))
        {
        {
          if ((format & M6812_OP_IDX_P2)
          if ((format & M6812_OP_IDX_P2)
              && (format & (M6811_OP_IMM8 | M6811_OP_IMM16 | M6811_OP_IND16)))
              && (format & (M6811_OP_IMM8 | M6811_OP_IMM16 | M6811_OP_IND16)))
            offset = 1;
            offset = 1;
        }
        }
 
 
      /* Operand with one more byte: - immediate, offset,
      /* Operand with one more byte: - immediate, offset,
         direct-low address.  */
         direct-low address.  */
      if (format &
      if (format &
          (M6811_OP_IMM8 | M6811_OP_IX | M6811_OP_IY | M6811_OP_DIRECT))
          (M6811_OP_IMM8 | M6811_OP_IX | M6811_OP_IY | M6811_OP_DIRECT))
        {
        {
          status = read_memory (memaddr + pos + offset, &buffer[0], 1, info);
          status = read_memory (memaddr + pos + offset, &buffer[0], 1, info);
          if (status != 0)
          if (status != 0)
            {
            {
              return status;
              return status;
            }
            }
 
 
          pos++;
          pos++;
          offset = -1;
          offset = -1;
          if (format & M6811_OP_IMM8)
          if (format & M6811_OP_IMM8)
            {
            {
              (*info->fprintf_func) (info->stream, "#%d", (int) buffer[0]);
              (*info->fprintf_func) (info->stream, "#%d", (int) buffer[0]);
              format &= ~M6811_OP_IMM8;
              format &= ~M6811_OP_IMM8;
            }
            }
          else if (format & M6811_OP_IX)
          else if (format & M6811_OP_IX)
            {
            {
              /* Offsets are in range 0..255, print them unsigned.  */
              /* Offsets are in range 0..255, print them unsigned.  */
              (*info->fprintf_func) (info->stream, "%u,x", buffer[0] & 0x0FF);
              (*info->fprintf_func) (info->stream, "%u,x", buffer[0] & 0x0FF);
              format &= ~M6811_OP_IX;
              format &= ~M6811_OP_IX;
            }
            }
          else if (format & M6811_OP_IY)
          else if (format & M6811_OP_IY)
            {
            {
              (*info->fprintf_func) (info->stream, "%u,y", buffer[0] & 0x0FF);
              (*info->fprintf_func) (info->stream, "%u,y", buffer[0] & 0x0FF);
              format &= ~M6811_OP_IY;
              format &= ~M6811_OP_IY;
            }
            }
          else if (format & M6811_OP_DIRECT)
          else if (format & M6811_OP_DIRECT)
            {
            {
              (*info->fprintf_func) (info->stream, "*");
              (*info->fprintf_func) (info->stream, "*");
              (*info->print_address_func) (buffer[0] & 0x0FF, info);
              (*info->print_address_func) (buffer[0] & 0x0FF, info);
              format &= ~M6811_OP_DIRECT;
              format &= ~M6811_OP_DIRECT;
            }
            }
        }
        }
 
 
#define M6812_INDEXED_FLAGS (M6812_OP_IDX|M6812_OP_IDX_1|M6812_OP_IDX_2)
#define M6812_INDEXED_FLAGS (M6812_OP_IDX|M6812_OP_IDX_1|M6812_OP_IDX_2)
      /* Analyze the 68HC12 indexed byte.  */
      /* Analyze the 68HC12 indexed byte.  */
      if (format & M6812_INDEXED_FLAGS)
      if (format & M6812_INDEXED_FLAGS)
        {
        {
          status = print_indexed_operand (memaddr + pos, info, 0);
          status = print_indexed_operand (memaddr + pos, info, 0);
          if (status < 0)
          if (status < 0)
            {
            {
              return status;
              return status;
            }
            }
          pos += status;
          pos += status;
        }
        }
 
 
      /* 68HC12 dbcc/ibcc/tbcc operands.  */
      /* 68HC12 dbcc/ibcc/tbcc operands.  */
      if ((format & M6812_OP_REG) && (format & M6811_OP_JUMP_REL))
      if ((format & M6812_OP_REG) && (format & M6811_OP_JUMP_REL))
        {
        {
          status = read_memory (memaddr + pos, &buffer[0], 2, info);
          status = read_memory (memaddr + pos, &buffer[0], 2, info);
          if (status != 0)
          if (status != 0)
            {
            {
              return status;
              return status;
            }
            }
          (*info->fprintf_func) (info->stream, "%s,",
          (*info->fprintf_func) (info->stream, "%s,",
                                 reg_src_table[buffer[0] & 0x07]);
                                 reg_src_table[buffer[0] & 0x07]);
          sval = buffer[1] & 0x0ff;
          sval = buffer[1] & 0x0ff;
          if (buffer[0] & 0x10)
          if (buffer[0] & 0x10)
            sval |= 0xff00;
            sval |= 0xff00;
 
 
          pos += 2;
          pos += 2;
          (*info->print_address_func) (memaddr + pos + sval, info);
          (*info->print_address_func) (memaddr + pos + sval, info);
          format &= ~(M6812_OP_REG | M6811_OP_JUMP_REL);
          format &= ~(M6812_OP_REG | M6811_OP_JUMP_REL);
        }
        }
      else if (format & (M6812_OP_REG | M6812_OP_REG_2))
      else if (format & (M6812_OP_REG | M6812_OP_REG_2))
        {
        {
          status = read_memory (memaddr + pos, &buffer[0], 1, info);
          status = read_memory (memaddr + pos, &buffer[0], 1, info);
          if (status != 0)
          if (status != 0)
            {
            {
              return status;
              return status;
            }
            }
 
 
          pos++;
          pos++;
          (*info->fprintf_func) (info->stream, "%s,%s",
          (*info->fprintf_func) (info->stream, "%s,%s",
                                 reg_src_table[(buffer[0] >> 4) & 7],
                                 reg_src_table[(buffer[0] >> 4) & 7],
                                 reg_dst_table[(buffer[0] & 7)]);
                                 reg_dst_table[(buffer[0] & 7)]);
        }
        }
 
 
      /* M6811_OP_BITMASK and M6811_OP_JUMP_REL must be treated separately
      /* M6811_OP_BITMASK and M6811_OP_JUMP_REL must be treated separately
         and in that order.  The brset/brclr insn have a bitmask and then
         and in that order.  The brset/brclr insn have a bitmask and then
         a relative branch offset.  */
         a relative branch offset.  */
      if (format & M6811_OP_BITMASK)
      if (format & M6811_OP_BITMASK)
        {
        {
          status = read_memory (memaddr + pos, &buffer[0], 1, info);
          status = read_memory (memaddr + pos, &buffer[0], 1, info);
          if (status != 0)
          if (status != 0)
            {
            {
              return status;
              return status;
            }
            }
          pos++;
          pos++;
          (*info->fprintf_func) (info->stream, " #$%02x%s",
          (*info->fprintf_func) (info->stream, " #$%02x%s",
                                 buffer[0] & 0x0FF,
                                 buffer[0] & 0x0FF,
                                 (format & M6811_OP_JUMP_REL ? " " : ""));
                                 (format & M6811_OP_JUMP_REL ? " " : ""));
          format &= ~M6811_OP_BITMASK;
          format &= ~M6811_OP_BITMASK;
        }
        }
      if (format & M6811_OP_JUMP_REL)
      if (format & M6811_OP_JUMP_REL)
        {
        {
          int val;
          int val;
 
 
          status = read_memory (memaddr + pos, &buffer[0], 1, info);
          status = read_memory (memaddr + pos, &buffer[0], 1, info);
          if (status != 0)
          if (status != 0)
            {
            {
              return status;
              return status;
            }
            }
 
 
          pos++;
          pos++;
          val = (buffer[0] & 0x80) ? buffer[0] | 0xFFFFFF00 : buffer[0];
          val = (buffer[0] & 0x80) ? buffer[0] | 0xFFFFFF00 : buffer[0];
          (*info->print_address_func) (memaddr + pos + val, info);
          (*info->print_address_func) (memaddr + pos + val, info);
          format &= ~M6811_OP_JUMP_REL;
          format &= ~M6811_OP_JUMP_REL;
        }
        }
      else if (format & M6812_OP_JUMP_REL16)
      else if (format & M6812_OP_JUMP_REL16)
        {
        {
          int val;
          int val;
 
 
          status = read_memory (memaddr + pos, &buffer[0], 2, info);
          status = read_memory (memaddr + pos, &buffer[0], 2, info);
          if (status != 0)
          if (status != 0)
            {
            {
              return status;
              return status;
            }
            }
 
 
          pos += 2;
          pos += 2;
          val = ((buffer[0] << 8) | (buffer[1] & 0x0FF));
          val = ((buffer[0] << 8) | (buffer[1] & 0x0FF));
          if (val & 0x8000)
          if (val & 0x8000)
            val |= 0xffff0000;
            val |= 0xffff0000;
 
 
          (*info->print_address_func) (memaddr + pos + val, info);
          (*info->print_address_func) (memaddr + pos + val, info);
          format &= ~M6812_OP_JUMP_REL16;
          format &= ~M6812_OP_JUMP_REL16;
        }
        }
      if (format & (M6811_OP_IMM16 | M6811_OP_IND16))
      if (format & (M6811_OP_IMM16 | M6811_OP_IND16))
        {
        {
          int val;
          int val;
 
 
          status = read_memory (memaddr + pos + offset, &buffer[0], 2, info);
          status = read_memory (memaddr + pos + offset, &buffer[0], 2, info);
          if (status != 0)
          if (status != 0)
            {
            {
              return status;
              return status;
            }
            }
          if (format & M6812_OP_IDX_P2)
          if (format & M6812_OP_IDX_P2)
            offset = -2;
            offset = -2;
          else
          else
            offset = 0;
            offset = 0;
          pos += 2;
          pos += 2;
 
 
          val = ((buffer[0] << 8) | (buffer[1] & 0x0FF));
          val = ((buffer[0] << 8) | (buffer[1] & 0x0FF));
          val &= 0x0FFFF;
          val &= 0x0FFFF;
          if (format & M6811_OP_IMM16)
          if (format & M6811_OP_IMM16)
            {
            {
              format &= ~M6811_OP_IMM16;
              format &= ~M6811_OP_IMM16;
              (*info->fprintf_func) (info->stream, "#");
              (*info->fprintf_func) (info->stream, "#");
            }
            }
          else
          else
            format &= ~M6811_OP_IND16;
            format &= ~M6811_OP_IND16;
 
 
          (*info->print_address_func) (val, info);
          (*info->print_address_func) (val, info);
        }
        }
 
 
      if (format & M6812_OP_IDX_P2)
      if (format & M6812_OP_IDX_P2)
        {
        {
          (*info->fprintf_func) (info->stream, ", ");
          (*info->fprintf_func) (info->stream, ", ");
          status = print_indexed_operand (memaddr + pos + offset, info, 1);
          status = print_indexed_operand (memaddr + pos + offset, info, 1);
          if (status < 0)
          if (status < 0)
            return status;
            return status;
          pos += status;
          pos += status;
        }
        }
 
 
      if (format & M6812_OP_IND16_P2)
      if (format & M6812_OP_IND16_P2)
        {
        {
          int val;
          int val;
 
 
          (*info->fprintf_func) (info->stream, ", ");
          (*info->fprintf_func) (info->stream, ", ");
 
 
          status = read_memory (memaddr + pos + offset, &buffer[0], 2, info);
          status = read_memory (memaddr + pos + offset, &buffer[0], 2, info);
          if (status != 0)
          if (status != 0)
            {
            {
              return status;
              return status;
            }
            }
          pos += 2;
          pos += 2;
 
 
          val = ((buffer[0] << 8) | (buffer[1] & 0x0FF));
          val = ((buffer[0] << 8) | (buffer[1] & 0x0FF));
          val &= 0x0FFFF;
          val &= 0x0FFFF;
          (*info->print_address_func) (val, info);
          (*info->print_address_func) (val, info);
        }
        }
 
 
#ifdef DEBUG
#ifdef DEBUG
      /* Consistency check.  'format' must be 0, so that we have handled
      /* Consistency check.  'format' must be 0, so that we have handled
         all formats; and the computed size of the insn must match the
         all formats; and the computed size of the insn must match the
         opcode table content.  */
         opcode table content.  */
      if (format & ~(M6811_OP_PAGE4 | M6811_OP_PAGE3 | M6811_OP_PAGE2))
      if (format & ~(M6811_OP_PAGE4 | M6811_OP_PAGE3 | M6811_OP_PAGE2))
        {
        {
          (*info->fprintf_func) (info->stream, "; Error, format: %x", format);
          (*info->fprintf_func) (info->stream, "; Error, format: %x", format);
        }
        }
      if (pos != opcode->size)
      if (pos != opcode->size)
        {
        {
          (*info->fprintf_func) (info->stream, "; Error, size: %d expect %d",
          (*info->fprintf_func) (info->stream, "; Error, size: %d expect %d",
                                 pos, opcode->size);
                                 pos, opcode->size);
        }
        }
#endif
#endif
      return pos;
      return pos;
    }
    }
 
 
  /* Opcode not recognized.  */
  /* Opcode not recognized.  */
  if (format == M6811_OP_PAGE2 && arch & cpu6812
  if (format == M6811_OP_PAGE2 && arch & cpu6812
      && ((code >= 0x30 && code <= 0x39) || (code >= 0x40 && code <= 0xff)))
      && ((code >= 0x30 && code <= 0x39) || (code >= 0x40 && code <= 0xff)))
    (*info->fprintf_func) (info->stream, "trap\t#%d", code & 0x0ff);
    (*info->fprintf_func) (info->stream, "trap\t#%d", code & 0x0ff);
 
 
  else if (format == M6811_OP_PAGE2)
  else if (format == M6811_OP_PAGE2)
    (*info->fprintf_func) (info->stream, ".byte\t0x%02x, 0x%02x",
    (*info->fprintf_func) (info->stream, ".byte\t0x%02x, 0x%02x",
                           M6811_OPCODE_PAGE2, code);
                           M6811_OPCODE_PAGE2, code);
  else if (format == M6811_OP_PAGE3)
  else if (format == M6811_OP_PAGE3)
    (*info->fprintf_func) (info->stream, ".byte\t0x%02x, 0x%02x",
    (*info->fprintf_func) (info->stream, ".byte\t0x%02x, 0x%02x",
                           M6811_OPCODE_PAGE3, code);
                           M6811_OPCODE_PAGE3, code);
  else if (format == M6811_OP_PAGE4)
  else if (format == M6811_OP_PAGE4)
    (*info->fprintf_func) (info->stream, ".byte\t0x%02x, 0x%02x",
    (*info->fprintf_func) (info->stream, ".byte\t0x%02x, 0x%02x",
                           M6811_OPCODE_PAGE4, code);
                           M6811_OPCODE_PAGE4, code);
  else
  else
    (*info->fprintf_func) (info->stream, ".byte\t0x%02x", code);
    (*info->fprintf_func) (info->stream, ".byte\t0x%02x", code);
 
 
  return pos;
  return pos;
}
}
 
 
/* Disassemble one instruction at address 'memaddr'.  Returns the number
/* Disassemble one instruction at address 'memaddr'.  Returns the number
   of bytes used by that instruction.  */
   of bytes used by that instruction.  */
int
int
print_insn_m68hc11 (memaddr, info)
print_insn_m68hc11 (memaddr, info)
     bfd_vma memaddr;
     bfd_vma memaddr;
     struct disassemble_info *info;
     struct disassemble_info *info;
{
{
  return print_insn (memaddr, info, cpu6811);
  return print_insn (memaddr, info, cpu6811);
}
}
 
 
int
int
print_insn_m68hc12 (memaddr, info)
print_insn_m68hc12 (memaddr, info)
     bfd_vma memaddr;
     bfd_vma memaddr;
     struct disassemble_info *info;
     struct disassemble_info *info;
{
{
  return print_insn (memaddr, info, cpu6812);
  return print_insn (memaddr, info, cpu6812);
}
}
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.