#include <sys/ioctl.h>
#include <sys/file.h>
#include <ctype.h>
+#include "serial.h"
+#if 0
#include "nindy-share/ttycntl.h"
#include "nindy-share/demux.h"
+#endif
#include "nindy-share/env.h"
#include "nindy-share/stop.h"
#define TRUE 1
#define FALSE 0
-int nindy_fd = 0; /* Descriptor for I/O to NINDY */
+/* From nindy-share/nindy.c. */
+extern serial_t nindy_serial;
+
static int have_regs = 0; /* 1 iff regs read since i960 last halted */
static int regs_changed = 0; /* 1 iff regs were modified since last read */
static void
nindy_store_registers PARAMS ((int));
\f
-/* FIXME, we can probably use the normal terminal_inferior stuff here.
- We have to do terminal_inferior and then set up the passthrough
- settings initially. Thereafter, terminal_ours and terminal_inferior
- will automatically swap the settings around for us. */
-
-/* Restore TTY to normal operation */
-
-static TTY_STRUCT orig_tty; /* TTY attributes before entering passthrough */
-
-static void
-restore_tty()
-{
- ioctl( 0, TIOCSETN, &orig_tty );
-}
-
-
-/* Recover from ^Z or ^C while remote process is running */
-
-static void (*old_ctrlc)(); /* Signal handlers before entering passthrough */
-
-#ifdef SIGTSTP
-static void (*old_ctrlz)();
-#endif
-
-static
-#ifdef USG
-void
-#endif
-cleanup()
-{
- restore_tty();
- signal(SIGINT, old_ctrlc);
-#ifdef SIGTSTP
- signal(SIGTSTP, old_ctrlz);
-#endif
- error("\n\nYou may need to reset the 80960 and/or reload your program.\n");
-}
-\f
-/* Clean up anything that needs cleaning when losing control. */
-
static char *savename;
static void
nindy_close (quitting)
int quitting;
{
- if (nindy_fd)
- close (nindy_fd);
- nindy_fd = 0;
+ if (nindy_serial != NULL)
+ SERIAL_CLOSE (nindy_serial);
+ nindy_serial = NULL;
if (savename)
free (savename);
nindy_close (0);
- have_regs = regs_changed = 0;
- dcache_init();
+ have_regs = regs_changed = 0;
+ dcache_init();
- /* Allow user to interrupt the following -- we could hang if
- * there's no NINDY at the other end of the remote tty.
- */
- immediate_quit++;
- nindy_fd = ninConnect( name, baud_rate? baud_rate: "9600",
- nindy_initial_brk, !from_tty, nindy_old_protocol );
- immediate_quit--;
+ /* Allow user to interrupt the following -- we could hang if there's
+ no NINDY at the other end of the remote tty. */
+ immediate_quit++;
+ ninConnect(name, baud_rate ? baud_rate : "9600",
+ nindy_initial_brk, !from_tty, nindy_old_protocol);
+ immediate_quit--;
- if ( nindy_fd < 0 ){
- nindy_fd = 0;
- error( "Can't open tty '%s'", name );
- }
+ if (nindy_serial == NULL)
+ {
+ perror_with_name (name);
+ }
- savename = savestring (name, strlen (name));
- push_target (&nindy_ops);
- target_fetch_registers(-1);
+ savename = savestring (name, strlen (name));
+ push_target (&nindy_ops);
+ target_fetch_registers(-1);
}
/* User-initiated quit of nindy operations. */
have_regs = 0;
ninGo( step );
}
+\f
+/* FIXME, we can probably use the normal terminal_inferior stuff here.
+ We have to do terminal_inferior and then set up the passthrough
+ settings initially. Thereafter, terminal_ours and terminal_inferior
+ will automatically swap the settings around for us. */
+
+struct clean_up_tty_args {
+ serial_ttystate state;
+ serial_t serial;
+};
+
+static void
+clean_up_tty (ptrarg)
+ PTR ptrarg;
+{
+ struct clean_up_tty_args *args = (struct clean_up_tty_args *) ptrarg;
+ SERIAL_SET_TTY_STATE (args->serial, args->state);
+ free (args->state);
+ warning ("\n\n\
+You may need to reset the 80960 and/or reload your program.\n");
+}
/* Wait until the remote machine stops. While waiting, operate in passthrough
* mode; i.e., pass everything NINDY sends to stdout, and everything from
nindy_wait( status )
WAITTYPE *status;
{
- DEMUX_DECL; /* OS-dependent data needed by DEMUX... macros */
- char buf[500]; /* FIXME, what is "500" here? */
- int i, n;
- unsigned char stop_exit;
- unsigned char stop_code;
- TTY_STRUCT tty;
- long ip_value, fp_value, sp_value; /* Reg values from stop */
-
-
- WSETEXIT( (*status), 0 );
-
- /* OPERATE IN PASSTHROUGH MODE UNTIL NINDY SENDS A DLE CHARACTER */
-
- /* Save current tty attributes, set up signals to restore them.
- */
- ioctl( 0, TIOCGETP, &orig_tty );
- old_ctrlc = signal( SIGINT, cleanup );
-#ifdef SIGTSTP
- old_ctrlz = signal( SIGTSTP, cleanup );
-#endif
-
- /* Pass input from keyboard to NINDY as it arrives.
- * NINDY will interpret <CR> and perform echo.
- */
- tty = orig_tty;
- TTY_NINDYTERM( tty );
- ioctl( 0, TIOCSETN, &tty );
-
- while ( 1 ){
- /* Go to sleep until there's something for us on either
- * the remote port or stdin.
- */
-
- DEMUX_WAIT( nindy_fd );
-
- /* Pass input through to correct place */
+ fd_set fds;
+ char buf[500]; /* FIXME, what is "500" here? */
+ int i, n;
+ unsigned char stop_exit;
+ unsigned char stop_code;
+ struct clean_up_tty_args tty_args;
+ struct cleanup *old_cleanups;
+ long ip_value, fp_value, sp_value; /* Reg values from stop */
+
+ WSETEXIT( (*status), 0 );
+
+ /* OPERATE IN PASSTHROUGH MODE UNTIL NINDY SENDS A DLE CHARACTER */
+
+ /* Save current tty attributes, and restore them when done. */
+ tty_args.serial = SERIAL_FDOPEN (0);
+ tty_args.state = SERIAL_GET_TTY_STATE (tty_args.serial);
+ old_cleanups = make_cleanup (clean_up_tty, &tty_args);
+
+ /* Pass input from keyboard to NINDY as it arrives. NINDY will interpret
+ <CR> and perform echo. */
+ /* This used to set CBREAK and clear ECHO and CRMOD. I hope this is close
+ enough. */
+ SERIAL_RAW (tty_args.serial);
+
+ while (1)
+ {
+ /* Wait for input on either the remote port or stdin. */
+ FD_ZERO (&fds);
+ FD_SET (0, &fds);
+ FD_SET (nindy_serial->fd, &fds);
+ if (select (nindy_serial->fd + 1, &fds, 0, 0, 0) <= 0)
+ continue;
+
+ /* Pass input through to correct place */
+ if (FD_ISSET (0, &fds))
+ {
+ /* Input on stdin */
+ n = read (0, buf, sizeof (buf));
+ if (n)
+ {
+ SERIAL_WRITE (nindy_serial, buf, n );
+ }
+ }
- n = DEMUX_READ( 0, buf, sizeof(buf) );
- if ( n ){ /* Input on stdin */
- write( nindy_fd, buf, n );
+ if (FD_ISSET (nindy_serial->fd, &fds))
+ {
+ /* Input on remote */
+ n = read (nindy_serial->fd, buf, sizeof (buf));
+ if (n)
+ {
+ /* Write out any characters in buffer preceding DLE */
+ i = non_dle( buf, n );
+ if ( i > 0 )
+ {
+ write (1, buf, i);
}
- n = DEMUX_READ( nindy_fd, buf, sizeof(buf) );
- if ( n ){ /* Input on remote */
- /* Write out any characters in buffer preceding DLE */
- i = non_dle( buf, n );
- if ( i > 0 ){
- write( 1, buf, i );
- }
-
- if ( i != n ){
- /* There *was* a DLE in the buffer */
- stop_exit = ninStopWhy( &stop_code,
- &ip_value, &fp_value, &sp_value);
- if ( !stop_exit && (stop_code==STOP_SRQ) ){
- immediate_quit++;
- ninSrq();
- immediate_quit--;
- } else {
- /* Get out of loop */
- supply_register (IP_REGNUM,
- (char *)&ip_value);
- supply_register (FP_REGNUM,
- (char *)&fp_value);
- supply_register (SP_REGNUM,
- (char *)&sp_value);
- break;
- }
- }
+ if (i != n)
+ {
+ /* There *was* a DLE in the buffer */
+ stop_exit = ninStopWhy(&stop_code,
+ &ip_value, &fp_value, &sp_value);
+ if (!stop_exit && (stop_code == STOP_SRQ))
+ {
+ immediate_quit++;
+ ninSrq();
+ immediate_quit--;
+ }
+ else
+ {
+ /* Get out of loop */
+ supply_register (IP_REGNUM,
+ (char *)&ip_value);
+ supply_register (FP_REGNUM,
+ (char *)&fp_value);
+ supply_register (SP_REGNUM,
+ (char *)&sp_value);
+ break;
+ }
}
+ }
}
+ }
- signal( SIGINT, old_ctrlc );
-#ifdef SIGTSTP
- signal( SIGTSTP, old_ctrlz );
-#endif
- restore_tty();
-
- if ( stop_exit ){ /* User program exited */
- WSETEXIT( (*status), stop_code );
- } else { /* Fault or trace */
- switch (stop_code){
- case STOP_GDB_BPT:
- case TRACE_STEP:
- /* Make it look like a VAX trace trap */
- stop_code = SIGTRAP;
- break;
- default:
- /* The target is not running Unix, and its
- faults/traces do not map nicely into Unix signals.
- Make sure they do not get confused with Unix signals
- by numbering them with values higher than the highest
- legal Unix signal. code in i960_print_fault(),
- called via PRINT_RANDOM_SIGNAL, will interpret the
- value. */
- stop_code += NSIG;
- break;
- }
- WSETSTOP( (*status), stop_code );
+ do_cleanups (old_cleanups);
+
+ if (stop_exit)
+ {
+ /* User program exited */
+ WSETEXIT ((*status), stop_code);
+ }
+ else
+ {
+ /* Fault or trace */
+ switch (stop_code)
+ {
+ case STOP_GDB_BPT:
+ case TRACE_STEP:
+ /* Breakpoint or single stepping. */
+ stop_code = SIGTRAP;
+ break;
+ default:
+ /* The target is not running Unix, and its faults/traces do
+ not map nicely into Unix signals. Make sure they do not
+ get confused with Unix signals by numbering them with
+ values higher than the highest legal Unix signal. code
+ in i960_print_fault(), called via PRINT_RANDOM_SIGNAL,
+ will interpret the value. */
+ stop_code += NSIG;
+ break;
}
- return inferior_pid;
+ WSETSTOP ((*status), stop_code);
+ }
+ return inferior_pid;
}
/* Read the remote registers into the block REGS. */
ninRegsGet( (char *) &nindy_regs );
immediate_quit--;
- bcopy (nindy_regs.local_regs, ®isters[REGISTER_BYTE (R0_REGNUM)], 16*4);
- bcopy (nindy_regs.global_regs, ®isters[REGISTER_BYTE (G0_REGNUM)], 16*4);
- bcopy (nindy_regs.pcw_acw, ®isters[REGISTER_BYTE (PCW_REGNUM)], 2*4);
- bcopy (nindy_regs.ip, ®isters[REGISTER_BYTE (IP_REGNUM)], 1*4);
- bcopy (nindy_regs.tcw, ®isters[REGISTER_BYTE (TCW_REGNUM)], 1*4);
+ memcpy (®isters[REGISTER_BYTE (R0_REGNUM)], nindy_regs.local_regs, 16*4);
+ memcpy (®isters[REGISTER_BYTE (G0_REGNUM)], nindy_regs.global_regs, 16*4);
+ memcpy (®isters[REGISTER_BYTE (PCW_REGNUM)], nindy_regs.pcw_acw, 2*4);
+ memcpy (®isters[REGISTER_BYTE (IP_REGNUM)], nindy_regs.ip, 1*4);
+ memcpy (®isters[REGISTER_BYTE (TCW_REGNUM)], nindy_regs.tcw, 1*4);
for (regnum = FP0_REGNUM; regnum < FP0_REGNUM + 4; regnum++) {
dub = unpack_double (builtin_type_double,
&nindy_regs.fp_as_double[8 * (regnum - FP0_REGNUM)],
int regnum, inv;
double dub;
- bcopy (®isters[REGISTER_BYTE (R0_REGNUM)], nindy_regs.local_regs, 16*4);
- bcopy (®isters[REGISTER_BYTE (G0_REGNUM)], nindy_regs.global_regs, 16*4);
- bcopy (®isters[REGISTER_BYTE (PCW_REGNUM)], nindy_regs.pcw_acw, 2*4);
- bcopy (®isters[REGISTER_BYTE (IP_REGNUM)], nindy_regs.ip, 1*4);
- bcopy (®isters[REGISTER_BYTE (TCW_REGNUM)], nindy_regs.tcw, 1*4);
+ memcpy (nindy_regs.local_regs, ®isters[REGISTER_BYTE (R0_REGNUM)], 16*4);
+ memcpy (nindy_regs.global_regs, ®isters[REGISTER_BYTE (G0_REGNUM)], 16*4);
+ memcpy (nindy_regs.pcw_acw, ®isters[REGISTER_BYTE (PCW_REGNUM)], 2*4);
+ memcpy (nindy_regs.ip, ®isters[REGISTER_BYTE (IP_REGNUM)], 1*4);
+ memcpy (nindy_regs.tcw, ®isters[REGISTER_BYTE (TCW_REGNUM)], 1*4);
/* Float regs. Only works on IEEE_FLOAT hosts. FIXME! */
for (regnum = FP0_REGNUM; regnum < FP0_REGNUM + 4; regnum++) {
ieee_extended_to_double (&ext_format_i960,
This mostly works but not quite. */
dub = unpack_double (builtin_type_double, (char *)&dub, &inv);
/* dub now in target byte order */
- bcopy ((char *)&dub, &nindy_regs.fp_as_double[8 * (regnum - FP0_REGNUM)],
- 8);
+ memcpy (&nindy_regs.fp_as_double[8 * (regnum - FP0_REGNUM)], &dub, 8);
}
immediate_quit++;
/* Copy data to be written over corresponding part of buffer */
- bcopy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len);
+ memcpy ((char *) buffer + (memaddr & (sizeof (int) - 1)), myaddr, len);
/* Write the entire buffer. */
}
/* Copy appropriate bytes out of the buffer. */
- bcopy ((char *) buffer + (memaddr & (sizeof (int) - 1)), myaddr, len);
+ memcpy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len);
}
return len;
}
char *args;
int from_tty;
{
- if ( !nindy_fd ){
- error( "No target system to reset -- use 'target nindy' command.");
- }
- if ( query("Really reset the target system?",0,0) ){
- send_break( nindy_fd );
- tty_flush( nindy_fd );
- }
+ if (nindy_serial == NULL)
+ {
+ error( "No target system to reset -- use 'target nindy' command.");
+ }
+ if ( query("Really reset the target system?",0,0) )
+ {
+ SERIAL_SEND_BREAK (nindy_serial);
+ tty_flush (nindy_serial);
+ }
}
void