]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Merge v850 branch ICE support onto devo.
authorKeith Seitz <keiths@cygnus>
Wed, 15 Jul 1998 20:13:34 +0000 (20:13 +0000)
committerKeith Seitz <keiths@cygnus>
Wed, 15 Jul 1998 20:13:34 +0000 (20:13 +0000)
gdb/v850ice.c

index 5e0ca677026f2e2b0ea21ac9e6241078a223fa27..d94ccdddfe3aa43f9bddf39c79a94bf78287e5ad 100755 (executable)
@@ -4,7 +4,7 @@
 This file is part of GDB.
 
 This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
+it under the terms of the GNU General Pessublic License as published by
 the Free Software Foundation; either version 2 of the License, or
 (at your option) any later version.
 
@@ -19,26 +19,47 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 #include "defs.h"
 #include "gdb_string.h"
-#if 0
 #include "frame.h"
-#endif
+#include "symtab.h"
 #include "inferior.h"
-#if 0
-#include "bfd.h"
-#endif
+#include "breakpoint.h"
 #include "symfile.h"
 #include "target.h"
-#if 0
-#include "wait.h"
-#include "gdbcmd.h"
 #include "objfiles.h"
-#include "gdb-stabs.h"
-#include "gdbthread.h"
-#endif
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h> 
+#include "gdbcore.h"
+#include "value.h"
+#include "command.h"
+
+#include <tcl.h>
+#include <tk.h>
+#include <windows.h>
+#include <winuser.h> /* for WM_USER */
+
+extern unsigned long int strtoul(const char *nptr, char **endptr,
+                                 int base);
+/* Local data definitions */
+struct MessageIO
+{
+  int    size;   /* length of input or output in bytes         */
+  char * buf;    /* buffer having the input/output information */
+};
+
+/* Prototypes for functions located in other files */
+extern void break_command PARAMS ((char *, int));
+
+extern void stepi_command PARAMS ((char *, int));
+
+extern void nexti_command PARAMS ((char *, int));
+
+extern void continue_command PARAMS ((char *, int));
+
+extern HINSTANCE Tk_GetHINSTANCE PARAMS ((void));
 
 /* Prototypes for local functions */
+static int init_hidden_window PARAMS ((void));
+
+static LRESULT CALLBACK v850ice_wndproc PARAMS ((HWND, UINT, WPARAM, LPARAM));
 
 static void v850ice_files_info PARAMS ((struct target_ops *ignore));
 
@@ -71,90 +92,218 @@ static int v850ice_insert_breakpoint PARAMS ((CORE_ADDR, char *));
 
 static int v850ice_remove_breakpoint PARAMS ((CORE_ADDR, char *));
 
-static int ice_open = 0;
+static void v850ice_command PARAMS ((char *, int));
 
-static struct target_ops v850ice_ops ; 
+static int ice_disassemble PARAMS ((unsigned long, int, char *));
 
-#ifndef EXPORT
-#define EXPORT __declspec(dllexport)
-#endif
+static int ice_lookup_addr PARAMS ((unsigned long *, char *, char *));
 
-struct MessageIO
+static int ice_lookup_symbol PARAMS ((unsigned long, char *));
+
+static void ice_SimulateDisassemble PARAMS ((char *, int));
+
+static void ice_SimulateAddrLookup PARAMS ((char *, int));
+
+static void ice_Simulate_SymLookup PARAMS ((char *, int));
+
+static void ice_fputs PARAMS ((const char *, GDB_FILE *));
+
+static int ice_file PARAMS ((char *));
+
+static int ice_cont PARAMS ((char *));
+
+static int ice_stepi PARAMS ((char *));
+
+static int ice_nexti PARAMS ((char *));
+
+static void togdb_force_update PARAMS ((void));
+
+/* Globals */
+static HWND hidden_hwnd;                 /* HWND for messages */
+
+long (__stdcall *ExeAppReq) PARAMS ((char *, long, char *, struct MessageIO *));
+
+long (__stdcall *RegisterClient) PARAMS ((HWND));
+
+long (__stdcall *UnregisterClient) PARAMS ((void));
+
+extern Tcl_Interp *gdbtk_interp;
+
+/* Globals local to this file only */
+static int ice_open = 0;        /* Is ICE open? */
+
+static char * v850_CB_Result;   /* special char array for saving 'callback' results */
+
+static int SimulateCallback;    /* simulate a callback event */
+
+#define MAX_BLOCK_SIZE    64*1024   /* Cannot transfer memory in blocks bigger
+                                       than this */
+/* MDI/ICE Message IDs */
+#define GSINGLESTEP     0x200   /* single-step target          */
+#define GRESUME         0x201   /* resume target               */
+#define GREADREG        0x202   /* read a register             */
+#define GWRITEREG       0x203   /* write a register            */
+#define GWRITEBLOCK     0x204   /* write a block of memory     */
+#define GREADBLOCK      0x205   /* read a block of memory      */
+#define GSETBREAK       0x206   /* set a breakpoint            */
+#define GREMOVEBREAK    0x207   /* remove a breakpoint         */
+#define GHALT           0x208   /* ??? */
+#define GCHECKSTATUS    0x209   /* check status of ICE         */
+#define GMDIREPLY       0x210   /* Reply for previous query - NOT USED */
+#define GDOWNLOAD       0x211   /* something for MDI           */
+#define GCOMMAND        0x212   /* execute command in ice      */
+#define GLOADFILENAME   0x213   /* retrieve load filename      */
+#define GWRITEMEM       0x214   /* write word, half-word, or byte */
+
+/* GCHECKSTATUS return codes: */
+#define ICE_Idle        0x00
+#define ICE_Breakpoint  0x01    /* hit a breakpoint */
+#define ICE_Stepped     0x02    /* have stepped     */
+#define ICE_Exception   0x03    /* have exception   */
+#define ICE_Halted      0x04    /* hit a user halt  */
+#define ICE_Exited      0x05    /* called exit      */
+#define ICE_Terminated  0x06    /* user terminated  */
+#define ICE_Running     0x07
+#define ICE_Unknown     0x99
+
+/* Windows messages */
+#define WM_STATE_CHANGE WM_USER+101
+#define WM_SYM_TO_ADDR  WM_USER+102
+#define WM_ADDR_TO_SYM  WM_USER+103
+#define WM_DISASSEMBLY  WM_USER+104
+
+/* STATE_CHANGE codes */
+#define STATE_CHANGE_REGS   1   /* Register(s) changed */
+#define STATE_CHANGE_LOAD   2   /* HW reset            */
+#define STATE_CHANGE_RESET  3   /* Load new file       */
+#define STATE_CHANGE_CONT   4   /* Run target          */
+#define STATE_CHANGE_STOP   5   /* Stop target         */
+#define STATE_CHANGE_STEPI  6   /* Stepi target        */
+#define STATE_CHANGE_NEXTI  7   /* Nexti target        */
+
+static struct target_ops v850ice_ops;  /* Forward decl */
+
+/* This function creates a hidden window */
+static int
+init_hidden_window ()
 {
-  int size;                    /* length of input or output in bytes */
-  char *buf;                   /* buffer having the input/output information */
-};
+  WNDCLASS class;
+
+  if (hidden_hwnd != NULL)
+    return TCL_OK;
+
+  class.style = 0;
+  class.cbClsExtra = 0;
+  class.cbWndExtra = 0;
+  class.hInstance = Tk_GetHINSTANCE();
+  class.hbrBackground = NULL;
+  class.lpszMenuName = NULL;
+  class.lpszClassName = "gdbtk_v850ice";
+  class.lpfnWndProc = v850ice_wndproc;
+  class.hIcon = NULL;
+  class.hCursor = NULL;
+
+  if (! RegisterClass (&class))
+    return TCL_ERROR;
+
+  hidden_hwnd = CreateWindow ("gdbtk_v850ice", "gdbtk_v850ice", WS_TILED,
+                              0, 0, 0, 0, NULL, NULL, class.hInstance,
+                              NULL);
+  if (hidden_hwnd == NULL)
+    {
+      char buf[200];
+      DWORD err;
+
+      err = GetLastError ();
+      FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM, NULL, err,
+                     0, buf, 200, NULL);
+      printf_unfiltered ("Could not create window: %s", buf);
+      return TCL_ERROR;
+    }
+
+  return TCL_OK;
+}
+
+/* 
+   This function is installed as the message handler for the hidden window
+   which QBox will use to communicate with gdbtk. It recognize and acts
+   on the following messages:
+
+   WM_SYM_TO_ADDR  \
+   WM_ADDR_TO_SYM   | Not implemented at NEC's request
+   WM_DISASSEMBLY  /
+   WM_STATE_CHANGE - tells us that a state change has occured in the ICE
+*/
+static LRESULT CALLBACK
+v850ice_wndproc (hwnd, message, wParam, lParam)
+     HWND hwnd;
+     UINT message;
+     WPARAM wParam;
+     LPARAM lParam;
+{
+  LRESULT result = FALSE;
+
+  switch (message)
+    {
+    case WM_SYM_TO_ADDR:
+      MessageBox (0, "Symbol resolution\nNot implemented", "GDB", MB_OK);
+      break;
+    case WM_ADDR_TO_SYM:
+      MessageBox (0, "Address resolution\nNot implemented", "GDB", MB_OK);
+      break;
+    case WM_STATE_CHANGE:
+      switch (wParam)
+        {
+        case STATE_CHANGE_LOAD:
+          {
+            struct MessageIO iob;
+            char buf[128];
+
+            iob.buf  = buf;
+            iob.size = 128;
+
+            /* Load in a new file... Need filename */
+            ExeAppReq ("GDB", GLOADFILENAME, NULL, &iob);
+            if (!catch_errors (ice_file, iob.buf, "", RETURN_MASK_ALL))
+              printf_unfiltered ("load errored\n");
+          }
+          break;
+        case STATE_CHANGE_RESET:
+          registers_changed ();
+          flush_cached_frames ();
+          togdb_force_update ();
+          result = TRUE;
+          break;
+        case STATE_CHANGE_REGS:
+          registers_changed ();
+          togdb_force_update ();
+          result = TRUE;
+          break;
+        case STATE_CHANGE_CONT:
+          if (!catch_errors (ice_cont, NULL, "", RETURN_MASK_ALL))
+            printf_unfiltered ("continue errored\n");
+          result = TRUE;
+          break;
+        case STATE_CHANGE_STEPI:
+          if (!catch_errors (ice_stepi, (PTR)(int) lParam, "",
+                             RETURN_MASK_ALL))
+            printf_unfiltered ("stepi errored\n");
+          result = TRUE;
+          break;
+        case STATE_CHANGE_NEXTI:
+          if (!catch_errors (ice_nexti, (PTR)(int) lParam, "",
+                             RETURN_MASK_ALL))
+            printf_unfiltered ("nexti errored\n");
+          result = TRUE;
+          break;
+        }
+    }
 
-struct MessageIO null_iob = { 0, NULL };
-
-EXPORT long __stdcall ExeAppReq (char *, long, char *, struct MessageIO *);
-EXPORT long __stdcall RegisterClient (HWND);
-EXPORT long __stdcall UnregisterClient (void);
-EXPORT long __stdcall GdbCallBack (void);
-
-#define        MREADREG          0x0001
-#define        MWRITEREG         0x0002
-#define        MREADMEM          0x0003
-#define        MWRITEMEM         0x0004
-#define        MSINGLESTEP       0x0005
-#define        MRESUME           0x0006
-#define        MLOADPROGRAM      0x0007
-#define        MSETBREAK         0x0008
-#define        MREMOVEBREAK      0x0009
-#define        MQUIT             0x000A
-#define        MTERMINATE        0x000B
-#define        MATTACH           0x000C
-#define        MCHECKSTATUS      0x000D
-#define        MHALT             0x000E
-#define        MDIRECTCMD        0x000F
-#define        MSYMADR           0x0010
-#define        MGETTASKLIST      0x0011
-#define        MREADVECREG       0x0012
-#define        MWRITEVECREG      0x0013
-#define        MGETCHANGEDREGS   0x0014
-#define        MGETSERVERINFO    0x0015
-#define        MREADBLOCK        0x0016
-#define        MSETHARDBRK       0x0017
-#define        MREMOVEHARDBRK    0x0018
-#define        MCOPYBLOCK        0x0019
-#define        MBLOCKFILL        0x001A
-#define        MFINDBLOCK        0x001B
-#define        MCOMPAREBLOCK     0x001C
-#define        MREFRESH          0x001D
-#define        MSPECIAL          0x001E
-#define        MGETCMDLIST       0x001F
-#define        MEXPVAL           0x0020
-#define        MEXPFAILED        0x0021
-#define        MSAVESTATE        0x0022
-#define        MWRITEBLOCK       0x0023
-#define        MDETACH           0x0024
-#define        MGETMODULES       0x0025
-#define        MREMOTESYMBOL     0x0026
-#define        MREADCSTRING      0x0027
-#define        MLOADMODULE       0x0028
-#define        MDIDSYSCALL       0x0029
-#define        MDBPWRITEBUFFERS  0x002A
-#define        MBPID             0x002B
-#define MINITEXEC         0x002C
-#define        MEXITEXEC         0x002D
-#define        MRCCMD            0x002E
-#define        MDOWNLOAD         0x0050
-
-#define StatRunning    0
-#define StatExecBreak  1   /* an execution breakpoint has been reached */
-#define StatStepped    2   /* a single step has been completed */
-#define StatException  3   /* the target has stopped due to an exception */
-#define StatHalted     4   /* target has been halted by a user request */
-#define StatExited      5   /* target called exit */
-#define StatTerminated  6   /* target program terminated by a user request */
-#define StatNoProcess   7   /* no process on target and none of the above */
-#define StatNeedInput   8   /* REV: obsolete */
-#define StatNeedDirCmd  9   /* waiting for an entry in the remote window */
-#define StatHardBreak  10  /* hit hardware breakpoint */
-#define StatFailure    11  /* an error occured in the last run/single */
-
-
-/*   "pir", "tkcw", "chcw", "adtre" */
+  if (result == FALSE)
+    return DefWindowProc (hwnd, message, wParam, lParam);
+
+  return FALSE;
+}
 
 /* Code for opening a connection to the ICE.  */
 
@@ -163,7 +312,7 @@ v850ice_open (name, from_tty)
      char *name;
      int from_tty;
 {
-  long retval;
+  HINSTANCE handle;
 
   if (name)
     error ("Too many arguments.");
@@ -179,34 +328,43 @@ v850ice_open (name, from_tty)
 
   target_terminal_init ();
 
+  /* Initialize everything necessary to facilitate communication
+     between QBox, gdbtk, and the DLLs which control the ICE */
+  if (ExeAppReq == NULL)
+    {
+      handle = LoadLibrary ("necmsg.dll");
+      if (handle == NULL)
+        error ("Cannot load necmsg.dll");
+
+      ExeAppReq = (long (*) PARAMS ((char *, long, char *, struct MessageIO *)))
+        GetProcAddress (handle, "ExeAppReq");
+      RegisterClient = (long (*) PARAMS ((HWND)))
+        GetProcAddress (handle, "RegisterClient");
+      UnregisterClient = (long (*) PARAMS ((void)))
+        GetProcAddress (handle, "UnregisterClient");
+
+      if (ExeAppReq == NULL || RegisterClient == NULL || UnregisterClient == NULL)
+        error ("Could not find requisite functions in necmsg.dll.");
+
+      if (init_hidden_window () != TCL_OK)
+        error ("could not initialize message handling");
+    }
+
+  /* Tell the DLL we are here */
+  RegisterClient (hidden_hwnd);
+
+  ice_open = 1;
+
   /* Without this, some commands which require an active target (such as kill)
      won't work.  This variable serves (at least) double duty as both the pid
      of the target process (if it has such), and as a flag indicating that a
      target is active.  These functions should be split out into seperate
      variables, especially since GDB will someday have a notion of debugging
      several processes.  */
-
   inferior_pid = 42000;
 
-  /* Start the v850ice connection; if error (0), discard this target.
-     In particular, if the user quits, be sure to discard it
-     (we'd be in an inconsistent state otherwise).  */
-
-  WinExec ("necsrv", SW_SHOW); /* Start up necsrv */
-
-  retval = RegisterClient (NULL);
-
-  if (retval == 0)
-    {
-      ice_open = 1;
-
-      start_remote ();
-      return;
-    }
-
-  pop_target();
-
-  error ("v850ice_open: MINITEXEC return error: 0x%x", retval);
+  start_remote ();
+  return;
 }
 
 /* Clean up connection to a remote debugger.  */
@@ -216,17 +374,11 @@ static void
 v850ice_close (quitting)
      int quitting;
 {
-  long retval;
-
   if (ice_open)
     {
-#if 0
-      retval = ExeAppReq ("GDB", MEXITEXEC, NULL, &null_iob);
-      if (retval)
-       error ("ExeAppReq (MEXITEXEC) returned %d", retval);
-#endif
-      ice_open = 0;
       UnregisterClient ();
+      ice_open = 0;
+      inferior_pid = 0;
     }
 }
 
@@ -250,12 +402,17 @@ v850ice_resume (pid, step, siggnal)
      int pid, step;
      enum target_signal siggnal;
 {
-  long retval;
+  long              retval;
+  char              buf[256];
+  struct MessageIO  iob;
+
+  iob.size = 0;
+  iob.buf  = buf;
 
   if (step)
-    retval = ExeAppReq ("GDB", MSINGLESTEP, "step", &null_iob);
+    retval = ExeAppReq ("GDB", GSINGLESTEP, "step", &iob);
   else
-    retval = ExeAppReq ("GDB", MRESUME, "run", &null_iob);
+    retval = ExeAppReq ("GDB", GRESUME, "run", &iob);
 
   if (retval)
     error ("ExeAppReq (step = %d) returned %d", step, retval);
@@ -272,12 +429,47 @@ v850ice_wait (pid, status)
      struct target_waitstatus *status;
 {
   long v850_status;
-
-  v850_status = ExeAppReq ("GDB", MCHECKSTATUS, NULL, &null_iob);
-
-  status->kind = TARGET_WAITKIND_STOPPED;
-  status->value.sig = TARGET_SIGNAL_TRAP;
-
+  char buf[256];
+  struct MessageIO  iob;
+  int done = 0;
+  iob.size = 0;
+  iob.buf  = buf;
+  
+  do
+    {
+      v850_status = ExeAppReq ("GDB", GCHECKSTATUS, NULL, &iob);
+
+      switch (v850_status)
+        {
+        case ICE_Idle:
+        case ICE_Breakpoint:
+        case ICE_Stepped:
+        case ICE_Halted:
+          status->kind = TARGET_WAITKIND_STOPPED;
+          status->value.sig = TARGET_SIGNAL_TRAP;
+          done = 1;
+          break;
+        case ICE_Exception:
+          status->kind = TARGET_WAITKIND_SIGNALLED;
+          status->value.sig = TARGET_SIGNAL_SEGV;
+          done = 1;
+          break;
+        case ICE_Exited:
+          status->kind = TARGET_WAITKIND_EXITED;
+          status->value.integer = 0;
+          done = 1;
+          break;
+        case ICE_Terminated:
+          status->kind = TARGET_WAITKIND_SIGNALLED;
+          status->value.sig = TARGET_SIGNAL_KILL;
+          done = 1;
+          break;
+        default:
+          break;
+        }
+    }
+  while (!done);
+      
   return inferior_pid;
 }
 
@@ -316,7 +508,7 @@ v850ice_fetch_registers (regno)
   if (regno == -1)
     {
       for (regno = 0; regno < NUM_REGS; regno++)
-       v850ice_fetch_registers (regno);
+        v850ice_fetch_registers (regno);
       return;
     }
 
@@ -326,14 +518,14 @@ v850ice_fetch_registers (regno)
 
   iob.size = sizeof val;
   iob.buf = val;
-  retval = ExeAppReq ("GDB", MREADREG, cmd, &iob);
+  retval = ExeAppReq ("GDB", GREADREG, cmd, &iob);
   if (retval)
-    error ("ExeAppReq returned %d: cmd = %s", retval, cmd);
+    error ("1: ExeAppReq returned %d: cmd = %s", retval, cmd);
 
-  regval = strtoul (val, &p, 16);
+  regval = strtoul (val, NULL, 16);
   if (regval == 0 && p == val)
     error ("v850ice_fetch_registers (%d):  bad value from ICE: %s.",
-          regno, val);
+           regno, val);
 
   store_unsigned_integer (val, REGISTER_RAW_SIZE (regno), regval);
   supply_register (regno, val);
@@ -349,6 +541,10 @@ v850ice_store_registers (regno)
   long retval;
   char cmd[100];
   unsigned long regval;
+  char buf[256];
+  struct MessageIO iob;
+  iob.size = 0;
+  iob.buf = buf;
 
   if (regno == -1)
     {
@@ -358,15 +554,15 @@ v850ice_store_registers (regno)
     }
 
   regval = extract_unsigned_integer (&registers[REGISTER_BYTE (regno)],
-                                    REGISTER_RAW_SIZE (regno));
+                                     REGISTER_RAW_SIZE (regno));
   strcpy (cmd, "reg ");
   if (!convert_register (regno, &cmd[4]))
     return;
   sprintf (cmd + strlen (cmd), "=0x%x", regval);
 
-  retval = ExeAppReq ("GDB", MWRITEREG, cmd, &null_iob);
+  retval = ExeAppReq ("GDB", GWRITEREG, cmd, &iob);
   if (retval)
-    error ("ExeAppReq returned %d: cmd = %s", retval, cmd);
+    error ("2: ExeAppReq returned %d: cmd = %s", retval, cmd);
 }
 
 /* Prepare to store registers.  Nothing to do here, since the ICE can write one
@@ -379,8 +575,10 @@ v850ice_prepare_to_store ()
 
 /* Read or write LEN bytes from inferior memory at MEMADDR, transferring
    to or from debugger address MYADDR.  Write to inferior if SHOULD_WRITE is
-   nonzero.  Returns length of data written or read; 0 for error.  */
+   nonzero.  Returns length of data written or read; 0 for error.
 
+   We can only read/write MAX_BLOCK_SIZE bytes at a time, though, or the DLL
+   dies */
 /* ARGSUSED */
 static int
 v850ice_xfer_memory (memaddr, myaddr, len, should_write, target)
@@ -393,51 +591,107 @@ v850ice_xfer_memory (memaddr, myaddr, len, should_write, target)
   long retval;
   char cmd[100];
   struct MessageIO iob;
-
-  iob.size = len;
-  iob.buf = myaddr;
+  int sent;
 
   if (should_write)
     {
-#if 1
-      sprintf (cmd, "memory b c 0x%x=0x00 l=%d", (int)memaddr, len);
-      retval = ExeAppReq ("GDB", MWRITEBLOCK, cmd, &iob);
-#else
-      sprintf (cmd, "memory b c 0x%x=0x%x", (int)memaddr, *myaddr & 0xff);
-      retval = ExeAppReq ("GDB", MWRITEBLOCK, cmd, &iob);
-      return 1;
-#endif
+      if (len == 4 || len == 2 || len == 1)
+        {
+          long value = 0;
+          char buf[256];
+          char c;
+
+          iob.size = 0;
+          iob.buf  = buf;
+
+          sent = 0;
+          switch (len)
+            {
+            case 4:
+              c = 'w';
+              value |= (long) (myaddr[3] << 24) & 0xff000000;
+              value |= (long) (myaddr[2] << 16) & 0x00ff0000;
+              value |= (long) (myaddr[1] << 8)  & 0x0000ff00;
+              value |= (long) myaddr[0] & 0x000000ff;
+            case 2:
+              c = 'h';
+              value |= (long) myaddr[1] << 8 & 0xff00;
+              value |= (long) myaddr[0] & 0x00ff;
+              break;
+            case 1:
+              c = 'b';
+              value |= (long) myaddr[0] & 0xff;
+              break;
+            }
+
+          sprintf (cmd, "memory %c c 0x%x=0x%x", c, (int) memaddr, value);
+          retval = ExeAppReq ("GDB", GWRITEMEM, cmd, &iob);
+          if (retval == 0)
+            sent = len;
+        }
+      else 
+        {
+          sent = 0;
+          do 
+            {
+              iob.size  = len > MAX_BLOCK_SIZE ? MAX_BLOCK_SIZE : len;
+              iob.buf   = myaddr;
+              sprintf (cmd, "memory b c 0x%x=0x00 l=%d", (int)memaddr, iob.size);
+              retval = ExeAppReq ("GDB", GWRITEBLOCK, cmd, &iob);
+              if (retval != 0)
+                break;
+              len      -= iob.size;
+              memaddr  += iob.size;
+              myaddr   += iob.size;
+              sent     += iob.size;
+            }
+          while (len > 0);
+        }
     }
   else
     {
       unsigned char *tmp;
+      unsigned char *t;
       int i;
-
+      
       tmp = alloca (len + 100);
+      t = tmp;
       memset (tmp + len, 0xff, 100);
-      
-#if 1
-      sprintf (cmd, "memory b 0x%x l=%d", (int)memaddr, len);
-      retval = ExeAppReq ("GDB", MREADBLOCK, cmd, &iob);
-#else
-      sprintf (cmd, "memory h 0x%x", (int)memaddr);
-      retval = ExeAppReq ("GDB", MREADMEM, cmd, &iob);
-#endif
-      for (i = 0; i <  100; i++)
-       {
-         if (tmp[len + i] != 0xff)
-           {
-             warning ("MREADBLOCK trashed bytes after transfer area.");
-             break;
-           }
-       }
-      memcpy (myaddr, tmp, len);
-    }
-
-  if (retval)
-    error ("ExeAppReq returned %d: cmd = %s", retval, cmd);
 
-  return len;
+      sent = 0;
+      do
+        {
+          iob.size = len > MAX_BLOCK_SIZE ? MAX_BLOCK_SIZE : len;
+          iob.buf  = tmp;
+          sprintf (cmd, "memory b 0x%x l=%d", (int)memaddr, iob.size);
+          retval = ExeAppReq ("GDB", GREADBLOCK, cmd, &iob);
+          if (retval != 0)
+            break;
+          len     -= iob.size;
+          memaddr += iob.size;
+          sent    += iob.size;
+          tmp     += iob.size;
+        }
+      while (len > 0);
+
+      if (retval == 0)
+        {
+          for (i = 0; i <  100; i++)
+            {
+              if (t[sent + i] != 0xff)
+                {
+                  warning ("GREADBLOCK trashed bytes after transfer area.");
+                  break;
+                }
+            }
+          memcpy (myaddr, t, sent);
+        }
+    }
+  if (retval != 0)
+    error ("3: ExeAppReq returned %d: cmd = %s", retval, cmd);
+  
+  return sent;
 }
 
 static void
@@ -454,16 +708,16 @@ v850ice_insert_breakpoint (addr, contents_cache)
 {
   long retval;
   char cmd[100];
+  char buf[256];
+  struct MessageIO iob;
 
+  iob.size = 0;
+  iob.buf  = buf;
   sprintf (cmd, "%d, ", addr);
 
-#if 1
-  retval = ExeAppReq ("GDB", MSETBREAK, cmd, &null_iob);
-#else
-  retval = ExeAppReq ("GDB", MSETHARDBRK, cmd, &null_iob);
-#endif
+  retval = ExeAppReq ("GDB", GSETBREAK, cmd, &iob);
   if (retval)
-    error ("ExeAppReq (MSETBREAK) returned %d: cmd = %s", retval, cmd);
+    error ("ExeAppReq (GSETBREAK) returned %d: cmd = %s", retval, cmd);
 
   return 0;
 }
@@ -475,16 +729,17 @@ v850ice_remove_breakpoint (addr, contents_cache)
 {
   long retval;
   char cmd[100];
+  char buf[256];
+  struct MessageIO iob;
+
+  iob.size = 0;
+  iob.buf  = buf;
 
   sprintf (cmd, "%d, ", addr);
 
-#if 1
-  retval = ExeAppReq ("GDB", MREMOVEBREAK, cmd, &null_iob);
-#else
-  retval = ExeAppReq ("GDB", MREMOVEHARDBRK, cmd, &null_iob);
-#endif
+  retval = ExeAppReq ("GDB", GREMOVEBREAK, cmd, &iob);
   if (retval)
-    error ("ExeAppReq (MREMOVEBREAK) returned %d: cmd = %s", retval, cmd);
+    error ("ExeAppReq (GREMOVEBREAK) returned %d: cmd = %s", retval, cmd);
 
   return 0;
 }
@@ -493,6 +748,7 @@ static void
 v850ice_kill ()
 {
   target_mourn_inferior ();
+  inferior_pid = 0;
 }
 
 static void
@@ -500,8 +756,118 @@ v850ice_mourn ()
 {
 }
 
-/* Define the target subroutine names */
+static void
+v850ice_load (filename, from_tty)
+  char * filename; 
+  int from_tty;
+{
+  struct MessageIO iob;
+  char buf[256];
+
+  iob.size = 0;
+  iob.buf  = buf;
+  generic_load(filename, from_tty);
+  ExeAppReq ("GDB", GDOWNLOAD, NULL, &iob);
+}
+
+static int
+ice_file (arg)
+     char *arg;
+{
+  char *s;
+  
+  target_detach (NULL, 0);
+  pop_target ();
+
+  printf_unfiltered ("\n");
+
+  s = arg;
+  while (*s != '\0')
+    {
+      if (*s == '\\')
+        *s = '/';
+      s++;
+    }
+
+  /* Safegaurd against confusing the breakpoint routines... */
+  delete_command(NULL, 0);
+
+  /* Must supress from_tty, otherwise we could start asking if the
+     user really wants to load a new symbol table, etc... */
+  printf_unfiltered ("Reading symbols from %s...", arg);
+  exec_file_command (arg, 0);
+  symbol_file_command (arg, 0);
+  printf_unfiltered ("done\n");
+
+  /* exec_file_command will kill our target, so reinstall the ICE as
+     the target. */
+  v850ice_open (NULL, 0);
 
+  togdb_force_update ();
+  return 1;
+}
+
+static int
+ice_cont (c)
+  char *c;
+{
+  printf_unfiltered ("continue (ice)\n");
+  continue_command (NULL, 1);
+  togdb_force_update ();
+  return 1;
+}
+
+static int
+ice_stepi (c)
+  char *c;
+{
+  char count_string[10] = "\0";
+  int count = (int) c;
+
+  sprintf (count_string, "%d", count);
+
+  printf_unfiltered ("stepi (ice)\n");
+  stepi_command (count_string, 1);
+  ReplyMessage ((LRESULT) 1);
+  togdb_force_update ();
+  return 1;
+}
+
+static int
+ice_nexti (c)
+  char *c;
+{
+  char count_string[10] = "\0";
+  int count = (int) c;
+
+  sprintf (count_string, "%d", count);
+
+  printf_unfiltered ("nexti (ice)\n");
+  nexti_command (count_string, 1);
+  togdb_force_update ();
+  return 1;
+}
+
+static void
+v850ice_command (arg, from_tty)
+  char *arg;
+  int   from_tty;
+{
+  struct MessageIO iob;
+  char buf[256];
+
+  iob.buf = buf;
+  iob.size = 0;
+  ExeAppReq ("GDB", GCOMMAND, arg, &iob);
+}
+
+static void
+togdb_force_update (void)
+{
+  Tcl_Eval (gdbtk_interp, "gdbtk_update");
+}
+
+/* Define the target subroutine names */
 
 static void init_850ice_ops(void)
 {
@@ -527,7 +893,7 @@ static void init_850ice_ops(void)
   v850ice_ops.to_terminal_ours   =   NULL;             
   v850ice_ops.to_terminal_info   =   NULL;             
   v850ice_ops.to_kill            =   v850ice_kill;             
-  v850ice_ops.to_load            =   generic_load;             
+  v850ice_ops.to_load            =   v850ice_load;             
   v850ice_ops.to_lookup_symbol   =   NULL;             
   v850ice_ops.to_create_inferior =   NULL;             
   v850ice_ops.to_mourn_inferior  =   v850ice_mourn;
@@ -550,6 +916,9 @@ static void init_850ice_ops(void)
 void
 _initialize_v850ice ()
 {
-  init_850ice_ops() ;
+  init_850ice_ops ();
   add_target (&v850ice_ops);
+
+  add_com ("ice", class_obscure, v850ice_command,
+           "Send command to ICE");
 }