]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/remote-adapt.c
import gdb-1999-07-07 post reformat
[thirdparty/binutils-gdb.git] / gdb / remote-adapt.c
CommitLineData
c906108c
SS
1/* Remote debugging interface for AMD 290*0 Adapt Monitor Version 2.1d18.
2 Copyright 1990, 1991, 1992 Free Software Foundation, Inc.
3 Contributed by David Wood at New York University (wood@lab.ultra.nyu.edu).
4 Adapted from work done at Cygnus Support in remote-eb.c.
5
c5aa993b 6 This file is part of GDB.
c906108c 7
c5aa993b
JM
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
c906108c 12
c5aa993b
JM
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
c906108c 17
c5aa993b
JM
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
c906108c
SS
22
23/* This is like remote.c but is for an esoteric situation--
24 having a 29k board attached to an Adapt inline monitor.
25 The monitor is connected via serial line to a unix machine
26 running gdb.
27
28 3/91 - developed on Sun3 OS 4.1, by David Wood
c5aa993b
JM
29 o - I can't get binary coff to load.
30 o - I can't get 19200 baud rate to work.
c906108c
SS
31 7/91 o - Freeze mode tracing can be done on a 29050. */
32
33
34
35#include "defs.h"
36#include "gdb_string.h"
37#include "inferior.h"
38#include "wait.h"
39#include "value.h"
40#include <ctype.h>
41#include <fcntl.h>
42#include <signal.h>
43#include <errno.h>
44#include "terminal.h"
45#include "target.h"
46#include "gdbcore.h"
47
48/* This processor is getting rusty but I am trying to keep it
49 up to date at least with data structure changes.
50 Activate this block to compile just this file.
c5aa993b 51 */
c906108c
SS
52#define COMPILE_CHECK 0
53#if COMPILE_CHECK
54#define Q_REGNUM 0
55#define VAB_REGNUM 0
56#define CPS_REGNUM 0
57#define IPA_REGNUM 0
58#define IPB_REGNUM 0
59#define GR1_REGNUM 0
60#define LR0_REGNUM 0
61#define IPC_REGNUM 0
62#define CR_REGNUM 0
63#define BP_REGNUM 0
64#define FC_REGNUM 0
65#define INTE_REGNUM 0
66#define EXO_REGNUM 0
67#define GR96_REGNUM 0
68#define NPC_REGNUM
69#define FPE_REGNUM 0
70#define PC2_REGNUM 0
71#define FPS_REGNUM 0
72#define ALU_REGNUM 0
73#define LRU_REGNUM 0
74#define TERMINAL int
75#define RAW 1
76#define ANYP 1
c5aa993b
JM
77extern int a29k_freeze_mode;
78extern int processor_type;
79extern char *processor_name;
c906108c
SS
80#endif
81
82/* External data declarations */
c5aa993b 83extern int stop_soon_quietly; /* for wait_for_inferior */
c906108c
SS
84
85/* Forward data declarations */
c5aa993b 86extern struct target_ops adapt_ops; /* Forward declaration */
c906108c
SS
87
88/* Forward function declarations */
89static void adapt_fetch_registers ();
90static void adapt_store_registers ();
91static void adapt_close ();
c5aa993b 92static int adapt_clear_breakpoints ();
c906108c 93
c5aa993b 94#define FREEZE_MODE (read_register(CPS_REGNUM) && 0x400)
c906108c
SS
95#define USE_SHADOW_PC ((processor_type == a29k_freeze_mode) && FREEZE_MODE)
96
97/* Can't seem to get binary coff working */
98#define ASCII_COFF /* Adapt will be downloaded with ascii coff */
99
100/* FIXME: Replace with `set remotedebug'. */
101#define LOG_FILE "adapt.log"
102#if defined (LOG_FILE)
c5aa993b 103FILE *log_file = NULL;
c906108c
SS
104#endif
105
106static int timeout = 5;
107static char *dev_name;
108
109/* Descriptor for I/O to remote machine. Initialize it to -1 so that
110 adapt_open knows that we don't have a file open when the program
111 starts. */
112int adapt_desc = -1;
113
114/* stream which is fdopen'd from adapt_desc. Only valid when
115 adapt_desc != -1. */
116FILE *adapt_stream;
117
118#define ON 1
119#define OFF 0
120static void
c5aa993b
JM
121rawmode (desc, turnon)
122 int desc;
123 int turnon;
c906108c 124{
c5aa993b 125
c906108c
SS
126 TERMINAL sg;
127
128 if (desc < 0)
129 return;
130
131 ioctl (desc, TIOCGETP, &sg);
132
c5aa993b
JM
133 if (turnon)
134 {
c906108c 135#ifdef HAVE_TERMIO
c5aa993b 136 sg.c_lflag &= ~(ICANON);
c906108c 137#else
c5aa993b 138 sg.sg_flags |= RAW;
c906108c 139#endif
c5aa993b
JM
140 }
141 else
142 {
c906108c 143#ifdef HAVE_TERMIO
c5aa993b 144 sg.c_lflag |= ICANON;
c906108c 145#else
c5aa993b 146 sg.sg_flags &= ~(RAW);
c906108c 147#endif
c5aa993b 148 }
c906108c
SS
149 ioctl (desc, TIOCSETP, &sg);
150}
151
152/* Suck up all the input from the adapt */
c5aa993b 153slurp_input ()
c906108c
SS
154{
155 char buf[8];
156
157#ifdef HAVE_TERMIO
158 /* termio does the timeout for us. */
159 while (read (adapt_desc, buf, 8) > 0);
160#else
161 alarm (timeout);
162 while (read (adapt_desc, buf, 8) > 0);
163 alarm (0);
164#endif
165}
166
167/* Read a character from the remote system, doing all the fancy
168 timeout stuff. */
169static int
170readchar ()
171{
172 char buf;
173
174 buf = '\0';
175#ifdef HAVE_TERMIO
176 /* termio does the timeout for us. */
177 read (adapt_desc, &buf, 1);
178#else
179 alarm (timeout);
180 if (read (adapt_desc, &buf, 1) < 0)
181 {
182 if (errno == EINTR)
183 error ("Timeout reading from remote system.");
184 else
185 perror_with_name ("remote");
186 }
187 alarm (0);
188#endif
189
190 if (buf == '\0')
191 error ("Timeout reading from remote system.");
192#if defined (LOG_FILE)
193 putc (buf & 0x7f, log_file);
194#endif
195 return buf & 0x7f;
196}
197
198/* Keep discarding input from the remote system, until STRING is found.
199 Let the user break out immediately. */
200static void
201expect (string)
202 char *string;
203{
204 char *p = string;
205
c5aa993b 206 fflush (adapt_stream);
c906108c
SS
207 immediate_quit = 1;
208 while (1)
209 {
c5aa993b 210 if (readchar () == *p)
c906108c
SS
211 {
212 p++;
213 if (*p == '\0')
214 {
215 immediate_quit = 0;
216 return;
217 }
218 }
219 else
220 p = string;
221 }
222}
223
224/* Keep discarding input until we see the adapt prompt.
225
226 The convention for dealing with the prompt is that you
227 o give your command
228 o *then* wait for the prompt.
229
230 Thus the last thing that a procedure does with the serial line
231 will be an expect_prompt(). Exception: adapt_resume does not
232 wait for the prompt, because the terminal is being handed over
233 to the inferior. However, the next thing which happens after that
234 is a adapt_wait which does wait for the prompt.
235 Note that this includes abnormal exit, e.g. error(). This is
236 necessary to prevent getting into states from which we can't
237 recover. */
238static void
239expect_prompt ()
240{
241#if defined (LOG_FILE)
242 /* This is a convenient place to do this. The idea is to do it often
243 enough that we never lose much data if we terminate abnormally. */
244 fflush (log_file);
245#endif
c5aa993b 246 fflush (adapt_stream);
c906108c
SS
247 expect ("\n# ");
248}
249
250/* Get a hex digit from the remote system & return its value.
251 If ignore_space is nonzero, ignore spaces (not newline, tab, etc). */
252static int
253get_hex_digit (ignore_space)
254 int ignore_space;
255{
256 int ch;
257 while (1)
258 {
259 ch = readchar ();
260 if (ch >= '0' && ch <= '9')
261 return ch - '0';
262 else if (ch >= 'A' && ch <= 'F')
263 return ch - 'A' + 10;
264 else if (ch >= 'a' && ch <= 'f')
265 return ch - 'a' + 10;
266 else if (ch == ' ' && ignore_space)
267 ;
268 else
269 {
270 expect_prompt ();
271 error ("Invalid hex digit from remote system.");
272 }
273 }
274}
275
276/* Get a byte from adapt_desc and put it in *BYT. Accept any number
277 leading spaces. */
278static void
279get_hex_byte (byt)
280 char *byt;
281{
282 int val;
283
284 val = get_hex_digit (1) << 4;
285 val |= get_hex_digit (0);
286 *byt = val;
287}
288
289/* Read a 32-bit hex word from the adapt, preceded by a space */
c5aa993b
JM
290static long
291get_hex_word ()
c906108c
SS
292{
293 long val;
294 int j;
c5aa993b 295
c906108c
SS
296 val = 0;
297 for (j = 0; j < 8; j++)
c5aa993b 298 val = (val << 4) + get_hex_digit (j == 0);
c906108c
SS
299 return val;
300}
301/* Get N 32-bit hex words from remote, each preceded by a space
302 and put them in registers starting at REGNO. */
303static void
304get_hex_regs (n, regno)
305 int n;
306 int regno;
307{
c5aa993b
JM
308 long val;
309 while (n--)
310 {
311 val = get_hex_word ();
312 supply_register (regno++, (char *) &val);
313 }
c906108c
SS
314}
315/* Called when SIGALRM signal sent due to alarm() timeout. */
316#ifndef HAVE_TERMIO
317
318#ifndef __STDC__
c5aa993b
JM
319#ifndef volatile
320#define volatile
321/**/
c906108c
SS
322# endif
323#endif
324volatile int n_alarms;
325
326void
327adapt_timer ()
328{
329#if 0
330 if (kiodebug)
331 printf ("adapt_timer called\n");
332#endif
333 n_alarms++;
334}
335#endif
336
337/* malloc'd name of the program on the remote system. */
338static char *prog_name = NULL;
339
340/* Number of SIGTRAPs we need to simulate. That is, the next
341 NEED_ARTIFICIAL_TRAP calls to adapt_wait should just return
342 SIGTRAP without actually waiting for anything. */
343
344static int need_artificial_trap = 0;
345
346void
c5aa993b
JM
347adapt_kill (arg, from_tty)
348 char *arg;
349 int from_tty;
c906108c 350{
c5aa993b
JM
351 fprintf (adapt_stream, "K");
352 fprintf (adapt_stream, "\r");
353 expect_prompt ();
c906108c
SS
354}
355/*
356 * Download a file specified in 'args', to the adapt.
357 * FIXME: Assumes the file to download is a binary coff file.
358 */
359static void
c5aa993b
JM
360adapt_load (args, fromtty)
361 char *args;
362 int fromtty;
c906108c 363{
c5aa993b
JM
364 FILE *fp;
365 int n;
366 char buffer[1024];
c906108c 367
c5aa993b
JM
368 if (!adapt_stream)
369 {
370 printf_filtered ("Adapt not open. Use 'target' command to open adapt\n");
371 return;
372 }
373
374 /* OK, now read in the file. Y=read, C=COFF, T=dTe port
375 0=start address. */
376
377#ifdef ASCII_COFF /* Ascii coff */
378 fprintf (adapt_stream, "YA T,0\r");
379 fflush (adapt_stream); /* Just in case */
380 /* FIXME: should check args for only 1 argument */
381 sprintf (buffer, "cat %s | btoa > /tmp/#adapt-btoa", args);
382 system (buffer);
383 fp = fopen ("/tmp/#adapt-btoa", "r");
384 rawmode (adapt_desc, OFF);
385 while (n = fread (buffer, 1, 1024, fp))
386 {
387 do
388 {
389 n -= write (adapt_desc, buffer, n);
c906108c 390 }
c5aa993b
JM
391 while (n > 0);
392 if (n < 0)
393 {
394 perror ("writing ascii coff");
395 break;
c906108c 396 }
c5aa993b
JM
397 }
398 fclose (fp);
399 rawmode (adapt_desc, ON);
400 system ("rm /tmp/#adapt-btoa");
401#else /* Binary coff - can't get it to work . */
402 fprintf (adapt_stream, "YC T,0\r");
403 fflush (adapt_stream); /* Just in case */
404 if (!(fp = fopen (args, "r")))
405 {
406 printf_filtered ("Can't open %s\n", args);
407 return;
408 }
409 while (n = fread (buffer, 1, 512, fp))
410 {
411 do
412 {
413 n -= write (adapt_desc, buffer, n);
c906108c 414 }
c5aa993b
JM
415 while (n > 0);
416 if (n < 0)
417 {
418 perror ("writing ascii coff");
419 break;
420 }
421 }
422 fclose (fp);
c906108c 423#endif
c5aa993b
JM
424 expect_prompt (); /* Skip garbage that comes out */
425 fprintf (adapt_stream, "\r");
426 expect_prompt ();
c906108c
SS
427}
428
429/* This is called not only when we first attach, but also when the
430 user types "run" after having attached. */
431void
432adapt_create_inferior (execfile, args, env)
433 char *execfile;
434 char *args;
435 char **env;
436{
437 int entry_pt;
438
439 if (args && *args)
440 error ("Can't pass arguments to remote adapt process.");
441
442 if (execfile == 0 || exec_bfd == 0)
443 error ("No executable file specified");
444
445 entry_pt = (int) bfd_get_start_address (exec_bfd);
446
c5aa993b
JM
447 if (adapt_stream)
448 {
449 adapt_kill (NULL, NULL);
450 adapt_clear_breakpoints ();
451 init_wait_for_inferior ();
452 /* Clear the input because what the adapt sends back is different
453 * depending on whether it was running or not.
454 */
455 slurp_input (); /* After this there should be a prompt */
456 fprintf (adapt_stream, "\r");
457 expect_prompt ();
458 printf_filtered ("Do you want to download '%s' (y/n)? [y] : ", prog_name);
459 {
460 char buffer[10];
461 gets (buffer);
462 if (*buffer != 'n')
463 {
464 adapt_load (prog_name, 0);
465 }
466 }
c906108c
SS
467
468#ifdef NOTDEF
c5aa993b
JM
469 /* Set the PC and wait for a go/cont */
470 fprintf (adapt_stream, "G %x,N\r", entry_pt);
471 printf_filtered ("Now use the 'continue' command to start.\n");
472 expect_prompt ();
c906108c 473#else
c5aa993b
JM
474 insert_breakpoints (); /* Needed to get correct instruction in cache */
475 proceed (entry_pt, TARGET_SIGNAL_DEFAULT, 0);
c906108c
SS
476#endif
477
c5aa993b
JM
478 }
479 else
480 {
481 printf_filtered ("Adapt not open yet.\n");
482 }
c906108c
SS
483}
484
485/* Translate baud rates from integers to damn B_codes. Unix should
486 have outgrown this crap years ago, but even POSIX wouldn't buck it. */
487
488#ifndef B19200
489#define B19200 EXTA
490#endif
491#ifndef B38400
492#define B38400 EXTB
493#endif
494
c5aa993b
JM
495static struct
496{
497 int rate, damn_b;
498}
499baudtab[] =
500{
501 {
502 0, B0
503 }
504 ,
505 {
506 50, B50
507 }
508 ,
509 {
510 75, B75
511 }
512 ,
513 {
514 110, B110
515 }
516 ,
517 {
518 134, B134
519 }
520 ,
521 {
522 150, B150
523 }
524 ,
525 {
526 200, B200
527 }
528 ,
529 {
530 300, B300
531 }
532 ,
533 {
534 600, B600
535 }
536 ,
537 {
538 1200, B1200
539 }
540 ,
541 {
542 1800, B1800
543 }
544 ,
545 {
546 2400, B2400
547 }
548 ,
549 {
550 4800, B4800
551 }
552 ,
553 {
554 9600, B9600
555 }
556 ,
557 {
558 19200, B19200
559 }
560 ,
561 {
562 38400, B38400
563 }
564 ,
565 {
566 -1, -1
567 }
568 ,
c906108c
SS
569};
570
c5aa993b
JM
571static int
572damn_b (rate)
c906108c
SS
573 int rate;
574{
575 int i;
576
577 for (i = 0; baudtab[i].rate != -1; i++)
c5aa993b
JM
578 if (rate == baudtab[i].rate)
579 return baudtab[i].damn_b;
580 return B38400; /* Random */
c906108c
SS
581}
582
583
584/* Open a connection to a remote debugger.
585 NAME is the filename used for communication, then a space,
586 then the baud rate.
587 */
588
589static int baudrate = 9600;
590static void
591adapt_open (name, from_tty)
592 char *name;
593 int from_tty;
594{
595 TERMINAL sg;
596 unsigned int prl;
597 char *p;
598
599 /* Find the first whitespace character, it separates dev_name from
600 prog_name. */
601 if (name == 0)
602 goto erroid;
603
604 for (p = name;
605 *p != '\0' && !isspace (*p); p++)
606 ;
607 if (*p == '\0')
c5aa993b 608 erroid:
c906108c
SS
609 error ("\
610Please include the name of the device for the serial port,\n\
611the baud rate, and the name of the program to run on the remote system.");
c5aa993b 612 dev_name = (char *) xmalloc (p - name + 1);
c906108c
SS
613 strncpy (dev_name, name, p - name);
614 dev_name[p - name] = '\0';
615
616 /* Skip over the whitespace after dev_name */
617 for (; isspace (*p); p++)
c5aa993b
JM
618 /*EMPTY */ ;
619
c906108c
SS
620 if (1 != sscanf (p, "%d ", &baudrate))
621 goto erroid;
622
623 /* Skip the number and then the spaces */
624 for (; isdigit (*p); p++)
c5aa993b 625 /*EMPTY */ ;
c906108c 626 for (; isspace (*p); p++)
c5aa993b
JM
627 /*EMPTY */ ;
628
c906108c
SS
629 if (prog_name != NULL)
630 free (prog_name);
631 prog_name = savestring (p, strlen (p));
632
633 adapt_close (0);
634
635 adapt_desc = open (dev_name, O_RDWR);
636 if (adapt_desc < 0)
637 perror_with_name (dev_name);
638 ioctl (adapt_desc, TIOCGETP, &sg);
c5aa993b 639#if ! defined(COMPILE_CHECK)
c906108c
SS
640#ifdef HAVE_TERMIO
641 sg.c_cc[VMIN] = 0; /* read with timeout. */
642 sg.c_cc[VTIME] = timeout * 10;
643 sg.c_lflag &= ~(ICANON | ECHO);
644 sg.c_cflag = (sg.c_cflag & ~CBAUD) | damn_b (baudrate);
645#else
646 sg.sg_ispeed = damn_b (baudrate);
647 sg.sg_ospeed = damn_b (baudrate);
648 sg.sg_flags |= RAW | ANYP;
649 sg.sg_flags &= ~ECHO;
650#endif
651
652 ioctl (adapt_desc, TIOCSETP, &sg);
653 adapt_stream = fdopen (adapt_desc, "r+");
654#endif /* compile_check */
655 push_target (&adapt_ops);
656
657#ifndef HAVE_TERMIO
658#ifndef NO_SIGINTERRUPT
659 /* Cause SIGALRM's to make reads fail with EINTR instead of resuming
660 the read. */
661 if (siginterrupt (SIGALRM, 1) != 0)
662 perror ("adapt_open: error in siginterrupt");
663#endif
664
665 /* Set up read timeout timer. */
666 if ((void (*)) signal (SIGALRM, adapt_timer) == (void (*)) -1)
667 perror ("adapt_open: error in signal");
668#endif
669
670#if defined (LOG_FILE)
671 log_file = fopen (LOG_FILE, "w");
672 if (log_file == NULL)
673 perror_with_name (LOG_FILE);
674#endif
675
676 /* Put this port into NORMAL mode, send the 'normal' character */
c5aa993b
JM
677 write (adapt_desc, "\ 1", 1); /* Control A */
678 write (adapt_desc, "\r", 1);
c906108c 679 expect_prompt ();
c5aa993b 680
c906108c
SS
681 /* Hello? Are you there? */
682 write (adapt_desc, "\r", 1);
c5aa993b 683
c906108c
SS
684 expect_prompt ();
685
686 /* Clear any break points */
c5aa993b 687 adapt_clear_breakpoints ();
c906108c
SS
688
689 /* Print out some stuff, letting the user now what's going on */
c5aa993b
JM
690 printf_filtered ("Connected to an Adapt via %s.\n", dev_name);
691 /* FIXME: can this restriction be removed? */
692 printf_filtered ("Remote debugging using virtual addresses works only\n");
693 printf_filtered ("\twhen virtual addresses map 1:1 to physical addresses.\n");
694 if (processor_type != a29k_freeze_mode)
695 {
696 fprintf_filtered (gdb_stderr,
697 "Freeze-mode debugging not available, and can only be done on an A29050.\n");
698 }
c906108c
SS
699}
700
701/* Close out all files and local state before this target loses control. */
702
703static void
704adapt_close (quitting)
705 int quitting;
706{
707
708 /* Clear any break points */
c5aa993b 709 adapt_clear_breakpoints ();
c906108c 710
c5aa993b
JM
711 /* Put this port back into REMOTE mode */
712 if (adapt_stream)
713 {
714 fflush (adapt_stream);
715 sleep (1); /* Let any output make it all the way back */
716 write (adapt_desc, "R\r", 2);
717 }
c906108c
SS
718
719 /* Due to a bug in Unix, fclose closes not only the stdio stream,
720 but also the file descriptor. So we don't actually close
721 adapt_desc. */
722 if (adapt_stream)
723 fclose (adapt_stream); /* This also closes adapt_desc */
724 if (adapt_desc >= 0)
725 /* close (adapt_desc); */
726
c5aa993b
JM
727 /* Do not try to close adapt_desc again, later in the program. */
728 adapt_stream = NULL;
c906108c
SS
729 adapt_desc = -1;
730
731#if defined (LOG_FILE)
c5aa993b
JM
732 if (log_file)
733 {
734 if (ferror (log_file))
735 printf_filtered ("Error writing log file.\n");
736 if (fclose (log_file) != 0)
737 printf_filtered ("Error closing log file.\n");
738 log_file = NULL;
739 }
c906108c
SS
740#endif
741}
742
743/* Attach to the target that is already loaded and possibly running */
744static void
745adapt_attach (args, from_tty)
746 char *args;
747 int from_tty;
748{
749
750 if (from_tty)
c5aa993b 751 printf_filtered ("Attaching to remote program %s.\n", prog_name);
c906108c
SS
752
753 /* Send the adapt a kill. It is ok if it is not already running */
c5aa993b
JM
754 fprintf (adapt_stream, "K\r");
755 fflush (adapt_stream);
756 expect_prompt (); /* Slurp the echo */
c906108c
SS
757}
758
759
760/* Terminate the open connection to the remote debugger.
761 Use this when you want to detach and do something else
762 with your gdb. */
763void
c5aa993b 764adapt_detach (args, from_tty)
c906108c
SS
765 char *args;
766 int from_tty;
767{
768
c5aa993b
JM
769 if (adapt_stream)
770 { /* Send it on its way (tell it to continue) */
771 adapt_clear_breakpoints ();
772 fprintf (adapt_stream, "G\r");
773 }
774
775 pop_target (); /* calls adapt_close to do the real work */
c906108c
SS
776 if (from_tty)
777 printf_filtered ("Ending remote %s debugging\n", target_shortname);
778}
c5aa993b 779
c906108c
SS
780/* Tell the remote machine to resume. */
781
782void
783adapt_resume (pid, step, sig)
784 int pid, step;
785 enum target_signal sig;
786{
c5aa993b 787 if (step)
c906108c
SS
788 {
789 write (adapt_desc, "t 1,s\r", 6);
790 /* Wait for the echo. */
791 expect ("t 1,s\r\n");
792 /* Then comes a line containing the instruction we stepped to. */
793 expect ("@");
794 /* Then we get the prompt. */
795 expect_prompt ();
796
797 /* Force the next adapt_wait to return a trap. Not doing anything
798 about I/O from the target means that the user has to type
799 "continue" to see any. FIXME, this should be fixed. */
800 need_artificial_trap = 1;
801 }
802 else
803 {
804 write (adapt_desc, "G\r", 2);
805 /* Swallow the echo. */
c5aa993b 806 expect_prompt ();
c906108c
SS
807 }
808}
809
810/* Wait until the remote machine stops, then return,
811 storing status in STATUS just as `wait' would. */
812
813int
814adapt_wait (status)
815 struct target_waitstatus *status;
816{
817 /* Strings to look for. '?' means match any single character.
818 Note that with the algorithm we use, the initial character
819 of the string cannot recur in the string, or we will not
820 find some cases of the string in the input. */
c5aa993b 821
c906108c
SS
822 static char bpt[] = "@";
823 /* It would be tempting to look for "\n[__exit + 0x8]\n"
824 but that requires loading symbols with "yc i" and even if
825 we did do that we don't know that the file has symbols. */
826 static char exitmsg[] = "@????????I JMPTI GR121,LR0";
827 char *bp = bpt;
828 char *ep = exitmsg;
829
830 /* Large enough for either sizeof (bpt) or sizeof (exitmsg) chars. */
831 char swallowed[50];
832 /* Current position in swallowed. */
833 char *swallowed_p = swallowed;
834
835 int ch;
836 int ch_handled;
837 int old_timeout = timeout;
838 int old_immediate_quit = immediate_quit;
839
840 status->kind = TARGET_WAITKIND_EXITED;
841 status->value.integer = 0;
842
843 if (need_artificial_trap != 0)
844 {
845 status->kind = TARGET_WAITKIND_STOPPED;
846 status->value.sig = TARGET_SIGNAL_TRAP;
847 need_artificial_trap--;
848 return 0;
849 }
850
c5aa993b
JM
851 timeout = 0; /* Don't time out -- user program is running. */
852 immediate_quit = 1; /* Helps ability to QUIT */
853 while (1)
854 {
855 QUIT; /* Let user quit and leave process running */
c906108c
SS
856 ch_handled = 0;
857 ch = readchar ();
c5aa993b
JM
858 if (ch == *bp)
859 {
c906108c
SS
860 bp++;
861 if (*bp == '\0')
862 break;
863 ch_handled = 1;
864
865 *swallowed_p++ = ch;
c5aa993b
JM
866 }
867 else
c906108c 868 bp = bpt;
c5aa993b
JM
869 if (ch == *ep || *ep == '?')
870 {
c906108c
SS
871 ep++;
872 if (*ep == '\0')
873 break;
874
875 if (!ch_handled)
876 *swallowed_p++ = ch;
877 ch_handled = 1;
c5aa993b
JM
878 }
879 else
c906108c 880 ep = exitmsg;
c5aa993b
JM
881 if (!ch_handled)
882 {
c906108c
SS
883 char *p;
884 /* Print out any characters which have been swallowed. */
885 for (p = swallowed; p < swallowed_p; ++p)
886 putc (*p, stdout);
887 swallowed_p = swallowed;
888 putc (ch, stdout);
c5aa993b
JM
889 }
890 }
c906108c 891 expect_prompt ();
c5aa993b 892 if (*bp == '\0')
c906108c
SS
893 {
894 status->kind = TARGET_WAITKIND_STOPPED;
895 status->value.sig = TARGET_SIGNAL_TRAP;
896 }
897 else
898 {
899 status->kind = TARGET_WAITKIND_EXITED;
900 status->value.integer = 0;
901 }
902 timeout = old_timeout;
903 immediate_quit = old_immediate_quit;
904 return 0;
905}
906
907/* Return the name of register number REGNO
908 in the form input and output by adapt.
909
910 Returns a pointer to a static buffer containing the answer. */
911static char *
912get_reg_name (regno)
913 int regno;
914{
915 static char buf[80];
c5aa993b 916 if (regno >= GR96_REGNUM && regno < GR96_REGNUM + 32)
c906108c
SS
917 sprintf (buf, "GR%03d", regno - GR96_REGNUM + 96);
918#if defined(GR64_REGNUM)
c5aa993b 919 else if (regno >= GR64_REGNUM && regno < GR64_REGNUM + 32)
c906108c
SS
920 sprintf (buf, "GR%03d", regno - GR64_REGNUM + 64);
921#endif
922 else if (regno >= LR0_REGNUM && regno < LR0_REGNUM + 128)
923 sprintf (buf, "LR%03d", regno - LR0_REGNUM);
c5aa993b 924 else if (regno == Q_REGNUM)
c906108c
SS
925 strcpy (buf, "SR131");
926 else if (regno >= BP_REGNUM && regno <= CR_REGNUM)
927 sprintf (buf, "SR%03d", regno - BP_REGNUM + 133);
928 else if (regno == ALU_REGNUM)
929 strcpy (buf, "SR132");
930 else if (regno >= IPC_REGNUM && regno <= IPB_REGNUM)
931 sprintf (buf, "SR%03d", regno - IPC_REGNUM + 128);
c5aa993b
JM
932 else if (regno >= VAB_REGNUM && regno <= LRU_REGNUM)
933 {
934 /* When a 29050 is in freeze-mode, read shadow pcs instead */
935 if ((regno >= NPC_REGNUM && regno <= PC2_REGNUM) && USE_SHADOW_PC)
936 sprintf (buf, "SR%03d", regno - NPC_REGNUM + 20);
937 else
938 sprintf (buf, "SR%03d", regno - VAB_REGNUM);
939 }
c906108c
SS
940 else if (regno == GR1_REGNUM)
941 strcpy (buf, "GR001");
942 return buf;
943}
944
945/* Read the remote registers. */
946
947static void
948adapt_fetch_registers ()
949{
950 int reg_index;
951 int regnum_index;
952 char tempbuf[10];
c5aa993b
JM
953 int sreg_buf[16];
954 int i, j;
c906108c
SS
955
956/*
957 * Global registers
958 */
959#if defined(GR64_REGNUM)
960 write (adapt_desc, "dw gr64,gr95\r", 13);
961 for (reg_index = 64, regnum_index = GR64_REGNUM;
962 reg_index < 96;
963 reg_index += 4, regnum_index += 4)
964 {
965 sprintf (tempbuf, "GR%03d ", reg_index);
966 expect (tempbuf);
967 get_hex_regs (4, regnum_index);
968 expect ("\n");
969 }
970#endif
971 write (adapt_desc, "dw gr96,gr127\r", 14);
972 for (reg_index = 96, regnum_index = GR96_REGNUM;
973 reg_index < 128;
974 reg_index += 4, regnum_index += 4)
975 {
976 sprintf (tempbuf, "GR%03d ", reg_index);
977 expect (tempbuf);
978 get_hex_regs (4, regnum_index);
979 expect ("\n");
980 }
981
982/*
983 * Local registers
984 */
985 for (i = 0; i < 128; i += 32)
986 {
987 /* The PC has a tendency to hang if we get these
c5aa993b 988 all in one fell swoop ("dw lr0,lr127"). */
c906108c
SS
989 sprintf (tempbuf, "dw lr%d\r", i);
990 write (adapt_desc, tempbuf, strlen (tempbuf));
991 for (reg_index = i, regnum_index = LR0_REGNUM + i;
992 reg_index < i + 32;
993 reg_index += 4, regnum_index += 4)
994 {
995 sprintf (tempbuf, "LR%03d ", reg_index);
996 expect (tempbuf);
997 get_hex_regs (4, regnum_index);
998 expect ("\n");
999 }
1000 }
1001
1002/*
1003 * Special registers
1004 */
1005 sprintf (tempbuf, "dw sr0\r");
1006 write (adapt_desc, tempbuf, strlen (tempbuf));
c5aa993b
JM
1007 for (i = 0; i < 4; i++)
1008 { /* SR0 - SR14 */
1009 sprintf (tempbuf, "SR%3d", i * 4);
1010 expect (tempbuf);
1011 for (j = 0; j < (i == 3 ? 3 : 4); j++)
1012 sreg_buf[i * 4 + j] = get_hex_word ();
1013 }
1014 expect_prompt ();
c906108c
SS
1015 /*
1016 * Read the pcs individually if we are in freeze mode.
1017 * See get_reg_name(), it translates the register names for the pcs to
1018 * the names of the shadow pcs.
c5aa993b
JM
1019 */
1020 if (USE_SHADOW_PC)
1021 {
1022 sreg_buf[10] = read_register (NPC_REGNUM); /* pc0 */
1023 sreg_buf[11] = read_register (PC_REGNUM); /* pc1 */
1024 sreg_buf[12] = read_register (PC2_REGNUM); /* pc2 */
1025 }
1026 for (i = 0; i < 14; i++) /* Supply vab -> lru */
1027 supply_register (VAB_REGNUM + i, (char *) &sreg_buf[i]);
c906108c
SS
1028 sprintf (tempbuf, "dw sr128\r");
1029 write (adapt_desc, tempbuf, strlen (tempbuf));
c5aa993b
JM
1030 for (i = 0; i < 2; i++)
1031 { /* SR128 - SR135 */
1032 sprintf (tempbuf, "SR%3d", 128 + i * 4);
1033 expect (tempbuf);
1034 for (j = 0; j < 4; j++)
1035 sreg_buf[i * 4 + j] = get_hex_word ();
1036 }
1037 expect_prompt ();
1038 supply_register (IPC_REGNUM, (char *) &sreg_buf[0]);
1039 supply_register (IPA_REGNUM, (char *) &sreg_buf[1]);
1040 supply_register (IPB_REGNUM, (char *) &sreg_buf[2]);
1041 supply_register (Q_REGNUM, (char *) &sreg_buf[3]);
1042 /* Skip ALU */
1043 supply_register (BP_REGNUM, (char *) &sreg_buf[5]);
1044 supply_register (FC_REGNUM, (char *) &sreg_buf[6]);
1045 supply_register (CR_REGNUM, (char *) &sreg_buf[7]);
c906108c
SS
1046
1047 /* There doesn't seem to be any way to get these. */
1048 {
1049 int val = -1;
1050 supply_register (FPE_REGNUM, (char *) &val);
1051 supply_register (INTE_REGNUM, (char *) &val);
1052 supply_register (FPS_REGNUM, (char *) &val);
1053 supply_register (EXO_REGNUM, (char *) &val);
1054 }
1055
1056 write (adapt_desc, "dw gr1,gr1\r", 11);
1057 expect ("GR001 ");
1058 get_hex_regs (1, GR1_REGNUM);
1059 expect_prompt ();
1060}
1061
1062/* Fetch register REGNO, or all registers if REGNO is -1.
1063 */
1064static void
1065adapt_fetch_register (regno)
1066 int regno;
1067{
1068 if (regno == -1)
1069 adapt_fetch_registers ();
1070 else
1071 {
1072 char *name = get_reg_name (regno);
1073 fprintf (adapt_stream, "dw %s,%s\r", name, name);
1074 expect (name);
1075 expect (" ");
1076 get_hex_regs (1, regno);
1077 expect_prompt ();
1078 }
1079}
1080
1081/* Store the remote registers from the contents of the block REGS. */
1082
1083static void
1084adapt_store_registers ()
1085{
1086 int i, j;
1087
1088 fprintf (adapt_stream, "s gr1,%x\r", read_register (GR1_REGNUM));
1089 expect_prompt ();
1090
1091#if defined(GR64_REGNUM)
1092 for (j = 0; j < 32; j += 16)
1093 {
1094 fprintf (adapt_stream, "s gr%d,", j + 64);
c5aa993b 1095 for (i = 0; i < 15; ++i)
c906108c
SS
1096 fprintf (adapt_stream, "%x,", read_register (GR64_REGNUM + j + i));
1097 fprintf (adapt_stream, "%x\r", read_register (GR64_REGNUM + j + 15));
1098 expect_prompt ();
1099 }
1100#endif
1101 for (j = 0; j < 32; j += 16)
1102 {
1103 fprintf (adapt_stream, "s gr%d,", j + 96);
c5aa993b 1104 for (i = 0; i < 15; ++i)
c906108c
SS
1105 fprintf (adapt_stream, "%x,", read_register (GR96_REGNUM + j + i));
1106 fprintf (adapt_stream, "%x\r", read_register (GR96_REGNUM + j + 15));
1107 expect_prompt ();
1108 }
1109
1110 for (j = 0; j < 128; j += 16)
1111 {
1112 fprintf (adapt_stream, "s lr%d,", j);
c5aa993b 1113 for (i = 0; i < 15; ++i)
c906108c
SS
1114 fprintf (adapt_stream, "%x,", read_register (LR0_REGNUM + j + i));
1115 fprintf (adapt_stream, "%x\r", read_register (LR0_REGNUM + j + 15));
1116 expect_prompt ();
1117 }
1118
1119 fprintf (adapt_stream, "s sr128,%x,%x,%x\r", read_register (IPC_REGNUM),
1120 read_register (IPA_REGNUM), read_register (IPB_REGNUM));
1121 expect_prompt ();
1122 fprintf (adapt_stream, "s sr133,%x,%x,%x\r", read_register (BP_REGNUM),
1123 read_register (FC_REGNUM), read_register (CR_REGNUM));
1124 expect_prompt ();
1125 fprintf (adapt_stream, "s sr131,%x\r", read_register (Q_REGNUM));
1126 expect_prompt ();
1127 fprintf (adapt_stream, "s sr0,");
c5aa993b 1128 for (i = 0; i < 7; ++i)
c906108c
SS
1129 fprintf (adapt_stream, "%x,", read_register (VAB_REGNUM + i));
1130 expect_prompt ();
1131 fprintf (adapt_stream, "s sr7,");
c5aa993b 1132 for (i = 7; i < 14; ++i)
c906108c
SS
1133 fprintf (adapt_stream, "%x,", read_register (VAB_REGNUM + i));
1134 expect_prompt ();
1135}
1136
1137/* Store register REGNO, or all if REGNO == -1.
1138 Return errno value. */
1139void
1140adapt_store_register (regno)
1141 int regno;
1142{
1143 /* printf("adapt_store_register() called.\n"); fflush(stdout); /* */
1144 if (regno == -1)
1145 adapt_store_registers ();
1146 else
1147 {
1148 char *name = get_reg_name (regno);
1149 fprintf (adapt_stream, "s %s,%x\r", name, read_register (regno));
1150 /* Setting GR1 changes the numbers of all the locals, so
c5aa993b
JM
1151 invalidate the register cache. Do this *after* calling
1152 read_register, because we want read_register to return the
1153 value that write_register has just stuffed into the registers
1154 array, not the value of the register fetched from the
1155 inferior. */
c906108c
SS
1156 if (regno == GR1_REGNUM)
1157 registers_changed ();
1158 expect_prompt ();
1159 }
1160}
1161
1162/* Get ready to modify the registers array. On machines which store
1163 individual registers, this doesn't need to do anything. On machines
1164 which store all the registers in one fell swoop, this makes sure
1165 that registers contains all the registers from the program being
1166 debugged. */
1167
1168void
1169adapt_prepare_to_store ()
1170{
1171 /* Do nothing, since we can store individual regs */
1172}
1173
c5aa993b
JM
1174static CORE_ADDR
1175translate_addr (addr)
1176 CORE_ADDR addr;
c906108c
SS
1177{
1178#if defined(KERNEL_DEBUGGING)
c5aa993b
JM
1179 /* Check for a virtual address in the kernel */
1180 /* Assume physical address of ublock is in paddr_u register */
1181 if (addr >= UVADDR)
1182 {
1183 /* PADDR_U register holds the physical address of the ublock */
1184 CORE_ADDR i = (CORE_ADDR) read_register (PADDR_U_REGNUM);
1185 return (i + addr - (CORE_ADDR) UVADDR);
1186 }
1187 else
1188 {
1189 return (addr);
1190 }
c906108c 1191#else
c5aa993b 1192 return (addr);
c906108c
SS
1193#endif
1194}
1195
1196
1197/* FIXME! Merge these two. */
1198int
1199adapt_xfer_inferior_memory (memaddr, myaddr, len, write)
1200 CORE_ADDR memaddr;
1201 char *myaddr;
1202 int len;
1203 int write;
1204{
1205
c5aa993b 1206 memaddr = translate_addr (memaddr);
c906108c
SS
1207
1208 if (write)
1209 return adapt_write_inferior_memory (memaddr, myaddr, len);
1210 else
1211 return adapt_read_inferior_memory (memaddr, myaddr, len);
1212}
1213
1214void
1215adapt_files_info ()
1216{
c5aa993b
JM
1217 printf_filtered ("\tAttached to %s at %d baud and running program %s\n",
1218 dev_name, baudrate, prog_name);
1219 printf_filtered ("\ton an %s processor.\n", processor_name[processor_type]);
c906108c
SS
1220}
1221
1222/* Copy LEN bytes of data from debugger memory at MYADDR
1223 to inferior's memory at MEMADDR. Returns errno value.
c5aa993b 1224 * sb/sh instructions don't work on unaligned addresses, when TU=1.
c906108c
SS
1225 */
1226int
1227adapt_write_inferior_memory (memaddr, myaddr, len)
1228 CORE_ADDR memaddr;
1229 char *myaddr;
1230 int len;
1231{
1232 int i;
1233 unsigned int cps;
1234
1235 /* Turn TU bit off so we can do 'sb' commands */
c5aa993b 1236 cps = read_register (CPS_REGNUM);
c906108c 1237 if (cps & 0x00000800)
c5aa993b 1238 write_register (CPS_REGNUM, cps & ~(0x00000800));
c906108c
SS
1239
1240 for (i = 0; i < len; i++)
1241 {
1242 if ((i % 16) == 0)
1243 fprintf (adapt_stream, "sb %x,", memaddr + i);
1244 if ((i % 16) == 15 || i == len - 1)
1245 {
c5aa993b 1246 fprintf (adapt_stream, "%x\r", ((unsigned char *) myaddr)[i]);
c906108c
SS
1247 expect_prompt ();
1248 }
1249 else
c5aa993b 1250 fprintf (adapt_stream, "%x,", ((unsigned char *) myaddr)[i]);
c906108c
SS
1251 }
1252 /* Restore the old value of cps if the TU bit was on */
1253 if (cps & 0x00000800)
c5aa993b 1254 write_register (CPS_REGNUM, cps);
c906108c
SS
1255 return len;
1256}
1257
1258/* Read LEN bytes from inferior memory at MEMADDR. Put the result
1259 at debugger address MYADDR. Returns errno value. */
1260int
c5aa993b 1261adapt_read_inferior_memory (memaddr, myaddr, len)
c906108c
SS
1262 CORE_ADDR memaddr;
1263 char *myaddr;
1264 int len;
1265{
1266 int i;
1267
1268 /* Number of bytes read so far. */
1269 int count;
1270
1271 /* Starting address of this pass. */
1272 unsigned long startaddr;
1273
1274 /* Number of bytes to read in this pass. */
1275 int len_this_pass;
1276
1277 /* Note that this code works correctly if startaddr is just less
1278 than UINT_MAX (well, really CORE_ADDR_MAX if there was such a
1279 thing). That is, something like
1280 adapt_read_bytes (CORE_ADDR_MAX - 4, foo, 4)
1281 works--it never adds len to memaddr and gets 0. */
1282 /* However, something like
1283 adapt_read_bytes (CORE_ADDR_MAX - 3, foo, 4)
1284 doesn't need to work. Detect it and give up if there's an attempt
1285 to do that. */
1286
1287 if (((memaddr - 1) + len) < memaddr)
1288 return EIO;
c5aa993b 1289
c906108c
SS
1290 startaddr = memaddr;
1291 count = 0;
1292 while (count < len)
1293 {
1294 len_this_pass = 16;
1295 if ((startaddr % 16) != 0)
1296 len_this_pass -= startaddr % 16;
1297 if (len_this_pass > (len - count))
1298 len_this_pass = (len - count);
1299
1300 fprintf (adapt_stream, "db %x,%x\r", startaddr,
1301 (startaddr - 1) + len_this_pass);
1302
c5aa993b 1303#ifdef NOTDEF /* Why do this */
c906108c
SS
1304 expect ("\n");
1305 /* Look for 8 hex digits. */
1306 i = 0;
1307 while (1)
1308 {
1309 if (isxdigit (readchar ()))
1310 ++i;
1311 else
1312 {
1313 expect_prompt ();
1314 error ("Hex digit expected from remote system.");
1315 }
1316 if (i >= 8)
1317 break;
1318 }
1319#endif /* NOTDEF */
1320
1321 expect (" ");
1322
1323 for (i = 0; i < len_this_pass; i++)
1324 get_hex_byte (&myaddr[count++]);
1325
1326 expect_prompt ();
1327
1328 startaddr += len_this_pass;
1329 }
1330 return count;
1331}
1332
1333#define MAX_BREAKS 8
c5aa993b 1334static int num_brkpts = 0;
c906108c 1335static int
c5aa993b
JM
1336adapt_insert_breakpoint (addr, save)
1337 CORE_ADDR addr;
1338 char *save; /* Throw away, let adapt save instructions */
c906108c 1339{
c5aa993b
JM
1340 if (num_brkpts < MAX_BREAKS)
1341 {
1342 num_brkpts++;
1343 fprintf (adapt_stream, "B %x", addr);
1344 fprintf (adapt_stream, "\r");
1345 expect_prompt ();
1346 return (0); /* Success */
1347 }
1348 else
1349 {
1350 fprintf_filtered (gdb_stderr,
1351 "Too many break points, break point not installed\n");
1352 return (1); /* Failure */
1353 }
c906108c
SS
1354
1355}
1356static int
c5aa993b
JM
1357adapt_remove_breakpoint (addr, save)
1358 CORE_ADDR addr;
1359 char *save; /* Throw away, let adapt save instructions */
c906108c 1360{
c5aa993b
JM
1361 if (num_brkpts > 0)
1362 {
1363 num_brkpts--;
1364 fprintf (adapt_stream, "BR %x", addr);
1365 fprintf (adapt_stream, "\r");
1366 fflush (adapt_stream);
1367 expect_prompt ();
1368 }
1369 return (0);
c906108c
SS
1370}
1371
1372/* Clear the adapts notion of what the break points are */
1373static int
c5aa993b
JM
1374adapt_clear_breakpoints ()
1375{
1376 if (adapt_stream)
1377 {
1378 fprintf (adapt_stream, "BR"); /* Clear all break points */
1379 fprintf (adapt_stream, "\r");
1380 fflush (adapt_stream);
1381 expect_prompt ();
1382 }
c906108c
SS
1383 num_brkpts = 0;
1384}
1385static void
c5aa993b
JM
1386adapt_mourn ()
1387{
1388 adapt_clear_breakpoints ();
1389 pop_target (); /* Pop back to no-child state */
c906108c
SS
1390 generic_mourn_inferior ();
1391}
1392
1393/* Display everthing we read in from the adapt until we match/see the
1394 * specified string
1395 */
1396static int
c5aa993b
JM
1397display_until (str)
1398 char *str;
c906108c 1399{
c5aa993b
JM
1400 int i = 0, j, c;
1401
1402 while (c = readchar ())
1403 {
1404 if (c == str[i])
1405 {
1406 i++;
1407 if (i == strlen (str))
1408 return;
1409 }
1410 else
1411 {
1412 if (i)
1413 {
1414 for (j = 0; j < i; j++) /* Put everthing we matched */
1415 putchar (str[j]);
1416 i = 0;
1417 }
1418 putchar (c);
c906108c 1419 }
c5aa993b 1420 }
c906108c
SS
1421
1422}
1423
1424
1425/* Put a command string, in args, out to the adapt. The adapt is assumed to
1426 be in raw mode, all writing/reading done through adapt_desc.
1427 Ouput from the adapt is placed on the users terminal until the
1428 prompt from the adapt is seen.
1429 FIXME: Can't handle commands that take input. */
1430
1431void
1432adapt_com (args, fromtty)
c5aa993b
JM
1433 char *args;
1434 int fromtty;
c906108c 1435{
c5aa993b
JM
1436 if (!adapt_stream)
1437 {
1438 printf_filtered ("Adapt not open. Use the 'target' command to open.\n");
1439 return;
1440 }
1441
1442 /* Clear all input so only command relative output is displayed */
1443 slurp_input ();
c906108c 1444
c5aa993b
JM
1445 switch (islower (args[0]) ? toupper (args[0]) : args[0])
1446 {
1447 default:
1448 printf_filtered ("Unknown/Unimplemented adapt command '%s'\n", args);
1449 break;
1450 case 'G': /* Go, begin execution */
1451 write (adapt_desc, args, strlen (args));
1452 write (adapt_desc, "\r", 1);
1453 expect_prompt ();
1454 break;
1455 case 'B': /* Break points, B or BR */
1456 case 'C': /* Check current 29k status (running/halted) */
1457 case 'D': /* Display data/registers */
1458 case 'I': /* Input from i/o space */
1459 case 'J': /* Jam an instruction */
1460 case 'K': /* Kill, stop execution */
1461 case 'L': /* Disassemble */
1462 case 'O': /* Output to i/o space */
1463 case 'T': /* Trace */
1464 case 'P': /* Pulse an input line */
1465 case 'X': /* Examine special purpose registers */
1466 case 'Z': /* Display trace buffer */
1467 write (adapt_desc, args, strlen (args));
1468 write (adapt_desc, "\r", 1);
1469 expect (args); /* Don't display the command */
1470 display_until ("# ");
1471 break;
1472 /* Begin commands that take input in the form 'c x,y[,z...]' */
1473 case 'S': /* Set memory or register */
1474 if (strchr (args, ','))
1475 { /* Assume it is properly formatted */
1476 write (adapt_desc, args, strlen (args));
1477 write (adapt_desc, "\r", 1);
1478 expect_prompt ();
c906108c 1479 }
c5aa993b
JM
1480 break;
1481 }
c906108c
SS
1482}
1483
1484/* Define the target subroutine names */
1485
c5aa993b 1486struct target_ops adapt_ops;
c906108c 1487
c5aa993b
JM
1488static void
1489init_adapt_ops (void)
c906108c 1490{
c5aa993b
JM
1491 adapt_ops.to_shortname = "adapt";
1492 adapt_ops.to_longname = "Remote AMD `Adapt' target";
1493 adapt_ops.to_doc = "Remote debug an AMD 290*0 using an `Adapt' monitor via RS232";
1494 adapt_ops.to_open = adapt_open;
1495 adapt_ops.to_close = adapt_close;
c906108c
SS
1496 adapt_ops.to_attach = adapt_attach;
1497 adapt_ops.to_post_attach = NULL;
c5aa993b 1498 adapt_ops.to_require_attach = NULL;
c906108c
SS
1499 adapt_ops.to_detach = adapt_detach;
1500 adapt_ops.to_require_detach = NULL;
1501 adapt_ops.to_resume = adapt_resume;
c5aa993b 1502 adapt_ops.to_wait = adapt_wait;
c906108c 1503 adapt_ops.to_post_wait = NULL;
c5aa993b
JM
1504 adapt_ops.to_fetch_registers = adapt_fetch_register;
1505 adapt_ops.to_store_registers = adapt_store_register;
c906108c 1506 adapt_ops.to_prepare_to_store = adapt_prepare_to_store;
c5aa993b
JM
1507 adapt_ops.to_xfer_memory = adapt_xfer_inferior_memory;
1508 adapt_ops.to_files_info = adapt_files_info;
c906108c 1509 adapt_ops.to_insert_breakpoint = adapt_insert_breakpoint;
c5aa993b
JM
1510 adapt_ops.to_remove_breakpoint = adapt_remove_breakpoint;
1511 adapt_ops.to_terminal_init = 0;
1512 adapt_ops.to_terminal_inferior = 0;
1513 adapt_ops.to_terminal_ours_for_output = 0;
1514 adapt_ops.to_terminal_ours = 0;
1515 adapt_ops.to_terminal_info = 0;
1516 adapt_ops.to_kill = adapt_kill;
1517 adapt_ops.to_load = adapt_load;
1518 adapt_ops.to_lookup_symbol = 0;
1519 adapt_ops.to_create_inferior = adapt_create_inferior;
c906108c
SS
1520 adapt_ops.to_post_startup_inferior = NULL;
1521 adapt_ops.to_acknowledge_created_inferior = NULL;
c5aa993b
JM
1522 adapt_ops.to_clone_and_follow_inferior = NULL;
1523 adapt_ops.to_post_follow_inferior_by_clone = NULL;
c906108c
SS
1524 adapt_ops.to_insert_fork_catchpoint = NULL;
1525 adapt_ops.to_remove_fork_catchpoint = NULL;
1526 adapt_ops.to_insert_vfork_catchpoint = NULL;
c5aa993b 1527 adapt_ops.to_remove_vfork_catchpoint = NULL;
c906108c
SS
1528 adapt_ops.to_has_forked = NULL;
1529 adapt_ops.to_has_vforked = NULL;
c5aa993b
JM
1530 adapt_ops.to_can_follow_vfork_prior_to_exec = NULL;
1531 adapt_ops.to_post_follow_vfork = NULL;
c906108c
SS
1532 adapt_ops.to_insert_exec_catchpoint = NULL;
1533 adapt_ops.to_remove_exec_catchpoint = NULL;
1534 adapt_ops.to_has_execd = NULL;
1535 adapt_ops.to_reported_exec_events_per_exec_call = NULL;
1536 adapt_ops.to_has_exited = NULL;
c5aa993b
JM
1537 adapt_ops.to_mourn_inferior = adapt_mourn;
1538 adapt_ops.to_can_run = 0;
1539 adapt_ops.to_notice_signals = 0;
1540 adapt_ops.to_thread_alive = 0;
1541 adapt_ops.to_stop = 0; /* process_stratum; */
c906108c
SS
1542 adapt_ops.to_pid_to_exec_file = NULL;
1543 adapt_ops.to_core_file_to_sym_file = NULL;
c5aa993b
JM
1544 adapt_ops.to_stratum = 0;
1545 adapt_ops.DONT_USE = 0;
1546 adapt_ops.to_has_all_memory = 1;
1547 adapt_ops.to_has_memory = 1;
1548 adapt_ops.to_has_stack = 1;
1549 adapt_ops.to_has_registers = 1;
1550 adapt_ops.to_has_execution = 0;
1551 adapt_ops.to_sections = 0;
1552 adapt_ops.to_sections_end = 0;
1553 adapt_ops.to_magic = OPS_MAGIC;
1554} /* init_adapt_ops */
c906108c
SS
1555
1556void
1557_initialize_remote_adapt ()
1558{
c5aa993b 1559 init_adapt_ops ();
c906108c
SS
1560 add_target (&adapt_ops);
1561 add_com ("adapt <command>", class_obscure, adapt_com,
c5aa993b 1562 "Send a command to the AMD Adapt remote monitor.");
c906108c 1563}