1 /* This file is part of GDB.
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2 of the License, or
6 (at your option) any later version.
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software
15 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
17 /* This started out life as code shared between the nindy monitor and
18 GDB. For various reasons, this is no longer true. Eventually, it
19 probably should be merged into remote-nindy.c. */
21 /******************************************************************************
23 * NINDY INTERFACE ROUTINES
25 * The caller of these routines should be aware that:
27 * (1) ninConnect() should be called to open communications with the
28 * remote NINDY board before any of the other routines are invoked.
30 * (2) almost all interactions are driven by the host: nindy sends information
31 * in response to host commands.
33 * (3) the lone exception to (2) is the single character DLE (^P, 0x10).
34 * Receipt of a DLE from NINDY indicates that the application program
35 * running under NINDY has stopped execution and that NINDY is now
36 * available to talk to the host (all other communication received after
37 * the application has been started should be presumed to come from the
38 * application and should be passed on by the host to stdout).
40 * (4) the reason the application program stopped can be determined with the
41 * ninStopWhy() function. There are three classes of stop reasons:
43 * (a) the application has terminated execution.
44 * The host should take appropriate action.
46 * (b) the application had a fault or trace event.
47 * The host should take appropriate action.
49 * (c) the application wishes to make a service request (srq) of the host;
50 * e.g., to open/close a file, read/write a file, etc. The ninSrq()
51 * function should be called to determine the nature of the request
58 #ifdef ANSI_PROTOTYPES
64 #if !defined (HAVE_TERMIOS) && !defined (HAVE_TERMIO) && !defined (HAVE_SGTTY)
69 #include <sys/ioctl.h>
72 #include <sys/types.h> /* Needed by file.h on Sys V */
84 #define DLE 0x10 /* ^P */
85 #define XON 0x11 /* ^Q */
86 #define XOFF 0x13 /* ^S */
91 int quiet
= 0; /* 1 => stifle unnecessary messages */
92 serial_t nindy_serial
;
94 static int old_nindy
= 0; /* 1 => use old (hex) communication protocol */
97 /****************************
99 * MISCELLANEOUS UTILTIES *
101 ****************************/
103 /******************************************************************************
105 * This is a printf that takes at most two arguments (in addition to the
106 * format string) and that outputs nothing if verbose output has been
108 *****************************************************************************/
112 #ifdef ANSI_PROTOTYPES
120 #ifdef ANSI_PROTOTYPES
126 fmt
= va_arg (args
, char *);
131 vfprintf_unfiltered (gdb_stdout
, fmt
, args
);
132 gdb_flush (gdb_stdout
);
137 /******************************************************************************
139 * Creates a full pathname by concatenating up to three name components
140 * onto a specified base name; optionally looks up the base name as a
141 * runtime environment variable; and checks to see if the file or
142 * directory specified by the pathname actually exists.
144 * Returns: the full pathname if it exists, NULL otherwise.
145 * (returned pathname is in malloc'd memory and must be freed
147 *****************************************************************************/
149 exists( base
, c1
, c2
, c3
, env
)
150 char *base
; /* Base directory of path */
151 char *c1
, *c2
, *c3
; /* Components (subdirectories and/or file name) to be
152 * appended onto the base directory name. One or
153 * more may be omitted by passing NULL pointers.
155 int env
; /* If 1, '*base' is the name of an environment variable
156 * to be examined for the base directory name;
157 * otherwise, '*base' is the actual name of the
161 struct stat buf
;/* For call to 'stat' -- never examined */
162 char *path
; /* Pointer to full pathname (malloc'd memory) */
163 int len
; /* Length of full pathname (incl. terminator) */
164 extern char *getenv();
168 base
= getenv( base
);
174 len
= strlen(base
) + 4;
175 /* +4 for terminator and "/" before each component */
186 path
= xmalloc (len
);
188 strcpy( path
, base
);
202 if ( stat(path
,&buf
) != 0 ){
209 /*****************************
211 * LOW-LEVEL COMMUNICATION *
213 *****************************/
215 /* Read *exactly* N characters from the NINDY tty, and put them in
216 *BUF. Translate escape sequences into single characters, counting
217 each such sequence as 1 character.
219 An escape sequence consists of ESC and a following character. The
220 ESC is discarded and the other character gets bit 0x40 cleared --
221 thus ESC P == ^P, ESC S == ^S, ESC [ == ESC, etc.
223 Return 1 if successful, 0 if more than TIMEOUT seconds pass without
227 rdnin (buf
,n
,timeout
)
228 unsigned char * buf
; /* Where to place characters read */
229 int n
; /* Number of characters to read */
230 int timeout
; /* Timeout, in seconds */
232 int escape_seen
; /* 1 => last character of a read was an ESC */
238 c
= SERIAL_READCHAR (nindy_serial
, timeout
);
265 /******************************************************************************
267 * Read a packet from a remote NINDY, with error checking, into the
270 * Return packet status byte on success, TIMEOUT on failure.
271 ******************************************************************************/
278 unsigned char hdr
[3]; /* Packet header:
279 * hdr[0] = low byte of message length
280 * hdr[1] = high byte of message length
281 * hdr[2] = message status
283 int cnt
; /* Message length (status byte + data) */
284 unsigned char cs_calc
; /* Checksum calculated */
285 unsigned char cs_recv
; /* Checksum received */
286 static char errfmt
[] =
287 "Bad checksum (recv=0x%02x; calc=0x%02x); retrying\r\n";
290 if ( !rdnin(hdr
,3,5) ){
293 cnt
= (hdr
[1]<<8) + hdr
[0] - 1;
294 /* -1 for status byte (already read) */
296 /* Caller's buffer may only be big enough for message body,
297 * without status byte and checksum, so make sure to read
298 * checksum into a separate buffer.
300 if ( !rdnin(buf
,cnt
,5) || !rdnin(&cs_recv
,1,5) ){
304 /* Calculate checksum
306 cs_calc
= hdr
[0] + hdr
[1] + hdr
[2];
307 for ( i
= 0; i
< cnt
; i
++ ){
310 if ( cs_calc
== cs_recv
){
311 SERIAL_WRITE (nindy_serial
, "+", 1);
315 /* Bad checksum: report, send NAK, and re-receive
317 fprintf(stderr
, errfmt
, cs_recv
, cs_calc
);
318 SERIAL_WRITE (nindy_serial
, "-", 1);
323 /******************************************************************************
325 * Send a packet to NINDY, checksumming it and converting special
326 * characters to escape sequences.
327 ******************************************************************************/
329 /* This macro puts the character 'c' into the buffer pointed at by 'p',
330 * and increments the pointer. If 'c' is one of the 4 special characters
331 * in the transmission protocol, it is converted into a 2-character
334 #define PUTBUF(c,p) \
335 if ( c == DLE || c == ESC || c == XON || c == XOFF ){ \
344 unsigned char *msg
; /* Command to be sent, without lead ^P (\020) or checksum */
345 int len
; /* Number of bytes in message */
347 static char *buf
= NULL
;/* Local buffer -- build packet here */
348 static int maxbuf
= 0; /* Current length of buffer */
349 unsigned char ack
; /* Response received from NINDY */
350 unsigned char checksum
; /* Packet checksum */
351 char *p
; /* Pointer into buffer */
352 int lenhi
, lenlo
; /* High and low bytes of message length */
356 /* Make sure local buffer is big enough. Must include space for
357 * packet length, message body, and checksum. And in the worst
358 * case, each character would expand into a 2-character escape
361 if ( maxbuf
< ((2*len
)+10) ){
365 buf
= xmalloc( maxbuf
=((2*len
)+10) );
370 SERIAL_WRITE (nindy_serial
, "\020", 1);
374 lenhi
= (len
>>8) & 0xff;
375 checksum
= lenlo
+ lenhi
;
381 for ( i
=0; i
<len
; i
++ ){
386 PUTBUF( checksum
, p
);
388 /* Send checksummed message over and over until we get a positive ack
390 SERIAL_WRITE (nindy_serial
, buf
, p
- buf
);
392 if ( !rdnin(&ack
,1,5) ){
394 fprintf(stderr
,"ACK timed out; resending\r\n");
395 /* Attention, NINDY! */
396 SERIAL_WRITE (nindy_serial
, "\020", 1);
397 SERIAL_WRITE (nindy_serial
, buf
, p
- buf
);
398 } else if ( ack
== '+' ){
400 } else if ( ack
== '-' ){
401 fprintf( stderr
, "Remote NAK; resending\r\n" );
402 SERIAL_WRITE (nindy_serial
, buf
, p
- buf
);
404 fprintf( stderr
, "Bad ACK, ignored: <%c>\r\n", ack
);
411 /******************************************************************************
413 * Send a message to a remote NINDY. Check message status byte
414 * for error responses. If no error, return NINDY reponse (if any).
415 ******************************************************************************/
418 unsigned char *out
; /* Message to be sent to NINDY */
419 int len
; /* Number of meaningful bytes in out buffer */
420 unsigned char *in
; /* Where to put response received from NINDY */
424 static char *errmsg
[] = {
426 "Buffer overflow", /* 1 */
427 "Unknown command", /* 2 */
428 "Wrong amount of data to load register(s)", /* 3 */
429 "Missing command argument(s)", /* 4 */
430 "Odd number of digits sent to load memory", /* 5 */
431 "Unknown register name", /* 6 */
432 "No such memory segment", /* 7 */
433 "No breakpoint available", /* 8 */
434 "Can't set requested baud rate", /* 9 */
436 # define NUMERRS ( sizeof(errmsg) / sizeof(errmsg[0]) )
438 static char err1
[] = "Unknown error response from NINDY: #%d\r\n";
439 static char err2
[] = "Error response #%d from NINDY: %s\r\n";
444 if ( status
== TIMEOUT
){
445 fprintf( stderr
, "Response timed out; resending\r\n" );
452 fmt
= status
> NUMERRS
? err1
: err2
;
453 fprintf( stderr
, fmt
, status
, errmsg
[status
] );
458 /************************
460 * BAUD RATE ROUTINES *
462 ************************/
464 /* Table of baudrates known to be acceptable to NINDY. Each baud rate
465 * appears both as character string and as a Unix baud rate constant.
472 static struct baudrate baudtab
[] = {
479 NULL
, 0 /* End of table */
482 /******************************************************************************
484 * Look up the passed baud rate in the baudrate table. If found, change
485 * our internal record of the current baud rate, but don't do anything
486 * about the tty just now.
488 * Return pointer to baudrate structure on success, NULL on failure.
489 ******************************************************************************/
493 char *s
; /* Desired baud rate, as an ASCII (decimal) string */
497 for ( i
=0; baudtab
[i
].string
!= NULL
; i
++ ){
498 if ( !strcmp(baudtab
[i
].string
,s
) ){
505 /******************************************************************************
507 * Try speaking to NINDY via the specified file descriptor at the
508 * specified baudrate. Assume success if we can send an empty command
509 * with a bogus checksum and receive a NAK (response of '-') back within
512 * Return 1 on success, 0 on failure.
513 ***************************************************************************/
516 try_baudrate (serial
, brp
)
518 struct baudrate
*brp
;
522 /* Set specified baud rate and flush all pending input */
523 SERIAL_SETBAUDRATE (serial
, brp
->rate
);
526 /* Send empty command with bad checksum, hope for NAK ('-') response */
527 SERIAL_WRITE (serial
, "\020\0\0\001", 4);
529 /* Anything but a quick '-', including error, eof, or timeout, means that
530 this baudrate doesn't work. */
531 return SERIAL_READCHAR (serial
, 1) == '-';
534 /******************************************************************************
536 * Get NINDY talking over the specified file descriptor at the specified
537 * baud rate. First see if NINDY's already talking at 'baudrate'. If
538 * not, run through all the legal baudrates in 'baudtab' until one works,
539 * and then tell NINDY to talk at 'baudrate' instead.
540 ******************************************************************************/
542 autobaud( serial
, brp
)
544 struct baudrate
*brp
;
549 say("NINDY at wrong baud rate? Trying to autobaud...\n");
553 say( "\r%s... ", baudtab
[i
].string
);
554 if (try_baudrate(serial
, &baudtab
[i
]))
558 if (baudtab
[++i
].string
== NULL
)
560 /* End of table -- wraparound */
564 say("\nAutobaud failed again. Giving up.\n");
569 say("\nAutobaud failed. Trying again...\n");
574 /* Found NINDY's current baud rate; now change it. */
575 say("Changing NINDY baudrate to %s\n", brp
->string
);
576 ninBaud (brp
->string
);
578 /* Change our baud rate back to rate to which we just set NINDY. */
579 SERIAL_SETBAUDRATE (serial
, brp
->rate
);
582 /**********************************
584 * NINDY INTERFACE ROUTINES *
586 * ninConnect *MUST* be the first *
587 * one of these routines called. *
588 **********************************/
591 /******************************************************************************
593 * Ask NINDY to change the baud rate on its serial port.
594 * Assumes we know the baud rate at which NINDY's currently talking.
595 ******************************************************************************/
597 char *baudrate
; /* Desired baud rate, as a string of ASCII decimal
601 unsigned char msg
[100];
603 tty_flush (nindy_serial
);
607 char *p
; /* Pointer into buffer */
608 unsigned char csum
; /* Calculated checksum */
610 /* Can't use putpkt() because after the baudrate change NINDY's
611 ack/nak will look like gibberish. */
613 for (p
=baudrate
, csum
=020+'z'; *p
; p
++)
617 sprintf (msg
, "\020z%s#%02x", baudrate
, csum
);
618 SERIAL_WRITE (nindy_serial
, msg
, strlen (msg
));
622 /* Can't use "send" because NINDY reply will be unreadable after
624 sprintf( msg
, "z%s", baudrate
);
625 putpkt( msg
, strlen(msg
)+1 ); /* "+1" to send terminator too */
629 /******************************************************************************
631 * Ask NINDY to delete the specified type of *hardware* breakpoint at
632 * the specified address. If the 'addr' is -1, all breakpoints of
633 * the specified type are deleted.
634 ***************************************************************************/
635 ninBptDel( addr
, type
)
636 long addr
; /* Address in 960 memory */
637 char type
; /* 'd' => data bkpt, 'i' => instruction breakpoint */
639 unsigned char buf
[10];
642 OninBptDel( addr
, type
== 'd' ? 1 : 0 );
650 send( buf
, 2, NULL
);
652 store_unsigned_integer (&buf
[2], 4, addr
);
653 send( buf
, 6, NULL
);
658 /******************************************************************************
660 * Ask NINDY to set the specified type of *hardware* breakpoint at
661 * the specified address.
662 ******************************************************************************/
663 ninBptSet( addr
, type
)
664 long addr
; /* Address in 960 memory */
665 char type
; /* 'd' => data bkpt, 'i' => instruction breakpoint */
667 unsigned char buf
[10];
670 OninBptSet( addr
, type
== 'd' ? 1 : 0 );
677 store_unsigned_integer (&buf
[2], 4, addr
);
678 send( buf
, 6, NULL
);
682 /******************************************************************************
684 * Open the specified tty. Get communications working at the specified
685 * baud rate. Flush any pending I/O on the tty.
687 * Return the file descriptor, or -1 on failure.
688 ******************************************************************************/
690 ninConnect( name
, baudrate
, brk
, silent
, old_protocol
)
691 char *name
; /* "/dev/ttyXX" to be opened */
692 char *baudrate
;/* baud rate: a string of ascii decimal digits (eg,"9600")*/
693 int brk
; /* 1 => send break to tty first thing after opening it*/
694 int silent
; /* 1 => stifle unnecessary messages when talking to
701 struct baudrate
*brp
;
703 /* We will try each of the following paths when trying to open the tty
705 static char *prefix
[] = { "", "/dev/", "/dev/tty", NULL
};
711 quiet
= silent
; /* Make global to this file */
713 for ( i
=0; prefix
[i
] != NULL
; i
++ ){
714 p
= xmalloc(strlen(prefix
[i
]) + strlen(name
) + 1 );
715 strcpy( p
, prefix
[i
] );
717 nindy_serial
= SERIAL_OPEN (p
);
718 if (nindy_serial
!= NULL
) {
720 /* Exclusive use mode (hp9000 does not support it) */
721 ioctl(nindy_serial
->fd
,TIOCEXCL
,NULL
);
723 SERIAL_RAW (nindy_serial
);
727 SERIAL_SEND_BREAK (nindy_serial
);
730 brp
= parse_baudrate( baudrate
);
732 say("Illegal baudrate %s ignored; using 9600\n",
734 brp
= parse_baudrate( "9600" );
737 if ( !try_baudrate(nindy_serial
, brp
) ){
738 autobaud(nindy_serial
, brp
);
740 tty_flush (nindy_serial
);
741 say( "Connected to %s\n", p
);
752 /* Currently unused; shouldn't we be doing this on target_kill and
753 perhaps target_mourn? FIXME. */
755 /******************************************************************************
757 * Ask NINDY to leave GDB mode and print a NINDY prompt.
758 ****************************************************************************/
765 putpkt((unsigned char *) "E", 1 );
769 /******************************************************************************
771 * Ask NINDY to start or continue execution of an application program
772 * in it's memory at the current ip.
773 ******************************************************************************/
775 int step_flag
; /* 1 => run in single-step mode */
781 putpkt((unsigned char *) (step_flag
? "s" : "c"), 1 );
785 /******************************************************************************
787 * Read a string of bytes from NINDY's address space (960 memory).
788 ******************************************************************************/
790 ninMemGet(ninaddr
, hostaddr
, len
)
791 long ninaddr
; /* Source address, in the 960 memory space */
792 unsigned char *hostaddr
; /* Destination address, in our memory space */
793 int len
; /* Number of bytes to read */
795 unsigned char buf
[BUFSIZE
+20];
796 int cnt
; /* Number of bytes in next transfer */
800 OninMemGet(ninaddr
, hostaddr
, len
);
804 for ( ; len
> 0; len
-= BUFSIZE
){
805 cnt
= len
> BUFSIZE
? BUFSIZE
: len
;
808 store_unsigned_integer (&buf
[1], 4, ninaddr
);
810 buf
[6] = (cnt
>>8) & 0xff;
812 send( buf
, 7, hostaddr
);
821 /******************************************************************************
823 * Write a string of bytes into NINDY's address space (960 memory).
824 ******************************************************************************/
826 ninMemPut( ninaddr
, hostaddr
, len
)
827 long ninaddr
; /* Destination address, in NINDY memory space */
828 unsigned char *hostaddr
; /* Source address, in our memory space */
829 int len
; /* Number of bytes to write */
831 unsigned char buf
[BUFSIZE
+20];
832 int cnt
; /* Number of bytes in next transfer */
836 OninMemPut( ninaddr
, hostaddr
, len
);
839 for ( ; len
> 0; len
-= BUFSIZE
){
840 cnt
= len
> BUFSIZE
? BUFSIZE
: len
;
843 store_unsigned_integer (&buf
[1], 4, ninaddr
);
844 memcpy(buf
+ 5, hostaddr
, cnt
);
845 send( buf
, cnt
+5, NULL
);
853 /******************************************************************************
855 * Retrieve the contents of a 960 register, and return them as a long
856 * in host byte order.
858 * THIS ROUTINE CAN ONLY BE USED TO READ THE LOCAL, GLOBAL, AND
859 * ip/ac/pc/tc REGISTERS.
861 ******************************************************************************/
864 char *regname
; /* Register name recognized by NINDY, subject to the
868 unsigned char outbuf
[10];
869 unsigned char inbuf
[20];
872 return OninRegGet( regname
);
875 sprintf( outbuf
, "u%s:", regname
);
876 send( outbuf
, strlen(outbuf
), inbuf
);
877 return extract_unsigned_integer (inbuf
, 4);
880 /******************************************************************************
882 * Set the contents of a 960 register.
884 * THIS ROUTINE CAN ONLY BE USED TO SET THE LOCAL, GLOBAL, AND
885 * ip/ac/pc/tc REGISTERS.
887 ******************************************************************************/
888 ninRegPut( regname
, val
)
889 char *regname
; /* Register name recognized by NINDY, subject to the
892 long val
; /* New contents of register, in host byte-order */
894 unsigned char buf
[20];
898 OninRegPut( regname
, val
);
902 sprintf( buf
, "U%s:", regname
);
904 store_unsigned_integer (&buf
[len
], 4, val
);
905 send( buf
, len
+4, NULL
);
908 /******************************************************************************
910 * Get a dump of the contents of the entire 960 register set. The
911 * individual registers appear in the dump in the following order:
913 * pfp sp rip r3 r4 r5 r6 r7
914 * r8 r9 r10 r11 r12 r13 r14 r15
915 * g0 g1 g2 g3 g4 g5 g6 g7
916 * g8 g9 g10 g11 g12 g13 g14 fp
917 * pc ac ip tc fp0 fp1 fp2 fp3
919 * Each individual register comprises exactly 4 bytes, except for
920 * fp0-fp3, which are 8 bytes. All register values are in 960
921 * (little-endian) byte order.
923 ******************************************************************************/
925 unsigned char *regp
; /* Where to place the register dump */
931 send( (unsigned char *) "r", 1, regp
);
935 /******************************************************************************
937 * Initialize the entire 960 register set to a specified set of values.
938 * The format of the register value data should be the same as that
939 * returned by ninRegsGet.
942 * All register values must be in 960 (little-endian) byte order.
944 ******************************************************************************/
946 char *regp
; /* Pointer to desired values of registers */
948 /* Number of bytes that we send to nindy. I believe this is defined by
949 the protocol (it does not agree with REGISTER_BYTES). */
950 #define NINDY_REGISTER_BYTES ((36*4) + (4*8))
951 unsigned char buf
[NINDY_REGISTER_BYTES
+10];
959 memcpy(buf
+1, regp
, NINDY_REGISTER_BYTES
);
960 send( buf
, NINDY_REGISTER_BYTES
+1, NULL
);
964 /******************************************************************************
966 * Ask NINDY to perform a soft reset; wait for the reset to complete.
968 ******************************************************************************/
979 putpkt((unsigned char *) "X", 1 );
981 if ( !rdnin(&ack
,1,5) ){
993 /******************************************************************************
995 * Assume NINDY has stopped execution of the 960 application program in
996 * order to process a host service request (srq). Ask NINDY for the
997 * srq arguments, perform the requested service, and send an "srq
998 * complete" message so NINDY will return control to the application.
1000 ******************************************************************************/
1003 /* FIXME: Imposes arbitrary limits on lengths of pathnames and such. */
1004 unsigned char buf
[BUFSIZE
];
1006 unsigned char srqnum
;
1009 int arg
[MAX_SRQ_ARGS
];
1017 /* Get srq number and arguments
1019 send((unsigned char *) "!", 1, buf
);
1022 for ( i
=0, offset
=1; i
< MAX_SRQ_ARGS
; i
++, offset
+=4 ){
1023 arg
[i
] = extract_unsigned_integer (&buf
[offset
], 4);
1030 /* args: file descriptor */
1032 retcode
= close( arg
[0] );
1038 /* args: filename, mode */
1039 ninStrGet( arg
[0], buf
);
1040 retcode
= creat(buf
,arg
[1]);
1043 /* args: filename, flags, mode */
1044 ninStrGet( arg
[0], buf
);
1045 retcode
= open(buf
,arg
[1],arg
[2]);
1048 /* args: file descriptor, buffer, count */
1049 retcode
= read(arg
[0],buf
,arg
[2]);
1051 ninMemPut( arg
[1], buf
, retcode
);
1055 /* args: file descriptor, offset, whence */
1056 retcode
= lseek(arg
[0],arg
[1],arg
[2]);
1059 /* args: file descriptor, buffer, count */
1060 ninMemGet( arg
[1], buf
, arg
[2] );
1061 retcode
= write(arg
[0],buf
,arg
[2]);
1068 /* Send request termination status to NINDY
1071 store_unsigned_integer (&buf
[1], 4, retcode
);
1072 send( buf
, 5, NULL
);
1076 /******************************************************************************
1078 * Assume the application program has stopped (i.e., a DLE was received
1079 * from NINDY). Ask NINDY for status information describing the
1080 * reason for the halt.
1082 * Returns a non-zero value if the user program has exited, 0 otherwise.
1083 * Also returns the following information, through passed pointers:
1084 * - why: an exit code if program the exited; otherwise the reason
1085 * why the program halted (see stop.h for values).
1086 * - contents of register ip (little-endian byte order)
1087 * - contents of register sp (little-endian byte order)
1088 * - contents of register fp (little-endian byte order)
1089 ******************************************************************************/
1091 ninStopWhy( whyp
, ipp
, fpp
, spp
)
1092 unsigned char *whyp
; /* Return the 'why' code through this pointer */
1093 long *ipp
; /* Return contents of register ip through this pointer */
1094 long *fpp
; /* Return contents of register fp through this pointer */
1095 long *spp
; /* Return contents of register sp through this pointer */
1097 unsigned char buf
[30];
1098 extern char OninStopWhy ();
1101 return OninStopWhy( whyp
, ipp
, fpp
, spp
);
1103 send((unsigned char *) "?", 1, buf
);
1106 memcpy ((char *)ipp
, &buf
[2], sizeof (*ipp
));
1107 memcpy ((char *)fpp
, &buf
[6], sizeof (*ipp
));
1108 memcpy ((char *)spp
, &buf
[10], sizeof (*ipp
));
1112 /******************************************************************************
1114 * Read a '\0'-terminated string of data out of the 960 memory space.
1116 ******************************************************************************/
1118 ninStrGet( ninaddr
, hostaddr
)
1119 unsigned long ninaddr
; /* Address of string in NINDY memory space */
1120 unsigned char *hostaddr
; /* Address of the buffer to which string should
1124 unsigned char cmd
[5];
1127 store_unsigned_integer (&cmd
[1], 4, ninaddr
);
1128 send( cmd
, 5, hostaddr
);
1134 /******************************************************************************
1136 * Ask NINDY for version information about itself.
1137 * The information is sent as an ascii string in the form "x.xx,<arch>",
1139 * x.xx is the version number
1140 * <arch> is the processor architecture: "KA", "KB", "MC", "CA" *
1142 ******************************************************************************/
1145 unsigned char *p
; /* Where to place version string */
1149 return OninVersion( p
);
1151 send((unsigned char *) "v", 1, p
);
This page took 0.05343 seconds and 4 git commands to generate.