]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/remote-st.c
Copyright updates for 2007.
[thirdparty/binutils-gdb.git] / gdb / remote-st.c
CommitLineData
c906108c 1/* Remote debugging interface for Tandem ST2000 phone switch, for GDB.
0a65a603 2
6aba47ca
DJ
3 Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1998, 1999, 2000, 2001,
4 2002, 2006, 2007 Free Software Foundation, Inc.
0a65a603 5
c906108c
SS
6 Contributed by Cygnus Support. Written by Jim Kingdon for Cygnus.
7
c5aa993b 8 This file is part of GDB.
c906108c 9
c5aa993b
JM
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
c906108c 14
c5aa993b
JM
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
c906108c 19
c5aa993b
JM
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
197e01b6
EZ
22 Foundation, Inc., 51 Franklin Street, Fifth Floor,
23 Boston, MA 02110-1301, USA. */
c906108c
SS
24
25/* This file was derived from remote-eb.c, which did a similar job, but for
26 an AMD-29K running EBMON. That file was in turn derived from remote.c
27 as mentioned in the following comment (left in for comic relief):
28
c5aa993b 29 "This is like remote.c but is for an esoteric situation--
c906108c
SS
30 having an a29k board in a PC hooked up to a unix machine with
31 a serial line, and running ctty com1 on the PC, through which
32 the unix machine can run ebmon. Not to mention that the PC
33 has PC/NFS, so it can access the same executables that gdb can,
34 over the net in real time."
35
36 In reality, this module talks to a debug monitor called 'STDEBUG', which
37 runs in a phone switch. We communicate with STDEBUG via either a direct
38 serial line, or a TCP (or possibly TELNET) stream to a terminal multiplexor,
90c065fb 39 which in turn talks to the phone switch. */
c906108c
SS
40
41#include "defs.h"
42#include "gdbcore.h"
43#include "target.h"
43ff13b4 44#include "gdb_string.h"
9846de1b 45#include <sys/types.h>
c906108c 46#include "serial.h"
4e052eda 47#include "regcache.h"
c906108c 48
c5aa993b 49extern struct target_ops st2000_ops; /* Forward declaration */
c906108c 50
c5aa993b
JM
51static void st2000_close ();
52static void st2000_fetch_register ();
53static void st2000_store_register ();
c906108c
SS
54
55#define LOG_FILE "st2000.log"
56#if defined (LOG_FILE)
57FILE *log_file;
58#endif
59
60static int timeout = 24;
61
62/* Descriptor for I/O to remote machine. Initialize it to -1 so that
63 st2000_open knows that we don't have a file open when the program
64 starts. */
65
819cc324 66static struct serial *st2000_desc;
c906108c
SS
67
68/* Send data to stdebug. Works just like printf. */
69
70static void
c5aa993b 71printf_stdebug (char *pattern,...)
c906108c
SS
72{
73 va_list args;
74 char buf[200];
75
c5aa993b 76 va_start (args, pattern);
c906108c 77
c5aa993b
JM
78 vsprintf (buf, pattern, args);
79 va_end (args);
c906108c 80
2cd58942 81 if (serial_write (st2000_desc, buf, strlen (buf)))
f8d17dc5
PM
82 fprintf_unfiltered (gdb_stderr, "serial_write failed: %s\n",
83 safe_strerror (errno));
c906108c
SS
84}
85
86/* Read a character from the remote system, doing all the fancy timeout
87 stuff. */
88
89static int
fba45db2 90readchar (int timeout)
c906108c
SS
91{
92 int c;
93
2cd58942 94 c = serial_readchar (st2000_desc, timeout);
c906108c
SS
95
96#ifdef LOG_FILE
c5aa993b 97 putc (c & 0x7f, log_file);
c906108c
SS
98#endif
99
100 if (c >= 0)
101 return c & 0x7f;
102
103 if (c == SERIAL_TIMEOUT)
104 {
105 if (timeout == 0)
106 return c; /* Polls shouldn't generate timeout errors */
107
8a3fe4f8 108 error (_("Timeout reading from remote system."));
c906108c
SS
109 }
110
e2e0b3e5 111 perror_with_name (_("remote-st2000"));
c906108c
SS
112}
113
114/* Scan input from the remote system, until STRING is found. If DISCARD is
115 non-zero, then discard non-matching input, else print it out.
116 Let the user break out immediately. */
117static void
fba45db2 118expect (char *string, int discard)
c906108c
SS
119{
120 char *p = string;
121 int c;
122
8edbea78 123 immediate_quit++;
c906108c
SS
124 while (1)
125 {
c5aa993b 126 c = readchar (timeout);
c906108c
SS
127 if (c == *p++)
128 {
129 if (*p == '\0')
130 {
8edbea78 131 immediate_quit--;
c906108c
SS
132 return;
133 }
134 }
135 else
136 {
137 if (!discard)
138 {
c5aa993b
JM
139 fwrite (string, 1, (p - 1) - string, stdout);
140 putchar ((char) c);
141 fflush (stdout);
c906108c
SS
142 }
143 p = string;
144 }
145 }
146}
147
148/* Keep discarding input until we see the STDEBUG prompt.
149
150 The convention for dealing with the prompt is that you
151 o give your command
152 o *then* wait for the prompt.
153
154 Thus the last thing that a procedure does with the serial line
155 will be an expect_prompt(). Exception: st2000_resume does not
156 wait for the prompt, because the terminal is being handed over
157 to the inferior. However, the next thing which happens after that
158 is a st2000_wait which does wait for the prompt.
159 Note that this includes abnormal exit, e.g. error(). This is
160 necessary to prevent getting into states from which we can't
161 recover. */
162static void
fba45db2 163expect_prompt (int discard)
c906108c
SS
164{
165#if defined (LOG_FILE)
166 /* This is a convenient place to do this. The idea is to do it often
167 enough that we never lose much data if we terminate abnormally. */
c5aa993b 168 fflush (log_file);
c906108c
SS
169#endif
170 expect ("dbug> ", discard);
171}
172
173/* Get a hex digit from the remote system & return its value.
174 If ignore_space is nonzero, ignore spaces (not newline, tab, etc). */
175static int
fba45db2 176get_hex_digit (int ignore_space)
c906108c
SS
177{
178 int ch;
179 while (1)
180 {
c5aa993b 181 ch = readchar (timeout);
c906108c
SS
182 if (ch >= '0' && ch <= '9')
183 return ch - '0';
184 else if (ch >= 'A' && ch <= 'F')
185 return ch - 'A' + 10;
186 else if (ch >= 'a' && ch <= 'f')
187 return ch - 'a' + 10;
188 else if (ch == ' ' && ignore_space)
189 ;
190 else
191 {
c5aa993b 192 expect_prompt (1);
8a3fe4f8 193 error (_("Invalid hex digit from remote system."));
c906108c
SS
194 }
195 }
196}
197
198/* Get a byte from stdebug and put it in *BYT. Accept any number
199 leading spaces. */
200static void
fba45db2 201get_hex_byte (char *byt)
c906108c
SS
202{
203 int val;
204
205 val = get_hex_digit (1) << 4;
206 val |= get_hex_digit (0);
207 *byt = val;
208}
209
210/* Get N 32-bit words from remote, each preceded by a space,
211 and put them in registers starting at REGNO. */
212static void
fba45db2 213get_hex_regs (int n, int regno)
c906108c
SS
214{
215 long val;
216 int i;
217
218 for (i = 0; i < n; i++)
219 {
220 int j;
c5aa993b 221
c906108c
SS
222 val = 0;
223 for (j = 0; j < 8; j++)
224 val = (val << 4) + get_hex_digit (j == 0);
23a6d369 225 regcache_raw_supply (current_regcache, regno++, (char *) &val);
c906108c
SS
226 }
227}
228
229/* This is called not only when we first attach, but also when the
230 user types "run" after having attached. */
231static void
c27cda74
AC
232st2000_create_inferior (char *execfile, char *args, char **env,
233 int from_tty)
c906108c
SS
234{
235 int entry_pt;
236
237 if (args && *args)
8a3fe4f8 238 error (_("Can't pass arguments to remote STDEBUG process"));
c906108c
SS
239
240 if (execfile == 0 || exec_bfd == 0)
8a3fe4f8 241 error (_("No executable file specified"));
c906108c
SS
242
243 entry_pt = (int) bfd_get_start_address (exec_bfd);
244
245/* The "process" (board) is already stopped awaiting our commands, and
246 the program is already downloaded. We just set its PC and go. */
247
248 clear_proceed_status ();
249
250 /* Tell wait_for_inferior that we've started a new process. */
251 init_wait_for_inferior ();
252
253 /* Set up the "saved terminal modes" of the inferior
254 based on what modes we are starting it with. */
255 target_terminal_init ();
256
257 /* Install inferior's terminal modes. */
258 target_terminal_inferior ();
259
260 /* insert_step_breakpoint (); FIXME, do we need this? */
281b533b 261 write_pc ((CORE_ADDR) entry_pt);
c906108c
SS
262}
263
264/* Open a connection to a remote debugger.
265 NAME is the filename used for communication. */
266
267static int baudrate = 9600;
268static char dev_name[100];
269
270static void
fba45db2 271st2000_open (char *args, int from_tty)
c906108c
SS
272{
273 int n;
274 char junk[100];
275
c5aa993b
JM
276 target_preopen (from_tty);
277
278 n = sscanf (args, " %s %d %s", dev_name, &baudrate, junk);
c906108c
SS
279
280 if (n != 2)
8a3fe4f8
AC
281 error (_("Bad arguments. Usage: target st2000 <device> <speed>\n\
282or target st2000 <host> <port>\n"));
c906108c 283
c5aa993b 284 st2000_close (0);
c906108c 285
2cd58942 286 st2000_desc = serial_open (dev_name);
c906108c
SS
287
288 if (!st2000_desc)
c5aa993b 289 perror_with_name (dev_name);
c906108c 290
2cd58942 291 if (serial_setbaudrate (st2000_desc, baudrate))
67dd5ca6 292 {
2cd58942 293 serial_close (dev_name);
67dd5ca6
FN
294 perror_with_name (dev_name);
295 }
c906108c 296
2cd58942 297 serial_raw (st2000_desc);
c906108c 298
c5aa993b 299 push_target (&st2000_ops);
c906108c
SS
300
301#if defined (LOG_FILE)
302 log_file = fopen (LOG_FILE, "w");
303 if (log_file == NULL)
e2e0b3e5 304 perror_with_name ((LOG_FILE));
c906108c
SS
305#endif
306
307 /* Hello? Are you there? */
c5aa993b
JM
308 printf_stdebug ("\003"); /* ^C wakes up dbug */
309
310 expect_prompt (1);
c906108c
SS
311
312 if (from_tty)
c5aa993b
JM
313 printf ("Remote %s connected to %s\n", target_shortname,
314 dev_name);
c906108c
SS
315}
316
317/* Close out all files and local state before this target loses control. */
318
319static void
fba45db2 320st2000_close (int quitting)
c906108c 321{
2cd58942 322 serial_close (st2000_desc);
c906108c
SS
323
324#if defined (LOG_FILE)
c5aa993b
JM
325 if (log_file)
326 {
327 if (ferror (log_file))
f8d17dc5 328 fprintf_unfiltered (gdb_stderr, "Error writing log file.\n");
c5aa993b 329 if (fclose (log_file) != 0)
f8d17dc5 330 fprintf_unfiltered (gdb_stderr, "Error closing log file.\n");
c5aa993b 331 }
c906108c
SS
332#endif
333}
334
335/* Terminate the open connection to the remote debugger.
336 Use this when you want to detach and do something else
337 with your gdb. */
338static void
fba45db2 339st2000_detach (int from_tty)
c906108c 340{
c5aa993b 341 pop_target (); /* calls st2000_close to do the real work */
c906108c
SS
342 if (from_tty)
343 printf ("Ending remote %s debugging\n", target_shortname);
344}
c5aa993b 345
c906108c
SS
346/* Tell the remote machine to resume. */
347
348static void
39f77062 349st2000_resume (ptid_t ptid, int step, enum target_signal sig)
c906108c
SS
350{
351 if (step)
352 {
353 printf_stdebug ("ST\r");
354 /* Wait for the echo. */
355 expect ("ST\r", 1);
356 }
357 else
358 {
359 printf_stdebug ("GO\r");
360 /* Swallow the echo. */
361 expect ("GO\r", 1);
362 }
363}
364
365/* Wait until the remote machine stops, then return,
366 storing status in STATUS just as `wait' would. */
367
39f77062
KB
368static ptid_t
369st2000_wait (ptid_t ptid, struct target_waitstatus *status)
c906108c
SS
370{
371 int old_timeout = timeout;
372
373 status->kind = TARGET_WAITKIND_EXITED;
374 status->value.integer = 0;
375
c5aa993b 376 timeout = 0; /* Don't time out -- user program is running. */
c906108c 377
c5aa993b 378 expect_prompt (0); /* Wait for prompt, outputting extraneous text */
c906108c
SS
379
380 status->kind = TARGET_WAITKIND_STOPPED;
381 status->value.sig = TARGET_SIGNAL_TRAP;
382
383 timeout = old_timeout;
384
39f77062 385 return inferior_ptid;
c906108c
SS
386}
387
77949794
AC
388/* Return the name of register number REGNO in the form input and
389 output by STDEBUG. Currently, REGISTER_NAME just happens return
390 exactly what STDEBUG wants. Lets take advantage of that just as
391 long as possible! */
c906108c
SS
392
393static char *
fba45db2 394get_reg_name (int regno)
c906108c
SS
395{
396 static char buf[50];
397 const char *p;
398 char *b;
399
400 b = buf;
401
402 for (p = REGISTER_NAME (regno); *p; p++)
c5aa993b 403 *b++ = toupper (*p);
c906108c
SS
404 *b = '\000';
405
406 return buf;
407}
408
409/* Read the remote registers into the block REGS. */
410
411static void
fba45db2 412st2000_fetch_registers (void)
c906108c
SS
413{
414 int regno;
415
416 /* Yeah yeah, I know this is horribly inefficient. But it isn't done
417 very often... I'll clean it up later. */
418
419 for (regno = 0; regno <= PC_REGNUM; regno++)
c5aa993b 420 st2000_fetch_register (regno);
c906108c
SS
421}
422
423/* Fetch register REGNO, or all registers if REGNO is -1.
424 Returns errno value. */
425static void
fba45db2 426st2000_fetch_register (int regno)
c906108c
SS
427{
428 if (regno == -1)
429 st2000_fetch_registers ();
430 else
431 {
432 char *name = get_reg_name (regno);
433 printf_stdebug ("DR %s\r", name);
434 expect (name, 1);
435 expect (" : ", 1);
436 get_hex_regs (1, regno);
437 expect_prompt (1);
438 }
439 return;
440}
441
442/* Store the remote registers from the contents of the block REGS. */
443
444static void
fba45db2 445st2000_store_registers (void)
c906108c
SS
446{
447 int regno;
448
449 for (regno = 0; regno <= PC_REGNUM; regno++)
c5aa993b 450 st2000_store_register (regno);
c906108c
SS
451
452 registers_changed ();
453}
454
455/* Store register REGNO, or all if REGNO == 0.
456 Return errno value. */
457static void
fba45db2 458st2000_store_register (int regno)
c906108c
SS
459{
460 if (regno == -1)
461 st2000_store_registers ();
462 else
463 {
464 printf_stdebug ("PR %s %x\r", get_reg_name (regno),
465 read_register (regno));
466
467 expect_prompt (1);
468 }
469}
470
471/* Get ready to modify the registers array. On machines which store
472 individual registers, this doesn't need to do anything. On machines
473 which store all the registers in one fell swoop, this makes sure
474 that registers contains all the registers from the program being
475 debugged. */
476
477static void
fba45db2 478st2000_prepare_to_store (void)
c906108c
SS
479{
480 /* Do nothing, since we can store individual regs */
481}
482
483static void
fba45db2 484st2000_files_info (void)
c906108c
SS
485{
486 printf ("\tAttached to %s at %d baud.\n",
487 dev_name, baudrate);
488}
489
490/* Copy LEN bytes of data from debugger memory at MYADDR
491 to inferior's memory at MEMADDR. Returns length moved. */
492static int
fba45db2 493st2000_write_inferior_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
c906108c
SS
494{
495 int i;
496
497 for (i = 0; i < len; i++)
498 {
499 printf_stdebug ("PM.B %x %x\r", memaddr + i, myaddr[i]);
500 expect_prompt (1);
501 }
502 return len;
503}
504
505/* Read LEN bytes from inferior memory at MEMADDR. Put the result
506 at debugger address MYADDR. Returns length moved. */
507static int
fba45db2 508st2000_read_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len)
c906108c
SS
509{
510 int i;
511
512 /* Number of bytes read so far. */
513 int count;
514
515 /* Starting address of this pass. */
516 unsigned long startaddr;
517
518 /* Number of bytes to read in this pass. */
519 int len_this_pass;
520
521 /* Note that this code works correctly if startaddr is just less
522 than UINT_MAX (well, really CORE_ADDR_MAX if there was such a
523 thing). That is, something like
524 st2000_read_bytes (CORE_ADDR_MAX - 4, foo, 4)
525 works--it never adds len to memaddr and gets 0. */
526 /* However, something like
527 st2000_read_bytes (CORE_ADDR_MAX - 3, foo, 4)
528 doesn't need to work. Detect it and give up if there's an attempt
529 to do that. */
c5aa993b
JM
530 if (((memaddr - 1) + len) < memaddr)
531 {
532 errno = EIO;
533 return 0;
534 }
535
c906108c
SS
536 startaddr = memaddr;
537 count = 0;
538 while (count < len)
539 {
540 len_this_pass = 16;
541 if ((startaddr % 16) != 0)
542 len_this_pass -= startaddr % 16;
543 if (len_this_pass > (len - count))
544 len_this_pass = (len - count);
545
546 printf_stdebug ("DI.L %x %x\r", startaddr, len_this_pass);
547 expect (": ", 1);
548
549 for (i = 0; i < len_this_pass; i++)
550 get_hex_byte (&myaddr[count++]);
551
552 expect_prompt (1);
553
554 startaddr += len_this_pass;
555 }
556 return len;
557}
558
832c69cf
KB
559/* Transfer LEN bytes between GDB address MYADDR and target address
560 MEMADDR. If WRITE is non-zero, transfer them to the target,
561 otherwise transfer them from the target. TARGET is unused.
562
563 Returns the number of bytes transferred. */
564
c906108c 565static int
832c69cf 566st2000_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len,
0a65a603
AC
567 int write, struct mem_attrib *attrib,
568 struct target_ops *target)
c906108c
SS
569{
570 if (write)
571 return st2000_write_inferior_memory (memaddr, myaddr, len);
572 else
573 return st2000_read_inferior_memory (memaddr, myaddr, len);
574}
575
576static void
fba45db2 577st2000_kill (char *args, int from_tty)
c906108c 578{
c5aa993b 579 return; /* Ignore attempts to kill target system */
c906108c
SS
580}
581
582/* Clean up when a program exits.
583
584 The program actually lives on in the remote processor's RAM, and may be
585 run again without a download. Don't leave it full of breakpoint
586 instructions. */
587
588static void
fba45db2 589st2000_mourn_inferior (void)
c906108c
SS
590{
591 remove_breakpoints ();
592 unpush_target (&st2000_ops);
593 generic_mourn_inferior (); /* Do all the proper things now */
594}
595
596#define MAX_STDEBUG_BREAKPOINTS 16
597
c5aa993b
JM
598static CORE_ADDR breakaddr[MAX_STDEBUG_BREAKPOINTS] =
599{0};
c906108c
SS
600
601static int
8181d85f 602st2000_insert_breakpoint (struct bp_target_info *bp_tgt)
c906108c 603{
8181d85f 604 CORE_ADDR addr = bp_tgt->placed_address;
c906108c 605 int i;
c906108c
SS
606
607 for (i = 0; i <= MAX_STDEBUG_BREAKPOINTS; i++)
608 if (breakaddr[i] == 0)
609 {
610 breakaddr[i] = addr;
611
c5aa993b
JM
612 printf_stdebug ("BR %x H\r", addr);
613 expect_prompt (1);
c906108c
SS
614 return 0;
615 }
616
f8d17dc5 617 fprintf_unfiltered (gdb_stderr, "Too many breakpoints (> 16) for STDBUG\n");
c906108c
SS
618 return 1;
619}
620
621static int
8181d85f 622st2000_remove_breakpoint (struct bp_target_info *bp_tgt)
c906108c 623{
8181d85f 624 CORE_ADDR addr = bp_tgt->placed_address;
c906108c
SS
625 int i;
626
627 for (i = 0; i < MAX_STDEBUG_BREAKPOINTS; i++)
628 if (breakaddr[i] == addr)
629 {
630 breakaddr[i] = 0;
631
c5aa993b
JM
632 printf_stdebug ("CB %d\r", i);
633 expect_prompt (1);
c906108c
SS
634 return 0;
635 }
636
f8d17dc5
PM
637 fprintf_unfiltered (gdb_stderr,
638 "Can't find breakpoint associated with 0x%x\n", addr);
c906108c
SS
639 return 1;
640}
641
642
643/* Put a command string, in args, out to STDBUG. Output from STDBUG is placed
644 on the users terminal until the prompt is seen. */
645
646static void
fba45db2 647st2000_command (char *args, int fromtty)
c906108c
SS
648{
649 if (!st2000_desc)
8a3fe4f8 650 error (_("st2000 target not open."));
c5aa993b 651
c906108c 652 if (!args)
8a3fe4f8 653 error (_("Missing command."));
c5aa993b
JM
654
655 printf_stdebug ("%s\r", args);
656 expect_prompt (0);
c906108c
SS
657}
658
659/* Connect the user directly to STDBUG. This command acts just like the
660 'cu' or 'tip' command. Use <CR>~. or <CR>~^D to break out. */
661
c5aa993b 662/*static struct ttystate ttystate; */
c906108c
SS
663
664static void
fba45db2 665cleanup_tty (void)
c906108c 666{
c5aa993b 667 printf ("\r\n[Exiting connect mode]\r\n");
2cd58942 668/* serial_restore(0, &ttystate); */
c906108c
SS
669}
670
671#if 0
672/* This all should now be in serial.c */
673
674static void
fba45db2 675connect_command (char *args, int fromtty)
c906108c
SS
676{
677 fd_set readfds;
678 int numfds;
679 int c;
680 char cur_esc = 0;
681
c5aa993b 682 dont_repeat ();
c906108c
SS
683
684 if (st2000_desc < 0)
8a3fe4f8 685 error (_("st2000 target not open."));
c5aa993b 686
c906108c 687 if (args)
c5aa993b 688 fprintf ("This command takes no args. They have been ignored.\n");
c906108c 689
c5aa993b 690 printf ("[Entering connect mode. Use ~. or ~^D to escape]\n");
c906108c 691
c5aa993b 692 serial_raw (0, &ttystate);
c906108c 693
c5aa993b
JM
694 make_cleanup (cleanup_tty, 0);
695
696 FD_ZERO (&readfds);
c906108c
SS
697
698 while (1)
699 {
700 do
701 {
c5aa993b 702 FD_SET (0, &readfds);
2cd58942 703 FD_SET (deprecated_serial_fd (st2000_desc), &readfds);
0ea3f30e 704 numfds = gdb_select (sizeof (readfds) * 8, &readfds, 0, 0, 0);
c906108c
SS
705 }
706 while (numfds == 0);
707
708 if (numfds < 0)
e2e0b3e5 709 perror_with_name (("select"));
c906108c 710
c5aa993b 711 if (FD_ISSET (0, &readfds))
c906108c 712 { /* tty input, send to stdebug */
c5aa993b 713 c = getchar ();
c906108c 714 if (c < 0)
e2e0b3e5 715 perror_with_name (("connect"));
c906108c 716
c5aa993b 717 printf_stdebug ("%c", c);
c906108c
SS
718 switch (cur_esc)
719 {
720 case 0:
721 if (c == '\r')
722 cur_esc = c;
723 break;
724 case '\r':
725 if (c == '~')
726 cur_esc = c;
727 else
728 cur_esc = 0;
729 break;
730 case '~':
731 if (c == '.' || c == '\004')
732 return;
733 else
734 cur_esc = 0;
735 }
736 }
737
2cd58942 738 if (FD_ISSET (deprecated_serial_fd (st2000_desc), &readfds))
c906108c
SS
739 {
740 while (1)
741 {
c5aa993b 742 c = readchar (0);
c906108c
SS
743 if (c < 0)
744 break;
c5aa993b 745 putchar (c);
c906108c 746 }
c5aa993b 747 fflush (stdout);
c906108c
SS
748 }
749 }
750}
751#endif /* 0 */
752
753/* Define the target subroutine names */
754
c5aa993b 755struct target_ops st2000_ops;
c906108c 756
c5aa993b
JM
757static void
758init_st2000_ops (void)
c906108c 759{
c5aa993b
JM
760 st2000_ops.to_shortname = "st2000";
761 st2000_ops.to_longname = "Remote serial Tandem ST2000 target";
762 st2000_ops.to_doc = "Use a remote computer running STDEBUG connected by a serial line;\n\
c906108c
SS
763or a network connection.\n\
764Arguments are the name of the device for the serial line,\n\
c5aa993b
JM
765the speed to connect at in bits per second.";
766 st2000_ops.to_open = st2000_open;
767 st2000_ops.to_close = st2000_close;
c5aa993b 768 st2000_ops.to_detach = st2000_detach;
c5aa993b
JM
769 st2000_ops.to_resume = st2000_resume;
770 st2000_ops.to_wait = st2000_wait;
c5aa993b
JM
771 st2000_ops.to_fetch_registers = st2000_fetch_register;
772 st2000_ops.to_store_registers = st2000_store_register;
773 st2000_ops.to_prepare_to_store = st2000_prepare_to_store;
c8e73a31 774 st2000_ops.deprecated_xfer_memory = st2000_xfer_inferior_memory;
c5aa993b
JM
775 st2000_ops.to_files_info = st2000_files_info;
776 st2000_ops.to_insert_breakpoint = st2000_insert_breakpoint;
777 st2000_ops.to_remove_breakpoint = st2000_remove_breakpoint; /* Breakpoints */
c5aa993b 778 st2000_ops.to_kill = st2000_kill;
c5aa993b 779 st2000_ops.to_create_inferior = st2000_create_inferior;
c5aa993b 780 st2000_ops.to_mourn_inferior = st2000_mourn_inferior;
c5aa993b 781 st2000_ops.to_stratum = process_stratum;
c5aa993b
JM
782 st2000_ops.to_has_all_memory = 1;
783 st2000_ops.to_has_memory = 1;
784 st2000_ops.to_has_stack = 1;
785 st2000_ops.to_has_registers = 1;
786 st2000_ops.to_has_execution = 1; /* all mem, mem, stack, regs, exec */
c5aa993b
JM
787 st2000_ops.to_magic = OPS_MAGIC; /* Always the last thing */
788};
c906108c
SS
789
790void
fba45db2 791_initialize_remote_st2000 (void)
c906108c 792{
c5aa993b 793 init_st2000_ops ();
c906108c 794 add_target (&st2000_ops);
24ec834b 795 add_com ("st2000", class_obscure, st2000_command,
1bedd215
AC
796 _("Send a command to the STDBUG monitor."));
797 add_com ("connect", class_obscure, connect_command, _("\
798Connect the terminal directly up to the STDBUG command monitor.\n\
799Use <CR>~. or <CR>~^D to break out."));
c906108c 800}