+/* Open a connection to a remote debugger. NAME is the filename used
+ for communication. */
+
+void
+monitor_open (char *args, struct monitor_ops *mon_ops, int from_tty)
+{
+ char *name;
+ char **p;
+
+ if (mon_ops->magic != MONITOR_OPS_MAGIC)
+ error ("Magic number of monitor_ops struct wrong.");
+
+ targ_ops = mon_ops->target;
+ name = targ_ops->to_shortname;
+
+ if (!args)
+ error ("Use `target %s DEVICE-NAME' to use a serial port, or \n\
+`target %s HOST-NAME:PORT-NUMBER' to use a network connection.", name, name);
+
+ target_preopen (from_tty);
+
+ /* Setup pattern for register dump */
+
+ if (mon_ops->register_pattern)
+ compile_pattern (mon_ops->register_pattern, ®ister_pattern,
+ register_fastmap);
+
+ if (mon_ops->getmem.resp_delim)
+ compile_pattern (mon_ops->getmem.resp_delim, &getmem_resp_delim_pattern,
+ getmem_resp_delim_fastmap);
+
+ if (mon_ops->setmem.resp_delim)
+ compile_pattern (mon_ops->setmem.resp_delim, &setmem_resp_delim_pattern,
+ setmem_resp_delim_fastmap);
+
+ if (mon_ops->setreg.resp_delim)
+ compile_pattern (mon_ops->setreg.resp_delim, &setreg_resp_delim_pattern,
+ setreg_resp_delim_fastmap);
+
+ unpush_target (targ_ops);
+
+ if (dev_name)
+ xfree (dev_name);
+ dev_name = xstrdup (args);
+
+ monitor_desc = serial_open (dev_name);
+
+ if (!monitor_desc)
+ perror_with_name (dev_name);
+
+ if (baud_rate != -1)
+ {
+ if (serial_setbaudrate (monitor_desc, baud_rate))
+ {
+ serial_close (monitor_desc);
+ perror_with_name (dev_name);
+ }
+ }
+
+ serial_raw (monitor_desc);
+
+ serial_flush_input (monitor_desc);
+
+ /* some systems only work with 2 stop bits */
+
+ serial_setstopbits (monitor_desc, mon_ops->stopbits);
+
+ current_monitor = mon_ops;
+
+ /* See if we can wake up the monitor. First, try sending a stop sequence,
+ then send the init strings. Last, remove all breakpoints. */
+
+ if (current_monitor->stop)
+ {
+ monitor_stop ();
+ if ((current_monitor->flags & MO_NO_ECHO_ON_OPEN) == 0)
+ {
+ monitor_debug ("EXP Open echo\n");
+ monitor_expect_prompt (NULL, 0);
+ }
+ }
+
+ /* wake up the monitor and see if it's alive */
+ for (p = mon_ops->init; *p != NULL; p++)
+ {
+ /* Some of the characters we send may not be echoed,
+ but we hope to get a prompt at the end of it all. */
+
+ if ((current_monitor->flags & MO_NO_ECHO_ON_OPEN) == 0)
+ monitor_printf (*p);
+ else
+ monitor_printf_noecho (*p);
+ monitor_expect_prompt (NULL, 0);
+ }
+
+ serial_flush_input (monitor_desc);
+
+ /* Alloc breakpoints */
+ if (mon_ops->set_break != NULL)
+ {
+ if (mon_ops->num_breakpoints == 0)
+ mon_ops->num_breakpoints = 8;
+
+ breakaddr = (CORE_ADDR *) xmalloc (mon_ops->num_breakpoints * sizeof (CORE_ADDR));
+ memset (breakaddr, 0, mon_ops->num_breakpoints * sizeof (CORE_ADDR));
+ }
+
+ /* Remove all breakpoints */
+
+ if (mon_ops->clr_all_break)
+ {
+ monitor_printf (mon_ops->clr_all_break);
+ monitor_expect_prompt (NULL, 0);
+ }
+
+ if (from_tty)
+ printf_unfiltered ("Remote target %s connected to %s\n", name, dev_name);
+
+ push_target (targ_ops);
+
+ inferior_ptid = pid_to_ptid (42000); /* Make run command think we are busy... */
+
+ /* Give monitor_wait something to read */
+
+ monitor_printf (current_monitor->line_term);
+
+ start_remote ();
+}
+
+/* Close out all files and local state before this target loses
+ control. */
+
+void
+monitor_close (int quitting)
+{
+ if (monitor_desc)
+ serial_close (monitor_desc);
+
+ /* Free breakpoint memory */
+ if (breakaddr != NULL)
+ {
+ xfree (breakaddr);
+ breakaddr = NULL;
+ }
+
+ monitor_desc = NULL;
+}
+
+/* Terminate the open connection to the remote debugger. Use this
+ when you want to detach and do something else with your gdb. */
+
+static void
+monitor_detach (char *args, int from_tty)
+{
+ pop_target (); /* calls monitor_close to do the real work */
+ if (from_tty)
+ printf_unfiltered ("Ending remote %s debugging\n", target_shortname);
+}
+
+/* Convert VALSTR into the target byte-ordered value of REGNO and store it. */
+
+char *
+monitor_supply_register (int regno, char *valstr)
+{
+ ULONGEST val;
+ unsigned char regbuf[MAX_REGISTER_RAW_SIZE];
+ char *p;
+
+ val = 0;
+ p = valstr;
+ while (p && *p != '\0')
+ {
+ if (*p == '\r' || *p == '\n')
+ {
+ while (*p != '\0')
+ p++;
+ break;
+ }
+ if (isspace (*p))
+ {
+ p++;
+ continue;
+ }
+ if (!isxdigit (*p) && *p != 'x')
+ {
+ break;
+ }
+
+ val <<= 4;
+ val += fromhex (*p++);
+ }
+ monitor_debug ("Supplying Register %d %s\n", regno, valstr);
+
+ if (val == 0 && valstr == p)
+ error ("monitor_supply_register (%d): bad value from monitor: %s.",
+ regno, valstr);
+
+ /* supply register stores in target byte order, so swap here */
+
+ store_unsigned_integer (regbuf, REGISTER_RAW_SIZE (regno), val);
+
+ supply_register (regno, regbuf);
+
+ return p;
+}
+
+/* Tell the remote machine to resume. */
+
+static void
+monitor_resume (ptid_t ptid, int step, enum target_signal sig)
+{
+ /* Some monitors require a different command when starting a program */
+ monitor_debug ("MON resume\n");
+ if (current_monitor->flags & MO_RUN_FIRST_TIME && first_time == 1)
+ {
+ first_time = 0;
+ monitor_printf ("run\r");
+ if (current_monitor->flags & MO_NEED_REGDUMP_AFTER_CONT)
+ dump_reg_flag = 1;
+ return;
+ }
+ if (step)
+ monitor_printf (current_monitor->step);
+ else
+ {
+ if (current_monitor->continue_hook)
+ (*current_monitor->continue_hook) ();
+ else
+ monitor_printf (current_monitor->cont);
+ if (current_monitor->flags & MO_NEED_REGDUMP_AFTER_CONT)
+ dump_reg_flag = 1;
+ }
+}
+
+/* Parse the output of a register dump command. A monitor specific
+ regexp is used to extract individual register descriptions of the
+ form REG=VAL. Each description is split up into a name and a value
+ string which are passed down to monitor specific code. */
+
+static void
+parse_register_dump (char *buf, int len)
+{
+ monitor_debug ("MON Parsing register dump\n");
+ while (1)
+ {
+ int regnamelen, vallen;
+ char *regname, *val;
+ /* Element 0 points to start of register name, and element 1
+ points to the start of the register value. */
+ struct re_registers register_strings;
+
+ memset (®ister_strings, 0, sizeof (struct re_registers));
+
+ if (re_search (®ister_pattern, buf, len, 0, len,
+ ®ister_strings) == -1)
+ break;
+
+ regnamelen = register_strings.end[1] - register_strings.start[1];
+ regname = buf + register_strings.start[1];
+ vallen = register_strings.end[2] - register_strings.start[2];
+ val = buf + register_strings.start[2];
+
+ current_monitor->supply_register (regname, regnamelen, val, vallen);
+
+ buf += register_strings.end[0];
+ len -= register_strings.end[0];
+ }
+}
+
+/* Send ^C to target to halt it. Target will respond, and send us a
+ packet. */
+
+static void
+monitor_interrupt (int signo)
+{
+ /* If this doesn't work, try more severe steps. */
+ signal (signo, monitor_interrupt_twice);
+
+ if (monitor_debug_p || remote_debug)
+ fprintf_unfiltered (gdb_stdlog, "monitor_interrupt called\n");
+
+ target_stop ();
+}
+
+/* The user typed ^C twice. */
+
+static void
+monitor_interrupt_twice (int signo)
+{
+ signal (signo, ofunc);
+
+ monitor_interrupt_query ();
+
+ signal (signo, monitor_interrupt);
+}
+
+/* Ask the user what to do when an interrupt is received. */
+
+static void
+monitor_interrupt_query (void)
+{
+ target_terminal_ours ();
+
+ if (query ("Interrupted while waiting for the program.\n\
+Give up (and stop debugging it)? "))
+ {
+ target_mourn_inferior ();
+ return_to_top_level (RETURN_QUIT);
+ }
+
+ target_terminal_inferior ();
+}
+
+static void
+monitor_wait_cleanup (void *old_timeout)
+{
+ timeout = *(int *) old_timeout;
+ signal (SIGINT, ofunc);
+ in_monitor_wait = 0;
+}
+
+
+
+void
+monitor_wait_filter (char *buf,
+ int bufmax,
+ int *ext_resp_len,
+ struct target_waitstatus *status
+)
+{
+ int resp_len;
+ do
+ {
+ resp_len = monitor_expect_prompt (buf, bufmax);
+ *ext_resp_len = resp_len;
+
+ if (resp_len <= 0)
+ fprintf_unfiltered (gdb_stderr, "monitor_wait: excessive response from monitor: %s.", buf);
+ }
+ while (resp_len < 0);
+
+ /* Print any output characters that were preceded by ^O. */
+ /* FIXME - This would be great as a user settabgle flag */
+ if (monitor_debug_p || remote_debug
+ || current_monitor->flags & MO_PRINT_PROGRAM_OUTPUT)
+ {
+ int i;
+
+ for (i = 0; i < resp_len - 1; i++)
+ if (buf[i] == 0x0f)
+ putchar_unfiltered (buf[++i]);
+ }
+}
+
+
+
+/* Wait until the remote machine stops, then return, storing status in
+ status just as `wait' would. */
+
+static ptid_t
+monitor_wait (ptid_t ptid, struct target_waitstatus *status)
+{
+ int old_timeout = timeout;
+ char buf[TARGET_BUF_SIZE];
+ int resp_len;
+ struct cleanup *old_chain;
+
+ status->kind = TARGET_WAITKIND_EXITED;
+ status->value.integer = 0;
+
+ old_chain = make_cleanup (monitor_wait_cleanup, &old_timeout);
+ monitor_debug ("MON wait\n");
+
+#if 0
+ /* This is somthing other than a maintenance command */
+ in_monitor_wait = 1;
+ timeout = watchdog > 0 ? watchdog : -1;
+#else
+ timeout = -1; /* Don't time out -- user program is running. */
+#endif
+
+ ofunc = (void (*)()) signal (SIGINT, monitor_interrupt);
+
+ if (current_monitor->wait_filter)
+ (*current_monitor->wait_filter) (buf, sizeof (buf), &resp_len, status);
+ else
+ monitor_wait_filter (buf, sizeof (buf), &resp_len, status);
+
+#if 0 /* Transferred to monitor wait filter */
+ do
+ {
+ resp_len = monitor_expect_prompt (buf, sizeof (buf));
+
+ if (resp_len <= 0)
+ fprintf_unfiltered (gdb_stderr, "monitor_wait: excessive response from monitor: %s.", buf);
+ }
+ while (resp_len < 0);
+
+ /* Print any output characters that were preceded by ^O. */
+ /* FIXME - This would be great as a user settabgle flag */
+ if (monitor_debug_p || remote_debug
+ || current_monitor->flags & MO_PRINT_PROGRAM_OUTPUT)
+ {
+ int i;
+
+ for (i = 0; i < resp_len - 1; i++)
+ if (buf[i] == 0x0f)
+ putchar_unfiltered (buf[++i]);
+ }
+#endif
+
+ signal (SIGINT, ofunc);
+
+ timeout = old_timeout;
+#if 0
+ if (dump_reg_flag && current_monitor->dump_registers)
+ {
+ dump_reg_flag = 0;
+ monitor_printf (current_monitor->dump_registers);
+ resp_len = monitor_expect_prompt (buf, sizeof (buf));
+ }
+
+ if (current_monitor->register_pattern)
+ parse_register_dump (buf, resp_len);
+#else
+ monitor_debug ("Wait fetching registers after stop\n");
+ monitor_dump_regs ();
+#endif
+
+ status->kind = TARGET_WAITKIND_STOPPED;
+ status->value.sig = TARGET_SIGNAL_TRAP;
+
+ discard_cleanups (old_chain);
+
+ in_monitor_wait = 0;
+
+ return inferior_ptid;
+}
+
+/* Fetch register REGNO, or all registers if REGNO is -1. Returns
+ errno value. */
+
+static void
+monitor_fetch_register (int regno)
+{
+ char *name;
+ char *zerobuf;
+ char *regbuf;
+ int i;
+
+ regbuf = alloca (MAX_REGISTER_RAW_SIZE * 2 + 1);
+ zerobuf = alloca (MAX_REGISTER_RAW_SIZE);
+ memset (zerobuf, 0, MAX_REGISTER_RAW_SIZE);
+
+ name = current_monitor->regnames[regno];
+ monitor_debug ("MON fetchreg %d '%s'\n", regno, name ? name : "(null name)");
+
+ if (!name || (*name == '\0'))
+ {
+ monitor_debug ("No register known for %d\n", regno);
+ supply_register (regno, zerobuf);
+ return;
+ }
+
+ /* send the register examine command */
+
+ monitor_printf (current_monitor->getreg.cmd, name);
+
+ /* If RESP_DELIM is specified, we search for that as a leading
+ delimiter for the register value. Otherwise, we just start
+ searching from the start of the buf. */
+
+ if (current_monitor->getreg.resp_delim)
+ {
+ monitor_debug ("EXP getreg.resp_delim\n");
+ monitor_expect (current_monitor->getreg.resp_delim, NULL, 0);
+ /* Handle case of first 32 registers listed in pairs. */
+ if (current_monitor->flags & MO_32_REGS_PAIRED
+ && (regno & 1) != 0 && regno < 32)
+ {
+ monitor_debug ("EXP getreg.resp_delim\n");
+ monitor_expect (current_monitor->getreg.resp_delim, NULL, 0);
+ }
+ }
+
+ /* Skip leading spaces and "0x" if MO_HEX_PREFIX flag is set */
+ if (current_monitor->flags & MO_HEX_PREFIX)
+ {
+ int c;
+ c = readchar (timeout);
+ while (c == ' ')
+ c = readchar (timeout);
+ if ((c == '0') && ((c = readchar (timeout)) == 'x'))
+ ;
+ else
+ error ("Bad value returned from monitor while fetching register %x.",
+ regno);
+ }
+
+ /* Read upto the maximum number of hex digits for this register, skipping
+ spaces, but stop reading if something else is seen. Some monitors
+ like to drop leading zeros. */
+
+ for (i = 0; i < REGISTER_RAW_SIZE (regno) * 2; i++)
+ {
+ int c;
+ c = readchar (timeout);
+ while (c == ' ')
+ c = readchar (timeout);
+
+ if (!isxdigit (c))
+ break;
+
+ regbuf[i] = c;
+ }
+
+ regbuf[i] = '\000'; /* terminate the number */
+ monitor_debug ("REGVAL '%s'\n", regbuf);
+
+ /* If TERM is present, we wait for that to show up. Also, (if TERM
+ is present), we will send TERM_CMD if that is present. In any
+ case, we collect all of the output into buf, and then wait for
+ the normal prompt. */
+
+ if (current_monitor->getreg.term)
+ {
+ monitor_debug ("EXP getreg.term\n");
+ monitor_expect (current_monitor->getreg.term, NULL, 0); /* get response */
+ }
+
+ if (current_monitor->getreg.term_cmd)
+ {
+ monitor_debug ("EMIT getreg.term.cmd\n");
+ monitor_printf (current_monitor->getreg.term_cmd);
+ }
+ if (!current_monitor->getreg.term || /* Already expected or */
+ current_monitor->getreg.term_cmd) /* ack expected */
+ monitor_expect_prompt (NULL, 0); /* get response */
+
+ monitor_supply_register (regno, regbuf);
+}
+
+/* Sometimes, it takes several commands to dump the registers */
+/* This is a primitive for use by variations of monitor interfaces in
+ case they need to compose the operation.
+ */
+int
+monitor_dump_reg_block (char *block_cmd)
+{
+ char buf[TARGET_BUF_SIZE];
+ int resp_len;
+ monitor_printf (block_cmd);
+ resp_len = monitor_expect_prompt (buf, sizeof (buf));
+ parse_register_dump (buf, resp_len);
+ return 1;
+}
+
+
+/* Read the remote registers into the block regs. */
+/* Call the specific function if it has been provided */
+
+static void
+monitor_dump_regs (void)
+{
+ char buf[TARGET_BUF_SIZE];
+ int resp_len;
+ if (current_monitor->dumpregs)
+ (*(current_monitor->dumpregs)) (); /* call supplied function */
+ else if (current_monitor->dump_registers) /* default version */
+ {
+ monitor_printf (current_monitor->dump_registers);
+ resp_len = monitor_expect_prompt (buf, sizeof (buf));
+ parse_register_dump (buf, resp_len);
+ }
+ else
+ internal_error (__FILE__, __LINE__, "failed internal consistency check"); /* Need some way to read registers */
+}
+
+static void
+monitor_fetch_registers (int regno)
+{
+ monitor_debug ("MON fetchregs\n");
+ if (current_monitor->getreg.cmd)
+ {
+ if (regno >= 0)
+ {
+ monitor_fetch_register (regno);
+ return;
+ }
+
+ for (regno = 0; regno < NUM_REGS; regno++)
+ monitor_fetch_register (regno);
+ }
+ else
+ {
+ monitor_dump_regs ();
+ }
+}
+
+/* Store register REGNO, or all if REGNO == 0. Return errno value. */
+
+static void
+monitor_store_register (int regno)
+{
+ char *name;
+ ULONGEST val;
+
+ name = current_monitor->regnames[regno];
+ if (!name || (*name == '\0'))
+ {
+ monitor_debug ("MON Cannot store unknown register\n");
+ return;
+ }
+
+ val = read_register (regno);
+ monitor_debug ("MON storeg %d %s\n", regno,
+ phex (val, REGISTER_RAW_SIZE (regno)));
+
+ /* send the register deposit command */
+
+ if (current_monitor->flags & MO_REGISTER_VALUE_FIRST)
+ monitor_printf (current_monitor->setreg.cmd, val, name);
+ else if (current_monitor->flags & MO_SETREG_INTERACTIVE)
+ monitor_printf (current_monitor->setreg.cmd, name);
+ else
+ monitor_printf (current_monitor->setreg.cmd, name, val);
+
+ if (current_monitor->setreg.resp_delim)
+ {
+ monitor_debug ("EXP setreg.resp_delim\n");
+ monitor_expect_regexp (&setreg_resp_delim_pattern, NULL, 0);
+ if (current_monitor->flags & MO_SETREG_INTERACTIVE)
+ monitor_printf ("%s\r", paddr_nz (val));
+ }
+ if (current_monitor->setreg.term)
+ {
+ monitor_debug ("EXP setreg.term\n");
+ monitor_expect (current_monitor->setreg.term, NULL, 0);
+ if (current_monitor->flags & MO_SETREG_INTERACTIVE)
+ monitor_printf ("%s\r", paddr_nz (val));
+ monitor_expect_prompt (NULL, 0);
+ }
+ else
+ monitor_expect_prompt (NULL, 0);
+ if (current_monitor->setreg.term_cmd) /* Mode exit required */
+ {
+ monitor_debug ("EXP setreg_termcmd\n");
+ monitor_printf ("%s", current_monitor->setreg.term_cmd);
+ monitor_expect_prompt (NULL, 0);
+ }
+} /* monitor_store_register */
+
+/* Store the remote registers. */
+
+static void
+monitor_store_registers (int regno)
+{
+ if (regno >= 0)
+ {
+ monitor_store_register (regno);
+ return;
+ }
+
+ for (regno = 0; regno < NUM_REGS; regno++)
+ monitor_store_register (regno);
+}
+
+/* Get ready to modify the registers array. On machines which store
+ individual registers, this doesn't need to do anything. On machines
+ which store all the registers in one fell swoop, this makes sure
+ that registers contains all the registers from the program being
+ debugged. */
+
+static void
+monitor_prepare_to_store (void)
+{
+ /* Do nothing, since we can store individual regs */
+}
+
+static void
+monitor_files_info (struct target_ops *ops)
+{
+ printf_unfiltered ("\tAttached to %s at %d baud.\n", dev_name, baud_rate);
+}
+
+static int
+monitor_write_memory (CORE_ADDR memaddr, char *myaddr, int len)
+{
+ unsigned int val, hostval;
+ char *cmd;
+ int i;
+
+ monitor_debug ("MON write %d %s\n", len, paddr (memaddr));
+
+ if (current_monitor->flags & MO_ADDR_BITS_REMOVE)
+ memaddr = ADDR_BITS_REMOVE (memaddr);
+
+ /* Use memory fill command for leading 0 bytes. */
+
+ if (current_monitor->fill)
+ {
+ for (i = 0; i < len; i++)
+ if (myaddr[i] != 0)
+ break;
+
+ if (i > 4) /* More than 4 zeros is worth doing */
+ {
+ monitor_debug ("MON FILL %d\n", i);
+ if (current_monitor->flags & MO_FILL_USES_ADDR)
+ monitor_printf (current_monitor->fill, memaddr, (memaddr + i) - 1, 0);
+ else
+ monitor_printf (current_monitor->fill, memaddr, i, 0);
+
+ monitor_expect_prompt (NULL, 0);
+
+ return i;
+ }
+ }
+
+#if 0
+ /* Can't actually use long longs if VAL is an int (nice idea, though). */
+ if ((memaddr & 0x7) == 0 && len >= 8 && current_monitor->setmem.cmdll)
+ {
+ len = 8;
+ cmd = current_monitor->setmem.cmdll;
+ }
+ else
+#endif
+ if ((memaddr & 0x3) == 0 && len >= 4 && current_monitor->setmem.cmdl)
+ {
+ len = 4;
+ cmd = current_monitor->setmem.cmdl;
+ }
+ else if ((memaddr & 0x1) == 0 && len >= 2 && current_monitor->setmem.cmdw)
+ {
+ len = 2;
+ cmd = current_monitor->setmem.cmdw;
+ }
+ else
+ {
+ len = 1;
+ cmd = current_monitor->setmem.cmdb;
+ }
+
+ val = extract_unsigned_integer (myaddr, len);
+
+ if (len == 4)
+ {
+ hostval = *(unsigned int *) myaddr;
+ monitor_debug ("Hostval(%08x) val(%08x)\n", hostval, val);
+ }
+
+
+ if (current_monitor->flags & MO_NO_ECHO_ON_SETMEM)
+ monitor_printf_noecho (cmd, memaddr, val);
+ else if (current_monitor->flags & MO_SETMEM_INTERACTIVE)
+ {
+
+ monitor_printf_noecho (cmd, memaddr);
+
+ if (current_monitor->setmem.resp_delim)
+ {
+ monitor_debug ("EXP setmem.resp_delim");
+ monitor_expect_regexp (&setmem_resp_delim_pattern, NULL, 0);
+ monitor_printf ("%x\r", val);
+ }
+ if (current_monitor->setmem.term)
+ {
+ monitor_debug ("EXP setmem.term");
+ monitor_expect (current_monitor->setmem.term, NULL, 0);
+ monitor_printf ("%x\r", val);
+ }
+ if (current_monitor->setmem.term_cmd)
+ { /* Emit this to get out of the memory editing state */
+ monitor_printf ("%s", current_monitor->setmem.term_cmd);
+ /* Drop through to expecting a prompt */
+ }
+ }
+ else
+ monitor_printf (cmd, memaddr, val);
+
+ monitor_expect_prompt (NULL, 0);
+
+ return len;
+}
+
+
+static int
+monitor_write_even_block (CORE_ADDR memaddr, char *myaddr, int len)
+{
+ unsigned int val;
+ int written = 0;;
+ /* Enter the sub mode */
+ monitor_printf (current_monitor->setmem.cmdl, memaddr);
+ monitor_expect_prompt (NULL, 0);
+
+ while (len)
+ {
+ val = extract_unsigned_integer (myaddr, 4); /* REALLY */
+ monitor_printf ("%x\r", val);
+ myaddr += 4;
+ memaddr += 4;
+ written += 4;
+ monitor_debug (" @ %s\n", paddr (memaddr));
+ /* If we wanted to, here we could validate the address */
+ monitor_expect_prompt (NULL, 0);
+ }
+ /* Now exit the sub mode */
+ monitor_printf (current_monitor->getreg.term_cmd);
+ monitor_expect_prompt (NULL, 0);
+ return written;
+}
+
+
+static int
+monitor_write_memory_bytes (CORE_ADDR memaddr, char *myaddr, int len)
+{
+ unsigned char val;
+ int written = 0;
+ if (len == 0)