⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 m68hc11_sim.c

📁 gdb-6.0 linux 下的调试工具
💻 C
📖 第 1 页 / 共 2 页
字号:
/* m6811_cpu.c -- 68HC11&68HC12 CPU Emulation   Copyright 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.   Written by Stephane Carrez (stcarrez@nerim.fr)This file is part of GDB, GAS, and the GNU binutils.GDB, GAS, and the GNU binutils are free software; you can redistributethem and/or modify them under the terms of the GNU General PublicLicense as published by the Free Software Foundation; either version1, or (at your option) any later version.GDB, GAS, and the GNU binutils are distributed in the hope that theywill be useful, but WITHOUT ANY WARRANTY; without even the impliedwarranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  Seethe GNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this file; see the file COPYING.  If not, write to the FreeSoftware Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */#include "sim-main.h"#include "sim-assert.h"#include "sim-module.h"#include "sim-options.h"enum {  OPTION_CPU_RESET = OPTION_START,  OPTION_EMUL_OS,  OPTION_CPU_CONFIG,  OPTION_CPU_BOOTSTRAP,  OPTION_CPU_MODE};static DECLARE_OPTION_HANDLER (cpu_option_handler);static const OPTION cpu_options[] ={  { {"cpu-reset", no_argument, NULL, OPTION_CPU_RESET },      '\0', NULL, "Reset the CPU",      cpu_option_handler },  { {"emulos",    no_argument, NULL, OPTION_EMUL_OS },      '\0', NULL, "Emulate some OS system calls (read, write, ...)",      cpu_option_handler },  { {"cpu-config", required_argument, NULL, OPTION_CPU_CONFIG },      '\0', NULL, "Specify the initial CPU configuration register",      cpu_option_handler },  { {"bootstrap", no_argument, NULL, OPTION_CPU_BOOTSTRAP },      '\0', NULL, "Start the processing in bootstrap mode",      cpu_option_handler },  { {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL }};static SIM_RCcpu_option_handler (SIM_DESC sd, sim_cpu *cpu,                    int opt, char *arg, int is_command){  int val;    cpu = STATE_CPU (sd, 0);  switch (opt)    {    case OPTION_CPU_RESET:      sim_board_reset (sd);      break;    case OPTION_EMUL_OS:      cpu->cpu_emul_syscall = 1;      break;    case OPTION_CPU_CONFIG:      if (sscanf(arg, "0x%x", &val) == 1          || sscanf(arg, "%d", &val) == 1)        {          cpu->cpu_config = val;          cpu->cpu_use_local_config = 1;        }      else        cpu->cpu_use_local_config = 0;      break;    case OPTION_CPU_BOOTSTRAP:       cpu->cpu_start_mode = "bootstrap";       break;    case OPTION_CPU_MODE:      break;    }  return SIM_RC_OK;}    voidcpu_call (sim_cpu *cpu, uint16 addr){  cpu_set_pc (cpu, addr);}voidcpu_return (sim_cpu *cpu){}/* Set the stack pointer and re-compute the current frame.  */voidcpu_set_sp (sim_cpu *cpu, uint16 val){  cpu->cpu_regs.sp = val;}uint16cpu_get_reg (sim_cpu* cpu, uint8 reg){  switch (reg)    {    case 0:      return cpu_get_x (cpu);    case 1:      return cpu_get_y (cpu);    case 2:      return cpu_get_sp (cpu);    case 3:      return cpu_get_pc (cpu);    default:      return 0;    }}uint16cpu_get_src_reg (sim_cpu* cpu, uint8 reg){  switch (reg)    {    case 0:      return cpu_get_a (cpu);    case 1:      return cpu_get_b (cpu);    case 2:      return cpu_get_ccr (cpu);    case 3:      return cpu_get_tmp3 (cpu);    case 4:      return cpu_get_d (cpu);    case 5:      return cpu_get_x (cpu);    case 6:      return cpu_get_y (cpu);    case 7:      return cpu_get_sp (cpu);    default:      return 0;    }}voidcpu_set_dst_reg (sim_cpu* cpu, uint8 reg, uint16 val){  switch (reg)    {    case 0:      cpu_set_a (cpu, val);      break;    case 1:      cpu_set_b (cpu, val);      break;    case 2:      cpu_set_ccr (cpu, val);      break;    case 3:      cpu_set_tmp2 (cpu, val);      break;    case 4:      cpu_set_d (cpu, val);      break;    case 5:      cpu_set_x (cpu, val);      break;    case 6:      cpu_set_y (cpu, val);      break;    case 7:      cpu_set_sp (cpu, val);      break;    default:      break;    }}voidcpu_set_reg (sim_cpu* cpu, uint8 reg, uint16 val){  switch (reg)    {    case 0:      cpu_set_x (cpu, val);      break;          case 1:      cpu_set_y (cpu, val);      break;          case 2:      cpu_set_sp (cpu, val);      break;          case 3:      cpu_set_pc (cpu, val);      break;          default:      break;    }}/* Returns the address of a 68HC12 indexed operand.   Pre and post modifications are handled on the source register.  */uint16cpu_get_indexed_operand_addr (sim_cpu* cpu, int restrict){  uint8 reg;  uint16 sval;  uint16 addr;  uint8 code;  code = cpu_fetch8 (cpu);  /* n,r with 5-bit signed constant.  */  if ((code & 0x20) == 0)    {      reg = (code >> 6) & 3;      sval = (code & 0x1f);      if (code & 0x10)	sval |= 0xfff0;      addr = cpu_get_reg (cpu, reg);      addr += sval;    }  /* Auto pre/post increment/decrement.  */  else if ((code & 0xc0) != 0xc0)    {      reg = (code >> 6) & 3;      sval = (code & 0x0f);      if (sval & 0x8)	{	  sval |= 0xfff0;	}      else	{	  sval = sval + 1;	}      addr = cpu_get_reg (cpu, reg);      cpu_set_reg (cpu, reg, addr + sval);      if ((code & 0x10) == 0)	{	  addr += sval;	}    }  /* [n,r] 16-bits offset indexed indirect.  */  else if ((code & 0x07) == 3)    {      if (restrict)	{	  return 0;	}      reg = (code >> 3) & 0x03;      addr = cpu_get_reg (cpu, reg);      addr += cpu_fetch16 (cpu);      addr = memory_read16 (cpu, addr);      cpu_add_cycles (cpu, 1);    }  else if ((code & 0x4) == 0)    {      if (restrict)	{	  return 0;	}      reg = (code >> 3) & 0x03;      addr = cpu_get_reg (cpu, reg);      if (code & 0x2)	{	  sval = cpu_fetch16 (cpu);	  cpu_add_cycles (cpu, 1);	}      else	{	  sval = cpu_fetch8 (cpu);	  if (code & 0x1)	    sval |= 0xff00;	  cpu_add_cycles (cpu, 1);	}      addr += sval;    }  else    {      reg = (code >> 3) & 0x03;      addr = cpu_get_reg (cpu, reg);      switch (code & 3)	{	case 0:	  addr += cpu_get_a (cpu);	  break;	case 1:	  addr += cpu_get_b (cpu);	  break;	case 2:	  addr += cpu_get_d (cpu);	  break;	case 3:	default:	  addr += cpu_get_d (cpu);	  addr = memory_read16 (cpu, addr);	  cpu_add_cycles (cpu, 1);	  break;	}    }  return addr;}uint8cpu_get_indexed_operand8 (sim_cpu* cpu, int restrict){  uint16 addr;  addr = cpu_get_indexed_operand_addr (cpu, restrict);  return memory_read8 (cpu, addr);}uint16cpu_get_indexed_operand16 (sim_cpu* cpu, int restrict){  uint16 addr;  addr = cpu_get_indexed_operand_addr (cpu, restrict);  return memory_read16 (cpu, addr);}voidcpu_move8 (sim_cpu *cpu, uint8 code){  uint8 src;  uint16 addr;  switch (code)    {    case 0x0b:      src = cpu_fetch8 (cpu);      addr = cpu_fetch16 (cpu);      break;    case 0x08:      addr = cpu_get_indexed_operand_addr (cpu, 1);      src = cpu_fetch8 (cpu);      break;    case 0x0c:      addr = cpu_fetch16 (cpu);      src = memory_read8 (cpu, addr);      addr = cpu_fetch16 (cpu);      break;    case 0x09:      addr = cpu_get_indexed_operand_addr (cpu, 1);      src = memory_read8 (cpu, cpu_fetch16 (cpu));      break;    case 0x0d:      src = cpu_get_indexed_operand8 (cpu, 1);      addr = cpu_fetch16 (cpu);      break;    case 0x0a:      src = cpu_get_indexed_operand8 (cpu, 1);      addr = cpu_get_indexed_operand_addr (cpu, 1);      break;    default:      sim_engine_abort (CPU_STATE (cpu), cpu, 0,			"Invalid code 0x%0x -- internal error?", code);      return;    }  memory_write8 (cpu, addr, src);}voidcpu_move16 (sim_cpu *cpu, uint8 code){  uint16 src;  uint16 addr;  switch (code)    {    case 0x03:      src = cpu_fetch16 (cpu);      addr = cpu_fetch16 (cpu);      break;    case 0x00:      addr = cpu_get_indexed_operand_addr (cpu, 1);      src = cpu_fetch16 (cpu);      break;    case 0x04:      addr = cpu_fetch16 (cpu);      src = memory_read16 (cpu, addr);      addr = cpu_fetch16 (cpu);      break;    case 0x01:      addr = cpu_get_indexed_operand_addr (cpu, 1);      src = memory_read16 (cpu, cpu_fetch16 (cpu));      break;    case 0x05:      src = cpu_get_indexed_operand16 (cpu, 1);      addr = cpu_fetch16 (cpu);      break;    case 0x02:      src = cpu_get_indexed_operand16 (cpu, 1);      addr = cpu_get_indexed_operand_addr (cpu, 1);      break;    default:      sim_engine_abort (CPU_STATE (cpu), cpu, 0,			"Invalid code 0x%0x -- internal error?", code);      return;    }  memory_write16 (cpu, addr, src);}intcpu_initialize (SIM_DESC sd, sim_cpu *cpu){  sim_add_option_table (sd, 0, cpu_options);  memset (&cpu->cpu_regs, 0, sizeof(cpu->cpu_regs));  cpu->cpu_absolute_cycle = 0;  cpu->cpu_current_cycle  = 0;  cpu->cpu_emul_syscall   = 1;  cpu->cpu_running        = 1;  cpu->cpu_stop_on_interrupt = 0;  cpu->cpu_frequency = 8 * 1000 * 1000;  cpu->cpu_use_elf_start = 0;  cpu->cpu_elf_start     = 0;  cpu->cpu_use_local_config = 0;  cpu->bank_start = 0;  cpu->bank_end   = 0;  cpu->bank_shift = 0;  cpu->cpu_config        = M6811_NOSEC | M6811_NOCOP | M6811_ROMON |    M6811_EEON;  interrupts_initialize (sd, cpu);  cpu->cpu_is_initialized = 1;  return 0;}/* Reinitialize the processor after a reset.  */intcpu_reset (sim_cpu *cpu){  /* Initialize the config register.     It is only initialized at reset time.  */  memset (cpu->ios, 0, sizeof (cpu->ios));  if (cpu->cpu_configured_arch->arch == bfd_arch_m68hc11)    cpu->ios[M6811_INIT] = 0x1;  else    cpu->ios[M6811_INIT] = 0;  /* Output compare registers set to 0xFFFF.  */  cpu->ios[M6811_TOC1_H] = 0xFF;  cpu->ios[M6811_TOC1_L] = 0xFF;  cpu->ios[M6811_TOC2_H] = 0xFF;  cpu->ios[M6811_TOC2_L] = 0xFF;  cpu->ios[M6811_TOC3_H] = 0xFF;  cpu->ios[M6811_TOC4_L] = 0xFF;  cpu->ios[M6811_TOC5_H] = 0xFF;  cpu->ios[M6811_TOC5_L] = 0xFF;  /* Setup the processor registers.  */  memset (&cpu->cpu_regs, 0, sizeof(cpu->cpu_regs));  cpu->cpu_absolute_cycle = 0;  cpu->cpu_current_cycle  = 0;  cpu->cpu_is_initialized = 0;  /* Reset interrupts.  */  interrupts_reset (&cpu->cpu_interrupts);  /* Reinitialize the CPU operating mode.  */  cpu->ios[M6811_HPRIO] = cpu->cpu_mode;  return 0;}/* Reinitialize the processor after a reset.  */intcpu_restart (sim_cpu *cpu){  uint16 addr;  /* Get CPU starting address depending on the CPU mode.  */  if (cpu->cpu_use_elf_start == 0)    {      switch ((cpu->ios[M6811_HPRIO]) & (M6811_SMOD | M6811_MDA))        {          /* Single Chip  */        default:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -