]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - sim/m68hc11/interp.c
sim: cris/m68hc11: move default endian/alignment to configure
[thirdparty/binutils-gdb.git] / sim / m68hc11 / interp.c
index f9de86575ba753a2fbb9fec92969d5cbc5c63c86..f1303b487bb7b963364c324cd03e3ae2c0833ac1 100644 (file)
@@ -1,22 +1,21 @@
-/* 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"
@@ -25,6 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "hw-tree.h"
 #include "hw-device.h"
 #include "hw-ports.h"
+#include "elf32-m68hc1x.h"
 
 #ifndef MONITOR_BASE
 # define MONITOR_BASE (0x0C000)
@@ -33,29 +33,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 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"},
@@ -64,18 +48,48 @@ struct sim_info_list dev_list[] = {
   {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;
@@ -96,7 +110,6 @@ sim_get_info (SIM_DESC sd, char *cmd)
       return;
     }
 
-  cpu = STATE_CPU (sd, 0);
   cpu_info (sd, cpu);
   interrupts_info (sd, &cpu->cpu_interrupts);
 }
@@ -107,13 +120,28 @@ sim_board_reset (SIM_DESC sd)
 {
   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;
     }
 
@@ -122,87 +150,310 @@ sim_board_reset (SIM_DESC sd)
   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@%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");
+      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 > 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.  */
@@ -211,14 +462,14 @@ sim_open (SIM_OPEN_KIND kind, host_callback *callback,
                            ? *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;
     }
 
@@ -226,47 +477,29 @@ sim_open (SIM_OPEN_KIND kind, host_callback *callback,
     {
       /* 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. */
 
@@ -292,65 +525,51 @@ sim_engine_run (SIM_DESC sd,
     }
 }
 
-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);
-
-  return SIM_RC_OK;
+  return sim_prepare_for_program (sd, abfd);
 }
 
-
-void
-sim_set_callbacks (host_callback *p)
+static int
+m68hc11_reg_fetch (SIM_CPU *cpu, int rn, unsigned char *memory, int length)
 {
-  /*  m6811_callback = p; */
-}
-
-
-int
-sim_fetch_register (SIM_DESC sd, 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:
@@ -375,24 +594,34 @@ sim_fetch_register (SIM_DESC sd, int rn, unsigned char *memory, int length)
 
     case PSW_REGNUM:
       val = cpu_get_ccr (cpu);
+      size = 1;
+      break;
+
+    case PAGE_REGNUM:
+      val = cpu_get_page (cpu);
+      size = 1;
       break;
 
     default:
       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)
@@ -406,11 +635,11 @@ sim_store_register (SIM_DESC sd, int rn, unsigned char *memory, int length)
 
     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);
@@ -430,7 +659,11 @@ sim_store_register (SIM_DESC sd, int rn, unsigned char *memory, int length)
 
     case PSW_REGNUM:
       cpu_set_ccr (cpu, val);
-      break;
+      return 1;
+
+    case PAGE_REGNUM:
+      cpu_set_page (cpu, val);
+      return 1;
 
     default:
       break;
@@ -438,32 +671,3 @@ sim_store_register (SIM_DESC sd, int rn, unsigned char *memory, int length)
 
   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);
-    }
-}