]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - sim/h8300/compile.c
sim: h8300: inline sim_state_initialize
[thirdparty/binutils-gdb.git] / sim / h8300 / compile.c
index 33a28f584c0c03f4f5c1e30d0de55fc58b5d201f..ef6a853a11976777a327382b627f8d014b3ee631 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Simulator for the Hitachi H8/300 architecture.
+ * Simulator for the Renesas (formerly Hitachi) H8/300 architecture.
  *
  * Written by Steve Chamberlain of Cygnus Support. sac@cygnus.com
  *
@@ -17,6 +17,7 @@
  * AND FITNESS FOR A PARTICULAR PURPOSE.
  */
 
+#include "config.h"
 #include <signal.h>
 #ifdef HAVE_TIME_H
 #include <time.h>
@@ -33,6 +34,7 @@
 #include "gdb/sim-h8300.h"
 #include "sys/stat.h"
 #include "sys/types.h"
+#include "sim-options.h"
 
 #ifndef SIGTRAP
 # define SIGTRAP 5
 
 int debug;
 
-host_callback *sim_callback;
-
-static SIM_OPEN_KIND sim_kind;
-static char *myname;
-
 /* FIXME: Needs to live in header file.
    This header should also include the things in remote-sim.h.
    One could move this to remote-sim.h but this function isn't needed
@@ -53,7 +50,7 @@ static void set_simcache_size (SIM_DESC, int);
 
 #define X(op, size)  (op * 4 + size)
 
-#define SP (h8300hmode ? SL : SW)
+#define SP (h8300hmode && !h8300_normal_mode ? SL : SW)
 
 #define h8_opcodes ops
 #define DEFINE_TABLE
@@ -61,32 +58,6 @@ static void set_simcache_size (SIM_DESC, int);
 
 /* CPU data object: */
 
-static int
-sim_state_initialize (SIM_DESC sd, sim_cpu *cpu)
-{
-  /* FIXME: not really necessary, since sim_cpu_alloc calls zalloc.  */
-
-  memset (&cpu->regs, 0, sizeof(cpu->regs));
-  cpu->regs[SBR_REGNUM] = 0xFFFFFF00;
-  cpu->pc = 0;
-  cpu->delayed_branch = 0;
-  cpu->memory = NULL;
-  cpu->eightbit = NULL;
-  cpu->mask = 0;
-
-  /* Initialize local simulator state.  */
-  sd->sim_cache = NULL;
-  sd->sim_cache_size = 0;
-  sd->cache_idx = NULL;
-  sd->cache_top = 0;
-  sd->memory_size = 0;
-  sd->compiles = 0;
-#ifdef ADEBUG
-  memset (&cpu->stats, 0, sizeof (cpu->stats));
-#endif
-  return 0;
-}
-
 static unsigned int
 h8_get_pc (SIM_DESC sd)
 {
@@ -484,6 +455,18 @@ enum { POLL_QUIT_INTERVAL = 0x80000 };
   h8_set_ccr (SD, (I << 7) | (UI << 6) | (H << 5) | (U << 4)   \
             | (N << 3) | (Z << 2) | (V << 1) | C)
 
+#define GETSR(SD) \
+  /* Get Status Register (flags).  */          \
+  c = (h8_get_ccr (sd) >> 0) & 1;              \
+  v = (h8_get_ccr (sd) >> 1) & 1;              \
+  nz = !((h8_get_ccr (sd) >> 2) & 1);          \
+  n = (h8_get_ccr (sd) >> 3) & 1;              \
+  u = (h8_get_ccr (sd) >> 4) & 1;              \
+  h = (h8_get_ccr (sd) >> 5) & 1;              \
+  ui = ((h8_get_ccr (sd) >> 6) & 1);           \
+  intMaskBit = (h8_get_ccr (sd) >> 7) & 1
+
+
 #ifdef __CHAR_IS_SIGNED__
 #define SEXTCHAR(x) ((char) (x))
 #endif
@@ -498,6 +481,7 @@ enum { POLL_QUIT_INTERVAL = 0x80000 };
 
 int h8300hmode  = 0;
 int h8300smode  = 0;
+int h8300_normal_mode  = 0;
 int h8300sxmode = 0;
 
 static int memory_size;
@@ -527,7 +511,7 @@ bitfrom (int x)
     case L_32:
       return SL;
     case L_P:
-      return h8300hmode ? SL : SW;
+      return (h8300hmode && !h8300_normal_mode)? SL : SW;
     }
   return 0;
 }
@@ -539,6 +523,8 @@ bitfrom (int x)
 static unsigned int
 lvalue (SIM_DESC sd, int x, int rn, unsigned int *val)
 {
+  SIM_CPU *cpu = STATE_CPU (sd, 0);
+
   if (val == NULL)     /* Paranoia.  */
     return -1;
 
@@ -554,7 +540,7 @@ lvalue (SIM_DESC sd, int x, int rn, unsigned int *val)
       *val = X (OP_MEM, SP);
       break;
     default:
-      sim_engine_set_run_state (sd, sim_stopped, SIGSEGV);
+      sim_engine_halt (sd, cpu, NULL, NULL_CIA, sim_stopped, SIM_SIGSEGV);
       return -1;
     }
   return 0;
@@ -563,9 +549,9 @@ lvalue (SIM_DESC sd, int x, int rn, unsigned int *val)
 static int
 cmdline_location()
 {
-  if (h8300smode)
+  if (h8300smode && !h8300_normal_mode)
     return 0xffff00L;
-  else if (h8300hmode)
+  else if (h8300hmode && !h8300_normal_mode)
     return 0x2ff00L;
   else
     return 0xff00L;
@@ -586,13 +572,18 @@ decode (SIM_DESC sd, int addr, unsigned char *data, decoded_inst *dst)
   /* Find the exact opcode/arg combo.  */
   for (q = h8_opcodes; q->name; q++)
     {
-      op_type *nib = q->data.nib;
+      const op_type *nib = q->data.nib;
       unsigned int len = 0;
 
       if ((q->available == AV_H8SX && !h8300sxmode) ||
+         (q->available == AV_H8S  && !h8300smode)  ||
          (q->available == AV_H8H  && !h8300hmode))
        continue;
 
+      cst[0]   = cst[1]   = cst[2]   = 0;
+      reg[0]   = reg[1]   = reg[2]   = 0;
+      rdisp[0] = rdisp[1] = rdisp[2] = 0;
+
       while (1)
        {
          op_type looking_for = *nib;
@@ -757,26 +748,11 @@ decode (SIM_DESC sd, int addr, unsigned char *data, decoded_inst *dst)
                       (looking_for & MODE) == INDEXB ||
                       (looking_for & MODE) == INDEXW ||
                       (looking_for & MODE) == INDEXL)
-
                {
                  switch (looking_for & SIZE)
                    {
                    case L_2:
                      cst[opnum] = thisnib & 3;
-
-                     /* DISP2 special treatment.  */
-                     if ((looking_for & MODE) == DISP)
-                       {
-                         switch (OP_SIZE (q->how)) {
-                         default: break;
-                         case SW:
-                           cst[opnum] *= 2;
-                           break;
-                         case SL:
-                           cst[opnum] *= 4;
-                           break;
-                         }
-                       }
                      break;
                    case L_8:
                      cst[opnum] = SEXTCHAR (data[len / 2]);
@@ -805,7 +781,9 @@ decode (SIM_DESC sd, int addr, unsigned char *data, decoded_inst *dst)
                       (looking_for & SIZE) == L_16U)
                {
                  cst[opnum] = (data[len / 2] << 8) + data[len / 2 + 1];
-                 if ((looking_for & SIZE) != L_16U)
+                 /* Immediates are always unsigned.  */
+                 if ((looking_for & SIZE) != L_16U &&
+                     (looking_for & MODE) != IMM)
                    cst[opnum] = (short) cst[opnum];    /* Sign extend.  */
                }
              else if (looking_for & ABSJMP)
@@ -831,6 +809,14 @@ decode (SIM_DESC sd, int addr, unsigned char *data, decoded_inst *dst)
                {
                  cst[opnum] = data[1];
                }
+             else if ((looking_for & MODE) == VECIND)
+               {
+                 if(h8300_normal_mode)
+                   cst[opnum] = ((data[1] & 0x7f) + 0x80) * 2;
+                 else
+                   cst[opnum] = ((data[1] & 0x7f) + 0x80) * 4;
+                 cst[opnum] += h8_get_vbr (sd); /* Add vector base reg.  */
+               }
              else if ((looking_for & SIZE) == L_32)
                {
                  int i = len / 2;
@@ -885,6 +871,10 @@ decode (SIM_DESC sd, int addr, unsigned char *data, decoded_inst *dst)
                      cst[opnum] = data[len / 2] & 0xff;
                    }
                }
+             else if ((looking_for & SIZE) == L_2)
+               {
+                 cst[opnum] = thisnib & 3;
+               }
              else if ((looking_for & SIZE) == L_3 ||
                       (looking_for & SIZE) == L_3NZ)
                {
@@ -907,7 +897,7 @@ decode (SIM_DESC sd, int addr, unsigned char *data, decoded_inst *dst)
 #endif
                  /* Fill in the args.  */
                  {
-                   op_type *args = q->args.nib;
+                   const op_type *args = q->args.nib;
                    int hadone = 0;
                    int nargs;
 
@@ -1001,7 +991,7 @@ decode (SIM_DESC sd, int addr, unsigned char *data, decoded_inst *dst)
                            p->literal = 0;
                            if (OP_KIND (q->how) == O_JSR ||
                                OP_KIND (q->how) == O_JMP)
-                             if (lvalue (sd, p->type, p->reg, &p->type))
+                             if (lvalue (sd, p->type, p->reg, (unsigned int *)&p->type))
                                goto end;
                          }
                        else if ((x & MODE) == ABS)
@@ -1025,14 +1015,15 @@ decode (SIM_DESC sd, int addr, unsigned char *data, decoded_inst *dst)
                            else
                              p->reg = ZERO_REGNUM;;
                          }
-                       else if ((x & MODE) == MEMIND)
+                       else if ((x & MODE) == MEMIND ||
+                                (x & MODE) == VECIND)
                          {
                            /* Size doesn't matter.  */
                            p->type = X (OP_MEM, SB);
                            p->literal = cst[opnum];
                            if (OP_KIND (q->how) == O_JSR ||
                                OP_KIND (q->how) == O_JMP)
-                             if (lvalue (sd, p->type, p->reg, &p->type))
+                             if (lvalue (sd, p->type, p->reg, (unsigned int *)&p->type))
                                goto end;
                          }
                        else if ((x & MODE) == PCREL)
@@ -1046,31 +1037,64 @@ decode (SIM_DESC sd, int addr, unsigned char *data, decoded_inst *dst)
                            p->type = X (OP_IMM, SP);
                            p->literal = cst[opnum];
                          }
-                       else if ((x & MODE) == INDEXB ||
-                                (x & MODE) == INDEXW ||
-                                (x & MODE) == INDEXL ||
-                                (x & MODE) == DISP)
+                       else if ((x & MODE) == INDEXB)
                          {
-                           /* Use the instruction to determine 
-                              the operand size.  */
-                           switch (x & MODE) {
-                           case INDEXB:
-                             p->type = X (OP_INDEXB, OP_SIZE (q->how));
-                             break;
-                           case INDEXW:
-                             p->type = X (OP_INDEXW, OP_SIZE (q->how));
-                             break;
-                           case INDEXL:
-                             p->type = X (OP_INDEXL, OP_SIZE (q->how));
-                             break;
-                           case DISP:
-                             p->type = X (OP_DISP,   OP_SIZE (q->how));
-                             break;
-                           }
-
+                           p->type = X (OP_INDEXB, OP_SIZE (q->how));
+                           p->literal = cst[opnum];
+                           p->reg     = rdisp[opnum];
+                         }
+                       else if ((x & MODE) == INDEXW)
+                         {
+                           p->type = X (OP_INDEXW, OP_SIZE (q->how));
+                           p->literal = cst[opnum];
+                           p->reg     = rdisp[opnum];
+                         }
+                       else if ((x & MODE) == INDEXL)
+                         {
+                           p->type = X (OP_INDEXL, OP_SIZE (q->how));
                            p->literal = cst[opnum];
                            p->reg     = rdisp[opnum];
                          }
+                       else if ((x & MODE) == DISP)
+                         {
+                           /* Yuck -- special for mova args.  */
+                           if (strncmp (q->name, "mova", 4) == 0 &&
+                               (x & SIZE) == L_2)
+                             {
+                               /* Mova can have a DISP2 dest, with an
+                                  INDEXB or INDEXW src.  The multiplier
+                                  for the displacement value is determined
+                                  by the src operand, not by the insn.  */
+
+                               switch (OP_KIND (dst->src.type))
+                                 {
+                                 case OP_INDEXB:
+                                   p->type = X (OP_DISP, SB);
+                                   p->literal = cst[opnum];
+                                   break;
+                                 case OP_INDEXW:
+                                   p->type = X (OP_DISP, SW);
+                                   p->literal = cst[opnum] * 2;
+                                   break;
+                                 default:
+                                   goto fail;
+                                 }
+                             }
+                           else
+                             {
+                               p->type = X (OP_DISP,   OP_SIZE (q->how));
+                               p->literal = cst[opnum];
+                               /* DISP2 is special.  */
+                               if ((x & SIZE) == L_2)
+                                 switch (OP_SIZE (q->how))
+                                   {
+                                   case SB:                  break;
+                                   case SW: p->literal *= 2; break;
+                                   case SL: p->literal *= 4; break;
+                                   }
+                             }
+                           p->reg     = rdisp[opnum];
+                         }
                        else if (x & CTRL)
                          {
                            switch (reg[opnum])
@@ -1104,7 +1128,7 @@ decode (SIM_DESC sd, int addr, unsigned char *data, decoded_inst *dst)
                            p->type = OP_EXR;
                          }
                        else
-                         printf ("Hmmmm %x...\n", x);
+                         printf ("Hmmmm 0x%x...\n", x);
 
                        args++;
                      }
@@ -1158,7 +1182,7 @@ decode (SIM_DESC sd, int addr, unsigned char *data, decoded_inst *dst)
                  return;
                }
              else
-               printf ("Don't understand %x \n", looking_for);
+               printf ("Don't understand 0x%x \n", looking_for);
            }
 
          len++;
@@ -1203,7 +1227,6 @@ compile (SIM_DESC sd, int pc)
 
 static unsigned char  *breg[32];
 static unsigned short *wreg[16];
-static unsigned int   *lreg[18];
 
 #define GET_B_REG(X)     *(breg[X])
 #define SET_B_REG(X, Y) (*(breg[X])) = (Y)
@@ -1259,6 +1282,7 @@ static unsigned int   *lreg[18];
 static int
 fetch_1 (SIM_DESC sd, ea_type *arg, int *val, int twice)
 {
+  SIM_CPU *cpu = STATE_CPU (sd, 0);
   int rn = arg->reg;
   int abs = arg->literal;
   int r;
@@ -1335,105 +1359,93 @@ fetch_1 (SIM_DESC sd, ea_type *arg, int *val, int twice)
       break;
     case X (OP_POSTINC, SB):   /* Register indirect w/post-incr: byte.  */
       t = GET_L_REG (rn);
-      t &= h8_get_mask (sd);
-      r = GET_MEMORY_B (t);
+      r = GET_MEMORY_B (t & h8_get_mask (sd));
       if (!twice)
        t += 1;
-      t = t & h8_get_mask (sd);
       SET_L_REG (rn, t);
       *val = r;
       break;
     case X (OP_POSTINC, SW):   /* Register indirect w/post-incr: word.  */
       t = GET_L_REG (rn);
-      t &= h8_get_mask (sd);
-      r = GET_MEMORY_W (t);
+      r = GET_MEMORY_W (t & h8_get_mask (sd));
       if (!twice)
        t += 2;
-      t = t & h8_get_mask (sd);
       SET_L_REG (rn, t);
       *val = r;
       break;
     case X (OP_POSTINC, SL):   /* Register indirect w/post-incr: long.  */
       t = GET_L_REG (rn);
-      t &= h8_get_mask (sd);
-      r = GET_MEMORY_L (t);
+      r = GET_MEMORY_L (t & h8_get_mask (sd));
       if (!twice)
        t += 4;
-      t = t & h8_get_mask (sd);
       SET_L_REG (rn, t);
       *val = r;
       break;
 
     case X (OP_POSTDEC, SB):   /* Register indirect w/post-decr: byte.  */
       t = GET_L_REG (rn);
-      t &= h8_get_mask (sd);
-      r = GET_MEMORY_B (t);
+      r = GET_MEMORY_B (t & h8_get_mask (sd));
       if (!twice)
        t -= 1;
-      t = t & h8_get_mask (sd);
       SET_L_REG (rn, t);
       *val = r;
       break;
     case X (OP_POSTDEC, SW):   /* Register indirect w/post-decr: word.  */
       t = GET_L_REG (rn);
-      t &= h8_get_mask (sd);
-      r = GET_MEMORY_W (t);
+      r = GET_MEMORY_W (t & h8_get_mask (sd));
       if (!twice)
        t -= 2;
-      t = t & h8_get_mask (sd);
       SET_L_REG (rn, t);
       *val = r;
       break;
     case X (OP_POSTDEC, SL):   /* Register indirect w/post-decr: long.  */
       t = GET_L_REG (rn);
-      t &= h8_get_mask (sd);
-      r = GET_MEMORY_L (t);
+      r = GET_MEMORY_L (t & h8_get_mask (sd));
       if (!twice)
        t -= 4;
-      t = t & h8_get_mask (sd);
       SET_L_REG (rn, t);
       *val = r;
       break;
 
     case X (OP_PREDEC, SB):    /* Register indirect w/pre-decr: byte.  */
       t = GET_L_REG (rn) - 1;
-      t &= h8_get_mask (sd);
       SET_L_REG (rn, t);
+      t &= h8_get_mask (sd);
       *val = GET_MEMORY_B (t);
       break;
       
     case X (OP_PREDEC, SW):    /* Register indirect w/pre-decr: word.  */
       t = GET_L_REG (rn) - 2;
-      t &= h8_get_mask (sd);
       SET_L_REG (rn, t);
+      t &= h8_get_mask (sd);
       *val = GET_MEMORY_W (t);
       break;
       
     case X (OP_PREDEC, SL):    /* Register indirect w/pre-decr: long.  */
       t = GET_L_REG (rn) - 4;
-      t &= h8_get_mask (sd);
       SET_L_REG (rn, t);
+      t &= h8_get_mask (sd);
       *val = GET_MEMORY_L (t);
       break;
       
     case X (OP_PREINC, SB):    /* Register indirect w/pre-incr: byte.  */
       t = GET_L_REG (rn) + 1;
-      t &= h8_get_mask (sd);
       SET_L_REG (rn, t);
+      t &= h8_get_mask (sd);
       *val = GET_MEMORY_B (t);
       break;
 
     case X (OP_PREINC, SW):    /* Register indirect w/pre-incr: long.  */
       t = GET_L_REG (rn) + 2;
-      t &= h8_get_mask (sd);
       SET_L_REG (rn, t);
+      t &= h8_get_mask (sd);
       *val = GET_MEMORY_W (t);
       break;
 
     case X (OP_PREINC, SL):    /* Register indirect w/pre-incr: long.  */
       t = GET_L_REG (rn) + 4;
-      t &= h8_get_mask (sd);
       SET_L_REG (rn, t);
+      t &= h8_get_mask (sd);
       *val = GET_MEMORY_L (t);
       break;
 
@@ -1476,7 +1488,7 @@ fetch_1 (SIM_DESC sd, ea_type *arg, int *val, int twice)
 
     case X (OP_MEM, SB):       /* Why isn't this implemented?  */
     default:
-      sim_engine_set_run_state (sd, sim_stopped, SIGSEGV);
+      sim_engine_halt (sd, cpu, NULL, NULL_CIA, sim_stopped, SIM_SIGSEGV);
       return -1;
     }
   return 0;    /* Success.  */
@@ -1507,6 +1519,7 @@ fetch2 (SIM_DESC sd, ea_type *arg, int *val)
 static int
 store_1 (SIM_DESC sd, ea_type *arg, int n, int twice)
 {
+  SIM_CPU *cpu = STATE_CPU (sd, 0);
   int rn = arg->reg;
   int abs = arg->literal;
   int t;
@@ -1570,8 +1583,8 @@ store_1 (SIM_DESC sd, ea_type *arg, int n, int twice)
       t = GET_L_REG (rn);
       if (!twice)
        t -= 1;
-      t &= h8_get_mask (sd);
       SET_L_REG (rn, t);
+      t &= h8_get_mask (sd);
       SET_MEMORY_B (t, n);
 
       break;
@@ -1579,8 +1592,8 @@ store_1 (SIM_DESC sd, ea_type *arg, int n, int twice)
       t = GET_L_REG (rn);
       if (!twice)
        t -= 2;
-      t &= h8_get_mask (sd);
       SET_L_REG (rn, t);
+      t &= h8_get_mask (sd);
       SET_MEMORY_W (t, n);
       break;
 
@@ -1588,8 +1601,8 @@ store_1 (SIM_DESC sd, ea_type *arg, int n, int twice)
       t = GET_L_REG (rn);
       if (!twice)
        t -= 4;
-      t &= h8_get_mask (sd);
       SET_L_REG (rn, t);
+      t &= h8_get_mask (sd);
       SET_MEMORY_L (t, n);
       break;
 
@@ -1597,8 +1610,8 @@ store_1 (SIM_DESC sd, ea_type *arg, int n, int twice)
       t = GET_L_REG (rn);
       if (!twice)
        t += 1;
-      t &= h8_get_mask (sd);
       SET_L_REG (rn, t);
+      t &= h8_get_mask (sd);
       SET_MEMORY_B (t, n);
 
       break;
@@ -1606,8 +1619,8 @@ store_1 (SIM_DESC sd, ea_type *arg, int n, int twice)
       t = GET_L_REG (rn);
       if (!twice)
        t += 2;
-      t &= h8_get_mask (sd);
       SET_L_REG (rn, t);
+      t &= h8_get_mask (sd);
       SET_MEMORY_W (t, n);
       break;
 
@@ -1615,45 +1628,51 @@ store_1 (SIM_DESC sd, ea_type *arg, int n, int twice)
       t = GET_L_REG (rn);
       if (!twice)
        t += 4;
-      t &= h8_get_mask (sd);
       SET_L_REG (rn, t);
+      t &= h8_get_mask (sd);
       SET_MEMORY_L (t, n);
       break;
 
     case X (OP_POSTDEC, SB):   /* Register indirect w/post-decr, byte.  */
-      t = GET_L_REG (rn) & h8_get_mask (sd);
-      SET_MEMORY_B (t, n);
+      t = GET_L_REG (rn);
       SET_L_REG (rn, t - 1);
+      t &= h8_get_mask (sd);
+      SET_MEMORY_B (t, n);
       break;
 
     case X (OP_POSTDEC, SW):   /* Register indirect w/post-decr, word.  */
-      t = GET_L_REG (rn) & h8_get_mask (sd);
-      SET_MEMORY_W (t, n);
+      t = GET_L_REG (rn);
       SET_L_REG (rn, t - 2);
+      t &= h8_get_mask (sd);
+      SET_MEMORY_W (t, n);
       break;
 
     case X (OP_POSTDEC, SL):   /* Register indirect w/post-decr, long.  */
-      t = GET_L_REG (rn) & h8_get_mask (sd);
-      SET_MEMORY_L (t, n);
+      t = GET_L_REG (rn);
       SET_L_REG (rn, t - 4);
+      t &= h8_get_mask (sd);
+      SET_MEMORY_L (t, n);
       break;
 
     case X (OP_POSTINC, SB):   /* Register indirect w/post-incr, byte.  */
-      t = GET_L_REG (rn) & h8_get_mask (sd);
-      SET_MEMORY_B (t, n);
+      t = GET_L_REG (rn);
       SET_L_REG (rn, t + 1);
+      t &= h8_get_mask (sd);
+      SET_MEMORY_B (t, n);
       break;
 
     case X (OP_POSTINC, SW):   /* Register indirect w/post-incr, word.  */
-      t = GET_L_REG (rn) & h8_get_mask (sd);
-      SET_MEMORY_W (t, n);
+      t = GET_L_REG (rn);
       SET_L_REG (rn, t + 2);
+      t &= h8_get_mask (sd);
+      SET_MEMORY_W (t, n);
       break;
 
     case X (OP_POSTINC, SL):   /* Register indirect w/post-incr, long.  */
-      t = GET_L_REG (rn) & h8_get_mask (sd);
-      SET_MEMORY_L (t, n);
+      t = GET_L_REG (rn);
       SET_L_REG (rn, t + 4);
+      t &= h8_get_mask (sd);
+      SET_MEMORY_L (t, n);
       break;
 
     case X (OP_DISP, SB):      /* Register indirect w/displacement, byte.  */
@@ -1679,7 +1698,7 @@ store_1 (SIM_DESC sd, ea_type *arg, int n, int twice)
     case X (OP_MEM, SW):       /* Why isn't this implemented?  */
     case X (OP_MEM, SL):       /* Why isn't this implemented?  */
     default:
-      sim_engine_set_run_state (sd, sim_stopped, SIGSEGV);
+      sim_engine_halt (sd, cpu, NULL, NULL_CIA, sim_stopped, SIM_SIGSEGV);
       return -1;
     }
   return 0;
@@ -1703,17 +1722,6 @@ store2 (SIM_DESC sd, ea_type *arg, int n)
   return store_1 (sd, arg, n, 1);
 }
 
-static union
-{
-  short int i;
-  struct
-    {
-      char low;
-      char high;
-    }
-  u;
-} littleendian;
-
 /* Flag to be set whenever a new SIM_DESC object is created.  */
 static int init_pointers_needed = 1;
 
@@ -1724,19 +1732,17 @@ init_pointers (SIM_DESC sd)
     {
       int i;
 
-      littleendian.i = 1;
-
-      if (h8300smode)
+      if (h8300smode && !h8300_normal_mode)
        memory_size = H8300S_MSIZE;
-      else if (h8300hmode)
+      else if (h8300hmode && !h8300_normal_mode)
        memory_size = H8300H_MSIZE;
       else
        memory_size = H8300_MSIZE;
       /* `msize' must be a power of two.  */
       if ((memory_size & (memory_size - 1)) != 0)
        {
-         (*sim_callback->printf_filtered) 
-           (sim_callback,
+         sim_io_printf
+           (sd,
             "init_pointers: bad memory size %d, defaulting to %d.\n", 
             memory_size, memory_size = H8300S_MSIZE);
        }
@@ -1796,15 +1802,11 @@ init_pointers (SIM_DESC sd)
            }
 
          if (wreg[i] == 0 || wreg[i + 8] == 0)
-           (*sim_callback->printf_filtered) (sim_callback, 
-                                             "init_pointers: internal error.\n");
+           sim_io_printf (sd, "init_pointers: internal error.\n");
 
          h8_set_reg (sd, i, 0);
-         lreg[i] = h8_get_reg_buf (sd) + i;
        }
 
-      /* Note: sim uses pseudo-register ZERO as a zero register.  */
-      lreg[ZERO_REGNUM] = h8_get_reg_buf (sd) + ZERO_REGNUM;
       init_pointers_needed = 0;
 
       /* Initialize the seg registers.  */
@@ -1813,23 +1815,6 @@ init_pointers (SIM_DESC sd)
     }
 }
 
-/* Grotty global variable for use by control_c signal handler.  */
-static SIM_DESC control_c_sim_desc;
-
-static void
-control_c (int sig)
-{
-  sim_engine_set_run_state (control_c_sim_desc, sim_stopped, SIGINT);
-}
-
-int
-sim_stop (SIM_DESC sd)
-{
-  /* FIXME: use a real signal value.  */
-  sim_engine_set_run_state (sd, sim_stopped, SIGINT);
-  return 1;
-}
-
 #define OBITOP(name, f, s, op)                         \
 case O (name, SB):                             \
 {                                              \
@@ -1840,7 +1825,7 @@ case O (name, SB):                                \
       goto end;                                        \
   if (fetch (sd, &code->src, &tmp))            \
     goto end;                                  \
-  m = 1 << tmp;                                        \
+  m = 1 << (tmp & 7);                          \
   op;                                          \
   if (s)                                       \
     if (store (sd, &code->dst,ea))             \
@@ -1848,15 +1833,12 @@ case O (name, SB):                              \
   goto next;                                   \
 }
 
-void
-sim_resume (SIM_DESC sd, int step, int siggnal)
+static void
+step_once (SIM_DESC sd, SIM_CPU *cpu)
 {
-  static int init1;
   int cycles = 0;
   int insts = 0;
   int tick_start = get_now ();
-  void (*prev) ();
-  int poll_count = 0;
   int res;
   int tmp;
   int rd;
@@ -1866,41 +1848,21 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
   int c, nz, v, n, u, h, ui, intMaskBit;
   int trace, intMask;
   int oldmask;
-  enum sim_stop reason;
-  int sigrc;
+  host_callback *sim_callback = STATE_CALLBACK (sd);
 
   init_pointers (sd);
 
-  control_c_sim_desc = sd;
-  prev = signal (SIGINT, control_c);
-
-  if (step)
-    {
-      sim_engine_set_run_state (sd, sim_stopped, SIGTRAP);
-    }
-  else
-    {
-      sim_engine_set_run_state (sd, sim_running, 0);
-    }
-
   pc = h8_get_pc (sd);
 
   /* The PC should never be odd.  */
   if (pc & 0x1)
     {
-      sim_engine_set_run_state (sd, sim_stopped, SIGBUS);
+      sim_engine_halt (sd, cpu, NULL, NULL_CIA, sim_stopped, SIM_SIGBUS);
       return;
     }
 
   /* Get Status Register (flags).  */
-  c = (h8_get_ccr (sd) >> 0) & 1;
-  v = (h8_get_ccr (sd) >> 1) & 1;
-  nz = !((h8_get_ccr (sd) >> 2) & 1);
-  n = (h8_get_ccr (sd) >> 3) & 1;
-  u = (h8_get_ccr (sd) >> 4) & 1;
-  h = (h8_get_ccr (sd) >> 5) & 1;
-  ui = ((h8_get_ccr (sd) >> 6) & 1);
-  intMaskBit = (h8_get_ccr (sd) >> 7) & 1;
+  GETSR (sd);
 
   if (h8300smode)      /* Get exr.  */
     {
@@ -1909,7 +1871,7 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
     }
 
   oldmask = h8_get_mask (sd);
-  if (!h8300hmode)
+  if (!h8300hmode || h8300_normal_mode)
     h8_set_mask (sd, 0xffff);
   do
     {
@@ -1960,8 +1922,47 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
                (mova/b, mova/w, mova/l).
             4) Add literal value of 1st argument (src).
             5) Store result in 3rd argument (op3).
+         */
+
+         /* Alas, since this is the only instruction with 3 arguments, 
+            decode doesn't handle them very well.  Some fix-up is required.
+
+            a) The size of dst is determined by whether src is 
+               INDEXB or INDEXW.  */
 
+         if (OP_KIND (code->src.type) == OP_INDEXB)
+           code->dst.type = X (OP_KIND (code->dst.type), SB);
+         else if (OP_KIND (code->src.type) == OP_INDEXW)
+           code->dst.type = X (OP_KIND (code->dst.type), SW);
+
+         /* b) If op3 == null, then this is the short form of the insn.
+               Dst is the dispreg of src, and op3 is the 32-bit form
+               of the same register.
          */
+
+         if (code->op3.type == 0)
+           {
+             /* Short form: src == INDEXB/INDEXW, dst == op3 == 0.
+                We get to compose dst and op3 as follows:
+
+                    op3 is a 32-bit register, ID == src.reg.
+                    dst is the same register, but 8 or 16 bits
+                    depending on whether src is INDEXB or INDEXW.
+             */
+
+             code->op3.type = X (OP_REG, SL);
+             code->op3.reg  = code->src.reg;
+             code->op3.literal = 0;
+
+             if (OP_KIND (code->src.type) == OP_INDEXB)
+               {
+                 code->dst.type = X (OP_REG, SB);
+                 code->dst.reg = code->op3.reg + 8;
+               }
+             else
+               code->dst.type = X (OP_REG, SW);
+           }
+
          if (fetch (sd, &code->dst, &ea))
            goto end;
 
@@ -2197,7 +2198,7 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
            goto end;
          goto just_flags_log32;
 
-       case O (O_MOVMD, SB):           /* movsd.b */
+       case O (O_MOVMD, SB):           /* movmd.b */
          ea = GET_W_REG (4);
          if (ea == 0)
            ea = 0x10000;
@@ -2212,7 +2213,7 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
            }
          goto next;
 
-       case O (O_MOVMD, SW):           /* movsd.b */
+       case O (O_MOVMD, SW):           /* movmd.w */
          ea = GET_W_REG (4);
          if (ea == 0)
            ea = 0x10000;
@@ -2227,7 +2228,7 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
            }
          goto next;
 
-       case O (O_MOVMD, SL):           /* movsd.b */
+       case O (O_MOVMD, SL):           /* movmd.l */
          ea = GET_W_REG (4);
          if (ea == 0)
            ea = 0x10000;
@@ -2486,7 +2487,7 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
            {
              if (h8300smode)
                h8_set_exr (sd, (trace << 7) | intMask);
-             res = h8_get_exr (sd);
+             rd = h8_get_exr (sd);
            }
          else
            goto illegal;
@@ -2713,7 +2714,7 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
 
            /* Setting char_ptr_size to the sizeof (char *) on the different
               architectures.  */
-           if (h8300hmode || h8300smode)
+           if ((h8300hmode || h8300smode) && !h8300_normal_mode)
              {
                char_ptr_size = 4;
              }
@@ -2727,7 +2728,7 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
                ind_arg_len = 0;
 
                /* The size of the commandline argument.  */
-               ind_arg_len = strlen (h8_get_cmdline_arg (sd, i) + 1);
+               ind_arg_len = strlen (h8_get_cmdline_arg (sd, i)) + 1;
 
                /* The total size of the command line string.  */
                size_cmdline += ind_arg_len;
@@ -2782,7 +2783,7 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
            for (i = 0; i < no_of_args; i++)
              {
                /* Saving the argv pointer.  */
-               if (h8300hmode || h8300smode)
+               if ((h8300hmode || h8300smode) && !h8300_normal_mode)
                  {
                    SET_MEMORY_L (argv_ptrs_location, argv_ptrs[i]);
                  }
@@ -2798,7 +2799,7 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
 
            /* Required by POSIX, Setting 0x0 at the end of the list of argv
               pointers.  */
-           if (h8300hmode || h8300smode)
+           if ((h8300hmode || h8300smode) && !h8300_normal_mode)
              {
                SET_MEMORY_L (old_sp, 0x0);
              }
@@ -2837,7 +2838,7 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
 
            /* Setting filename_ptr to first argument of open,  */
            /* and trying to get mode.  */
-           if (h8300sxmode || h8300hmode || h8300smode)
+           if ((h8300sxmode || h8300hmode || h8300smode) && !h8300_normal_mode)
              {
                filename_ptr = GET_L_REG (0);
                mode = GET_MEMORY_L (h8_get_reg (sd, SP_REGNUM) + 4);
@@ -2888,8 +2889,8 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
            int read_return = 0;        /* Return value from callback to
                                           read.  */
 
-           fd = h8300hmode ? GET_L_REG (0) : GET_W_REG (0);
-           buf_size = h8300hmode ? GET_L_REG (2) : GET_W_REG (2);
+           fd = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0);
+           buf_size = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (2) : GET_W_REG (2);
 
            char_ptr = (char *) malloc (sizeof (char) * buf_size);
 
@@ -2923,9 +2924,9 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
            int write_return;   /* Return value from callback to write.  */
            int i = 0;          /* Loop counter */
 
-           fd = h8300hmode ? GET_L_REG (0) : GET_W_REG (0);
-           char_ptr = h8300hmode ? GET_L_REG (1) : GET_W_REG (1);
-           len = h8300hmode ? GET_L_REG (2) : GET_W_REG (2);
+           fd = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0);
+           char_ptr = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (1) : GET_W_REG (1);
+           len = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (2) : GET_W_REG (2);
 
            /* Allocating space for the characters to be written.  */
            ptr = (char *) malloc (sizeof (char) * len);
@@ -2955,9 +2956,9 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
            int origin;         /* Origin */
            int lseek_return;   /* Return value from callback to lseek.  */
 
-           fd = h8300hmode ? GET_L_REG (0) : GET_W_REG (0);
-           offset = h8300hmode ? GET_L_REG (1) : GET_W_REG (1);
-           origin = h8300hmode ? GET_L_REG (2) : GET_W_REG (2);
+           fd = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0);
+           offset = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (1) : GET_W_REG (1);
+           origin = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (2) : GET_W_REG (2);
 
            /* Callback lseek and return offset.  */
            lseek_return =
@@ -2973,7 +2974,7 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
            int fd;             /* File descriptor */
            int close_return;   /* Return value from callback to close.  */
 
-           fd = h8300hmode ? GET_L_REG (0) : GET_W_REG (0);
+           fd = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0);
 
            /* Callback close and return.  */
            close_return = sim_callback->close (sim_callback, fd);
@@ -2991,13 +2992,14 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
            int stat_ptr;       /* Pointer to stat record.  */
            char *temp_stat_ptr;        /* Temporary stat_rec pointer.  */
 
-           fd = h8300hmode ? GET_L_REG (0) : GET_W_REG (0);
+           fd = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0);
 
            /* Setting stat_ptr to second argument of stat.  */
-           stat_ptr = h8300hmode ? GET_L_REG (1) : GET_W_REG (1);
+           stat_ptr = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (1) : GET_W_REG (1);
 
            /* Callback stat and return.  */
-           fstat_return = sim_callback->fstat (sim_callback, fd, &stat_rec);
+           fstat_return = sim_callback->to_fstat (sim_callback, fd,
+                                                  &stat_rec);
 
            /* Have stat_ptr point to starting of stat_rec.  */
            temp_stat_ptr = (char *) (&stat_rec);
@@ -3043,7 +3045,7 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
            int i = 0;          /* Loop Counter */
 
            /* Setting filename_ptr to first argument of open.  */
-           filename_ptr = h8300hmode ? GET_L_REG (0) : GET_W_REG (0);
+           filename_ptr = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0);
 
            /* Trying to find the length of the filename.  */
            temp_char = GET_MEMORY_B (h8_get_reg (sd, 0));
@@ -3067,11 +3069,11 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
 
            /* Setting stat_ptr to second argument of stat.  */
            /* stat_ptr = h8_get_reg (sd, 1); */
-           stat_ptr = h8300hmode ? GET_L_REG (1) : GET_W_REG (1);
+           stat_ptr = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (1) : GET_W_REG (1);
 
            /* Callback stat and return.  */
            stat_return =
-             sim_callback->stat (sim_callback, filename, &stat_rec);
+             sim_callback->to_stat (sim_callback, filename, &stat_rec);
 
            /* Have stat_ptr point to starting of stat_rec.  */
            temp_stat_ptr = (char *) (&stat_rec);
@@ -3134,10 +3136,10 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
          if (fetch2 (sd, &code->dst, &rd))
            goto end;
 
-         if (code->src.type == X (OP_IMM, SB))
+         if (memcmp (&code->src, &code->dst, sizeof (code->src)) == 0)
+           ea = 1;             /* unary  op */
+         else                  /* binary op */
            fetch (sd, &code->src, &ea);
-         else
-           ea = 1;
 
          if (code->opcode == O (O_SHLL, SB))
            {
@@ -3158,10 +3160,10 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
          if (fetch2 (sd, &code->dst, &rd))
            goto end;
 
-         if (code->src.type == X (OP_IMM, SW))
-           fetch (sd, &code->src, &ea);
+         if (memcmp (&code->src, &code->dst, sizeof (code->src)) == 0)
+           ea = 1;             /* unary  op */
          else
-           ea = 1;
+           fetch (sd, &code->src, &ea);
 
          if (code->opcode == O (O_SHLL, SW))
            {
@@ -3182,10 +3184,10 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
          if (fetch2 (sd, &code->dst, &rd))
            goto end;
 
-         if (code->src.type == X (OP_IMM, SL))
-           fetch (sd, &code->src, &ea);
+         if (memcmp (&code->src, &code->dst, sizeof (code->src)) == 0)
+           ea = 1;             /* unary  op */
          else
-           ea = 1;
+           fetch (sd, &code->src, &ea);
 
          if (code->opcode == O (O_SHLL, SL))
            {
@@ -3463,36 +3465,31 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
         case O (O_JMP, SL):
         case O (O_JMP, SB):            /* jmp */
         case O (O_JMP, SW):
-         {
-           fetch (sd, &code->src, &pc);
-           goto end;
-         }
+         fetch (sd, &code->src, &pc);
+         goto end;
 
        case O (O_JSR, SN):
        case O (O_JSR, SL):
        case O (O_JSR, SB):             /* jsr, jump to subroutine */
        case O (O_JSR, SW):
-         {
-           int tmp;
-           if (fetch (sd, &code->src, &pc))
-             goto end;
-         call:
-           tmp = h8_get_reg (sd, SP_REGNUM);
+         if (fetch (sd, &code->src, &pc))
+           goto end;
+       call:
+         tmp = h8_get_reg (sd, SP_REGNUM);
 
-           if (h8300hmode)
-             {
-               tmp -= 4;
-               SET_MEMORY_L (tmp, code->next_pc);
-             }
-           else
-             {
-               tmp -= 2;
-               SET_MEMORY_W (tmp, code->next_pc);
-             }
-           h8_set_reg (sd, SP_REGNUM, tmp);
+         if (h8300hmode && !h8300_normal_mode)
+           {
+             tmp -= 4;
+             SET_MEMORY_L (tmp, code->next_pc);
+           }
+         else
+           {
+             tmp -= 2;
+             SET_MEMORY_W (tmp, code->next_pc);
+           }
+         h8_set_reg (sd, SP_REGNUM, tmp);
 
-           goto end;
-         }
+         goto end;
 
        case O (O_BSR, SW):
        case O (O_BSR, SL):
@@ -3502,29 +3499,55 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
          pc = code->next_pc + res;
          goto call;
 
-       case O (O_RTS, SN):             /* rts, return from subroutine */
-         {
-           int tmp;
+       case O (O_RTE, SN):             /* rte, return from exception */
+       rte:
+         /* Pops exr and ccr before pc -- otherwise identical to rts.  */
+         tmp = h8_get_reg (sd, SP_REGNUM);
 
-           tmp = h8_get_reg (sd, SP_REGNUM);
+         if (h8300smode)                       /* pop exr */
+           {
+             h8_set_exr (sd, GET_MEMORY_L (tmp));
+             tmp += 4;
+           }
+         if (h8300hmode && !h8300_normal_mode)
+           {
+             h8_set_ccr (sd, GET_MEMORY_L (tmp));
+             tmp += 4;
+             pc = GET_MEMORY_L (tmp);
+             tmp += 4;
+           }
+         else
+           {
+             h8_set_ccr (sd, GET_MEMORY_W (tmp));
+             tmp += 2;
+             pc = GET_MEMORY_W (tmp);
+             tmp += 2;
+           }
 
-           if (h8300hmode)
-             {
-               pc = GET_MEMORY_L (tmp);
-               tmp += 4;
-             }
-           else
-             {
-               pc = GET_MEMORY_W (tmp);
-               tmp += 2;
-             }
+         GETSR (sd);
+         h8_set_reg (sd, SP_REGNUM, tmp);
+         goto end;
 
-           h8_set_reg (sd, SP_REGNUM, tmp);
-           goto end;
-         }
+       case O (O_RTS, SN):             /* rts, return from subroutine */
+       rts:
+         tmp = h8_get_reg (sd, SP_REGNUM);
+
+         if (h8300hmode && !h8300_normal_mode)
+           {
+             pc = GET_MEMORY_L (tmp);
+             tmp += 4;
+           }
+         else
+           {
+             pc = GET_MEMORY_W (tmp);
+             tmp += 2;
+           }
+
+         h8_set_reg (sd, SP_REGNUM, tmp);
+         goto end;
 
        case O (O_ILL, SB):             /* illegal */
-         sim_engine_set_run_state (sd, sim_stopped, SIGILL);
+         sim_engine_halt (sd, cpu, NULL, pc, sim_stopped, SIM_SIGILL);
          goto end;
 
        case O (O_SLEEP, SN):           /* sleep */
@@ -3534,18 +3557,65 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
              SIM_WIFEXITED (h8_get_reg (sd, 0)))
            {
              /* This trap comes from _exit, not from gdb.  */
-             sim_engine_set_run_state (sd, sim_exited, 
-                                       SIM_WEXITSTATUS (h8_get_reg (sd, 0)));
+             sim_engine_halt (sd, cpu, NULL, pc, sim_exited,
+                              SIM_WEXITSTATUS (h8_get_reg (sd, 0)));
+           }
+#if 0
+         /* Unfortunately this won't really work, because
+            when we take a breakpoint trap, R0 has a "random", 
+            user-defined value.  Don't see any immediate solution.  */
+         else if (SIM_WIFSTOPPED (h8_get_reg (sd, 0)))
+           {
+             /* Pass the stop signal up to gdb.  */
+             sim_engine_halt (sd, cpu, NULL, pc, sim_stopped,
+                              SIM_WSTOPSIG (h8_get_reg (sd, 0)));
            }
+#endif
          else
            {
              /* Treat it as a sigtrap.  */
-             sim_engine_set_run_state (sd, sim_stopped, SIGTRAP);
+             sim_engine_halt (sd, cpu, NULL, pc, sim_stopped, SIM_SIGTRAP);
+           }
+         goto end;
+
+       case O (O_TRAPA, SB):           /* trapa */
+         if (fetch (sd, &code->src, &res))
+           goto end;                   /* res is vector number.  */
+  
+         tmp = h8_get_reg (sd, SP_REGNUM);
+         if(h8300_normal_mode)
+           {
+             tmp -= 2;
+             SET_MEMORY_W (tmp, code->next_pc);
+             tmp -= 2;
+             SET_MEMORY_W (tmp, h8_get_ccr (sd));
+           }
+         else
+           {
+             tmp -= 4;
+             SET_MEMORY_L (tmp, code->next_pc);
+             tmp -= 4;
+             SET_MEMORY_L (tmp, h8_get_ccr (sd));
+           }
+         intMaskBit = 1;
+         BUILDSR (sd);
+         if (h8300smode)
+           {
+             tmp -= 4;
+             SET_MEMORY_L (tmp, h8_get_exr (sd));
            }
+
+         h8_set_reg (sd, SP_REGNUM, tmp);
+
+         if(h8300_normal_mode)
+           pc = GET_MEMORY_L (0x10 + res * 2); /* Vector addresses are 0x10,0x12,0x14 and 0x16 */
+         else
+           pc = GET_MEMORY_L (0x20 + res * 4);
          goto end;
 
        case O (O_BPT, SN):
-         sim_engine_set_run_state (sd, sim_stopped, SIGTRAP);
+         sim_engine_halt (sd, cpu, NULL, pc, sim_stopped, SIM_SIGTRAP);
          goto end;
 
        case O (O_BSETEQ, SB):
@@ -3738,13 +3808,7 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
              fetch (sd, &code->dst, &rd))
            goto end;
 
-         /* FIXME: is this the right place to be doing sign extend?  */
-         if (OP_KIND (code->src.type) == OP_IMM &&
-             (ea & 8) != 0)
-           ea |= 0xfff0;
-         else
-           ea = SEXTSHORT (ea);
-
+         ea = SEXTSHORT (ea);
          res = SEXTSHORT (ea * SEXTSHORT (rd));
 
          n  = res & 0x8000;
@@ -3759,11 +3823,6 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
              fetch (sd, &code->dst, &rd))
            goto end;
 
-         /* FIXME: is this the right place to be doing sign extend?  */
-         if (OP_KIND (code->src.type) == OP_IMM &&
-             (ea & 8) != 0)
-           ea |= 0xfffffff0;
-
          res = ea * rd;
 
          n  = res & 0x80000000;
@@ -3777,11 +3836,6 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
              fetch (sd, &code->dst, &rd))
            goto end;
 
-         /* FIXME: is this the right place to be doing sign extend?  */
-         if (OP_KIND (code->src.type) == OP_IMM &&
-             (ea & 8) != 0)
-           ea |= 0xfffffff0;
-
          /* Compute upper 32 bits of the 64-bit result.  */
          res = (((long long) ea) * ((long long) rd)) >> 32;
 
@@ -3837,13 +3891,7 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
              fetch (sd, &code->dst, &rd))
            goto end;
 
-         /* FIXME: is this the right place to be doing sign extend?  */
-         if (OP_KIND (code->src.type) == OP_IMM &&
-             (ea & 8) != 0)
-           ea |= 0xfffffff0;
-         else
-           ea = SEXTCHAR (ea);
-
+         ea = SEXTCHAR (ea);
          res = ea * SEXTCHAR (rd);
 
          n  = res & 0x8000;
@@ -3858,13 +3906,7 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
              fetch (sd, &code->dst, &rd))
            goto end;
 
-         /* FIXME: is this the right place to be doing sign extend?  */
-         if (OP_KIND (code->src.type) == OP_IMM &&
-             (ea & 8) != 0)
-           ea |= 0xfff0;
-         else
-           ea = SEXTSHORT (ea);
-
+         ea = SEXTSHORT (ea);
          res = ea * SEXTSHORT (rd & 0xffff);
 
          n  = res & 0x80000000;
@@ -3898,19 +3940,19 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
 
          goto next;
 
-       case O (O_TAS, SB):             /* tas, (test and set?) */
-         if (!h8300smode || code->src.type != X (OP_REG, SL))
-           goto illegal;
-         switch (code->src.reg)
-           {
-           case R0_REGNUM:
-           case R1_REGNUM:
-           case R4_REGNUM:
-           case R5_REGNUM:
-             break;
-           default:
-             goto illegal;
-           }
+       case O (O_TAS, SB):             /* tas (test and set) */
+         if (!h8300sxmode)             /* h8sx can use any register. */
+           switch (code->src.reg)
+             {
+             case R0_REGNUM:
+             case R1_REGNUM:
+             case R4_REGNUM:
+             case R5_REGNUM:
+               break;
+             default:
+               goto illegal;
+             }
+
          if (fetch (sd, &code->src, &res))
            goto end;
          if (store (sd, &code->src, res | 0x80))
@@ -3955,11 +3997,6 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
              fetch (sd, &code->dst, &rd))
            goto end;
 
-         /* FIXME: is this the right place to be doing sign extend?  */
-         if (OP_KIND (code->src.type) == OP_IMM &&
-             (ea & 8) != 0)
-           ea |= 0xfffffff0;
-
          if (ea)
            {
              res = SEXTSHORT (rd) / SEXTSHORT (ea);
@@ -3981,11 +4018,6 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
              fetch (sd, &code->dst, &rd))
            goto end;
 
-         /* FIXME: is this the right place to be doing sign extend?  */
-         if (OP_KIND (code->src.type) == OP_IMM &&
-             (ea & 8) != 0)
-           ea |= 0xfffffff0;
-
          if (ea)
            {
              res = rd / ea;
@@ -4023,7 +4055,7 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
              res = 0;
            }
 
-         if (store (sd, &code->dst, (res & 0xffff) | (tmp << 8)))
+         if (store (sd, &code->dst, (res & 0xff) | (tmp << 8)))
            goto end;
          goto next;
 
@@ -4057,13 +4089,7 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
            goto end;
 
          rd = SEXTSHORT (rd);
-
-         /* FIXME: is this the right place to be doing sign extend?  */
-         if (OP_KIND (code->src.type) == OP_IMM &&
-             (ea & 8) != 0)
-           ea |= 0xfffffff0;
-         else
-           ea = SEXTCHAR (ea);
+         ea = SEXTCHAR (ea);
 
          if (ea)
            {
@@ -4088,12 +4114,7 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
              fetch (sd, &code->dst, &rd))
            goto end;
 
-         /* FIXME: is this the right place to be doing sign extend?  */
-         if (OP_KIND (code->src.type) == OP_IMM &&
-             (ea & 8) != 0)
-           ea |= 0xfffffff0;
-         else
-           ea = SEXTSHORT (ea);
+         ea = SEXTSHORT (ea);
 
          if (ea)
            {
@@ -4190,25 +4211,33 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
          goto next;
 
        case O (O_LDM, SL):                     /* ldm,  load from memory */
+       case O (O_RTEL, SN):                    /* rte/l, ldm plus rte */
+       case O (O_RTSL, SN):                    /* rts/l, ldm plus rts */
          {
            int nregs, firstreg, i;
 
-           nregs = GET_MEMORY_B (pc + 1);
-           nregs >>= 4;
-           nregs &= 0xf;
-           firstreg = code->dst.reg;
-           firstreg &= 0xf;
+           nregs = ((GET_MEMORY_B (pc + 1) >> 4) & 0xf);
+           firstreg = code->dst.reg & 0xf;
            for (i = firstreg; i >= firstreg - nregs; i--)
              {
                h8_set_reg (sd, i, GET_MEMORY_L (h8_get_reg (sd, SP_REGNUM)));
                h8_set_reg (sd, SP_REGNUM, h8_get_reg (sd, SP_REGNUM) + 4);
              }
          }
-         goto next;
+         switch (code->opcode) {
+         case O (O_RTEL, SN):
+           goto rte;
+         case O (O_RTSL, SN):
+           goto rts;
+         case O (O_LDM, SL):
+           goto next;
+         default:
+           goto illegal;
+         }
 
        case O (O_DAA, SB):
          /* Decimal Adjust Addition.  This is for BCD arithmetic.  */
-         res = GET_B_REG (code->src.reg);
+         res = GET_B_REG (code->src.reg);      /* FIXME fetch? */
          if (!c && (0 <= (res >>  4) && (res >>  4) <= 9) && 
              !h && (0 <= (res & 0xf) && (res & 0xf) <= 9))
            res = res;          /* Value added == 0.  */
@@ -4259,14 +4288,13 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
 
        default:
        illegal:
-         sim_engine_set_run_state (sd, sim_stopped, SIGILL);
+         sim_engine_halt (sd, cpu, NULL, pc, sim_stopped, SIM_SIGILL);
          goto end;
 
        }
 
-      (*sim_callback->printf_filtered) (sim_callback,
-                                       "sim_resume: internal error.\n");
-      sim_engine_set_run_state (sd, sim_stopped, SIGILL);
+      sim_io_printf (sd, "sim_resume: internal error.\n");
+      sim_engine_halt (sd, cpu, NULL, pc, sim_stopped, SIM_SIGILL);
       goto end;
 
     setc:
@@ -4274,15 +4302,7 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
          code->dst.type == X (OP_CCR, SW))
        {
          h8_set_ccr (sd, res);
-         /* Get Status Register (flags).  */
-         c = (h8_get_ccr (sd) >> 0) & 1;
-         v = (h8_get_ccr (sd) >> 1) & 1;
-         nz = !((h8_get_ccr (sd) >> 2) & 1);
-         n = (h8_get_ccr (sd) >> 3) & 1;
-         u = (h8_get_ccr (sd) >> 4) & 1;
-         h = (h8_get_ccr (sd) >> 5) & 1;
-         ui = ((h8_get_ccr (sd) >> 6) & 1);
-         intMaskBit = (h8_get_ccr (sd) >> 7) & 1;
+         GETSR (sd);
        }
       else if (h8300smode &&
               (code->dst.type == X (OP_EXR, SB) ||
@@ -4485,18 +4505,9 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
       else
        pc = code->next_pc;
 
-    end:
-      
-      if (--poll_count < 0)
-       {
-         poll_count = POLL_QUIT_INTERVAL;
-         if ((*sim_callback->poll_quit) != NULL
-             && (*sim_callback->poll_quit) (sim_callback))
-           sim_engine_set_run_state (sd, sim_stopped, SIGINT);
-       }
-      sim_engine_get_run_state (sd, &reason, &sigrc);
-    } while (reason == sim_running);
+    } while (0);
 
+ end:
   h8_set_ticks (sd, h8_get_ticks (sd) + get_now () - tick_start);
   h8_set_cycles (sd, h8_get_cycles (sd) + cycles);
   h8_set_insts (sd, h8_get_insts (sd) + insts);
@@ -4507,20 +4518,30 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
     h8_set_exr (sd, (trace<<7) | intMask);
 
   h8_set_mask (sd, oldmask);
-  signal (SIGINT, prev);
 }
 
-int
-sim_trace (SIM_DESC sd)
+void
+sim_engine_run (SIM_DESC sd,
+               int next_cpu_nr,  /* ignore  */
+               int nr_cpus,      /* ignore  */
+               int siggnal)
 {
-  /* FIXME: Unfinished.  */
-  (*sim_callback->printf_filtered) (sim_callback,
-                                   "sim_trace: trace not supported.\n");
-  return 1;    /* Done.  */
+  sim_cpu *cpu;
+
+  SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
+
+  cpu = STATE_CPU (sd, 0);
+
+  while (1)
+    {
+      step_once (sd, cpu);
+      if (sim_events_tick (sd))
+       sim_events_process (sd);
+    }
 }
 
 int
-sim_write (SIM_DESC sd, SIM_ADDR addr, unsigned char *buffer, int size)
+sim_write (SIM_DESC sd, SIM_ADDR addr, const unsigned char *buffer, int size)
 {
   int i;
 
@@ -4555,9 +4576,8 @@ sim_read (SIM_DESC sd, SIM_ADDR addr, unsigned char *buffer, int size)
   return size;
 }
 
-
-int
-sim_store_register (SIM_DESC sd, int rn, unsigned char *value, int length)
+static int
+h8300_reg_store (SIM_CPU *cpu, int rn, unsigned char *value, int length)
 {
   int longval;
   int shortval;
@@ -4566,16 +4586,17 @@ sim_store_register (SIM_DESC sd, int rn, unsigned char *value, int length)
   shortval = (value[0] << 8) | (value[1]);
   intval = h8300hmode ? longval : shortval;
 
-  init_pointers (sd);
+  init_pointers (CPU_STATE (cpu));
   switch (rn)
     {
     case PC_REGNUM:
-      h8_set_pc (sd, intval);
+      if(h8300_normal_mode)
+        cpu->pc = shortval; /* PC for Normal mode is 2 bytes */
+      else
+        cpu->pc = intval;
       break;
     default:
-      (*sim_callback->printf_filtered) (sim_callback, 
-                                       "sim_store_register: bad regnum %d.\n",
-                                       rn);
+      return -1;
     case R0_REGNUM:
     case R1_REGNUM:
     case R2_REGNUM:
@@ -4584,56 +4605,46 @@ sim_store_register (SIM_DESC sd, int rn, unsigned char *value, int length)
     case R5_REGNUM:
     case R6_REGNUM:
     case R7_REGNUM:
-      h8_set_reg (sd, rn, intval);
-      break;
     case CCR_REGNUM:
-      h8_set_ccr (sd, intval);
-      break;
     case EXR_REGNUM:
-      h8_set_exr (sd, intval);
+    case SBR_REGNUM:
+    case VBR_REGNUM:
+    case MACH_REGNUM:
+    case MACL_REGNUM:
+      cpu->regs[rn] = intval;
       break;
     case CYCLE_REGNUM:
-      h8_set_cycles (sd, longval);
-      break;
-
     case INST_REGNUM:
-      h8_set_insts (sd, longval);
-      break;
-
     case TICK_REGNUM:
-      h8_set_ticks (sd, longval);
+      cpu->regs[rn] = longval;
       break;
     }
-  return -1;
+  return length;
 }
 
-int
-sim_fetch_register (SIM_DESC sd, int rn, unsigned char *buf, int length)
+static int
+h8300_reg_fetch (SIM_CPU *cpu, int rn, unsigned char *buf, int length)
 {
   int v;
   int longreg = 0;
 
-  init_pointers (sd);
+  init_pointers (CPU_STATE (cpu));
 
   if (!h8300smode && rn >= EXR_REGNUM)
     rn++;
   switch (rn)
     {
     default:
-      (*sim_callback->printf_filtered) (sim_callback, 
-                                       "sim_fetch_register: bad regnum %d.\n",
-                                       rn);
-      v = 0;
+      return -1;
+    case PC_REGNUM:
+      v = cpu->pc;
       break;
     case CCR_REGNUM:
-      v = h8_get_ccr (sd);
-      break;
     case EXR_REGNUM:
-      v = h8_get_exr (sd);
-      break;
-    case PC_REGNUM:
-      v = h8_get_pc (sd);
-      break;
+    case SBR_REGNUM:
+    case VBR_REGNUM:
+    case MACH_REGNUM:
+    case MACL_REGNUM:
     case R0_REGNUM:
     case R1_REGNUM:
     case R2_REGNUM:
@@ -4642,48 +4653,33 @@ sim_fetch_register (SIM_DESC sd, int rn, unsigned char *buf, int length)
     case R5_REGNUM:
     case R6_REGNUM:
     case R7_REGNUM:
-      v = h8_get_reg (sd, rn);
+      v = cpu->regs[rn];
       break;
     case CYCLE_REGNUM:
-      v = h8_get_cycles (sd);
-      longreg = 1;
-      break;
     case TICK_REGNUM:
-      v = h8_get_ticks (sd);
-      longreg = 1;
-      break;
     case INST_REGNUM:
-      v = h8_get_insts (sd);
+      v = cpu->regs[rn];
       longreg = 1;
       break;
+    case ZERO_REGNUM:
+      v = 0;
+      break;
     }
-  if (h8300hmode || longreg)
+  /* In Normal mode PC is 2 byte, but other registers are 4 byte */
+  if ((h8300hmode || longreg) && !(rn == PC_REGNUM && h8300_normal_mode))
     {
       buf[0] = v >> 24;
       buf[1] = v >> 16;
       buf[2] = v >> 8;
       buf[3] = v >> 0;
+      return 4;
     }
   else
     {
       buf[0] = v >> 8;
       buf[1] = v;
+      return 2;
     }
-  return -1;
-}
-
-void
-sim_stop_reason (SIM_DESC sd, enum sim_stop *reason, int *sigrc)
-{
-  sim_engine_get_run_state (sd, reason, sigrc);
-}
-
-/* FIXME: Rename to sim_set_mem_size.  */
-
-void
-sim_size (int n)
-{
-  /* Memory size is fixed.  */
 }
 
 static void
@@ -4705,28 +4701,14 @@ sim_info (SIM_DESC sd, int verbose)
   double timetaken = (double) h8_get_ticks (sd) / (double) now_persec ();
   double virttime = h8_get_cycles (sd) / 10.0e6;
 
-  (*sim_callback->printf_filtered) (sim_callback,
-                                   "\n\n#instructions executed  %10d\n",
-                                   h8_get_insts (sd));
-  (*sim_callback->printf_filtered) (sim_callback,
-                                   "#cycles (v approximate) %10d\n",
-                                   h8_get_cycles (sd));
-  (*sim_callback->printf_filtered) (sim_callback,
-                                   "#real time taken        %10.4f\n",
-                                   timetaken);
-  (*sim_callback->printf_filtered) (sim_callback,
-                                   "#virtual time taken     %10.4f\n",
-                                   virttime);
+  sim_io_printf (sd, "\n\n#instructions executed  %10d\n", h8_get_insts (sd));
+  sim_io_printf (sd, "#cycles (v approximate) %10d\n", h8_get_cycles (sd));
+  sim_io_printf (sd, "#real time taken        %10.4f\n", timetaken);
+  sim_io_printf (sd, "#virtual time taken     %10.4f\n", virttime);
   if (timetaken != 0.0)
-    (*sim_callback->printf_filtered) (sim_callback,
-                                     "#simulation ratio       %10.4f\n",
-                                     virttime / timetaken);
-  (*sim_callback->printf_filtered) (sim_callback,
-                                   "#compiles               %10d\n",
-                                   h8_get_compiles (sd));
-  (*sim_callback->printf_filtered) (sim_callback,
-                                   "#cache size             %10d\n",
-                                   sd->sim_cache_size);
+    sim_io_printf (sd, "#simulation ratio       %10.4f\n", virttime / timetaken);
+  sim_io_printf (sd, "#compiles               %10d\n", h8_get_compiles (sd));
+  sim_io_printf (sd, "#cache size             %10d\n", sd->sim_cache_size);
 
 #ifdef ADEBUG
   /* This to be conditional on `what' (aka `verbose'),
@@ -4737,8 +4719,7 @@ sim_info (SIM_DESC sd, int verbose)
       for (i = 0; i < O_LAST; i++)
        {
          if (h8_get_stats (sd, i))
-           (*sim_callback->printf_filtered) (sim_callback, "%d: %d\n", 
-                                             i, h8_get_stats (sd, i));
+           sim_io_printf (sd, "%d: %d\n", i, h8_get_stats (sd, i));
        }
     }
 #endif
@@ -4748,15 +4729,85 @@ sim_info (SIM_DESC sd, int verbose)
    FLAG is non-zero for the H8/300H.  */
 
 void
-set_h8300h (int h_flag, int s_flag, int sx_flag)
+set_h8300h (unsigned long machine)
 {
   /* FIXME: Much of the code in sim_load can be moved to sim_open.
      This function being replaced by a sim_open:ARGV configuration
      option.  */
 
-  h8300hmode  = h_flag;
-  h8300smode  = s_flag;
-  h8300sxmode = sx_flag;
+  h8300hmode = h8300smode = h8300sxmode = h8300_normal_mode = 0;
+
+  if (machine == bfd_mach_h8300sx || machine == bfd_mach_h8300sxn)
+    h8300sxmode = 1;
+
+  if (machine == bfd_mach_h8300s || machine == bfd_mach_h8300sn || h8300sxmode)
+    h8300smode = 1;
+
+  if (machine == bfd_mach_h8300h || machine == bfd_mach_h8300hn || h8300smode)
+    h8300hmode = 1;
+
+  if(machine == bfd_mach_h8300hn || machine == bfd_mach_h8300sn || machine == bfd_mach_h8300sxn)
+    h8300_normal_mode = 1;
+}
+
+/* H8300-specific options.
+   TODO: These really should be merged into the common model modules.  */
+typedef enum {
+  OPTION_H8300H,
+  OPTION_H8300S,
+  OPTION_H8300SX
+} H8300_OPTIONS;
+
+static SIM_RC
+h8300_option_handler (SIM_DESC sd, sim_cpu *cpu ATTRIBUTE_UNUSED, int opt,
+                     char *arg, int is_command ATTRIBUTE_UNUSED)
+{
+  switch ((H8300_OPTIONS) opt)
+    {
+    case OPTION_H8300H:
+      set_h8300h (bfd_mach_h8300h);
+      break;
+    case OPTION_H8300S:
+      set_h8300h (bfd_mach_h8300s);
+      break;
+    case OPTION_H8300SX:
+      set_h8300h (bfd_mach_h8300sx);
+      break;
+
+      default:
+       /* We'll actually never get here; the caller handles the error
+          case.  */
+       sim_io_eprintf (sd, "Unknown option `%s'\n", arg);
+       return SIM_RC_FAIL;
+    }
+
+  return SIM_RC_OK;
+}
+
+static const OPTION h8300_options[] =
+{
+  { {"h8300h", no_argument, NULL, OPTION_H8300H},
+      'h', NULL, "Indicate the CPU is H8/300H",
+      h8300_option_handler },
+  { {"h8300s", no_argument, NULL, OPTION_H8300S},
+      'S', NULL, "Indicate the CPU is H8S",
+      h8300_option_handler },
+  { {"h8300sx", no_argument, NULL, OPTION_H8300SX},
+      'x', NULL, "Indicate the CPU is H8SX",
+      h8300_option_handler },
+  { {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL, NULL }
+};
+
+static sim_cia
+h8300_pc_get (sim_cpu *cpu)
+{
+  return cpu->pc;
+}
+
+static void
+h8300_pc_set (sim_cpu *cpu, sim_cia pc)
+{
+  cpu->pc = pc;
 }
 
 /* Cover function of sim_state_free to free the cpu buffers as well.  */
@@ -4777,27 +4828,37 @@ sim_open (SIM_OPEN_KIND kind,
          struct bfd *abfd, 
          char **argv)
 {
+  int i;
   SIM_DESC sd;
   sim_cpu *cpu;
 
   sd = sim_state_alloc (kind, callback);
-  sd->cpu = sim_cpu_alloc (sd, 0);
+
+  /* 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)
+    {
+      free_state (sd);
+      return 0;
+    }
+
   cpu = STATE_CPU (sd, 0);
   SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
-  sim_state_initialize (sd, cpu);
+  cpu->regs[SBR_REGNUM] = 0xFFFFFF00;
   /* sim_cpu object is new, so some initialization is needed.  */
   init_pointers_needed = 1;
 
-  /* For compatibility (FIXME: is this right?).  */
-  current_alignment = NONSTRICT_ALIGNMENT;
-  current_target_byte_order = BIG_ENDIAN;
-
   if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
     {
       free_state (sd);
       return 0;
     }
 
+  if (sim_add_option_table (sd, NULL, h8300_options) != SIM_RC_OK)
+    {
+      free_state (sd);
+      return 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.  */
@@ -4834,26 +4895,28 @@ sim_open (SIM_OPEN_KIND kind,
       return 0;
     }
 
+  /* CPU specific initialization.  */
+  for (i = 0; i < MAX_NR_PROCESSORS; ++i)
+    {
+      SIM_CPU *cpu = STATE_CPU (sd, i);
+
+      CPU_REG_FETCH (cpu) = h8300_reg_fetch;
+      CPU_REG_STORE (cpu) = h8300_reg_store;
+      CPU_PC_FETCH (cpu) = h8300_pc_get;
+      CPU_PC_STORE (cpu) = h8300_pc_set;
+    }
+
   /*  sim_hw_configure (sd); */
 
   /* FIXME: Much of the code in sim_load can be moved here.  */
 
-  sim_kind = kind;
-  myname = argv[0];
-  sim_callback = callback;
   return sd;
 }
 
-void
-sim_close (SIM_DESC sd, int quitting)
-{
-  /* Nothing to do.  */
-}
-
 /* Called by gdb to load a program into memory.  */
 
 SIM_RC
-sim_load (SIM_DESC sd, char *prog, bfd *abfd, int from_tty)
+sim_load (SIM_DESC sd, const char *prog, bfd *abfd, int from_tty)
 {
   bfd *prog_bfd;
 
@@ -4866,21 +4929,14 @@ sim_load (SIM_DESC sd, char *prog, bfd *abfd, int from_tty)
   if (abfd != NULL)
     prog_bfd = abfd;
   else
-    prog_bfd = bfd_openr (prog, "coff-h8300");
+    prog_bfd = bfd_openr (prog, NULL);
   if (prog_bfd != NULL)
     {
       /* Set the cpu type.  We ignore failure from bfd_check_format
         and bfd_openr as sim_load_file checks too.  */
       if (bfd_check_format (prog_bfd, bfd_object))
        {
-         unsigned long mach = bfd_get_mach (prog_bfd);
-
-         set_h8300h (mach == bfd_mach_h8300h || 
-                     mach == bfd_mach_h8300s ||
-                     mach == bfd_mach_h8300sx,
-                     mach == bfd_mach_h8300s ||
-                     mach == bfd_mach_h8300sx,
-                     mach == bfd_mach_h8300sx);
+         set_h8300h (bfd_get_mach (prog_bfd));
        }
     }
 
@@ -4899,9 +4955,9 @@ sim_load (SIM_DESC sd, char *prog, bfd *abfd, int from_tty)
      switching between H8/300 and H8/300H programs without exiting
      gdb.  */
 
-  if (h8300smode)
+  if (h8300smode && !h8300_normal_mode)
     memory_size = H8300S_MSIZE;
-  else if (h8300hmode)
+  else if (h8300hmode && !h8300_normal_mode)
     memory_size = H8300H_MSIZE;
   else
     memory_size = H8300_MSIZE;
@@ -4917,19 +4973,19 @@ sim_load (SIM_DESC sd, char *prog, bfd *abfd, int from_tty)
                     calloc (sizeof (char), memory_size));
   h8_set_cache_idx_buf (sd, (unsigned short *) 
                        calloc (sizeof (short), memory_size));
+  sd->memory_size = memory_size;
   h8_set_eightbit_buf (sd, (unsigned char *) calloc (sizeof (char), 256));
 
   /* `msize' must be a power of two.  */
   if ((memory_size & (memory_size - 1)) != 0)
     {
-      (*sim_callback->printf_filtered) (sim_callback, 
-                                       "sim_load: bad memory size.\n");
+      sim_io_printf (sd, "sim_load: bad memory size.\n");
       return SIM_RC_FAIL;
     }
   h8_set_mask (sd, memory_size - 1);
 
-  if (sim_load_file (sd, myname, sim_callback, prog, prog_bfd,
-                    sim_kind == SIM_OPEN_DEBUG,
+  if (sim_load_file (sd, STATE_MY_NAME (sd), STATE_CALLBACK (sd), prog,
+                    prog_bfd, STATE_OPEN_KIND (sd) == SIM_OPEN_DEBUG,
                     0, sim_write)
       == NULL)
     {
@@ -4978,16 +5034,3 @@ sim_create_inferior (SIM_DESC sd, struct bfd *abfd, char **argv, char **env)
   
   return SIM_RC_OK;
 }
-
-void
-sim_do_command (SIM_DESC sd, char *cmd)
-{
-  (*sim_callback->printf_filtered) (sim_callback,
-                                   "This simulator does not accept any commands.\n");
-}
-
-void
-sim_set_callbacks (struct host_callback_struct *ptr)
-{
-  sim_callback = ptr;
-}