* test-build.mk (HOLES): Add "xargs" for gdb.
[deliverable/binutils-gdb.git] / gdb / remote-e7000.c
index 644650e5a2b150d55b6190c85b448153dbfc7bb2..7088e8b2a9180ada921cbf7f07b0b58134771d0b 100644 (file)
@@ -1,5 +1,5 @@
 /* Remote debugging interface for Hitachi E7000 ICE, for GDB
-   Copyright 1993 Free Software Foundation, Inc.
+   Copyright 1993, 1994, 1996 Free Software Foundation, Inc.
    Contributed by Cygnus Support. 
 
    Written by Steve Chamberlain for Cygnus Support.
 
    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., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
+/* The E7000 is an in-circuit emulator for the Hitachi H8/300-H and
+   Hitachi-SH processor.  It has serial port and a lan port.  
+
+   The monitor command set makes it difficult to load large ammounts of
+   data over the lan without using ftp - so try not to issue load
+   commands when communicating over ethernet; use the ftpload command.
+
+   The monitor pauses for a second when dumping srecords to the serial
+   line too, so we use a slower per byte mechanism but without the
+   startup overhead.  Even so, it's pretty slow... */
 
 #include "defs.h"
 #include "gdbcore.h"
+#include "inferior.h"
 #include "target.h"
 #include "wait.h"
-#include <varargs.h>
+#include "value.h"
+#include "command.h"
 #include <signal.h>
-#include <string.h>
+#include "gdb_string.h"
+#include "gdbcmd.h"
 #include <sys/types.h>
 #include "serial.h"
+#include "remote-utils.h"
+#include "symfile.h"
+#include <time.h>
 
+#if 1
+#define HARD_BREAKPOINTS       /* Now handled by set option. */
+#define BC_BREAKPOINTS use_hard_breakpoints
+#endif
 
-/* The E7000 is an in-circuit emulator for the Hitachi H8/300-H and
-Hitachi-SH processor.  It has serial port and a lan port.  
-
-The monitor command set makes it difficult to load large ammounts of
-data over the lan without using ftp - so try not to issue load
-commands when communicating over ethernet; use the ftpload command.
-
-The monitor pauses for a second when dumping srecords to the serial
-line too, so we use a slower per byte mechanism but without the
-startup overhead.  Even so, it's pretty slow... */
-
-int using_tcp; /* nonzero if using the tcp serial driver */
-
-extern struct target_ops e7000_ops;    /* Forward declaration */
 #define CTRLC 0x03
 #define ENQ  0x05
 #define ACK  0x06
 #define CTRLZ 0x1a
 
-char *ENQSTRING = "\005";
+extern void report_transfer_performance PARAMS ((unsigned long,
+                                                time_t, time_t));
+
+extern char *sh_processor_type;
+
+/* Local function declarations.  */
+
+static void e7000_close PARAMS ((int));
+
+static void e7000_fetch_register PARAMS ((int));
 
-int echo;
-int ctrl_c;
-static void e7000_close ();
-static void e7000_fetch_register ();
-static void e7000_store_register ();
+static void e7000_store_register PARAMS ((int));
 
-static int timeout = 5;
+static void e7000_command PARAMS ((char *, int));
+
+static void e7000_login_command PARAMS ((char *, int));
+
+static void e7000_ftp_command PARAMS ((char *, int));
+
+static void e7000_drain_command PARAMS ((char *, int));
 
 static void expect PARAMS ((char *));
-static void expect_full_prompt PARAMS (());
-static void expect_prompt PARAMS (());
+
+static void expect_full_prompt PARAMS ((void));
+
+static void expect_prompt PARAMS ((void));
+
+/* Variables. */
+
 static serial_t e7000_desc;
 
+/* Allow user to chose between using hardware breakpoints or memory. */
+static int use_hard_breakpoints = 0; /* use sw breakpoints by default */
 
-/* Send data to e7000debug.  Works just like printf. */
-#if 0
-static void
-printf_e7000debug (va_alist)
-     va_dcl
-{
-  va_list args;
-  char *pattern;
-  char buf[200];
+/* Nonzero if using the tcp serial driver.  */
 
-  va_start (args);
+static int using_tcp;  /* direct tcp connection to target */
+static int using_tcp_remote;   /* indirect connection to target 
+                                  via tcp to controller */
 
-  pattern = va_arg (args, char *);
+/* Nonzero if using the pc isa card.  */
 
-  vsprintf (buf, pattern, args);
-#else
+static int using_pc;
+
+extern struct target_ops e7000_ops;    /* Forward declaration */
+
+char *ENQSTRING = "\005";
+
+/* Nonzero if some routine (as opposed to the user) wants echoing.
+   FIXME: Do this reentrantly with an extra parameter.  */
+
+static int echo;
+
+static int ctrl_c;
+
+static int timeout = 20;
+
+/* Send data to e7000debug.  */
 
 static void
-printf_e7000debug(a,b,c,d,e)
-  {
-    char buf[200];
-    sprintf(buf, a,b,c,d,e);
-#endif
+puts_e7000debug (buf)
+     char *buf;
+{
+  if (!e7000_desc)
+    error ("Use \"target e7000 ...\" first.");
+
+  if (remote_debug)
+    printf("Sending %s\n", buf);
+
   if (SERIAL_WRITE (e7000_desc, buf, strlen (buf)))
     fprintf (stderr, "SERIAL_WRITE failed: %s\n", safe_strerror (errno));
 
-  /* And expect to see it echoed */
-  expect (buf);
+  /* And expect to see it echoed, unless using the pc interface */
+#if 0
+  if (!using_pc)
+#endif
+    expect (buf);
 }
 
 static void
 putchar_e7000 (x)
+     int x;
 {
   char b[1];
+
   b[0] = x;
   SERIAL_WRITE (e7000_desc, b, 1);
 }
@@ -112,6 +153,15 @@ write_e7000 (s)
   SERIAL_WRITE (e7000_desc, s, strlen (s));
 }
 
+static int
+normal (x)
+     int x;
+{
+  if (x == '\n')
+    return '\r';
+  return x;
+}
+
 /* Read a character from the remote system, doing all the fancy timeout
    stuff.  */
 
@@ -120,47 +170,78 @@ readchar (timeout)
      int timeout;
 {
   int c;
+
   do
     {
       c = SERIAL_READCHAR (e7000_desc, timeout);
     }
   while (c > 127);
+
   if (c == SERIAL_TIMEOUT)
     {
       if (timeout == 0)
-       return c;               /* Polls shouldn't generate timeout errors */
-
+       return -1;
+      echo = 0;
       error ("Timeout reading from remote system.");
     }
-  return c;
+  if (remote_debug) 
+    {
+      putchar (c);
+      fflush (stdout);
+    }
+
+  return normal (c);
 }
 
+#if 0
+char *
+tl (x)
+{
+  static char b[8][10];
+  static int p;
+
+  p++;
+  p &= 7;
+  if (x >= ' ') 
+    { 
+      b[p][0] = x;
+      b[p][1] = 0;
+    }
+  else
+    {
+      sprintf(b[p], "<%d>", x);
+    }
+
+  return b[p];
+}
+#endif
+
+/* Scan input from the remote system, until STRING is found.  If
+   DISCARD is non-zero, then discard non-matching input, else print it
+   out.  Let the user break out immediately.  */
 
-/* Scan input from the remote system, until STRING is found.  If DISCARD is
-   non-zero, then discard non-matching input, else print it out.
-   Let the user break out immediately.  */
 static void
 expect (string)
      char *string;
 {
   char *p = string;
   int c;
+  int nl = 0;
 
   while (1)
-
     {
       c = readchar (timeout);
-
       notice_quit ();
       if (quit_flag == 1) 
        {
-         if (ctrl_c) {
-           putchar_e7000(CTRLC);
-           ctrl_c -- ;
-         }
+         if (ctrl_c)
+           {
+             putchar_e7000(CTRLC);
+             --ctrl_c;
+           }
          else 
            {
-             quit();
+             quit ();
            }
        }
       
@@ -168,22 +249,32 @@ expect (string)
        {
          error ("Serial communication error");
        }
-      if (echo)
+      if (echo || remote_debug)
        {
-         if (c != '\r')
-           putchar (c);
+         if (c == '\r' || c == '\n')
+           {
+             if (!nl)
+               putchar ('\n');
+             nl = 1;
+           }
+         else
+           {
+             nl = 0;
+             putchar (c);
+           }
          fflush (stdout);
        }
-      if (c == *p++)
+      if (normal (c) == normal (*p++))
        {
          if (*p == '\0')
-           {
-             return;
-           }
+           return;
        }
       else
        {
          p = string;
+
+         if (normal (c) == normal (string[0]))
+           p++;
        }
     }
 }
@@ -194,27 +285,29 @@ expect (string)
    o give your command
    o *then* wait for the prompt.
 
-   Thus the last thing that a procedure does with the serial line
-   will be an expect_prompt().  Exception:  e7000_resume does not
-   wait for the prompt, because the terminal is being handed over
-   to the inferior.  However, the next thing which happens after that
-   is a e7000_wait which does wait for the prompt.
-   Note that this includes abnormal exit, e.g. error().  This is
-   necessary to prevent getting into states from which we can't
-   recover.  */
+   Thus the last thing that a procedure does with the serial line will
+   be an expect_prompt().  Exception: e7000_resume does not wait for
+   the prompt, because the terminal is being handed over to the
+   inferior.  However, the next thing which happens after that is a
+   e7000_wait which does wait for the prompt.  Note that this includes
+   abnormal exit, e.g. error().  This is necessary to prevent getting
+   into states from which we can't recover.  */
+
 static void
 expect_prompt ()
 {
   expect (":");
 }
+
 static void
 expect_full_prompt ()
 {
-  expect ("\n:");
+  expect ("\r:");
 }
 
 static int
-get_hex_digit (ch)
+convert_hex_digit (ch)
+     int ch;
 {
   if (ch >= '0' && ch <= '9')
     return ch - '0';
@@ -223,20 +316,17 @@ get_hex_digit (ch)
   else if (ch >= 'a' && ch <= 'f')
     return ch - 'a' + 10;
   return -1;
-
 }
 
-
-
 static int
 get_hex (start)
      int *start;
 {
-  int value = get_hex_digit (*start);
+  int value = convert_hex_digit (*start);
   int try;
 
   *start = readchar (timeout);
-  while ((try = get_hex_digit (*start)) >= 0)
+  while ((try = convert_hex_digit (*start)) >= 0)
     {
       value <<= 4;
       value += try;
@@ -245,8 +335,9 @@ get_hex (start)
   return value;
 }
 
-/* Get N 32-bit words from remote, each preceded by a space,
-   and put them in registers starting at REGNO.  */
+#if 0
+/* Get N 32-bit words from remote, each preceded by a space, and put
+   them in registers starting at REGNO.  */
 
 static void
 get_hex_regs (n, regno)
@@ -266,9 +357,11 @@ get_hex_regs (n, regno)
       supply_register (regno++, (char *) &val);
     }
 }
+#endif
 
 /* This is called not only when we first attach, but also when the
    user types "run" after having attached.  */
+
 static void
 e7000_create_inferior (execfile, args, env)
      char *execfile;
@@ -308,8 +401,8 @@ e7000_create_inferior (execfile, args, env)
   proceed ((CORE_ADDR) entry_pt, -1, 0);       /* Let 'er rip... */
 }
 
-/* Open a connection to a remote debugger.
-   NAME is the filename used for communication.  */
+/* Open a connection to a remote debugger.  NAME is the filename used
+   for communication.  */
 
 static int baudrate = 9600;
 static char dev_name[100];
@@ -320,6 +413,7 @@ static char *passwd = "";
 static char *dir = "";
 
 /* Grab the next token and buy some space for it */
+
 static char *
 next (ptr)
      char **ptr;
@@ -328,10 +422,9 @@ next (ptr)
   char *s;
   char *r;
   int l = 0;
+
   while (*p && *p == ' ')
-    {
-      p++;
-    }
+    p++;
   s = p;
   while (*p && (*p != ' ' && *p != '\t'))
     {
@@ -345,8 +438,8 @@ next (ptr)
   return r;
 }
 
-static
-e7000_login (args, from_tty)
+static void
+e7000_login_command (args, from_tty)
      char *args;
      int from_tty;
 {
@@ -369,76 +462,129 @@ e7000_login (args, from_tty)
 
 /* Start an ftp transfer from the E7000 to a host */
 
-static
-e7000_ftp (args, from_tty)
+static void
+e7000_ftp_command (args, from_tty)
      char *args;
      int from_tty;
 {
+  /* FIXME: arbitrary limit on machine names and such.  */
+  char buf[200];
+
   int oldtimeout = timeout;
-  timeout = 10;
-  printf_e7000debug ("ftp %s\r", machine);
+  timeout = remote_timeout;
+
+  sprintf (buf, "ftp %s\r", machine);
+  puts_e7000debug (buf);
   expect (" Username : ");
-  printf_e7000debug ("%s\r", user);
+  sprintf (buf, "%s\r", user);
+  puts_e7000debug (buf);
   expect (" Password : ");
   write_e7000 (passwd);
   write_e7000 ("\r");
   expect ("success\r");
   expect ("FTP>");
-  printf_e7000debug ("cd %s\r", dir);
+  sprintf (buf, "cd %s\r", dir);
+  puts_e7000debug (buf);
   expect ("FTP>");
-  printf_e7000debug ("ll 0;s:%s\r", args);
+  sprintf (buf, "ll 0;s:%s\r", args);
+  puts_e7000debug (buf);
   expect ("FTP>");
-  printf_e7000debug ("bye\r");
+  puts_e7000debug ("bye\r");
   expect (":");
   timeout = oldtimeout;
 }
 
+static int 
+e7000_parse_device(args,dev_name,serial_flag,baudrate) 
+    char *args;
+    char *dev_name;
+    int serial_flag;
+    int baudrate;
+{
+  char junk[128];
+  int n = 0;
+  if (args && strcasecmp (args, "pc") == 0)
+    {
+      strcpy (dev_name, args);
+      using_pc = 1;
+    }
+  else 
+    {
+      /* FIXME! temp hack to allow use with port master -
+            target tcp_remote <device> */
+      if (args && strncmp (args, "tcp_remote", 10) == 0) 
+        {
+         char com_type[128];
+         n = sscanf (args, " %s %s %d %s", com_type, dev_name, &baudrate, junk);
+         using_tcp_remote=1;
+         n--;
+        }
+      else if (args) 
+       {
+         n = sscanf (args, " %s %d %s", dev_name, &baudrate, junk);
+       }
+
+      if (n != 1 && n != 2)
+       {
+         error ("Bad arguments.  Usage:\ttarget e7000 <device> <speed>\n\
+or \t\ttarget e7000 <host>[:<port>]\n\
+or \t\ttarget e7000 tcp_remote <host>[:<port>]\n\
+or \t\ttarget e7000 pc\n");
+       }
+
+#if !defined(__GO32__) && !defined(__WIN32__)
+      /* FIXME!  test for ':' is ambiguous */
+      if (n == 1 && strchr (dev_name, ':') == 0)
+       {
+         /* Default to normal telnet port */
+         /* serial_open will use this to determine tcp communication */
+         strcat (dev_name, ":23");
+       }
+#endif
+      if (!using_tcp_remote && strchr (dev_name, ':'))
+        using_tcp = 1;
+    }
+
+  return n;
+}
+
 static void
 e7000_open (args, from_tty)
      char *args;
      int from_tty;
 {
   int n;
-  char junk[100];
+  int loop;
   int sync;
-  target_preopen (from_tty);
+  int serial_flag;
 
-  if (args)
-    n = sscanf (args, " %s %d %s", dev_name, &baudrate, junk);
-  else
-    n = 0;
-  if (n != 1 && n != 2)
-    error ("Bad arguments.  Usage:\ttarget e7000 <device> <speed>\n\
-or \t\ttarget e7000 <host>[:<port>]\n");
+  target_preopen (from_tty);
 
-  if (n == 1 && strchr (dev_name, ':') == 0)
-    {
-      /* Default to normal telnet port */
-      strcat (dev_name, ":23");
-    }
+  n = e7000_parse_device(args,dev_name,serial_flag,baudrate);
 
   push_target (&e7000_ops);
-  e7000_desc = SERIAL_OPEN (dev_name);
 
+  e7000_desc = SERIAL_OPEN (dev_name);
 
   if (!e7000_desc)
     perror_with_name (dev_name);
 
-  using_tcp = strcmp (e7000_desc->ops->name, "tcp") == 0;
-
   SERIAL_SETBAUDRATE (e7000_desc, baudrate);
   SERIAL_RAW (e7000_desc);
 
   /* Hello?  Are you there?  */
   sync = 0;
+  loop =  0;
   putchar_e7000 (CTRLC);
   while (!sync)
     {
       int c;
+
       if (from_tty)
        printf_unfiltered ("[waiting for e7000...]\n");
-      write_e7000 ("\r\n");
-      c = SERIAL_READCHAR (e7000_desc, 3);
+
+      write_e7000 ("\r");
+      c = SERIAL_READCHAR (e7000_desc, 1);
       while (c != SERIAL_TIMEOUT)
        {
          /* Dont echo cr's */
@@ -448,22 +594,35 @@ or \t\ttarget e7000 <host>[:<port>]\n");
              fflush (stdout);
            }
          if (c == ':')
+           sync = 1;
+
+         if (loop++ == 20) 
            {
-             sync = 1;
+             putchar_e7000 (CTRLC);
+             loop = 0;
            }
-         c = SERIAL_READCHAR (e7000_desc, 3);
+
+         QUIT ;
+
+
          if (quit_flag)
            {
              putchar_e7000 (CTRLC);
              quit_flag = 0;
            }
+         c = SERIAL_READCHAR (e7000_desc, 1);
        }
     }
-  printf_e7000debug ("\r\n");
+  puts_e7000debug ("\r");
+
+  expect_prompt ();
+
+  puts_e7000debug ("b -\r");
+
   expect_prompt ();
 
   if (from_tty)
-    printf_filtered ("Remote %s connected to %s\n", target_shortname,
+    printf_filtered ("Remote target %s connected to %s\n", target_shortname,
                     dev_name);
 
 #ifdef GDB_TARGET_IS_H8300
@@ -484,9 +643,9 @@ e7000_close (quitting)
     }
 }
 
-/* Terminate the open connection to the remote debugger.
-   Use this when you want to detach and do something else
-   with your gdb.  */
+/* Terminate the open connection to the remote debugger.  Use this
+   when you want to detach and do something else with your gdb.  */
+
 static void
 e7000_detach (from_tty)
      int from_tty;
@@ -503,31 +662,26 @@ e7000_resume (pid, step, sig)
      int pid, step, sig;
 {
   if (step)
-    {
-      printf_e7000debug ("S\r");
-    }
+    puts_e7000debug ("S\r");
   else
-    {
-      printf_e7000debug ("G\r");
-    }
+    puts_e7000debug ("G\r");
 }
 
 /* Read the remote registers into the block REGS.  
 
    For the H8/300 a register dump looks like:
 
-
- PC=00021A  CCR=80:I*******
- ER0 - ER3  0000000A 0000002E 0000002E 00000000
- ER4 - ER7  00000000 00000000 00000000 00FFEFF6
- 000218           MOV.B     R1L,R2L
- STEP NORMAL END or
- BREAK POINT
- */
+   PC=00021A  CCR=80:I*******
+   ER0 - ER3  0000000A 0000002E 0000002E 00000000
+   ER4 - ER7  00000000 00000000 00000000 00FFEFF6
+   000218           MOV.B     R1L,R2L
+   STEP NORMAL END or
+   BREAK POINT
+   */
 
 #ifdef GDB_TARGET_IS_H8300
-char *want = "\n\
- PC=%p CCR=%c\n\
+
+char *want = "PC=%p CCR=%c\n\
  ER0 - ER3  %0 %1 %2 %3\n\
  ER4 - ER7  %4 %5 %6 %7\n";
 
@@ -535,14 +689,15 @@ char *want_nopc = "%p CCR=%c\n\
  ER0 - ER3  %0 %1 %2 %3\n\
  ER4 - ER7  %4 %5 %6 %7";
 
-
 #endif
+
 #ifdef GDB_TARGET_IS_SH
-char *want = "\n PC=%16 SR=%22\n\
- PR=%17 GBR=%18 VBR=%19\n\
- MACH=%20 MACL=%21\n\
- R0-7  %0 %1 %2 %3 %4 %5 %6 %7\n\
- R8-15 %8 %9 %10 %11 %12 %13 %14 %15\n";
+
+char *want = "PC=%16 SR=%22\n\
+PR=%17 GBR=%18 VBR=%19\n\
+MACH=%20 MACL=%21\n\
+R0-7  %0 %1 %2 %3 %4 %5 %6 %7\n\
+R8-15 %8 %9 %10 %11 %12 %13 %14 %15\n";
 
 char *want_nopc = "%16 SR=%22\n\
  PR=%17 GBR=%18 VBR=%19\n\
@@ -550,31 +705,49 @@ char *want_nopc = "%16 SR=%22\n\
  R0-7  %0 %1 %2 %3 %4 %5 %6 %7\n\
  R8-15 %8 %9 %10 %11 %12 %13 %14 %15";
 
+char *want_sh3 = "PC=%16 SR=%22\n\
+PR=%17 GBR=%18 VBR=%19\n\
+MACH=%20 MACL=%21 SSR=%23 SPC=%24\n\
+R0-7  %0 %1 %2 %3 %4 %5 %6 %7\n\
+R8-15 %8 %9 %10 %11 %12 %13 %14 %15\n\
+R0_BANK0-R3_BANK0 %25 %26 %27 %28\n\
+R4_BANK0-R7_BANK0 %29 %30 %31 %32\n\
+R0_BANK1-R3_BANK1 %33 %34 %35 %36\n\
+R4_BANK1-R7_BANK1 %37 %38 %39 %40";
+
+char *want_sh3_nopc = "%16 SR=%22\n\
+ PR=%17 GBR=%18 VBR=%19\n\
+ MACH=%20 MACL=%21 SSR=%22 SPC=%23\n\
+ R0-7  %0 %1 %2 %3 %4 %5 %6 %7\n\
+ R8-15 %8 %9 %10 %11 %12 %13 %14 %15\n\
+ R0_BANK0-R3_BANK0 %25 %26 %27 %28\n\
+ R4_BANK0-R7_BANK0 %29 %30 %31 %32\n\
+ R0_BANK1-R3_BANK1 %33 %34 %35 %36\n\
+ R4_BANK1-R7_BANK1 %37 %38 %39 %40";
 
 #endif
 
-static
-int
+static int
 gch ()
 {
   int c = readchar (timeout);
-  if (echo)
+
+  if (remote_debug)
     {
       if (c >= ' ')
        printf ("%c", c);
       else if (c == '\n')
-       printf ("\n", c);
+       printf ("\n");
     }
   return c;
 }
 
-
-static
-unsigned int
+static unsigned int
 gbyte ()
 {
-  int high = get_hex_digit (gch ());
-  int low = get_hex_digit (gch ());
+  int high = convert_hex_digit (gch ());
+  int low = convert_hex_digit (gch ());
+
   return (high << 4) + low;
 }
 
@@ -586,24 +759,27 @@ fetch_regs_from_dump (nextchar, want)
   int regno;
   char buf[MAX_REGISTER_RAW_SIZE];
 
-  int  thischar = nextchar();
-  
+  int thischar = nextchar ();
+
   while (*want)
     {
       switch (*want)
        {
        case '\n':
-         while (thischar != '\n')
-           thischar = nextchar();
-         thischar = nextchar();
-         while (thischar == '\r')
-           thischar = nextchar();
+         /* Skip to end of line and then eat all new line type stuff */
+         while (thischar != '\n' && thischar != '\r') 
+           thischar = nextchar ();
+         while (thischar == '\n' || thischar == '\r') 
+           thischar = nextchar ();
          want++;
          break;
 
        case ' ':
-         while (thischar == ' ' || thischar == '\t' || thischar == '\r' || thischar == '\n')
-           thischar = nextchar();
+         while (thischar == ' '
+                || thischar == '\t'
+                || thischar == '\r'
+                || thischar == '\n')
+           thischar = nextchar ();
          want++;
          break;
          
@@ -612,15 +788,16 @@ fetch_regs_from_dump (nextchar, want)
            {
              want++;
              if (*want)
-               thischar = nextchar();
+               thischar = nextchar ();
              
            }
-         else if (thischar == ' ')
+         else if (thischar == ' ' || thischar == '\n' || thischar == '\r')
            {
-             thischar = nextchar();
+             thischar = nextchar ();
            }
          else {
-           error("out of sync in fetch registers");
+           error ("out of sync in fetch registers wanted <%s>, got <%c 0x%x>",
+                  want, thischar, thischar);
          }
     
          break;
@@ -654,14 +831,13 @@ fetch_regs_from_dump (nextchar, want)
              break;
 #endif
 
-
            default:
-             if (isdigit(want[0])) 
+             if (isdigit (want[0])) 
                {
-                 if (isdigit(want[1]))
+                 if (isdigit (want[1]))
                    {
                      regno = (want[0] - '0') * 10 + want[1] - '0';
-                     want+=2;
+                     want += 2;
                    }
                  else 
                    {
@@ -671,11 +847,11 @@ fetch_regs_from_dump (nextchar, want)
                }
              
              else
-               abort();
+               abort ();
            }
          store_signed_integer (buf,
                                REGISTER_RAW_SIZE(regno),
-                               (LONGEST)get_hex(&thischar, nextchar));
+                               (LONGEST) get_hex (&thischar, nextchar));
          supply_register (regno, buf);
          break;
        }
@@ -687,22 +863,31 @@ e7000_fetch_registers ()
 {
   int regno;
 
-  printf_e7000debug ("R\r");
+  puts_e7000debug ("R\r");
+
+#ifdef GDB_TARGET_IS_SH
+  if  ((sh_processor_type != NULL) && (*(sh_processor_type+2) == '3')) 
+     fetch_regs_from_dump (gch, want_sh3);
+  else
+     fetch_regs_from_dump (gch, want);
+#else
   fetch_regs_from_dump (gch, want);
+#endif
+
 
   /* And supply the extra ones the simulator uses */
   for (regno = NUM_REALREGS; regno < NUM_REGS; regno++)
     {
       int buf = 0;
+
       supply_register (regno, (char *) (&buf));
     }
 }
 
-/* Fetch register REGNO, or all registers if REGNO is -1.
-   Returns errno value.  */
+/* Fetch register REGNO, or all registers if REGNO is -1.  Returns
+   errno value.  */
 
-static
-void
+static void
 e7000_fetch_register (regno)
      int regno;
 {
@@ -722,80 +907,84 @@ e7000_store_registers ()
   registers_changed ();
 }
 
-/* Store register REGNO, or all if REGNO == 0.
-   Return errno value.  */
+/* Store register REGNO, or all if REGNO == 0.  Return errno value.  */
+
 static void
 e7000_store_register (regno)
      int regno;
 {
+  char buf[200];
+
   if (regno == -1)
     {
       e7000_store_registers ();
       return;
     }
+
 #ifdef GDB_TARGET_IS_H8300
   if (regno <= 7)
     {
-      printf_e7000debug (".ER%d %x\r", regno,
-                        read_register (regno));
-
+      sprintf (buf, ".ER%d %x\r", regno, read_register (regno));
+      puts_e7000debug (buf);
     }
   else if (regno == PC_REGNUM)
     {
-      printf_e7000debug (".PC %x\r",
-                        read_register (regno));
+      sprintf (buf, ".PC %x\r", read_register (regno));
+      puts_e7000debug (buf);
     }
   else if (regno == CCR_REGNUM)
     {
-      printf_e7000debug (".CCR %x\r",
-                        read_register (regno));
+      sprintf (buf, ".CCR %x\r", read_register (regno));
+      puts_e7000debug (buf);
     }
-#endif
+#endif /* GDB_TARGET_IS_H8300 */
 
 #ifdef  GDB_TARGET_IS_SH
   switch (regno)
     {
     default:
-      printf_e7000debug (".R%d %x\r", regno,
-                        read_register (regno));
-
+      sprintf (buf, ".R%d %x\r", regno, read_register (regno));
+      puts_e7000debug (buf);
       break;
+
     case PC_REGNUM:
-      printf_e7000debug (".PC %x\r",
-                        read_register (regno));
+      sprintf (buf, ".PC %x\r", read_register (regno));
+      puts_e7000debug (buf);
       break;
+
     case SR_REGNUM:
-      printf_e7000debug (".SR %x\r",
-                        read_register (regno));
+      sprintf (buf, ".SR %x\r", read_register (regno));
+      puts_e7000debug (buf);
       break;
 
     case PR_REGNUM:
-      printf_e7000debug (".PR %x\r",
-                        read_register (regno));
+      sprintf (buf, ".PR %x\r", read_register (regno));
+      puts_e7000debug (buf);
       break;
 
     case GBR_REGNUM:
-      printf_e7000debug (".GBR %x\r",
-                        read_register (regno));
+      sprintf (buf, ".GBR %x\r", read_register (regno));
+      puts_e7000debug (buf);
       break;
 
     case VBR_REGNUM:
-      printf_e7000debug (".VBR %x\r",
-                        read_register (regno));
+      sprintf (buf, ".VBR %x\r", read_register (regno));
+      puts_e7000debug (buf);
       break;
 
     case MACH_REGNUM:
-      printf_e7000debug (".MACH %x\r",
-                        read_register (regno));
+      sprintf (buf, ".MACH %x\r", read_register (regno));
+      puts_e7000debug (buf);
       break;
 
     case MACL_REGNUM:
-      printf_e7000debug (".MACL %x\r",
-                        read_register (regno));
+      sprintf (buf, ".MACL %x\r", read_register (regno));
+      puts_e7000debug (buf);
       break;
     }
 
-#endif
+#endif /* GDB_TARGET_IS_SH */
+
   expect_prompt ();
 }
 
@@ -814,23 +1003,24 @@ e7000_prepare_to_store ()
 static void
 e7000_files_info ()
 {
-  printf ("\tAttached to %s at %d baud.\n",
-         dev_name, baudrate);
+  printf ("\tAttached to %s at %d baud.\n", dev_name, baudrate);
 }
 
-static
-int
+static int
 stickbyte (where, what)
      char *where;
      unsigned int what;
 {
   static CONST char digs[] = "0123456789ABCDEF";
+
   where[0] = digs[(what >> 4) & 0xf];
   where[1] = digs[(what & 0xf) & 0xf];
+
   return what;
 }
 
-/* Write a small ammount of memory */
+/* Write a small ammount of memory. */
+
 static int
 write_small (memaddr, myaddr, len)
      CORE_ADDR memaddr;
@@ -838,30 +1028,34 @@ write_small (memaddr, myaddr, len)
      int len;
 {
   int i;
+  char buf[200];
+
   for (i = 0; i < len; i++)
     {
-      if (((memaddr + i) & 3) == 0
-         && (i + 3 < len))
+      if (((memaddr + i) & 3) == 0 && (i + 3 < len))
        {
          /* Can be done with a long word */
-         printf_e7000debug ("m %x %x%02x%02x%02x;l\r",
-                            memaddr + i,
-                            myaddr[i],
-                            myaddr[i + 1],
-                            myaddr[i + 2],
-                            myaddr[i + 3]);
+         sprintf (buf, "m %x %x%02x%02x%02x;l\r",
+                  memaddr + i,
+                  myaddr[i], myaddr[i + 1], myaddr[i + 2], myaddr[i + 3]);
+         puts_e7000debug (buf);
          i += 3;
        }
       else
        {
-         printf_e7000debug ("m %x %x\r", memaddr + i, myaddr[i]);
+         sprintf (buf, "m %x %x\r", memaddr + i, myaddr[i]);
+         puts_e7000debug (buf);
        }
     }
+
   expect_prompt ();
+
   return len;
 }
-/* Write a large ammount of memory, this only works with the serial mode enabled.
-   Command is sent as
+
+/* Write a large ammount of memory, this only works with the serial
+   mode enabled.  Command is sent as
+
        il ;s:s\r        ->
                        <- il ;s:s\r
                        <-      ENQ
@@ -872,7 +1066,7 @@ write_small (memaddr, myaddr, len)
                        <-      ENQ
        ACK             ->  
                        <-      :       
- */
 */
 
 static int
 write_large (memaddr, myaddr, len)
@@ -881,14 +1075,14 @@ write_large (memaddr, myaddr, len)
      int len;
 {
   int i;
-  int c;
 #define maxstride  128
   int stride;
 
-  printf_e7000debug ("IL ;S:FK\r");
+  puts_e7000debug ("IL ;S:FK\r");
   expect (ENQSTRING);
   putchar_e7000 (ACK);
   expect ("LO FK\r");
+
   for (i = 0; i < len; i += stride)
     {
       char compose[maxstride * 2 + 50];
@@ -897,6 +1091,7 @@ write_large (memaddr, myaddr, len)
       int check_sum;
       int where = 0;
       int alen;
+
       stride = len - i;
       if (stride > maxstride)
        stride = maxstride;
@@ -904,17 +1099,15 @@ write_large (memaddr, myaddr, len)
       compose[where++] = 'S';
       check_sum = 0;
       if (address >= 0xffffff)
-       {
-         alen = 4;
-       }
+       alen = 4;
       else if (address >= 0xffff)
-       {
-         alen = 3;
-       }
+       alen = 3;
       else
        alen = 2;
-      compose[where++] = alen - 1 + '0'; /* insert type */
-      check_sum += stickbyte (compose + where, alen + stride + 1); /* Insert length */
+      /* Insert type. */
+      compose[where++] = alen - 1 + '0';
+      /* Insert length. */
+      check_sum += stickbyte (compose + where, alen + stride + 1);
       where += 2;
       while (alen > 0)
        {
@@ -928,81 +1121,69 @@ write_large (memaddr, myaddr, len)
          check_sum += stickbyte (compose + where, myaddr[i + j]);
          where += 2;
        }
-
       stickbyte (compose + where, ~check_sum);
-
       where += 2;
       compose[where++] = '\r';
       compose[where++] = '\n';
       compose[where++] = 0;
-      {
-       char *z;
-       for (z = compose; *z; z++) ;
+
+      SERIAL_WRITE (e7000_desc, compose, where);
+      j = SERIAL_READCHAR (e7000_desc, 0);
+      if (j == SERIAL_TIMEOUT)
        {
-         SERIAL_WRITE (e7000_desc, compose, where);
-         j = SERIAL_READCHAR (e7000_desc, 0);
-         if (j == SERIAL_TIMEOUT)
-           {
-             /* This is ok - nothing there */
-           }
-         else if (j == ENQ)
-           {
-             /* Hmm, it's trying to tell us something */
-             expect (":");
-             error ("Error writing memory");
-           }
-         else
+         /* This is ok - nothing there */
+       }
+      else if (j == ENQ)
+       {
+         /* Hmm, it's trying to tell us something */
+         expect (":");
+         error ("Error writing memory");
+       }
+      else
+       {
+         printf ("@%d}@", j);
+         while ((j = SERIAL_READCHAR(e7000_desc,0)) > 0) 
            {
-             printf ("@%d}@", j);
-             while ((j = SERIAL_READCHAR(e7000_desc,0)) > 0) 
-               {
-                 printf ("@{%d}@",j);
-               }
+             printf ("@{%d}@",j);
            }
        }
-      }
     }
+
   /* Send the trailer record */
   write_e7000 ("S70500000000FA\r");
   putchar_e7000 (CTRLZ);
   expect (ENQSTRING);
   putchar_e7000 (ACK);
   expect (":");
+
   return len;
 }
 
-/* Copy LEN bytes of data from debugger memory at MYADDR
-   to inferior's memory at MEMADDR.  Returns length moved.  
+/* Copy LEN bytes of data from debugger memory at MYADDR to inferior's
+   memory at MEMADDR.  Returns length moved.
+
+   Can't use the Srecord load over ethernet, so don't use fast method
+   then.  */
 
-   Can't use the Srecord load over ethernet, so dont use 
-   fast method then.
- */
 static int
 e7000_write_inferior_memory (memaddr, myaddr, len)
      CORE_ADDR memaddr;
      unsigned char *myaddr;
      int len;
 {
-  if (len < 16 || using_tcp)
-    {
-      return write_small (memaddr, myaddr, len);
-    }
+  if (len < 16 || using_tcp || using_pc)
+    return write_small (memaddr, myaddr, len);
   else
-    {
-      return write_large (memaddr, myaddr, len);
-    }
+    return write_large (memaddr, myaddr, len);
 }
 
-
 /* Read LEN bytes from inferior memory at MEMADDR.  Put the result
    at debugger address MYADDR.  Returns length moved. 
 
-
   Small transactions we send
   m <addr>;l
   and receive
     00000000 12345678 ?
-
  */
 
 static int
@@ -1014,30 +1195,33 @@ e7000_read_inferior_memory (memaddr, myaddr, len)
   int count;
   int c;
   int i;
+  char buf[200];
   /* Starting address of this pass.  */
 
+/*  printf("READ INF %x %x %d\n", memaddr, myaddr, len);*/
   if (((memaddr - 1) + len) < memaddr)
     {
       errno = EIO;
       return 0;
     }
 
-  printf_e7000debug ("m %x;l\r", memaddr);
+  sprintf (buf, "m %x;l\r", memaddr);
+  puts_e7000debug (buf);
 
   for (count = 0; count < len; count += 4) 
     {
       /* Suck away the address */
-      c = gch();       
+      c = gch ();      
       while (c != ' ')
-       c = gch();      
-      c = gch();
+       c = gch ();     
+      c = gch ();
       if (c == '*') 
        {                       /* Some kind of error */
          expect_prompt();
          return -1;
        }
       while (c != ' ')
-       c = gch();      
+       c = gch ();     
 
       /* Now read in the data */
       for (i = 0; i < 4; i++) 
@@ -1049,18 +1233,20 @@ e7000_read_inferior_memory (memaddr, myaddr, len)
        }
 
       /* Skip the trailing ? and send a . to end and a cr for more */
-      gch();   
-      gch();
+      gch ();  
+      gch ();
       if (count + 4 >= len)
-       printf_e7000debug(".\r");
+       puts_e7000debug(".\r");
       else
-       printf_e7000debug("\r");
+       puts_e7000debug("\r");
+
     }
   expect_prompt();
+  return len;
 }
 
 
-#if 0
+
 /*
   For large transfers we used to send
 
@@ -1068,27 +1254,27 @@ e7000_read_inferior_memory (memaddr, myaddr, len)
   d <addr> <endaddr>\r
 
   and receive
-   <ADDR>              <    D   A   T   A    >               <   ASCII CODE   >
-   000000  5F FD FD FF DF 7F DF FF  01 00 01 00 02 00 08 04  "_..............."
-   000010  FF D7 FF 7F D7 F1 7F FF  00 05 00 00 08 00 40 00  "..............@."
-   000020  7F FD FF F7 7F FF FF F7  00 00 00 00 00 00 00 00  "................"
+   <ADDRESS>           <    D   A   T   A    >               <   ASCII CODE   >
+   00000000 5F FD FD FF DF 7F DF FF  01 00 01 00 02 00 08 04  "_..............."
+   00000010 FF D7 FF 7F D7 F1 7F FF  00 05 00 00 08 00 40 00  "..............@."
+   00000020 7F FD FF F7 7F FF FF F7  00 00 00 00 00 00 00 00  "................"
 
   A cost in chars for each transaction of 80 + 5*n-bytes. 
 
-
   Large transactions could be done with the srecord load code, but
   there is a pause for a second before dumping starts, which slows the
   average rate down!
 */
 
 static int
-e7000_read_inferior_memory (memaddr, myaddr, len)
+e7000_read_inferior_memory_large (memaddr, myaddr, len)
      CORE_ADDR memaddr;
      unsigned char *myaddr;
      int len;
 {
   int count;
   int c;
+  char buf[200];
 
   /* Starting address of this pass.  */
 
@@ -1098,33 +1284,27 @@ e7000_read_inferior_memory (memaddr, myaddr, len)
       return 0;
     }
 
-  printf_e7000debug ("d %x %x\r", memaddr, memaddr + len - 1);
+  sprintf (buf, "d %x %x\r", memaddr, memaddr + len - 1);
+  puts_e7000debug (buf);
 
   count = 0;
   c = gch ();
-
-  /* First skip the command */
-  while (c == '\n')
-    c = gch ();
-
-  while (c == ' ')
+  
+  /* skip down to the first ">" */
+  while( c != '>' )
     c = gch ();
-  if (c == '*')
-    {
-      expect ("\r");
-      return -1;
-    }
-
-  /* Skip the title line */
-  while (c != '\n')
+  /* now skip to the end of that line */
+  while( c != '\r' )
     c = gch ();
   c = gch ();
+
   while (count < len)
     {
-      /* Skip the address */
+      /* get rid of any white space before the address */
       while (c <= ' ')
        c = gch ();
 
+      /* Skip the address */
       get_hex (&c);
 
       /* read in the bytes on the line */
@@ -1137,17 +1317,20 @@ e7000_read_inferior_memory (memaddr, myaddr, len)
              myaddr[count++] = get_hex (&c);
            }
        }
-
-      while (c != '\n')
+      /* throw out the rest of the line */
+      while( c != '\r' )
        c = gch ();
     }
 
+  /* wait for the ":" prompt */
   while (c != ':')
     c = gch ();
 
   return len;
 }
 
+#if 0
+
 static int
 fast_but_for_the_pause_e7000_read_inferior_memory (memaddr, myaddr, len)
      CORE_ADDR memaddr;
@@ -1156,6 +1339,7 @@ fast_but_for_the_pause_e7000_read_inferior_memory (memaddr, myaddr, len)
 {
   int loop;
   int c;
+  char buf[200];
 
   if (((memaddr - 1) + len) < memaddr)
     {
@@ -1163,7 +1347,8 @@ fast_but_for_the_pause_e7000_read_inferior_memory (memaddr, myaddr, len)
       return 0;
     }
 
-  printf_e7000debug ("is %x@%x:s\r", memaddr, len);
+  sprintf (buf, "is %x@%x:s\r", memaddr, len);
+  puts_e7000debug (buf);
   gch ();
   c = gch ();
   if (c != ENQ)
@@ -1180,6 +1365,7 @@ fast_but_for_the_pause_e7000_read_inferior_memory (memaddr, myaddr, len)
       int length;
       int addr;
       int i;
+
       c = gch ();
       switch (c)
        {
@@ -1207,6 +1393,7 @@ fast_but_for_the_pause_e7000_read_inferior_memory (memaddr, myaddr, len)
            case '3':
              {
                int alen;
+
                alen = type - '0' + 1;
                addr = 0;
                while (alen--)
@@ -1216,14 +1403,14 @@ fast_but_for_the_pause_e7000_read_inferior_memory (memaddr, myaddr, len)
                  }
 
                for (i = 0; i < length - 1; i++)
-                 {
-                   myaddr[i + addr - memaddr] = gbyte ();
-                 }
+                 myaddr[i + addr - memaddr] = gbyte ();
+
                gbyte ();       /* Ignore checksum */
              }
            }
        }
     }
+
   putchar_e7000 (ACK);
   expect ("TOP ADDRESS =");
   expect ("END ADDRESS =");
@@ -1243,13 +1430,12 @@ e7000_xfer_inferior_memory (memaddr, myaddr, len, write, target)
      struct target_ops *target;        /* ignored */
 {
   if (write)
-    {
-      return e7000_write_inferior_memory( memaddr, myaddr, len);
-    }
-  else
-    {
+    return e7000_write_inferior_memory( memaddr, myaddr, len);
+  else 
+    if( len < 16 )
       return e7000_read_inferior_memory( memaddr, myaddr, len);
-    }
+    else
+      return e7000_read_inferior_memory_large( memaddr, myaddr, len);
 }
 
 static void
@@ -1257,7 +1443,187 @@ e7000_kill (args, from_tty)
      char *args;
      int from_tty;
 {
+}
+
+static void
+e7000_load (args, from_tty)
+     char *args;
+     int from_tty;
+{
+  struct cleanup *old_chain;
+  asection *section;
+  bfd *pbfd;
+  bfd_vma entry;
+  int i;
+#define WRITESIZE 0x1000
+  char buf[2 + 4 + 4 + WRITESIZE]; /* `DT' + <addr> + <len> + <data> */
+  char *filename;
+  int quiet;
+  int nostart;
+  time_t start_time, end_time; /* Start and end times of download */
+  unsigned long data_count;    /* Number of bytes transferred to memory */
+  int oldtimeout = timeout;    
+
+  timeout = remote_timeout;
+
+
+  /* FIXME! change test to test for type of download */
+  if (!using_tcp)
+    {
+      generic_load (args, from_tty);
+      return;
+    }
+
+  /* for direct tcp connections, we can do a fast binary download */
+  buf[0] = 'D';
+  buf[1] = 'T';
+  quiet = 0;
+  nostart = 0;
+  filename = NULL;
+
+  while (*args != '\000')
+    {
+      char *arg;
+
+      while (isspace (*args)) args++;
+
+      arg = args;
+
+      while ((*args != '\000') && !isspace (*args)) args++;
+
+      if (*args != '\000')
+       *args++ = '\000';
+
+      if (*arg != '-')
+       filename = arg;
+      else if (strncmp (arg, "-quiet", strlen (arg)) == 0)
+       quiet = 1;
+      else if (strncmp (arg, "-nostart", strlen (arg)) == 0)
+       nostart = 1;
+      else
+       error ("unknown option `%s'", arg);
+    }
+
+  if (!filename)
+    filename = get_exec_file (1);
+
+  pbfd = bfd_openr (filename, gnutarget);
+  if (pbfd == NULL)
+    {
+      perror_with_name (filename);
+      return;
+    }
+  old_chain = make_cleanup (bfd_close, pbfd);
+
+  if (!bfd_check_format (pbfd, bfd_object)) 
+    error ("\"%s\" is not an object file: %s", filename,
+          bfd_errmsg (bfd_get_error ()));
+
+  start_time = time (NULL);
+  data_count = 0;
+
+  puts_e7000debug ("mw\r");
+
+  expect ("\nOK");
+
+  for (section = pbfd->sections; section; section = section->next) 
+    {
+      if (bfd_get_section_flags (pbfd, section) & SEC_LOAD)
+       {
+         bfd_vma section_address;
+         bfd_size_type section_size;
+         file_ptr fptr;
+
+         section_address = bfd_get_section_vma (pbfd, section);
+         section_size = bfd_get_section_size_before_reloc (section);
+
+         if (!quiet)
+           printf_filtered ("[Loading section %s at 0x%x (%d bytes)]\n",
+                            bfd_get_section_name (pbfd, section),
+                            section_address,
+                            section_size);
 
+         fptr = 0;
+         
+         data_count += section_size;
+
+         while (section_size > 0)
+           {
+             int count;
+             static char inds[] = "|/-\\";
+             static int k = 0;
+
+             QUIT;
+
+             count = min (section_size, WRITESIZE);
+
+             buf[2] = section_address >> 24;
+             buf[3] = section_address >> 16;
+             buf[4] = section_address >> 8;
+             buf[5] = section_address;
+
+             buf[6] = count >> 24;
+             buf[7] = count >> 16;
+             buf[8] = count >> 8;
+             buf[9] = count;
+
+             bfd_get_section_contents (pbfd, section, buf + 10, fptr, count);
+
+             if (SERIAL_WRITE (e7000_desc, buf, count + 10))
+               fprintf_unfiltered (gdb_stderr,
+                                   "e7000_load: SERIAL_WRITE failed: %s\n",
+                                   safe_strerror(errno));
+
+             expect ("OK");
+
+             if (!quiet)
+               {
+                 printf_unfiltered ("\r%c", inds[k++ % 4]);
+                 gdb_flush (gdb_stdout);
+               }
+
+             section_address += count;
+             fptr += count;
+             section_size -= count;
+           }
+       }
+    }
+
+  write_e7000 ("ED");
+
+  expect_prompt ();
+
+  end_time = time (NULL);
+
+/* Finally, make the PC point at the start address */
+
+  if (exec_bfd)
+    write_pc (bfd_get_start_address (exec_bfd));
+
+  inferior_pid = 0;            /* No process now */
+
+/* This is necessary because many things were based on the PC at the time that
+   we attached to the monitor, which is no longer valid now that we have loaded
+   new code (and just changed the PC).  Another way to do this might be to call
+   normal_stop, except that the stack may not be valid, and things would get
+   horribly confused... */
+
+  clear_symtab_users ();
+
+  if (!nostart)
+    {
+      entry = bfd_get_start_address (pbfd);
+
+      if (!quiet)
+       printf_unfiltered ("[Starting %s at 0x%x]\n", filename, entry);
+
+/*      start_routine (entry);*/
+    }
+
+  report_transfer_performance (data_count, start_time, end_time);
+
+  do_cleanups (old_chain);
+  timeout = oldtimeout;
 }
 
 /* Clean up when a program exits.
@@ -1274,11 +1640,18 @@ e7000_mourn_inferior ()
   generic_mourn_inferior ();   /* Do all the proper things now */
 }
 
-#define MAX_E7000DEBUG_BREAKPOINTS 200
+#define MAX_BREAKPOINTS 200
+#ifdef  HARD_BREAKPOINTS
+#define MAX_E7000DEBUG_BREAKPOINTS (BC_BREAKPOINTS ? 5 :  MAX_BREAKPOINTS)
+#else
+#define MAX_E7000DEBUG_BREAKPOINTS MAX_BREAKPOINTS
+#endif
 
 extern int memory_breakpoint_size;
-static CORE_ADDR breakaddr[MAX_E7000DEBUG_BREAKPOINTS] =
-{0};
+
+/* Since we can change to soft breakpoints dynamically, we must define 
+   more than enough.  Was breakaddr[MAX_E7000DEBUG_BREAKPOINTS]. */
+static CORE_ADDR breakaddr[MAX_BREAKPOINTS] = {0};
 
 static int
 e7000_insert_breakpoint (addr, shadow)
@@ -1286,6 +1659,7 @@ e7000_insert_breakpoint (addr, shadow)
      unsigned char *shadow;
 {
   int i;
+  char buf[200];
   static char nop[2] = NOP;
 
   for (i = 0; i <= MAX_E7000DEBUG_BREAKPOINTS; i++)
@@ -1293,14 +1667,32 @@ e7000_insert_breakpoint (addr, shadow)
       {
        breakaddr[i] = addr;
        /* Save old contents, and insert a nop in the space */
+#ifdef HARD_BREAKPOINTS
+       if (BC_BREAKPOINTS) 
+         {
+           sprintf (buf, "BC%d A=%x\r", i+1, addr);
+           puts_e7000debug (buf);
+         }
+       else 
+         {
+           sprintf (buf, "B %x\r", addr);
+           puts_e7000debug (buf);
+         }
+#else
+#if 0
        e7000_read_inferior_memory (addr, shadow, 2);
        e7000_write_inferior_memory (addr, nop, 2);
-       printf_e7000debug ("B %x\r", addr);
+#endif
+
+       sprintf (buf, "B %x\r", addr);
+       puts_e7000debug (buf);
+#endif
        expect_prompt ();
        return 0;
       }
 
-  error("Too many breakpoints ( > %d) for the E7000\n", MAX_E7000DEBUG_BREAKPOINTS);
+  error ("Too many breakpoints ( > %d) for the E7000\n",
+        MAX_E7000DEBUG_BREAKPOINTS);
   return 1;
 }
 
@@ -1310,70 +1702,93 @@ e7000_remove_breakpoint (addr, shadow)
      unsigned char *shadow;
 {
   int i;
+  char buf[200];
 
   for (i = 0; i < MAX_E7000DEBUG_BREAKPOINTS; i++)
     if (breakaddr[i] == addr)
       {
        breakaddr[i] = 0;
-       printf_e7000debug ("B - %x\r", addr);
+#ifdef HARD_BREAKPOINTS
+       if (BC_BREAKPOINTS) 
+         {
+           sprintf (buf, "BC%d - \r",  i+1);
+           puts_e7000debug (buf);
+         }
+       else 
+         {
+           sprintf (buf, "B - %x\r",  addr);
+           puts_e7000debug (buf);
+         }
+       expect_prompt ();
+#else
+       sprintf (buf, "B - %x\r", addr);
+       puts_e7000debug (buf);
        expect_prompt ();
+
+#if 0
        /* Replace the insn under the break */
        e7000_write_inferior_memory (addr, shadow, 2);
+#endif
+#endif
+
        return 0;
       }
 
-  fprintf (stderr, "Can't find breakpoint associated with 0x%x\n", addr);
+  warning ("Can't find breakpoint associated with 0x%x\n", addr);
   return 1;
 }
 
-
-/* Put a command string, in args, out to STDBUG.  Output from STDBUG is placed
-   on the users terminal until the prompt is seen. */
+/* Put a command string, in args, out to STDBUG.  Output from STDBUG
+   is placed on the users terminal until the prompt is seen. */
 
 static void
 e7000_command (args, fromtty)
      char *args;
      int fromtty;
 {
+  /* FIXME: arbitrary limit on length of args.  */
+  char buf[200];
+
+  echo = 0;
 
   if (!e7000_desc)
     error ("e7000 target not open.");
   if (!args)
     {
-      printf_e7000debug ("\r");
+      puts_e7000debug ("\r");
     }
   else
     {
-      printf_e7000debug ("%s\r", args);
+      sprintf (buf, "%s\r", args);
+      puts_e7000debug (buf);
     }
+
   echo++;
   ctrl_c = 2;
   expect_full_prompt ();
   echo--;
   ctrl_c = 0;
   printf_unfiltered ("\n");
-}
 
-static void
-e7000_load (args, fromtty)
-     char *args;
-     int fromtty;
-{
-  gr_load_image (args, fromtty);
+  /* Who knows what the command did... */
+  registers_changed ();
 }
 
+
 static void
-e7000_drain (args, fromtty)
+e7000_drain_command (args, fromtty)
      char *args;
      int fromtty;
 
 {
   int c;
-  printf_e7000debug("end\r");
+
+  puts_e7000debug("end\r");
   putchar_e7000 (CTRLC);
+
   while ((c = SERIAL_READCHAR (e7000_desc, 1) != SERIAL_TIMEOUT))
     {
-      if(quit_flag)
+      if (quit_flag)
        {
          putchar_e7000(CTRLC);
          quit_flag = 0;
@@ -1385,36 +1800,30 @@ e7000_drain (args, fromtty)
     }
 }
 
-e7000_noecho ()
-{
-  echo = !echo;
-  if (echo)
-    printf_filtered ("Snoop enabled\n");
-  else
-    printf_filtered ("Snoop disabled\n");
-
-}
+#define NITEMS 7
 
-#define NITEMS 3
 static int
 why_stop ()
 {
-  static  char *strings[NITEMS] = 
-    {
-      "STEP NORMAL",
-      "BREAK POINT",
-      "BREAK KEY",
-    };
+  static  char *strings[NITEMS] = {
+    "STEP NORMAL",
+    "BREAK POINT",
+    "BREAK KEY",
+    "BREAK CONDI",
+    "CYCLE ACCESS",
+    "ILLEGAL INSTRUCTION",
+    "WRITE PROTECT",
+  };
   char *p[NITEMS];
   int c;
-  p[0] = strings[0];
-  p[1] = strings[1];
-  p[2] = strings[2];
+  int i;
+
+  for (i = 0; i < NITEMS; ++i)
+    p[i] = strings[i];
   
-  c = gch();
+  c = gch ();
   while (1)
     {
-      int i;
       for (i = 0; i < NITEMS; i++)
        {
          if (c == *(p[i])) 
@@ -1426,18 +1835,19 @@ why_stop ()
                  return i;
                }
            }
-         else {
+         else
            p[i] = strings[i];
-         }
        }
 
-      c = gch();
+      c = gch ();
     }
 }
+
 /* Suck characters, if a string match, then return the strings index
-   otherwise echo them */
+   otherwise echo them.  */
+
 int
-expect_n ( strings)
+expect_n (strings)
 char **strings;
 {
   char *(ptr[10]);
@@ -1447,120 +1857,132 @@ char **strings;
   char *buffer = saveaway;
   /* Count number of expect strings  */
 
-  for (n =0; strings[n]; n++) 
+  for (n = 0; strings[n]; n++) 
     {
       ptr[n] = strings[n];
     }
 
-  while (1) {
-    int i;
-    int gotone = 0;
+  while (1)
+    {
+      int i;
+      int gotone = 0;
 
-    c = SERIAL_READCHAR (e7000_desc, 1);
-    if (c == SERIAL_TIMEOUT) {
-      printf_unfiltered ("[waiting for e7000...]\n");
-    }
+      c = SERIAL_READCHAR (e7000_desc, 1);
+      if (c == SERIAL_TIMEOUT)
+       {
+         printf_unfiltered ("[waiting for e7000...]\n");
+       }
 #ifdef __GO32__
-    if (kbhit())
-      {
-       int k = getkey();
-       if (k == 1)
-         quit_flag = 1;
-      }
-#endif
-
-    if (quit_flag)
-      {
-       putchar_e7000 (CTRLC);  /* interrupt the running program */
-       quit_flag = 0;
-      }
+      if (kbhit ())
+       {
+         int k = getkey();
 
-    for (i = 0; i < n; i++)
-      {
-       if (c == ptr[i][0]) 
-         {
-           ptr[i]++;
-           if (ptr[i][0] == 0)
-             {
-               /* Gone all the way */
-               return i;
-             }
-           gotone = 1;
-         }
-       else 
-         {
-           ptr[i] = strings[i];
-         }
-      }
+         if (k == 1)
+           quit_flag = 1;
+       }
+#endif
+      if (quit_flag)
+       {
+         putchar_e7000 (CTRLC);        /* interrupt the running program */
+         quit_flag = 0;
+       }
 
+      for (i = 0; i < n; i++)
+       {
+         if (c == ptr[i][0]) 
+           {
+             ptr[i]++;
+             if (ptr[i][0] == 0)
+               {
+                 /* Gone all the way */
+                 return i;
+               }
+             gotone = 1;
+           }
+         else
+           {
+             ptr[i] = strings[i];
+           }
+       }
     
-    if (gotone)
-      {
-       /* Save it up incase we find that there was no match */
-       *buffer ++ = c;
-      }
-    else
-      {
-       if (buffer != saveaway) 
-         {
-           *buffer++ = 0;
-           printf(buffer);
-           buffer = saveaway;
-         }
-       if (c != SERIAL_TIMEOUT) {
-         putchar (c);
-         fflush(stdout);
+      if (gotone)
+       {
+         /* Save it up incase we find that there was no match */
+         *buffer ++ = c;
        }
-      }
-  }
+      else
+       {
+         if (buffer != saveaway) 
+           {
+             *buffer++ = 0;
+             printf ("%s", buffer);
+             buffer = saveaway;
+           }
+         if (c != SERIAL_TIMEOUT)
+           {
+             putchar (c);
+             fflush (stdout);
+           }
+       }
+    }
 }
 
-/* We subtract two from the pc here rather than use DECR_PC_AFTER_BREAK
-   since the e7000 doesn't always add two to the pc, and the simulators never do. */
+/* We subtract two from the pc here rather than use
+   DECR_PC_AFTER_BREAK since the e7000 doesn't always add two to the
+   pc, and the simulators never do. */
 
 static void
-sub2_from_pc()
+sub2_from_pc ()
 {
   char buf[4];
+  char buf2[200];
+
   store_signed_integer (buf,
                        REGISTER_RAW_SIZE(PC_REGNUM), 
                        read_register (PC_REGNUM) -2);
   supply_register (PC_REGNUM, buf);
-  printf_e7000debug (".PC %x\r", read_register (PC_REGNUM));
+  sprintf (buf2, ".PC %x\r", read_register (PC_REGNUM));
+  puts_e7000debug (buf2);
 }
+
 #define WAS_SLEEP 0
 #define WAS_INT 1
 #define WAS_RUNNING 2
 #define WAS_OTHER 3
-static char *estrings[] = { "** SLEEP", "BREAK !", "** PC", "PC", 0};
 
-/* Wait until the remote machine stops, then return,
-   storing status in STATUS just as `wait' would.  */
+static char *estrings[] = {
+  "** SLEEP",
+  "BREAK !",
+  "** PC",
+  "PC",
+  NULL
+};
+
+/* Wait until the remote machine stops, then return, storing status in
+   STATUS just as `wait' would.  */
 
 static int
 e7000_wait (pid, status)
      int pid;
-     WAITTYPE *status;
+     struct target_waitstatus *status;
 {
-  int c;
-  int reset_pc;
+  int stop_reason;
   int regno;
   int running_count = 0;
   int had_sleep = 0;
   int loop = 1;
-  char *reg;
-  int time = 0;
-  WSETSTOP ((*status), 0);
+
   /* Then echo chars until PC= string seen */
   gch ();                      /* Drop cr */
   gch ();                      /* and space */
+
   while (loop)
     {
-      switch (expect_n(estrings))
+      switch (expect_n (estrings))
        {        
        case WAS_OTHER:
          /* how did this happen ? */
-         loop =0;
+         loop = 0;
          break;
        case WAS_SLEEP:
          had_sleep = 1;
@@ -1578,11 +2000,23 @@ e7000_wait (pid, status)
              running_count = 0;
            }
          break;
+       default:
+         /* error? */
+         break;
        }
     }
-  /* Skip till the PC=*/
-  expect("=");
+
+  /* Skip till the PC= */
+  expect ("=");
+
+#ifdef GDB_TARGET_IS_SH
+  if  ((sh_processor_type != NULL) && (*(sh_processor_type+2) == '3')) 
+     fetch_regs_from_dump (gch, want_sh3_nopc);
+  else
+     fetch_regs_from_dump (gch, want_nopc);
+#else
   fetch_regs_from_dump (gch, want_nopc);
+#endif
 
   /* And supply the extra ones the simulator uses */
   for (regno = NUM_REALREGS; regno < NUM_REGS; regno++)
@@ -1591,36 +2025,66 @@ e7000_wait (pid, status)
       supply_register (regno, (char *) &buf);
     }
 
-  reset_pc = why_stop ();
+  stop_reason = why_stop ();
   expect_full_prompt ();
 
-  switch (reset_pc)
+  status->kind = TARGET_WAITKIND_STOPPED;
+  status->value.sig = TARGET_SIGNAL_TRAP;
+
+  switch (stop_reason)
     {
     case 1:                    /* Breakpoint */
-  
-      WSETSTOP ((*status), SIGTRAP);
+      write_pc (read_pc ()); /* PC is always off by 2 for breakpoints */
+      status->value.sig = TARGET_SIGNAL_TRAP;      
       break;
-    case 0:
-      /* Single step */
-      WSETSTOP ((*status), SIGTRAP);
+    case 0:                    /* Single step */
+      status->value.sig = TARGET_SIGNAL_TRAP;      
       break;
-    case 2:
-      /* Interrupt */
+    case 2:                    /* Interrupt */
       if (had_sleep)
        {
-         sub2_from_pc();
-         WSETSTOP ((*status), SIGTRAP);
+         status->value.sig = TARGET_SIGNAL_TRAP;      
+         sub2_from_pc ();
        }
       else
        {
-         WSETSTOP ((*status), SIGINT);
+         status->value.sig = TARGET_SIGNAL_INT;      
        }
       break;
+    case 3:
+      break;
+    case 4:
+      printf_unfiltered ("a cycle address error?\n");
+      status->value.sig = TARGET_SIGNAL_UNKNOWN;      
+      break;
+    case 5:
+      status->value.sig = TARGET_SIGNAL_ILL;      
+      break;
+    case 6:
+      status->value.sig = TARGET_SIGNAL_SEGV;      
+      break;
+    case 7:                    /* Anything else (NITEMS + 1) */
+      printf_unfiltered ("a write protect error?\n");
+      status->value.sig = TARGET_SIGNAL_UNKNOWN;      
+      break;
+    default:
+      /* Get the user's attention - this should never happen. */
+      abort ();
     }
+
   return 0;
 }
 
-/* Define the target subroutine names */
+/* Stop the running program.  */
+
+static void
+e7000_stop ()  
+{
+  /* Sending a ^C is supposed to stop the running program.  */
+  putchar_e7000 (CTRLC);
+}
+
+/* Define the target subroutine names. */
 
 struct target_ops e7000_ops =
 {
@@ -1633,40 +2097,42 @@ the speed to connect at in bits per second.\n\
 eg\n\
 target e7000 /dev/ttya 9600\n\
 target e7000 foobar",
-  e7000_open,
-  e7000_close,
-  0,
-  e7000_detach,
-  e7000_resume,
-  e7000_wait,
-  e7000_fetch_register,
-  e7000_store_register,
-  e7000_prepare_to_store,
-  e7000_xfer_inferior_memory,
-  e7000_files_info,
-0,0,/*  e7000_insert_breakpoint,
-  e7000_remove_breakpoint,     /* Breakpoints */
-  0,
-  0,
-  0,
-  0,
-  0,                           /* Terminal handling */
-  e7000_kill,
-  e7000_load,                  /* load */
-  0,                           /* lookup_symbol */
-  e7000_create_inferior,
-  e7000_mourn_inferior,
-  0,                           /* can_run */
-  0,                           /* notice_signals */
-  process_stratum,
-  0,                           /* next */
-  1,
-  1,
-  1,
-  1,
-  1,                           /* all mem, mem, stack, regs, exec */
-  0,
-  0,                           /* Section pointers */
+  e7000_open,                  /* to_open */
+  e7000_close,                 /* to_close */
+  0,                           /* to_attach */
+  e7000_detach,                        /* to_detach */
+  e7000_resume,                        /* to_resume */
+  e7000_wait,                  /* to_wait */
+  e7000_fetch_register,                /* to_fetch_registers */
+  e7000_store_register,                /* to_store_registers */
+  e7000_prepare_to_store,      /* to_prepare_to_store */
+  e7000_xfer_inferior_memory,  /* to_xfer_memory */
+  e7000_files_info,            /* to_files_info */
+  e7000_insert_breakpoint,     /* to_insert_breakpoint */
+  e7000_remove_breakpoint,     /* to_remove_breakpoint */
+  0,                           /* to_terminal_init */
+  0,                           /* to_terminal_inferior */
+  0,                           /* to_terminal_ours_for_output */
+  0,                           /* to_terminal_ours */
+  0,                           /* to_terminal_info */
+  e7000_kill,                  /* to_kill */
+  e7000_load,                  /* to_load */
+  0,                           /* to_lookup_symbol */
+  e7000_create_inferior,       /* to_create_inferior */
+  e7000_mourn_inferior,                /* to_mourn_inferior */
+  0,                           /* to_can_run */
+  0,                           /* to_notice_signals */
+  0,                           /* to_thread_alive */
+  e7000_stop,                  /* to_stop */
+  process_stratum,             /* to_stratum */
+  0,                           /* next (unused) */
+  1,                           /* to_has_all_memory */
+  1,                           /* to_has_memory */
+  1,                           /* to_has_stack */
+  1,                           /* to_has_registers */
+  1,                           /* to_has_execution */
+  0,                           /* to_sections */
+  0,                           /* to_sections_end */
   OPS_MAGIC,                   /* Always the last thing */
 };
 
@@ -1674,16 +2140,21 @@ void
 _initialize_remote_e7000 ()
 {
   add_target (&e7000_ops);
+
   add_com ("e7000 <command>", class_obscure, e7000_command,
           "Send a command to the e7000 monitor.");
 
-  add_com ("ftplogin <machine> <name> <passwd> <dir>", class_obscure, e7000_login,
+  add_com ("ftplogin <machine> <name> <passwd> <dir>", class_obscure, e7000_login_command,
           "Login to machine and change to directory.");
 
-  add_com ("ftpload <file>", class_obscure, e7000_ftp,
+  add_com ("ftpload <file>", class_obscure, e7000_ftp_command,
           "Fetch and load a file from previously described place.");
 
-  add_com ("drain", class_obscure, e7000_drain,
+  add_com ("drain", class_obscure, e7000_drain_command,
           "Drain pending e7000 text buffers.");
-  add_com ("snoop",  class_obscure, e7000_noecho, "Toggle monitor echo.");
+
+  add_show_from_set (add_set_cmd ("usehardbreakpoints", no_class,
+                                 var_integer, (char *)&use_hard_breakpoints,
+                                 "Set use of hardware breakpoints for all breakpoints.\n", &setlist),
+                    &showlist);
 }
This page took 0.052496 seconds and 4 git commands to generate.