📄 remote-es1800.c
字号:
#endif return (buf[0] & 0x7f);}#else /* !DEBUG_STDIN *//* Read a character from the remote system, doing all the fancy timeout stuff. */static intreadchar (){ char buf[1]; buf[0] = '\0';#ifdef HAVE_TERMIO /* termio does the timeout for us. */ read (es1800_desc, buf, 1);#else alarm (timeout); while (read (es1800_desc, buf, 1) != 1) { if (errno == EINTR) { error ("Timeout reading from remote system."); } else if (errno != EWOULDBLOCK) { perror_with_name ("remote read"); } } alarm (0);#endif#if defined (LOG_FILE) putc (buf[0] & 0x7f, log_file); fflush (log_file);#endif return (buf[0] & 0x7f);}#endif /* DEBUG_STDIN *//* Send a command to the emulator and save the reply. Report an error if we get an error reply. string - the es1800 command buf - containing the emulator reply on return len - size of buf */static voidsend_with_reply (string, buf, len) char *string, *buf; int len;{ send (string); write (es1800_desc, "\r", 1);#ifndef DEBUG_STDIN expect (string, 1); expect ("\r\n", 0);#endif getmessage (buf, len);}/* Send the command in STR to the emulator adding \r. check the echo for consistency. string - the es1800 command */ static voidsend_command (string) char *string;{ send (string); write (es1800_desc, "\r", 1);#ifndef DEBUG_STDIN expect (string, 0); expect_prompt ();#endif}/* Send a string string - the es1800 command */static voidsend (string) char *string;{ if (kiodebug) { fprintf (stderr, "Sending: %s\n", string); } write (es1800_desc, string, strlen (string));}/* Read a message from the emulator and store it in BUF. buf - containing the emulator reply on return len - size of buf */ static voidgetmessage (buf, len) char *buf; int len;{ char *bp; int c; int prompt_found = 0; extern kiodebug;#if defined (LOG_FILE) /* This is a convenient place to do this. The idea is to do it often enough that we never lose much data if we terminate abnormally. */ fflush (log_file);#endif bp = buf; c = readchar (); do { if (c) { if (len-- < 2) /* char and terminaling NULL */ { error ("input buffer overrun\n"); } *bp++ = c; } c = readchar (); if ((c == '>') && (*(bp - 1) == ' ')) { prompt_found = 1; } } while (!prompt_found); *bp = 0; if (kiodebug) { fprintf (stderr,"message received :%s\n", buf); }}static voiddownload (instream, from_tty, format)FILE *instream; int from_tty; int format;{ char c; char buf[160]; int i = 0; send_command ("SET #2,$1A"); /* reset char = ^Z */ send_command ("SET #3,$11,$13"); /* XON XOFF */ if (format == 2) { send_command ("SET #26,#2"); } else { send_command ("SET #26,#5"); /* Format=Extended Tekhex */ } send_command ("DFB = $10"); send_command ("PUR"); send_command ("CES"); send ("DNL\r"); expect ("DNL", 1); if (from_tty) { printf (" 0 records loaded...\r"); } while (fgets (buf, 160, instream)) { send (buf); if (from_tty) { printf ("%5d\b\b\b\b\b",++i); fflush (stdout); } if ((c = readchar ()) != 006) { error ("expected ACK"); } } if (from_tty) { printf ("- All"); }}/* Additional commands *//* Talk directly to the emulator FIXME, uses busy wait, and is SUNOS (or at least BSD) specific *//*ARGSUSED*/static void es1800_transparent (args, from_tty) char *args; int from_tty;{ int console; struct sgttyb modebl; int fcflag; int cc; struct sgttyb console_mode_save; int console_fc_save; int es1800_fc_save; int inputcnt = 80; char inputbuf[80]; int consolecnt = 0; char consolebuf[80]; int es1800_cnt = 0; char es1800_buf[80]; int i; dont_repeat (); if (es1800_desc < 0) { printf ("No emulator attached, type emulator-command first\n"); return; } printf ("\n"); printf ("You are now communicating directly with the ES 1800 emulator.\n"); printf ("To leave this mode (transparent mode), press ^E.\n"); printf ("\n"); printf (" >"); fflush (stdout); if ((console = open ("/dev/tty", O_RDWR)) == -1) { perror_with_name ("/dev/tty:"); } if ((fcflag = fcntl (console, F_GETFL, 0)) == -1) { perror_with_name ("fcntl console"); } console_fc_save = fcflag; fcflag = fcflag | FNDELAY; if (fcntl (console, F_SETFL, fcflag) == -1) { perror_with_name ("fcntl console"); } if (ioctl (console, TIOCGETP, &modebl)) { perror_with_name ("ioctl console"); } console_mode_save = modebl; modebl.sg_flags = RAW; if (ioctl (console, TIOCSETP, &modebl)) { perror_with_name ("ioctl console"); } if ((fcflag = fcntl (es1800_desc, F_GETFL, 0)) == -1) { perror_with_name ("fcntl serial"); } es1800_fc_save = fcflag; fcflag = fcflag | FNDELAY; if (fcntl (es1800_desc, F_SETFL, fcflag) == -1) { perror_with_name ("fcntl serial"); } while (1) { cc = read (console, inputbuf, inputcnt); if (cc != -1) { if ((*inputbuf & 0x7f) == 0x05) { break; } for (i = 0; i < cc; ) { es1800_buf[es1800_cnt++] = inputbuf[i++]; } if ((cc = write (es1800_desc, es1800_buf, es1800_cnt)) == -1) { perror_with_name ("FEL! read:"); } es1800_cnt -= cc; if (es1800_cnt && cc) { for (i = 0; i < es1800_cnt; i++) { es1800_buf[i] = es1800_buf[cc+i]; } } } else if (errno != EWOULDBLOCK) { perror_with_name ("FEL! read:"); } cc = read (es1800_desc,inputbuf,inputcnt); if (cc != -1) { for (i = 0; i < cc; ) { consolebuf[consolecnt++] = inputbuf[i++]; } if ((cc = write (console,consolebuf,consolecnt)) == -1) { perror_with_name ("FEL! write:"); } consolecnt -= cc; if (consolecnt && cc) { for (i = 0; i < consolecnt; i++) { consolebuf[i] = consolebuf[cc+i]; } } } else if (errno != EWOULDBLOCK) { perror_with_name ("FEL! read:"); } } console_fc_save = console_fc_save & !FNDELAY; if (fcntl (console, F_SETFL, console_fc_save) == -1) { perror_with_name ("FEL! fcntl"); } if (ioctl (console, TIOCSETP, &console_mode_save)) { perror_with_name ("FEL! ioctl"); } close (console); if (fcntl (es1800_desc, F_SETFL, es1800_fc_save) == -1) { perror_with_name ("FEL! fcntl"); } printf ("\n");}static voides1800_init_break (args, from_tty) char *args; int from_tty;{ CORE_ADDR memaddress = 0; char buf[PBUFSIZ]; char base_addr[4]; char *space_index; char *p; int k; if (args == NULL) { error_no_arg ("a trap vector"); } if (!(space_index = strchr (args, ' '))) { error ("Two arguments needed (trap vector and address of break routine).\n"); } *space_index = '\0'; es1800_break_vec = strtol (args, (char **) NULL, 0); es1800_break_address = parse_and_eval_address (space_index + 1); es1800_create_break_insn (es1800_break_insn, es1800_break_vec); if (m68020) { send_with_reply ("VBR ", buf, sizeof (buf)); p = buf; for (k = 0; k < 4; k++) { if ((p[k*2 + 1] == 0) || (p[k*2 + 2] == 0)) { error ("Emulator reply is too short: %s", buf); } base_addr[k] = (fromhex (p[k*2 + 1]) * 16) + fromhex (p[k*2 + 2]); } /* base addr of exception vector table */ memaddress = *((CORE_ADDR *) base_addr); } memaddress += (es1800_break_vec + 32) * 4; /* address of trap vector */ sprintf (buf, "@.L%lx=$%lx", memaddress, es1800_break_address); send_command (buf); /* set the address of the break routine in the */ /* trap vector */ sprintf (buf, "@.L%lx=$4E714E71", es1800_break_address); /* NOP; NOP */ send_command (buf); sprintf (buf, "@.L%lx=$4E714E73", es1800_break_address + 4); /* NOP; RTE */ send_command (buf); sprintf (buf, "AC2=$%lx", es1800_break_address + 4); /* breakpoint at es1800-break_address */ send_command (buf); send_command ("WHEN AC2 THEN BRK"); /* ie in exception routine */ if (from_tty) { printf ("Breakpoint (trap $%x) routine at address: %lx\n", es1800_break_vec, es1800_break_address); }} static voides1800_child_open (arg, from_tty) char *arg; int from_tty;{ error ("Use the \"run\" command to start a child process.");}static voides1800_child_detach (args, from_tty) char *args; int from_tty;{ if (args) { error ("Argument given to \"detach\" when remotely debugging."); } pop_target (); if (from_tty) { printf ("Ending debugging the process %d.\n", inferior_pid); }}/* Define the target subroutine names */static struct target_ops es1800_ops ={ "es1800", /* to_shortname */ /* to_longname */ "Remote serial target in ES1800-emulator protocol", /* to_doc */ "Remote debugging on the es1800 emulator via a serial line.\n\Specify the serial device it is connected to (e.g. /dev/ttya).", es1800_open, /* to_open */ es1800_close, /* to_close */ es1800_attach, /* to_attach */ es1800_detach, /* to_detach */ es1800_resume, /* to_resume */ NULL, /* to_wait */ NULL, /* to_fetch_registers */ NULL, /* to_store_registers */ es1800_prepare_to_store, /* to_prepare_to_store */ es1800_xfer_inferior_memory, /* to_xfer_memory */ es1800_files_info, /* to_files_info */ es1800_insert_breakpoint, /* to_insert_breakpoint */ es1800_remove_breakpoint, /* to_remove_breakpoint */ NULL, /* to_terminal_init */ NULL, /* to_terminal_inferior */ NULL, /* to_terminal_ours_for_output */ NULL, /* to_terminal_ours */ NULL, /* to_terminal_info */ NULL, /* to_kill */ es1800_load, /* to_load */ NULL, /* to_lookup_symbol */ es1800_create_inferior, /* to_create_inferior */ NULL, /* to_mourn_inferior */ 0, /* to_can_run */ 0, /* notice_signals */ core_stratum, /* to_stratum */ 0, /* to_next */ 0, /* to_has_all_memory */ 1, /* to_has_memory */ 0, /* to_has_stack */ 0, /* to_has_registers */ 0, /* to_has_execution */ NULL, /* to_sections */ NULL, /* to_sections_end */ OPS_MAGIC /* to_magic (always last) */};/* Define the target subroutine names */static struct target_ops es1800_child_ops ={ "es1800_process", /* to_shortname */ /* to_longname */ "Remote serial target in ES1800-emulator protocol", /* to_doc */ "Remote debugging on the es1800 emulator via a serial line.\n\Specify the serial device it is connected to (e.g. /dev/ttya).", es1800_child_open, /* to_open */ NULL, /* to_close */ es1800_attach, /* to_attach */ es1800_child_detach, /* to_detach */ es1800_resume, /* to_resume */ es1800_wait, /* to_wait */ es1800_fetch_register, /* to_fetch_registers */ es1800_store_register, /* to_store_registers */ es1800_prepare_to_store, /* to_prepare_to_store */ es1800_xfer_inferior_memory, /* to_xfer_memory */ es1800_files_info, /* to_files_info */ es1800_insert_breakpoint, /* to_insert_breakpoint */ es1800_remove_breakpoint, /* to_remove_breakpoint */ NULL, /* to_terminal_init */ NULL, /* to_terminal_inferior */ NULL, /* to_terminal_ours_for_output */ NULL, /* to_terminal_ours */ NULL, /* to_terminal_info */ es1800_kill, /* to_kill */ es1800_load, /* to_load */ NULL, /* to_lookup_symbol */ es1800_create_inferior, /* to_create_inferior */ es1800_mourn_inferior, /* to_mourn_inferior */ 0, /* to_can_run */ 0, /* notice_signals */ process_stratum, /* to_stratum */ 0, /* to_next */ 1, /* to_has_all_memory */ 1, /* to_has_memory */ 1, /* to_has_stack */ 1, /* to_has_registers */ 1, /* to_has_execution */ NULL, /* to_sections */ NULL, /* to_sections_end */ OPS_MAGIC /* to_magic (always last) */};/* _initialize_es1800 () */void_initialize_es1800 (){ add_target (&es1800_ops); add_target (&es1800_child_ops); add_com ("transparent", class_support, es1800_transparent, "Start transparent communication with the ES 1800 emulator."); add_com ("init_break", class_support, es1800_init_break, "Download break routine and initialize break facility on ES 1800");}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -