1 /* Remote debugging interface for boot monitors, for GDB.
2 Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
4 This file is part of GDB.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
20 /* This file was derived from remote-eb.c, which did a similar job, but for
21 an AMD-29K running EBMON. That file was in turn derived from remote.c
22 as mentioned in the following comment (left in for comic relief):
24 "This is like remote.c but is for a different situation--
25 having a PC running os9000 hook up with a unix machine with
26 a serial line, and running ctty com2 on the PC. os9000 has a debug
27 monitor called ROMBUG running. Not to mention that the PC
28 has PC/NFS, so it can access the same executables that gdb can,
29 over the net in real time."
31 In reality, this module talks to a debug monitor called 'ROMBUG', which
32 We communicate with ROMBUG via a direct serial line, the network version
33 of ROMBUG is not available yet.
43 #include <sys/types.h>
47 #include "remote-utils.h"
51 #include "gdb-stabs.h"
55 # define TERMINAL struct termios
57 # define TERMINAL struct sgttyb
60 struct monitor_ops
*current_monitor
;
61 struct cmd_list_element
*showlist
;
62 extern struct target_ops rombug_ops
; /* Forward declaration */
63 extern struct monitor_ops rombug_cmds
; /* Forward declaration */
64 extern struct cmd_list_element
*setlist
;
65 extern struct cmd_list_element
*unsetlist
;
66 extern int attach_flag
;
68 static void rombug_close();
69 static void rombug_fetch_register();
70 static void rombug_fetch_registers();
71 static void rombug_store_register();
73 static int sr_get_debug(); /* flag set by "set remotedebug" */
75 static int hashmark
; /* flag set by "set hash" */
76 static int rombug_is_open
= 0;
78 /* FIXME: Replace with sr_get_debug (). */
79 #define LOG_FILE "monitor.log"
81 static int monitor_log
= 0;
82 static int tty_xon
= 0;
83 static int tty_xoff
= 0;
85 static int timeout
= 10;
86 static int is_trace_mode
= 0;
87 /* Descriptor for I/O to remote machine. Initialize it to NULL*/
88 static serial_t monitor_desc
= NULL
;
90 static CORE_ADDR bufaddr
= 0;
91 static int buflen
= 0;
92 static char readbuf
[16];
94 /* Send data to monitor. Works just like printf. */
96 printf_monitor(va_alist
)
106 pattern
= va_arg(args
, char *);
108 vsprintf(buf
, pattern
, args
);
110 if (SERIAL_WRITE(monitor_desc
, buf
, strlen(buf
)))
111 fprintf(stderr
, "SERIAL_WRITE failed: %s\n", safe_strerror(errno
));
114 /* Read a character from the remote system, doing all the fancy timeout stuff*/
121 c
= SERIAL_READCHAR(monitor_desc
, timeout
);
126 if (monitor_log
&& isascii(c
))
127 putc(c
& 0x7f, log_file
);
132 if (c
== SERIAL_TIMEOUT
)
135 return c
; /* Polls shouldn't generate timeout errors */
137 error("Timeout reading from remote system.");
140 perror_with_name("remote-monitor");
143 /* Scan input from the remote system, until STRING is found. If DISCARD is
144 non-zero, then discard non-matching input, else print it out.
145 Let the user break out immediately. */
147 expect(string
, discard
)
155 printf ("Expecting \"%s\"\n", string
);
160 c
= readchar(timeout
);
169 printf ("\nMatched\n");
177 fwrite(string
, 1, (p
- 1) - string
, stdout
);
186 /* Keep discarding input until we see the ROMBUG prompt.
188 The convention for dealing with the prompt is that you
190 o *then* wait for the prompt.
192 Thus the last thing that a procedure does with the serial line
193 will be an expect_prompt(). Exception: rombug_resume does not
194 wait for the prompt, because the terminal is being handed over
195 to the inferior. However, the next thing which happens after that
196 is a rombug_wait which does wait for the prompt.
197 Note that this includes abnormal exit, e.g. error(). This is
198 necessary to prevent getting into states from which we can't
201 expect_prompt(discard
)
205 /* This is a convenient place to do this. The idea is to do it often
206 enough that we never lose much data if we terminate abnormally. */
210 expect("trace", discard
);
212 expect (PROMPT
, discard
);
216 /* Get a hex digit from the remote system & return its value.
217 If ignore_space is nonzero, ignore spaces (not newline, tab, etc). */
219 get_hex_digit(ignore_space
)
225 ch
= readchar(timeout
);
226 if (ch
>= '0' && ch
<= '9')
228 else if (ch
>= 'A' && ch
<= 'F')
229 return ch
- 'A' + 10;
230 else if (ch
>= 'a' && ch
<= 'f')
231 return ch
- 'a' + 10;
232 else if (ch
== ' ' && ignore_space
)
237 error("Invalid hex digit from remote system.");
242 /* Get a byte from monitor and put it in *BYT. Accept any number
250 val
= get_hex_digit (1) << 4;
251 val
|= get_hex_digit (0);
255 /* Get N 32-bit words from remote, each preceded by a space,
256 and put them in registers starting at REGNO. */
258 get_hex_regs (n
, regno
)
266 for (i
= 0; i
< n
; i
++)
271 for (j
= 0; j
< 4; j
++)
274 if (TARGET_BYTE_ORDER
== BIG_ENDIAN
)
275 val
= (val
<< 8) + b
;
277 val
= val
+ (b
<< (j
*8));
279 supply_register (regno
++, (char *) &val
);
283 /* This is called not only when we first attach, but also when the
284 user types "run" after having attached. */
286 rombug_create_inferior (execfile
, args
, env
)
294 error("Can't pass arguments to remote ROMBUG process");
296 if (execfile
== 0 || exec_bfd
== 0)
297 error("No exec file specified");
299 entry_pt
= (int) bfd_get_start_address (exec_bfd
);
302 fputs ("\nIn Create_inferior()", log_file
);
305 /* The "process" (board) is already stopped awaiting our commands, and
306 the program is already downloaded. We just set its PC and go. */
308 init_wait_for_inferior ();
309 proceed ((CORE_ADDR
)entry_pt
, TARGET_SIGNAL_DEFAULT
, 0);
312 /* Open a connection to a remote debugger.
313 NAME is the filename used for communication. */
315 static char dev_name
[100];
318 rombug_open(args
, from_tty
)
323 error ("Use `target RomBug DEVICE-NAME' to use a serial port, or \n\
324 `target RomBug HOST-NAME:PORT-NUMBER' to use a network connection.");
326 target_preopen(from_tty
);
329 unpush_target(&rombug_ops
);
331 strcpy(dev_name
, args
);
332 monitor_desc
= SERIAL_OPEN(dev_name
);
333 if (monitor_desc
== NULL
)
334 perror_with_name(dev_name
);
336 /* if baud rate is set by 'set remotebaud' */
337 if (SERIAL_SETBAUDRATE (monitor_desc
, sr_get_baud_rate()))
339 SERIAL_CLOSE (monitor_desc
);
340 perror_with_name ("RomBug");
342 SERIAL_RAW(monitor_desc
);
343 if (tty_xon
|| tty_xoff
)
345 struct hardware_ttystate
{ struct termios t
;} *tty_s
;
347 tty_s
=(struct hardware_ttystate
*)SERIAL_GET_TTY_STATE(monitor_desc
);
348 if (tty_xon
) tty_s
->t
.c_iflag
|= IXON
;
349 if (tty_xoff
) tty_s
->t
.c_iflag
|= IXOFF
;
350 SERIAL_SET_TTY_STATE(monitor_desc
, (serial_ttystate
) tty_s
);
355 log_file
= fopen (LOG_FILE
, "w");
356 if (log_file
== NULL
)
357 perror_with_name (LOG_FILE
);
359 push_monitor (&rombug_cmds
);
360 printf_monitor("\r"); /* CR wakes up monitor */
363 push_target (&rombug_ops
);
365 printf("Remote %s connected to %s\n", target_shortname
,
369 rombug_fetch_registers();
375 * Close out all files and local state before this target loses control.
379 rombug_close (quitting
)
382 if (rombug_is_open
) {
383 SERIAL_CLOSE(monitor_desc
);
389 if (ferror(log_file
))
390 fprintf(stderr
, "Error writing log file.\n");
391 if (fclose(log_file
) != 0)
392 fprintf(stderr
, "Error closing log file.\n");
398 rombug_link(mod_name
, text_reloc
)
400 CORE_ADDR
*text_reloc
;
406 printf_monitor("l %s \r", mod_name
);
408 printf_monitor(".r \r");
409 expect(REG_DELIM
, 1);
410 for (i
=0; i
<= 7; i
++)
413 for (j
= 0; j
< 4; j
++)
416 val
= (val
<< 8) + b
;
424 /* Terminate the open connection to the remote debugger.
425 Use this when you want to detach and do something else
428 rombug_detach (from_tty
)
432 printf_monitor (GO_CMD
);
435 pop_target(); /* calls rombug_close to do the real work */
437 printf ("Ending remote %s debugging\n", target_shortname
);
441 * Tell the remote machine to resume.
444 rombug_resume (pid
, step
, sig
)
446 enum target_signal sig
;
449 fprintf (log_file
, "\nIn Resume (step=%d, sig=%d)\n", step
, sig
);
454 printf_monitor (STEP_CMD
);
455 /* wait for the echo. **
456 expect (STEP_CMD, 1);
461 printf_monitor (GO_CMD
);
462 /* swallow the echo. **
471 * Wait until the remote machine stops, then return,
472 * storing status in status just as `wait' would.
476 rombug_wait (pid
, status
)
478 struct target_waitstatus
*status
;
480 int old_timeout
= timeout
;
481 struct section_offsets
*offs
;
483 struct obj_section
*obj_sec
;
486 fputs ("\nIn wait ()", log_file
);
488 status
->kind
= TARGET_WAITKIND_EXITED
;
489 status
->value
.integer
= 0;
491 timeout
= 0; /* Don't time out -- user program is running. */
492 expect_prompt(1); /* Wait for prompt, outputting extraneous text */
494 status
->kind
= TARGET_WAITKIND_STOPPED
;
495 status
->value
.sig
= TARGET_SIGNAL_TRAP
;
496 timeout
= old_timeout
;
497 rombug_fetch_registers();
500 pc
= read_register(PC_REGNUM
);
501 addr
= read_register(DATABASE_REG
);
502 obj_sec
= find_pc_section (pc
);
505 if (obj_sec
->objfile
!= symfile_objfile
)
506 new_symfile_objfile(obj_sec
->objfile
, 1, 0);
507 offs
= ((struct section_offsets
*)
508 alloca (sizeof (struct section_offsets
)
509 + (symfile_objfile
->num_sections
* sizeof (offs
->offsets
))));
510 memcpy (offs
, symfile_objfile
->section_offsets
,
511 (sizeof (struct section_offsets
) +
512 (symfile_objfile
->num_sections
* sizeof (offs
->offsets
))));
513 ANOFFSET (offs
, SECT_OFF_DATA
) = addr
;
514 ANOFFSET (offs
, SECT_OFF_BSS
) = addr
;
516 objfile_relocate(symfile_objfile
, offs
);
522 /* Return the name of register number regno in the form input and output by
523 monitor. Currently, register_names just happens to contain exactly what
524 monitor wants. Lets take advantage of that just as long as possible! */
539 for (p = reg_names[regno]; *p; p++)
543 p
= (char *)reg_names
[regno
];
550 /* read the remote registers into the block regs. */
553 rombug_fetch_registers ()
559 printf_monitor (GET_REG
);
570 for (regno
= 8; regno
<= 15; regno
++)
572 expect(REG_DELIM
, 1);
573 if (regno
>= 8 && regno
<= 13)
576 for (j
= 0; j
< 2; j
++)
579 if (TARGET_BYTE_ORDER
== BIG_ENDIAN
)
580 val
= (val
<< 8) + b
;
582 val
= val
+ (b
<< (j
*8));
585 if (regno
== 8) i
= 10;
586 if (regno
>= 9 && regno
<= 12) i
= regno
+ 3;
587 if (regno
== 13) i
= 11;
588 supply_register (i
, (char *) &val
);
590 else if (regno
== 14)
592 get_hex_regs(1, PC_REGNUM
);
594 else if (regno
== 15)
601 supply_register(regno
, (char *) &val
);
608 /* Fetch register REGNO, or all registers if REGNO is -1.
609 Returns errno value. */
611 rombug_fetch_register (regno
)
618 fprintf (log_file
, "\nIn Fetch Register (reg=%s)\n", get_reg_name (regno
));
624 rombug_fetch_registers ();
628 char *name
= get_reg_name (regno
);
629 printf_monitor (GET_REG
);
630 if (regno
>= 10 && regno
<= 15)
635 expect (REG_DELIM
, 1);
637 for (j
= 0; j
< 2; j
++)
640 if (TARGET_BYTE_ORDER
== BIG_ENDIAN
)
641 val
= (val
<< 8) + b
;
643 val
= val
+ (b
<< (j
*8));
645 supply_register (regno
, (char *) &val
);
647 else if (regno
== 8 || regno
== 9)
653 expect (REG_DELIM
, 1);
654 get_hex_regs (1, regno
);
659 expect (REG_DELIM
, 1);
675 /* Store the remote registers from the contents of the block REGS. */
678 rombug_store_registers ()
682 for (regno
= 0; regno
<= PC_REGNUM
; regno
++)
683 rombug_store_register(regno
);
685 registers_changed ();
688 /* Store register REGNO, or all if REGNO == 0.
689 return errno value. */
691 rombug_store_register (regno
)
697 fprintf (log_file
, "\nIn Store_register (regno=%d)\n", regno
);
700 rombug_store_registers ();
704 printf ("Setting register %s to 0x%x\n", get_reg_name (regno
), read_register (regno
));
706 name
= get_reg_name(regno
);
707 if (name
== 0) return;
708 printf_monitor (SET_REG
, name
, read_register (regno
));
715 /* Get ready to modify the registers array. On machines which store
716 individual registers, this doesn't need to do anything. On machines
717 which store all the registers in one fell swoop, this makes sure
718 that registers contains all the registers from the program being
722 rombug_prepare_to_store ()
724 /* Do nothing, since we can store individual regs */
730 printf ("\tAttached to %s at %d baud.\n",
731 dev_name
, sr_get_baud_rate());
734 /* Copy LEN bytes of data from debugger memory at MYADDR
735 to inferior's memory at MEMADDR. Returns length moved. */
737 rombug_write_inferior_memory (memaddr
, myaddr
, len
)
739 unsigned char *myaddr
;
746 fprintf (log_file
, "\nIn Write_inferior_memory (memaddr=%x, len=%d)\n", memaddr
, len
);
748 printf_monitor (MEM_SET_CMD
, memaddr
);
749 for (i
= 0; i
< len
; i
++)
751 expect (CMD_DELIM
, 1);
752 printf_monitor ("%x \r", myaddr
[i
]);
754 printf ("\nSet 0x%x to 0x%x\n", memaddr
+ i
, myaddr
[i
]);
756 expect (CMD_DELIM
, 1);
758 printf_monitor (CMD_END
);
765 /* Read LEN bytes from inferior memory at MEMADDR. Put the result
766 at debugger address MYADDR. Returns length moved. */
768 rombug_read_inferior_memory(memaddr
, myaddr
, len
)
775 /* Number of bytes read so far. */
778 /* Starting address of this pass. */
779 unsigned long startaddr
;
781 /* Number of bytes to read in this pass. */
785 fprintf (log_file
, "\nIn Read_inferior_memory (memaddr=%x, len=%d)\n", memaddr
, len
);
787 /* Note that this code works correctly if startaddr is just less
788 than UINT_MAX (well, really CORE_ADDR_MAX if there was such a
789 thing). That is, something like
790 rombug_read_bytes (CORE_ADDR_MAX - 4, foo, 4)
791 works--it never adds len To memaddr and gets 0. */
792 /* However, something like
793 rombug_read_bytes (CORE_ADDR_MAX - 3, foo, 4)
794 doesn't need to work. Detect it and give up if there's an attempt
796 if (((memaddr
- 1) + len
) < memaddr
) {
800 if (bufaddr
<= memaddr
&& (memaddr
+len
) <= (bufaddr
+buflen
))
802 memcpy(myaddr
, &readbuf
[memaddr
-bufaddr
], len
);
811 if ((startaddr
% 16) != 0)
812 len_this_pass
-= startaddr
% 16;
813 if (len_this_pass
> (len
- count
))
814 len_this_pass
= (len
- count
);
816 printf ("\nDisplay %d bytes at %x\n", len_this_pass
, startaddr
);
818 printf_monitor (MEM_DIS_CMD
, startaddr
, 8);
820 for (i
= 0; i
< 16; i
++)
822 get_hex_byte (&readbuf
[i
]);
826 memcpy(&myaddr
[count
], readbuf
, len_this_pass
);
827 count
+= len_this_pass
;
828 startaddr
+= len_this_pass
;
829 expect(CMD_DELIM
, 1);
832 printf_monitor (CMD_END
);
839 /* FIXME-someday! merge these two. */
841 rombug_xfer_inferior_memory (memaddr
, myaddr
, len
, write
, target
)
846 struct target_ops
*target
; /* ignored */
849 return rombug_write_inferior_memory (memaddr
, myaddr
, len
);
851 return rombug_read_inferior_memory (memaddr
, myaddr
, len
);
855 rombug_kill (args
, from_tty
)
859 return; /* ignore attempts to kill target system */
862 /* Clean up when a program exits.
863 The program actually lives on in the remote processor's RAM, and may be
864 run again without a download. Don't leave it full of breakpoint
868 rombug_mourn_inferior ()
870 remove_breakpoints ();
871 generic_mourn_inferior (); /* Do all the proper things now */
874 #define MAX_MONITOR_BREAKPOINTS 16
876 extern int memory_breakpoint_size
;
877 static CORE_ADDR breakaddr
[MAX_MONITOR_BREAKPOINTS
] = {0};
880 rombug_insert_breakpoint (addr
, shadow
)
887 fprintf (log_file
, "\nIn Insert_breakpoint (addr=%x)\n", addr
);
889 for (i
= 0; i
<= MAX_MONITOR_BREAKPOINTS
; i
++)
890 if (breakaddr
[i
] == 0)
894 printf ("Breakpoint at %x\n", addr
);
895 rombug_read_inferior_memory(addr
, shadow
, memory_breakpoint_size
);
896 printf_monitor(SET_BREAK_CMD
, addr
);
902 fprintf(stderr
, "Too many breakpoints (> 16) for monitor\n");
907 * _remove_breakpoint -- Tell the monitor to remove a breakpoint
910 rombug_remove_breakpoint (addr
, shadow
)
917 fprintf (log_file
, "\nIn Remove_breakpoint (addr=%x)\n", addr
);
919 for (i
= 0; i
< MAX_MONITOR_BREAKPOINTS
; i
++)
920 if (breakaddr
[i
] == addr
)
923 printf_monitor(CLR_BREAK_CMD
, addr
);
929 fprintf(stderr
, "Can't find breakpoint associated with 0x%x\n", addr
);
933 /* Load a file. This is usually an srecord, which is ascii. No
934 protocol, just sent line by line. */
936 #define DOWNLOAD_LINE_SIZE 100
941 /* this part comment out for os9* */
944 char buf
[DOWNLOAD_LINE_SIZE
];
948 printf ("Loading %s to monitor\n", arg
);
950 download
= fopen (arg
, "r");
951 if (download
== NULL
)
953 error (sprintf (buf
, "%s Does not exist", arg
));
957 printf_monitor (LOAD_CMD
);
958 /* expect ("Waiting for S-records from host... ", 1); */
960 while (!feof (download
))
962 bytes_read
= fread (buf
, sizeof (char), DOWNLOAD_LINE_SIZE
, download
);
969 if (SERIAL_WRITE(monitor_desc
, buf
, bytes_read
)) {
970 fprintf(stderr
, "SERIAL_WRITE failed: (while downloading) %s\n", safe_strerror(errno
));
974 while (i
++ <=200000) {} ; /* Ugly HACK, probably needs flow control */
975 if (bytes_read
< DOWNLOAD_LINE_SIZE
)
977 if (!feof (download
))
978 error ("Only read %d bytes\n", bytes_read
);
987 if (!feof (download
))
988 error ("Never got EOF while downloading");
993 /* Put a command string, in args, out to MONITOR.
994 Output from MONITOR is placed on the users terminal until the prompt
998 rombug_command (args
, fromtty
)
1002 if (monitor_desc
== NULL
)
1003 error("monitor target not open.");
1006 fprintf (log_file
, "\nIn command (args=%s)\n", args
);
1009 error("Missing command.");
1011 printf_monitor("%s\r", args
);
1016 /* Connect the user directly to MONITOR. This command acts just like the
1017 'cu' or 'tip' command. Use <CR>~. or <CR>~^D to break out. */
1019 static struct ttystate ttystate
;
1023 { printf("\r\n[Exiting connect mode]\r\n");
1024 /*SERIAL_RESTORE(0, &ttystate);*/
1028 connect_command (args
, fromtty
)
1039 if (monitor_desc
== NULL
)
1040 error("monitor target not open.");
1043 fprintf("This command takes no args. They have been ignored.\n");
1045 printf("[Entering connect mode. Use ~. or ~^D to escape]\n");
1047 serial_raw(0, &ttystate
);
1049 make_cleanup(cleanup_tty
, 0);
1057 FD_SET(0, &readfds
);
1058 FD_SET(monitor_desc
, &readfds
);
1059 numfds
= select(sizeof(readfds
)*8, &readfds
, 0, 0, 0);
1061 while (numfds
== 0);
1064 perror_with_name("select");
1066 if (FD_ISSET(0, &readfds
))
1067 { /* tty input, send to monitor */
1070 perror_with_name("connect");
1072 printf_monitor("%c", c
);
1086 if (c
== '.' || c
== '\004')
1093 if (FD_ISSET(monitor_desc
, &readfds
))
1109 * Define the monitor command strings. Since these are passed directly
1110 * through to a printf style function, we need can include formatting
1111 * strings. We also need a CR or LF on the end.
1113 struct monitor_ops rombug_cmds
= {
1114 "g \r", /* execute or usually GO command */
1115 "g \r", /* continue command */
1116 "t \r", /* single step */
1117 "b %x\r", /* set a breakpoint */
1118 "k %x\r", /* clear a breakpoint */
1119 "c %x\r", /* set memory to a value */
1120 "d %x %d\r", /* display memory */
1121 "$%08X", /* prompt memory commands use */
1122 ".%s %x\r", /* set a register */
1123 ":", /* delimiter between registers */
1124 ". \r", /* read a register */
1125 "mf \r", /* download command */
1126 "RomBug: ", /* monitor command prompt */
1127 ": ", /* end-of-command delimitor */
1128 ".\r" /* optional command terminator */
1131 struct target_ops rombug_ops
= {
1133 "Microware's ROMBUG debug monitor",
1134 "Use a remote computer running the ROMBUG debug monitor.\n\
1135 Specify the serial device it is connected to (e.g. /dev/ttya).",
1142 rombug_fetch_register
,
1143 rombug_store_register
,
1144 rombug_prepare_to_store
,
1145 rombug_xfer_inferior_memory
,
1147 rombug_insert_breakpoint
,
1148 rombug_remove_breakpoint
, /* Breakpoints */
1153 0, /* Terminal handling */
1155 rombug_load
, /* load */
1156 rombug_link
, /* lookup_symbol */
1157 rombug_create_inferior
,
1158 rombug_mourn_inferior
,
1160 0, /* notice_signals */
1168 1, /* has execution */
1170 0, /* Section pointers */
1171 OPS_MAGIC
, /* Always the last thing */
1175 _initialize_remote_os9k ()
1177 add_target (&rombug_ops
);
1180 add_set_cmd ("hash", no_class
, var_boolean
, (char *)&hashmark
,
1181 "Set display of activity while downloading a file.\nWhen enabled, a period \'.\' is displayed.",
1186 add_set_cmd ("timeout", no_class
, var_zinteger
,
1188 "Set timeout in seconds for remote MIPS serial I/O.",
1193 add_set_cmd ("remotelog", no_class
, var_zinteger
,
1194 (char *) &monitor_log
,
1195 "Set monitor activity log on(=1) or off(=0).",
1200 add_set_cmd ("remotexon", no_class
, var_zinteger
,
1202 "Set remote tty line XON control",
1207 add_set_cmd ("remotexoff", no_class
, var_zinteger
,
1209 "Set remote tty line XOFF control",
1213 add_com ("rombug <command>", class_obscure
, rombug_command
,
1214 "Send a command to the debug monitor.");
1216 add_com ("connect", class_obscure
, connect_command
,
1217 "Connect the terminal directly up to a serial based command monitor.\nUse <CR>~. or <CR>~^D to break out.");