-/* interp.c -- Simulator for Motorola 68HC11
- Copyright (C) 1999, 2000 Free Software Foundation, Inc.
- Written by Stephane Carrez (stcarrez@worldnet.fr)
+/* interp.c -- Simulator for Motorola 68HC11/68HC12
+ Copyright (C) 1999-2015 Free Software Foundation, Inc.
+ Written by Stephane Carrez (stcarrez@nerim.fr)
This file is part of GDB, the GNU debugger.
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
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-You should have received a copy of the GNU General Public License along
-with this program; if not, write to the Free Software Foundation, Inc.,
-59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "sim-main.h"
#include "sim-assert.h"
#include "hw-tree.h"
#include "hw-device.h"
#include "hw-ports.h"
+#include "elf32-m68hc1x.h"
#ifndef MONITOR_BASE
# define MONITOR_BASE (0x0C000)
static void sim_get_info (SIM_DESC sd, char *cmd);
-
-char *interrupt_names[] = {
- "reset",
- "nmi",
- "int",
- NULL
-};
-
-#ifndef INLINE
-#if defined(__GNUC__) && defined(__OPTIMIZE__)
-#define INLINE __inline__
-#else
-#define INLINE
-#endif
-#endif
-
struct sim_info_list
{
const char *name;
const char *device;
};
-struct sim_info_list dev_list[] = {
+struct sim_info_list dev_list_68hc11[] = {
{"cpu", "/m68hc11"},
{"timer", "/m68hc11/m68hc11tim"},
{"sio", "/m68hc11/m68hc11sio"},
{0, 0}
};
+struct sim_info_list dev_list_68hc12[] = {
+ {"cpu", "/m68hc12"},
+ {"timer", "/m68hc12/m68hc12tim"},
+ {"sio", "/m68hc12/m68hc12sio"},
+ {"spi", "/m68hc12/m68hc12spi"},
+ {"eeprom", "/m68hc12/m68hc12eepr"},
+ {0, 0}
+};
+
+/* Cover function of sim_state_free to free the cpu buffers as well. */
+
+static void
+free_state (SIM_DESC sd)
+{
+ if (STATE_MODULES (sd) != NULL)
+ sim_module_uninstall (sd);
+
+ sim_state_free (sd);
+}
+
/* Give some information about the simulator. */
static void
sim_get_info (SIM_DESC sd, char *cmd)
{
sim_cpu *cpu;
+ cpu = STATE_CPU (sd, 0);
if (cmd != 0 && (cmd[0] == ' ' || cmd[0] == '-'))
{
int i;
struct hw *hw_dev;
+ struct sim_info_list *dev_list;
+ const struct bfd_arch_info *arch;
+
+ arch = STATE_ARCHITECTURE (sd);
cmd++;
+ if (arch->arch == bfd_arch_m68hc11)
+ dev_list = dev_list_68hc11;
+ else
+ dev_list = dev_list_68hc12;
+
for (i = 0; dev_list[i].name; i++)
if (strcmp (cmd, dev_list[i].name) == 0)
break;
return;
}
- cpu = STATE_CPU (sd, 0);
cpu_info (sd, cpu);
interrupts_info (sd, &cpu->cpu_interrupts);
}
{
struct hw *hw_cpu;
sim_cpu *cpu;
+ const struct bfd_arch_info *arch;
+ const char *cpu_type;
cpu = STATE_CPU (sd, 0);
+ arch = STATE_ARCHITECTURE (sd);
+
/* hw_cpu = sim_hw_parse (sd, "/"); */
- hw_cpu = sim_hw_parse (sd, "/m68hc11");
+ if (arch->arch == bfd_arch_m68hc11)
+ {
+ cpu->cpu_type = CPU_M6811;
+ cpu_type = "/m68hc11";
+ }
+ else
+ {
+ cpu->cpu_type = CPU_M6812;
+ cpu_type = "/m68hc12";
+ }
+
+ hw_cpu = sim_hw_parse (sd, cpu_type);
if (hw_cpu == 0)
{
- sim_io_eprintf (sd, "m68hc11 cpu not found in device tree.");
+ sim_io_eprintf (sd, "%s cpu not found in device tree.", cpu_type);
return;
}
cpu_restart (cpu);
}
-SIM_DESC
-sim_open (SIM_OPEN_KIND kind, host_callback *callback,
- struct _bfd *abfd, char **argv)
+static int
+sim_hw_configure (SIM_DESC sd)
{
- char **p;
- SIM_DESC sd;
- sim_cpu *cpu;
+ const struct bfd_arch_info *arch;
struct hw *device_tree;
+ sim_cpu *cpu;
+
+ arch = STATE_ARCHITECTURE (sd);
+ if (arch == 0)
+ return 0;
- sd = sim_state_alloc (kind, callback);
cpu = STATE_CPU (sd, 0);
+ cpu->cpu_configured_arch = arch;
+ device_tree = sim_hw_parse (sd, "/");
+ if (arch->arch == bfd_arch_m68hc11)
+ {
+ cpu->cpu_interpretor = cpu_interp_m6811;
+ if (hw_tree_find_property (device_tree, "/m68hc11/reg") == 0)
+ {
+ /* Allocate core managed memory */
+
+ /* the monitor */
+ sim_do_commandf (sd, "memory region 0x%lx@%d,0x%lx",
+ /* MONITOR_BASE, MONITOR_SIZE */
+ 0x8000, M6811_RAM_LEVEL, 0x8000);
+ sim_do_commandf (sd, "memory region 0x000@%d,0x8000",
+ M6811_RAM_LEVEL);
+ sim_hw_parse (sd, "/m68hc11/reg 0x1000 0x03F");
+ if (cpu->bank_start < cpu->bank_end)
+ {
+ sim_do_commandf (sd, "memory region 0x%lx@%d,0x100000",
+ cpu->bank_virtual, M6811_RAM_LEVEL);
+ sim_hw_parse (sd, "/m68hc11/use_bank 1");
+ }
+ }
+ if (cpu->cpu_start_mode)
+ {
+ sim_hw_parse (sd, "/m68hc11/mode %s", cpu->cpu_start_mode);
+ }
+ if (hw_tree_find_property (device_tree, "/m68hc11/m68hc11sio/reg") == 0)
+ {
+ sim_hw_parse (sd, "/m68hc11/m68hc11sio/reg 0x2b 0x5");
+ sim_hw_parse (sd, "/m68hc11/m68hc11sio/backend stdio");
+ sim_hw_parse (sd, "/m68hc11 > cpu-reset reset /m68hc11/m68hc11sio");
+ }
+ if (hw_tree_find_property (device_tree, "/m68hc11/m68hc11tim/reg") == 0)
+ {
+ /* M68hc11 Timer configuration. */
+ sim_hw_parse (sd, "/m68hc11/m68hc11tim/reg 0x1b 0x5");
+ sim_hw_parse (sd, "/m68hc11 > cpu-reset reset /m68hc11/m68hc11tim");
+ sim_hw_parse (sd, "/m68hc11 > capture capture /m68hc11/m68hc11tim");
+ }
- SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
+ /* Create the SPI device. */
+ if (hw_tree_find_property (device_tree, "/m68hc11/m68hc11spi/reg") == 0)
+ {
+ sim_hw_parse (sd, "/m68hc11/m68hc11spi/reg 0x28 0x3");
+ sim_hw_parse (sd, "/m68hc11 > cpu-reset reset /m68hc11/m68hc11spi");
+ }
+ if (hw_tree_find_property (device_tree, "/m68hc11/nvram/reg") == 0)
+ {
+ /* M68hc11 persistent ram configuration. */
+ sim_hw_parse (sd, "/m68hc11/nvram/reg 0x0 256");
+ sim_hw_parse (sd, "/m68hc11/nvram/file m68hc11.ram");
+ sim_hw_parse (sd, "/m68hc11/nvram/mode save-modified");
+ /*sim_hw_parse (sd, "/m68hc11 > cpu-reset reset /m68hc11/pram"); */
+ }
+ if (hw_tree_find_property (device_tree, "/m68hc11/m68hc11eepr/reg") == 0)
+ {
+ sim_hw_parse (sd, "/m68hc11/m68hc11eepr/reg 0xb000 512");
+ sim_hw_parse (sd, "/m68hc11 > cpu-reset reset /m68hc11/m68hc11eepr");
+ }
+ sim_hw_parse (sd, "/m68hc11 > port-a cpu-write-port /m68hc11");
+ sim_hw_parse (sd, "/m68hc11 > port-b cpu-write-port /m68hc11");
+ sim_hw_parse (sd, "/m68hc11 > port-c cpu-write-port /m68hc11");
+ sim_hw_parse (sd, "/m68hc11 > port-d cpu-write-port /m68hc11");
+ cpu->hw_cpu = sim_hw_parse (sd, "/m68hc11");
+ }
+ else
+ {
+ cpu->cpu_interpretor = cpu_interp_m6812;
+ if (hw_tree_find_property (device_tree, "/m68hc12/reg") == 0)
+ {
+ /* Allocate core external memory. */
+ sim_do_commandf (sd, "memory region 0x%lx@%d,0x%lx",
+ 0x8000, M6811_RAM_LEVEL, 0x8000);
+ sim_do_commandf (sd, "memory region 0x000@%d,0x8000",
+ M6811_RAM_LEVEL);
+ if (cpu->bank_start < cpu->bank_end)
+ {
+ sim_do_commandf (sd, "memory region 0x%lx@%d,0x100000",
+ cpu->bank_virtual, M6811_RAM_LEVEL);
+ sim_hw_parse (sd, "/m68hc12/use_bank 1");
+ }
+ sim_hw_parse (sd, "/m68hc12/reg 0x0 0x3FF");
+ }
- /* for compatibility */
- current_alignment = NONSTRICT_ALIGNMENT;
- current_target_byte_order = BIG_ENDIAN;
+ if (!hw_tree_find_property (device_tree, "/m68hc12/m68hc12sio@1/reg"))
+ {
+ sim_hw_parse (sd, "/m68hc12/m68hc12sio@1/reg 0xC0 0x8");
+ sim_hw_parse (sd, "/m68hc12/m68hc12sio@1/backend stdio");
+ sim_hw_parse (sd, "/m68hc12 > cpu-reset reset /m68hc12/m68hc12sio@1");
+ }
+ if (hw_tree_find_property (device_tree, "/m68hc12/m68hc12tim/reg") == 0)
+ {
+ /* M68hc11 Timer configuration. */
+ sim_hw_parse (sd, "/m68hc12/m68hc12tim/reg 0x1b 0x5");
+ sim_hw_parse (sd, "/m68hc12 > cpu-reset reset /m68hc12/m68hc12tim");
+ sim_hw_parse (sd, "/m68hc12 > capture capture /m68hc12/m68hc12tim");
+ }
- cpu_initialize (sd, cpu);
+ /* Create the SPI device. */
+ if (hw_tree_find_property (device_tree, "/m68hc12/m68hc12spi/reg") == 0)
+ {
+ sim_hw_parse (sd, "/m68hc12/m68hc12spi/reg 0x28 0x3");
+ sim_hw_parse (sd, "/m68hc12 > cpu-reset reset /m68hc12/m68hc12spi");
+ }
+ if (hw_tree_find_property (device_tree, "/m68hc12/nvram/reg") == 0)
+ {
+ /* M68hc11 persistent ram configuration. */
+ sim_hw_parse (sd, "/m68hc12/nvram/reg 0x2000 8192");
+ sim_hw_parse (sd, "/m68hc12/nvram/file m68hc12.ram");
+ sim_hw_parse (sd, "/m68hc12/nvram/mode save-modified");
+ }
+ if (hw_tree_find_property (device_tree, "/m68hc12/m68hc12eepr/reg") == 0)
+ {
+ sim_hw_parse (sd, "/m68hc12/m68hc12eepr/reg 0x0800 2048");
+ sim_hw_parse (sd, "/m68hc12 > cpu-reset reset /m68hc12/m68hc12eepr");
+ }
- cpu->cpu_use_elf_start = 1;
- if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
- return 0;
+ sim_hw_parse (sd, "/m68hc12 > port-a cpu-write-port /m68hc12");
+ sim_hw_parse (sd, "/m68hc12 > port-b cpu-write-port /m68hc12");
+ sim_hw_parse (sd, "/m68hc12 > port-c cpu-write-port /m68hc12");
+ sim_hw_parse (sd, "/m68hc12 > port-d cpu-write-port /m68hc12");
+ cpu->hw_cpu = sim_hw_parse (sd, "/m68hc12");
+ }
+ return 1;
+}
- /* getopt will print the error message so we just have to exit if this fails.
- FIXME: Hmmm... in the case of gdb we need getopt to call
- print_filtered. */
- if (sim_parse_args (sd, argv) != SIM_RC_OK)
+/* Get the memory bank parameters by looking at the global symbols
+ defined by the linker. */
+static int
+sim_get_bank_parameters (SIM_DESC sd, bfd* abfd)
+{
+ sim_cpu *cpu;
+ long symsize;
+ long symbol_count, i;
+ unsigned size;
+ asymbol** asymbols;
+ asymbol** current;
+
+ cpu = STATE_CPU (sd, 0);
+
+ symsize = bfd_get_symtab_upper_bound (abfd);
+ if (symsize < 0)
{
- /* Uninstall the modules to avoid memory leaks,
- file descriptor leaks, etc. */
- sim_module_uninstall (sd);
+ sim_io_eprintf (sd, "Cannot read symbols of program");
return 0;
}
-
- device_tree = sim_hw_parse (sd, "/");
- if (hw_tree_find_property (device_tree, "/m68hc11/reg") == 0)
+ asymbols = (asymbol **) xmalloc (symsize);
+ symbol_count = bfd_canonicalize_symtab (abfd, asymbols);
+ if (symbol_count < 0)
{
- /* Allocate core managed memory */
-
- /* the monitor */
- sim_do_commandf (sd, "memory region 0x%lx,0x%lx",
- /* MONITOR_BASE, MONITOR_SIZE */
- 0x8000, 0x8000);
- sim_do_command (sd, " memory region 0x000,0x8000");
- sim_hw_parse (sd, "/m68hc11/reg 0x1000 0x03F");
+ sim_io_eprintf (sd, "Cannot read symbols of program");
+ return 0;
}
- if (hw_tree_find_property (device_tree, "/m68hc11/m68hc11sio/reg") == 0)
+ size = 0;
+ for (i = 0, current = asymbols; i < symbol_count; i++, current++)
{
- sim_hw_parse (sd, "/m68hc11/m68hc11sio/reg 0x2b 0x5");
- sim_hw_parse (sd, "/m68hc11/m68hc11sio/backend stdio");
- sim_hw_parse (sd, "/m68hc11 > cpu-reset reset /m68hc11/m68hc11sio");
+ const char* name = bfd_asymbol_name (*current);
+
+ if (strcmp (name, BFD_M68HC11_BANK_START_NAME) == 0)
+ {
+ cpu->bank_start = bfd_asymbol_value (*current);
+ }
+ else if (strcmp (name, BFD_M68HC11_BANK_SIZE_NAME) == 0)
+ {
+ size = bfd_asymbol_value (*current);
+ }
+ else if (strcmp (name, BFD_M68HC11_BANK_VIRTUAL_NAME) == 0)
+ {
+ cpu->bank_virtual = bfd_asymbol_value (*current);
+ }
}
- if (hw_tree_find_property (device_tree, "/m68hc11/m68hc11tim/reg") == 0)
+ free (asymbols);
+
+ cpu->bank_end = cpu->bank_start + size;
+ cpu->bank_shift = 0;
+ for (; size > 1; size >>= 1)
+ cpu->bank_shift++;
+
+ return 0;
+}
+
+static int
+sim_prepare_for_program (SIM_DESC sd, bfd* abfd)
+{
+ sim_cpu *cpu;
+ int elf_flags = 0;
+
+ cpu = STATE_CPU (sd, 0);
+
+ if (abfd != NULL)
{
- /* M68hc11 Timer configuration. */
- sim_hw_parse (sd, "/m68hc11/m68hc11tim/reg 0x1b 0x5");
- sim_hw_parse (sd, "/m68hc11 > cpu-reset reset /m68hc11/m68hc11tim");
+ asection *s;
+
+ if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
+ elf_flags = elf_elfheader (abfd)->e_flags;
+
+ cpu->cpu_elf_start = bfd_get_start_address (abfd);
+ /* See if any section sets the reset address */
+ cpu->cpu_use_elf_start = 1;
+ for (s = abfd->sections; s && cpu->cpu_use_elf_start; s = s->next)
+ {
+ if (s->flags & SEC_LOAD)
+ {
+ bfd_size_type size;
+
+ size = bfd_get_section_size (s);
+ if (size > 0)
+ {
+ bfd_vma lma;
+
+ if (STATE_LOAD_AT_LMA_P (sd))
+ lma = bfd_section_lma (abfd, s);
+ else
+ lma = bfd_section_vma (abfd, s);
+
+ if (lma <= 0xFFFE && lma+size >= 0x10000)
+ cpu->cpu_use_elf_start = 0;
+ }
+ }
+ }
+
+ if (elf_flags & E_M68HC12_BANKS)
+ {
+ if (sim_get_bank_parameters (sd, abfd) != 0)
+ sim_io_eprintf (sd, "Memory bank parameters are not initialized\n");
+ }
}
- /* Create the SPI device. */
- if (hw_tree_find_property (device_tree, "/m68hc11/m68hc11spi/reg") == 0)
+ if (!sim_hw_configure (sd))
+ return SIM_RC_FAIL;
+
+ /* reset all state information */
+ sim_board_reset (sd);
+
+ return SIM_RC_OK;
+}
+
+static sim_cia
+m68hc11_pc_get (sim_cpu *cpu)
+{
+ return cpu_get_pc (cpu);
+}
+
+static void
+m68hc11_pc_set (sim_cpu *cpu, sim_cia pc)
+{
+ cpu_set_pc (cpu, pc);
+}
+
+static int m68hc11_reg_fetch (SIM_CPU *, int, unsigned char *, int);
+static int m68hc11_reg_store (SIM_CPU *, int, unsigned char *, int);
+
+SIM_DESC
+sim_open (SIM_OPEN_KIND kind, host_callback *callback,
+ bfd *abfd, char **argv)
+{
+ int i;
+ SIM_DESC sd;
+ sim_cpu *cpu;
+
+ sd = sim_state_alloc (kind, callback);
+
+ SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
+
+ /* The cpu data is kept in a separately allocated chunk of memory. */
+ if (sim_cpu_alloc_all (sd, 1, /*cgen_cpu_max_extra_bytes ()*/0) != SIM_RC_OK)
{
- sim_hw_parse (sd, "/m68hc11/m68hc11spi/reg 0x28 0x3");
- sim_hw_parse (sd, "/m68hc11 > cpu-reset reset /m68hc11/m68hc11spi");
+ free_state (sd);
+ return 0;
}
- if (hw_tree_find_property (device_tree, "/m68hc11/pram/reg") == 0)
+
+ cpu = STATE_CPU (sd, 0);
+
+ cpu_initialize (sd, cpu);
+
+ if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
{
- /* M68hc11 persistent ram configuration. */
- sim_hw_parse (sd, "/m68hc11/nvram/reg 0x0 256");
- sim_hw_parse (sd, "/m68hc11/nvram/file m68hc11.ram");
- sim_hw_parse (sd, "/m68hc11/nvram/mode save-modified");
- sim_hw_parse (sd, "/m68hc11/nvram/overlap? true");
- /*sim_hw_parse (sd, "/m68hc11 > cpu-reset reset /m68hc11/pram"); */
+ free_state (sd);
+ return 0;
}
- if (hw_tree_find_property (device_tree, "/m68hc11/m68hc11eepr/reg") == 0)
+
+ /* getopt will print the error message so we just have to exit if this fails.
+ FIXME: Hmmm... in the case of gdb we need getopt to call
+ print_filtered. */
+ if (sim_parse_args (sd, argv) != SIM_RC_OK)
{
- sim_hw_parse (sd, "/m68hc11/m68hc11eepr/reg 0xb000 512");
- /* Connect the CPU reset to all devices. */
- sim_hw_parse (sd, "/m68hc11 > cpu-reset reset /m68hc11/m68hc11eepr");
+ /* Uninstall the modules to avoid memory leaks,
+ file descriptor leaks, etc. */
+ free_state (sd);
+ return 0;
}
/* Check for/establish the a reference program image. */
? *STATE_PROG_ARGV (sd)
: NULL), abfd) != SIM_RC_OK)
{
- sim_module_uninstall (sd);
+ free_state (sd);
return 0;
}
/* Establish any remaining configuration options. */
if (sim_config (sd) != SIM_RC_OK)
{
- sim_module_uninstall (sd);
+ free_state (sd);
return 0;
}
{
/* Uninstall the modules to avoid memory leaks,
file descriptor leaks, etc. */
- sim_module_uninstall (sd);
+ free_state (sd);
return 0;
}
+ if (sim_prepare_for_program (sd, abfd) != SIM_RC_OK)
+ {
+ free_state (sd);
+ return 0;
+ }
- if (abfd != NULL)
+ /* CPU specific initialization. */
+ for (i = 0; i < MAX_NR_PROCESSORS; ++i)
{
- cpu->cpu_elf_start = bfd_get_start_address (abfd);
- }
+ SIM_CPU *cpu = STATE_CPU (sd, i);
- sim_board_reset (sd);
+ CPU_REG_FETCH (cpu) = m68hc11_reg_fetch;
+ CPU_REG_STORE (cpu) = m68hc11_reg_store;
+ CPU_PC_FETCH (cpu) = m68hc11_pc_get;
+ CPU_PC_STORE (cpu) = m68hc11_pc_set;
+ }
- /* Fudge our descriptor. */
return sd;
}
-
-void
-sim_close (SIM_DESC sd, int quitting)
-{
- /* shut down modules */
- sim_module_uninstall (sd);
-
- /* Ensure that any resources allocated through the callback
- mechanism are released: */
- sim_io_shutdown (sd);
-
- /* FIXME - free SD */
-
- return;
-}
-
-void
-sim_set_profile (int n)
-{
-}
-
-void
-sim_set_profile_size (int n)
-{
-}
-
/* Generic implementation of sim_engine_run that works within the
sim_engine setjmp/longjmp framework. */
}
}
-int
-sim_trace (SIM_DESC sd)
-{
- sim_resume (sd, 0, 0);
- return 1;
-}
-
void
sim_info (SIM_DESC sd, int verbose)
{
+ const char *cpu_type;
+ const struct bfd_arch_info *arch;
+
+ /* Nothing to do if there is no verbose flag set. */
+ if (verbose == 0 && STATE_VERBOSE_P (sd) == 0)
+ return;
+
+ arch = STATE_ARCHITECTURE (sd);
+ if (arch->arch == bfd_arch_m68hc11)
+ cpu_type = "68HC11";
+ else
+ cpu_type = "68HC12";
+
sim_io_eprintf (sd, "Simulator info:\n");
- sim_io_eprintf (sd, " CPU Motorola 68HC11\n");
+ sim_io_eprintf (sd, " CPU Motorola %s\n", cpu_type);
sim_get_info (sd, 0);
sim_module_info (sd, verbose || STATE_VERBOSE_P (sd));
}
SIM_RC
-sim_create_inferior (SIM_DESC sd, struct _bfd *abfd,
+sim_create_inferior (SIM_DESC sd, struct bfd *abfd,
char **argv, char **env)
{
- sim_cpu *cpu;
- int i;
-
- cpu = STATE_CPU (sd, 0);
-
- if (abfd != NULL)
- {
- cpu->cpu_elf_start = bfd_get_start_address (abfd);
- }
-
- /* reset all state information */
- sim_board_reset (sd);
-
- /* Get information about the number of pseudo registers. */
- for (i = FIRST_SOFT_REGNUM; i <= ZD32_REGNUM; i++)
- {
- switch (i)
- {
- case TMP_REGNUM:
- cpu->cpu_page0_reg[i - FIRST_SOFT_REGNUM] = 0;
- break;
- case Z_REGNUM:
- case ZS_REGNUM:
- cpu->cpu_page0_reg[i - FIRST_SOFT_REGNUM] = 2;
- break;
- case XY_REGNUM:
- cpu->cpu_page0_reg[i - FIRST_SOFT_REGNUM] = 4;
- break;
- case FP_REGNUM:
- cpu->cpu_page0_reg[i - FIRST_SOFT_REGNUM] = 6;
- break;
- default:
- cpu->cpu_page0_reg[i - FIRST_SOFT_REGNUM]
- = ((i - FIRST_SOFT_REGNUM) * 2) - 2;
- break;
- }
- }
- cpu->cpu_nb_pseudo_regs = 8;
-
- return SIM_RC_OK;
-}
-
-
-void
-sim_set_callbacks (host_callback *p)
-{
- /* m6811_callback = p; */
+ return sim_prepare_for_program (sd, abfd);
}
-
-int
-sim_fetch_register (SIM_DESC sd, int rn, unsigned char *memory, int length)
+static int
+m68hc11_reg_fetch (SIM_CPU *cpu, int rn, unsigned char *memory, int length)
{
- sim_cpu *cpu;
uint16 val;
+ int size = 2;
- cpu = STATE_CPU (sd, 0);
switch (rn)
{
case A_REGNUM:
val = cpu_get_a (cpu);
+ size = 1;
break;
case B_REGNUM:
val = cpu_get_b (cpu);
+ size = 1;
break;
case D_REGNUM:
case PSW_REGNUM:
val = cpu_get_ccr (cpu);
+ size = 1;
break;
+ case PAGE_REGNUM:
+ val = cpu_get_page (cpu);
+ size = 1;
+ break;
- /* Read a pseudo register. Pseudo registers are located at
- beginning of page 0. Each of them is 2 bytes. */
default:
- if (rn < FIRST_SOFT_REGNUM || rn >= ZD32_REGNUM)
- {
- val = 0;
- }
- else
- {
- uint16 addr;
-
- addr = cpu->cpu_page0_reg[rn - FIRST_SOFT_REGNUM];
- val = memory_read16 (cpu, addr);
- }
+ val = 0;
break;
}
- memory[0] = val >> 8;
- memory[1] = val & 0x0FF;
- return 2;
+ if (size == 1)
+ {
+ memory[0] = val;
+ }
+ else
+ {
+ memory[0] = val >> 8;
+ memory[1] = val & 0x0FF;
+ }
+ return size;
}
-int
-sim_store_register (SIM_DESC sd, int rn, unsigned char *memory, int length)
+static int
+m68hc11_reg_store (SIM_CPU *cpu, int rn, unsigned char *memory, int length)
{
uint16 val;
- sim_cpu *cpu;
-
- cpu = STATE_CPU (sd, 0);
val = *memory++;
if (length == 2)
case A_REGNUM:
cpu_set_a (cpu, val);
- break;
+ return 1;
case B_REGNUM:
cpu_set_b (cpu, val);
- break;
+ return 1;
case X_REGNUM:
cpu_set_x (cpu, val);
case PSW_REGNUM:
cpu_set_ccr (cpu, val);
- break;
+ return 1;
- /* Write a pseudo register. Pseudo registers are located at
- beginning of page 0. Each of them is 2 bytes. */
- default:
- if (rn >= FIRST_SOFT_REGNUM && rn <= ZD32_REGNUM)
- {
- uint16 addr;
+ case PAGE_REGNUM:
+ cpu_set_page (cpu, val);
+ return 1;
- addr = cpu->cpu_page0_reg[rn - FIRST_SOFT_REGNUM];
- memory_write16 (cpu, addr, val);
- }
+ default:
break;
}
return 2;
}
-
-void
-sim_size (int s)
-{
- ;
-}
-
-void
-sim_do_command (SIM_DESC sd, char *cmd)
-{
- char *mm_cmd = "memory-map";
- char *int_cmd = "interrupt";
-
- /* Commands available from GDB: */
- if (sim_args_command (sd, cmd) != SIM_RC_OK)
- {
- if (strncmp (cmd, "info", sizeof ("info") - 1) == 0)
- sim_get_info (sd, &cmd[4]);
- else if (strncmp (cmd, "frame", sizeof ("frame") - 1) == 0)
- cpu_print_frame (sd, STATE_CPU (sd, 0));
- else if (strncmp (cmd, mm_cmd, strlen (mm_cmd) == 0))
- sim_io_eprintf (sd,
- "`memory-map' command replaced by `sim memory'\n");
- else if (strncmp (cmd, int_cmd, strlen (int_cmd)) == 0)
- sim_io_eprintf (sd, "`interrupt' command replaced by `sim watch'\n");
- else
- sim_io_eprintf (sd, "Unknown command `%s'\n", cmd);
- }
-}