* inftarg.c (child_thread_alive): New function to see if a
[deliverable/binutils-gdb.git] / gdb / remote-e7000.c
index 695180443d693962f05f29c3129ac4a6353da89b..644650e5a2b150d55b6190c85b448153dbfc7bb2 100644 (file)
@@ -1,6 +1,8 @@
-/* Remote debugging interface for Hitachi E7000 ICE, for GDB.
+/* Remote debugging interface for Hitachi E7000 ICE, for GDB
    Copyright 1993 Free Software Foundation, Inc.
-   Contributed by Cygnus Support.  Written by Steve Chamberlain for Cygnus.
+   Contributed by Cygnus Support. 
+
+   Written by Steve Chamberlain for Cygnus Support.
 
    This file is part of GDB.
 
@@ -52,7 +54,7 @@ extern struct target_ops e7000_ops;   /* Forward declaration */
 char *ENQSTRING = "\005";
 
 int echo;
-static int echo_index;
+int ctrl_c;
 static void e7000_close ();
 static void e7000_fetch_register ();
 static void e7000_store_register ();
@@ -66,7 +68,7 @@ static serial_t e7000_desc;
 
 
 /* Send data to e7000debug.  Works just like printf. */
-
+#if 0
 static void
 printf_e7000debug (va_alist)
      va_dcl
@@ -80,6 +82,14 @@ printf_e7000debug (va_alist)
   pattern = va_arg (args, char *);
 
   vsprintf (buf, pattern, args);
+#else
+
+static void
+printf_e7000debug(a,b,c,d,e)
+  {
+    char buf[200];
+    sprintf(buf, a,b,c,d,e);
+#endif
   if (SERIAL_WRITE (e7000_desc, buf, strlen (buf)))
     fprintf (stderr, "SERIAL_WRITE failed: %s\n", safe_strerror (errno));
 
@@ -125,6 +135,7 @@ readchar (timeout)
   return c;
 }
 
+
 /* 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.  */
@@ -135,16 +146,29 @@ expect (string)
   char *p = string;
   int c;
 
-  immediate_quit = 1;
   while (1)
 
     {
       c = readchar (timeout);
+
+      notice_quit ();
+      if (quit_flag == 1) 
+       {
+         if (ctrl_c) {
+           putchar_e7000(CTRLC);
+           ctrl_c -- ;
+         }
+         else 
+           {
+             quit();
+           }
+       }
+      
       if (c == SERIAL_ERROR)
        {
          error ("Serial communication error");
        }
-      if (echo_index)
+      if (echo)
        {
          if (c != '\r')
            putchar (c);
@@ -154,7 +178,6 @@ expect (string)
        {
          if (*p == '\0')
            {
-             immediate_quit = 0;
              return;
            }
        }
@@ -182,21 +205,11 @@ expect (string)
 static void
 expect_prompt ()
 {
-#if defined (LOG_FILE)
-  /* This is a convenient place to do this.  The idea is to do it often
-     enough that we never lose much data if we terminate abnormally.  */
-  fflush (log_file);
-#endif
   expect (":");
 }
 static void
 expect_full_prompt ()
 {
-#if defined (LOG_FILE)
-  /* This is a convenient place to do this.  The idea is to do it often
-     enough that we never lose much data if we terminate abnormally.  */
-  fflush (log_file);
-#endif
   expect ("\n:");
 }
 
@@ -363,7 +376,6 @@ e7000_ftp (args, from_tty)
 {
   int oldtimeout = timeout;
   timeout = 10;
-  echo_index++;
   printf_e7000debug ("ftp %s\r", machine);
   expect (" Username : ");
   printf_e7000debug ("%s\r", user);
@@ -378,7 +390,6 @@ e7000_ftp (args, from_tty)
   expect ("FTP>");
   printf_e7000debug ("bye\r");
   expect (":");
-  echo_index--;
   timeout = oldtimeout;
 }
 
@@ -420,6 +431,7 @@ or \t\ttarget e7000 <host>[:<port>]\n");
 
   /* Hello?  Are you there?  */
   sync = 0;
+  putchar_e7000 (CTRLC);
   while (!sync)
     {
       int c;
@@ -454,6 +466,9 @@ or \t\ttarget e7000 <host>[:<port>]\n");
     printf_filtered ("Remote %s connected to %s\n", target_shortname,
                     dev_name);
 
+#ifdef GDB_TARGET_IS_H8300
+  h8300hmode = 1;
+#endif
 }
 
 /* Close out all files and local state before this target loses control. */
@@ -499,25 +514,35 @@ e7000_resume (pid, step, sig)
 
 /* Read the remote registers into the block REGS.  
 
-   A reg dump looks like:
+   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
  */
 
 #ifdef GDB_TARGET_IS_H8300
 char *want = "\n\
  PC=%p CCR=%c\n\
  ER0 - ER3  %0 %1 %2 %3\n\
- ER4 - ER7  %4 %5 %6 %7\n\
-:";
+ ER4 - ER7  %4 %5 %6 %7\n";
+
+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\
+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\
-:";
+ 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\
@@ -577,7 +602,7 @@ fetch_regs_from_dump (nextchar, want)
          break;
 
        case ' ':
-         while (thischar == ' ' || thischar == '\t')
+         while (thischar == ' ' || thischar == '\t' || thischar == '\r' || thischar == '\n')
            thischar = nextchar();
          want++;
          break;
@@ -856,14 +881,14 @@ write_large (memaddr, myaddr, len)
      int len;
 {
   int i;
+  int c;
 #define maxstride  128
   int stride;
 
-  printf_e7000debug ("il ;s:s\r");
+  printf_e7000debug ("IL ;S:FK\r");
   expect (ENQSTRING);
   putchar_e7000 (ACK);
-  expect ("LO s\r");
-
+  expect ("LO FK\r");
   for (i = 0; i < len; i += stride)
     {
       char compose[maxstride * 2 + 50];
@@ -888,8 +913,8 @@ write_large (memaddr, myaddr, len)
        }
       else
        alen = 2;
-      compose[where++] = alen - 1 + '0';       /* insert type */
-      check_sum += stickbyte (compose + where, alen + stride + 1);     /* Insert length */
+      compose[where++] = alen - 1 + '0'; /* insert type */
+      check_sum += stickbyte (compose + where, alen + stride + 1); /* Insert length */
       where += 2;
       while (alen > 0)
        {
@@ -908,23 +933,34 @@ write_large (memaddr, myaddr, len)
 
       where += 2;
       compose[where++] = '\r';
-      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
+      compose[where++] = '\n';
+      compose[where++] = 0;
+      {
+       char *z;
+       for (z = compose; *z; z++) ;
        {
-         printf ("Whats this %d\n", j);
+         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
+           {
+             printf ("@%d}@", j);
+             while ((j = SERIAL_READCHAR(e7000_desc,0)) > 0) 
+               {
+                 printf ("@{%d}@",j);
+               }
+           }
        }
-
+      }
     }
   /* Send the trailer record */
   write_e7000 ("S70500000000FA\r");
@@ -957,13 +993,6 @@ e7000_write_inferior_memory (memaddr, myaddr, len)
     }
 }
 
-/* Read LEN bytes from inferior memory at MEMADDR.  Put the result
-   at debugger address MYADDR.  Returns length moved. 
-
-   Done by requesting an srecord dump from the E7000.
- */
-
-
 
 /* Read LEN bytes from inferior memory at MEMADDR.  Put the result
    at debugger address MYADDR.  Returns length moved. 
@@ -1257,8 +1286,7 @@ e7000_insert_breakpoint (addr, shadow)
      unsigned char *shadow;
 {
   int i;
-  static char nop[2] =
-    {0x20, 0x0b};
+  static char nop[2] = NOP;
 
   for (i = 0; i <= MAX_E7000DEBUG_BREAKPOINTS; i++)
     if (breakaddr[i] == 0)
@@ -1318,9 +1346,11 @@ e7000_command (args, fromtty)
     {
       printf_e7000debug ("%s\r", args);
     }
-  echo_index++;
+  echo++;
+  ctrl_c = 2;
   expect_full_prompt ();
-  echo_index--;
+  echo--;
+  ctrl_c = 0;
   printf_unfiltered ("\n");
 }
 
@@ -1329,7 +1359,7 @@ e7000_load (args, fromtty)
      char *args;
      int fromtty;
 {
-  load_target_image (args, fromtty);
+  gr_load_image (args, fromtty);
 }
 
 static void
@@ -1339,9 +1369,15 @@ e7000_drain (args, fromtty)
 
 {
   int c;
-
-  while ((c = SERIAL_READCHAR (e7000_desc, 2) != SERIAL_TIMEOUT))
+  printf_e7000debug("end\r");
+  putchar_e7000 (CTRLC);
+  while ((c = SERIAL_READCHAR (e7000_desc, 1) != SERIAL_TIMEOUT))
     {
+      if(quit_flag)
+       {
+         putchar_e7000(CTRLC);
+         quit_flag = 0;
+       }
       if (c > ' ' && c < 127)
        printf ("%c", c & 0xff);
       else
@@ -1352,8 +1388,152 @@ e7000_drain (args, fromtty)
 e7000_noecho ()
 {
   echo = !echo;
+  if (echo)
+    printf_filtered ("Snoop enabled\n");
+  else
+    printf_filtered ("Snoop disabled\n");
+
+}
+
+#define NITEMS 3
+static int
+why_stop ()
+{
+  static  char *strings[NITEMS] = 
+    {
+      "STEP NORMAL",
+      "BREAK POINT",
+      "BREAK KEY",
+    };
+  char *p[NITEMS];
+  int c;
+  p[0] = strings[0];
+  p[1] = strings[1];
+  p[2] = strings[2];
+  
+  c = gch();
+  while (1)
+    {
+      int i;
+      for (i = 0; i < NITEMS; i++)
+       {
+         if (c == *(p[i])) 
+           {
+             p[i]++;
+             if (*(p[i]) == 0) 
+               { 
+                 /* found one of the choices */
+                 return i;
+               }
+           }
+         else {
+           p[i] = strings[i];
+         }
+       }
+
+      c = gch();
+    }
+}
+/* Suck characters, if a string match, then return the strings index
+   otherwise echo them */
+int
+expect_n ( strings)
+char **strings;
+{
+  char *(ptr[10]);
+  int n; 
+  int c;
+  char saveaway[100];
+  char *buffer = saveaway;
+  /* Count number of expect strings  */
+
+  for (n =0; strings[n]; n++) 
+    {
+      ptr[n] = strings[n];
+    }
+
+  while (1) {
+    int i;
+    int gotone = 0;
+
+    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;
+      }
+
+    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);
+       }
+      }
+  }
 }
 
+/* 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()
+{
+  char buf[4];
+  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));
+}
+#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.  */
 
@@ -1363,8 +1543,12 @@ e7000_wait (pid, status)
      WAITTYPE *status;
 {
   int c;
+  int reset_pc;
   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 */
@@ -1372,51 +1556,32 @@ e7000_wait (pid, status)
   gch ();                      /* and space */
   while (loop)
     {
-      c = SERIAL_READCHAR (e7000_desc, 1);
-      if (c < 0)
-       {
-         time++;
-         if (time == 5)
-           {
-             printf_unfiltered ("[waiting for e7000..]\n");
-             time = 0;
-           }
-       }
-      if (quit_flag)
-       {
-         quit_flag = 0;
-         putchar_e7000 (CTRLC);                /* interrupt the running program */
-       }
-      if (c == 'P')
-       {
-         c = SERIAL_READCHAR (e7000_desc, 1);
-         if (c == 'C')
-           {
-             c = SERIAL_READCHAR (e7000_desc, 1);
-             if (c == '=')
-               {
-                 /* Got break */
-                 loop = 0;
-               }
-             else
-               {
-                 printf ("PC");
-               }
-           }
-         else
-           {
-             printf ("P");
-           }
-       }
-      else
-       {
-         if (c > 0)
+      switch (expect_n(estrings))
+       {        
+       case WAS_OTHER:
+         /* how did this happen ? */
+         loop =0;
+         break;
+       case WAS_SLEEP:
+         had_sleep = 1;
+         putchar_e7000 (CTRLC);
+         loop = 0;
+         break;
+       case WAS_INT:
+         loop = 0;
+         break;
+       case WAS_RUNNING:
+         running_count++;
+         if (running_count == 20)
            {
-             putchar (c);
-             fflush (stdout);
+             printf_unfiltered ("[running...]\n");
+             running_count = 0;
            }
+         break;
        }
     }
+  /* Skip till the PC=*/
+  expect("=");
   fetch_regs_from_dump (gch, want_nopc);
 
   /* And supply the extra ones the simulator uses */
@@ -1426,9 +1591,32 @@ e7000_wait (pid, status)
       supply_register (regno, (char *) &buf);
     }
 
+  reset_pc = why_stop ();
   expect_full_prompt ();
-  WSETSTOP ((*status), SIGTRAP);
 
+  switch (reset_pc)
+    {
+    case 1:                    /* Breakpoint */
+  
+      WSETSTOP ((*status), SIGTRAP);
+      break;
+    case 0:
+      /* Single step */
+      WSETSTOP ((*status), SIGTRAP);
+      break;
+    case 2:
+      /* Interrupt */
+      if (had_sleep)
+       {
+         sub2_from_pc();
+         WSETSTOP ((*status), SIGTRAP);
+       }
+      else
+       {
+         WSETSTOP ((*status), SIGINT);
+       }
+      break;
+    }
   return 0;
 }
 
@@ -1456,7 +1644,7 @@ target e7000 foobar",
   e7000_prepare_to_store,
   e7000_xfer_inferior_memory,
   e7000_files_info,
-  e7000_insert_breakpoint,
+0,0,/*  e7000_insert_breakpoint,
   e7000_remove_breakpoint,     /* Breakpoints */
   0,
   0,
@@ -1497,6 +1685,5 @@ _initialize_remote_e7000 ()
 
   add_com ("drain", class_obscure, e7000_drain,
           "Drain pending e7000 text buffers.");
-  add_com ("echo", class_obscure, e7000_noecho, "Toggle monitor echo.");
-
+  add_com ("snoop",  class_obscure, e7000_noecho, "Toggle monitor echo.");
 }
This page took 0.029779 seconds and 4 git commands to generate.