From 593e616e19616d78c5ebbddb4f08b43316f2ef17 Mon Sep 17 00:00:00 2001 From: Richard Cornwell Date: Sat, 3 Oct 2020 12:33:29 -0400 Subject: [PATCH] SCP: updated to current. --- scp.c | 20 +++---- sim_console.c | 10 ++-- sim_tape.c | 141 ++++++++++++++++++++++++++++---------------------- sim_tmxr.c | 3 +- 4 files changed, 98 insertions(+), 76 deletions(-) diff --git a/scp.c b/scp.c index af2c143..c4888a2 100644 --- a/scp.c +++ b/scp.c @@ -3455,12 +3455,12 @@ t_stat help_cmd_output (int32 flag, const char *help, const char *help_base) switch (help[0]) { case '*': scp_help (stdout, NULL, NULL, flag, help_base ? help_base : simh_help, help+1); - if (sim_log) + if (sim_log && (!sim_oline)) scp_help (sim_log, NULL, NULL, flag | SCP_HELP_FLAT, help_base ? help_base : simh_help, help+1); break; default: fputs (help, stdout); - if (sim_log) + if (sim_log && (!sim_oline)) fputs (help, sim_log); break; } @@ -3511,7 +3511,7 @@ if (*cptr) { dptr = find_dev (gbuf); if (dptr != NULL) { r = help_dev_help (stdout, dptr, uptr, flag, (cmdp->action == &set_cmd) ? "SET" : "SHOW"); - if (sim_log) + if (sim_log && (!sim_oline)) help_dev_help (sim_log, dptr, uptr, flag | SCP_HELP_FLAT, (cmdp->action == &set_cmd) ? "SET" : "SHOW"); return r; } @@ -3564,7 +3564,7 @@ if (*cptr) { if (((cmdp->action == &exdep_cmd) || (0 == strcmp(cmdp->name, "BOOT"))) && sim_dflt_dev->help) { sim_dflt_dev->help (stdout, sim_dflt_dev, sim_dflt_dev->units, 0, cmdp->name); - if (sim_log) + if (sim_log && (!sim_oline)) sim_dflt_dev->help (sim_log, sim_dflt_dev, sim_dflt_dev->units, 0, cmdp->name); } } @@ -3596,14 +3596,14 @@ if (*cptr) { if (dptr->flags & DEV_DIS) sim_printf ("Device %s is currently disabled\n", dptr->name); r = help_dev_help (stdout, dptr, uptr, flag, cptr); - if (sim_log) + if (sim_log && (!sim_oline)) help_dev_help (sim_log, dptr, uptr, flag | SCP_HELP_FLAT, cptr); return r; } } else { fprint_help (stdout); - if (sim_log) + if (sim_log && (!sim_oline)) fprint_help (sim_log); } return SCPE_OK; @@ -9498,7 +9498,7 @@ for (i = a = 0; a < lim; ) { sim_printf ("%d:\t", a); if ((r = fprint_sym (stdout, a, &sim_eval[i], dptr->units, sim_switches)) > 0) r = fprint_val (stdout, sim_eval[i], rdx, dptr->dwidth, PV_RZRO); - if (sim_log) { + if (sim_log && (!sim_oline)) { if ((r = fprint_sym (sim_log, a, &sim_eval[i], dptr->units, sim_switches)) > 0) r = fprint_val (sim_log, sim_eval[i], rdx, dptr->dwidth, PV_RZRO); } @@ -13692,9 +13692,9 @@ if (sim_mfile || (sim_deb && (f == sim_deb))) { } else { va_start (args, fmt); - if (sim_oline) + if (sim_oline) /* output to tmxr socket if it is defined */ tmxr_linemsgvf (sim_oline, fmt, args); - else + else /* otherwise, output to provided file stream */ ret = vfprintf (f, fmt, args); va_end (args); } @@ -14276,7 +14276,7 @@ flat_help = flat_help || !sim_ttisatty() || (flag & SCP_HELP_FLAT); if (flat_help) { flag |= SCP_HELP_FLAT; - if (sim_ttisatty()) + if (sim_ttisatty() && (!sim_oline)) fprintf (st, "%s help.\nThis help is also available in hierarchical form.\n", top.title); else fprintf (st, "%s help.\n", top.title); diff --git a/sim_console.c b/sim_console.c index 069eac0..7b68c57 100644 --- a/sim_console.c +++ b/sim_console.c @@ -1752,11 +1752,15 @@ for (i=(was_active_command ? sim_rem_cmd_active_line : 0); stat = sim_rem_collect_cmd_setup (i, &cptr); } else { - if (sim_con_stable_registers && - sim_rem_master_mode) { /* can we process command now? */ + if ((sim_con_stable_registers && /* can we process command now? */ + sim_rem_master_mode) || + (cmdp->action == &x_help_cmd)) { sim_debug (DBG_CMD, &sim_remote_console, "Processing Command directly\n"); sim_oline = lp; /* specify output socket */ - sim_remote_process_command (); + if (cmdp->action == &x_help_cmd) + x_help_cmd (0, cptr); + else + sim_remote_process_command (); stat = SCPE_OK; /* any message has already been emitted */ } else { diff --git a/sim_tape.c b/sim_tape.c index 40b9062..6555f2b 100644 --- a/sim_tape.c +++ b/sim_tape.c @@ -376,6 +376,9 @@ return FALSE; (_callback) (uptr, r); #endif +#define MIN_RECORD_SIZE 14 /* Mag tape records <14 bytes are considered noise */ +#define MAX_RECORD_SIZE 65535 /* DEC tape controllers have a 16-bit byte count reg */ + typedef struct VOL1 { char type[3]; /* VOL */ char num; /* 1 */ @@ -637,7 +640,6 @@ uint32 objc; DEVICE *dptr; char gbuf[CBUFSIZE]; char export_file[CBUFSIZE] = ""; -uint32 recsize = 0; t_stat r; t_bool auto_format = FALSE; t_bool had_debug = (sim_deb != NULL); @@ -660,21 +662,28 @@ if (sim_switches & SWMASK ('B')) { /* Record Size (blocking cptr = get_glyph (cptr, gbuf, 0); /* get spec */ if (*cptr == 0) /* must be more */ return sim_messagef (SCPE_2FARG, "Missing Record Size and/or filename to attach\n"); - recsize = (uint32) get_uint (gbuf, 10, 65536, &r); - if ((r != SCPE_OK) || (recsize == 0)) - return sim_messagef (SCPE_ARG, "Invalid Tape Record Size: %s\n", gbuf); - uptr->recsize = recsize; + if ((MT_GET_FMT (uptr) != MTUF_F_TAR) && /* -B is honored for TAR, */ + (MT_GET_FMT (uptr) != MTUF_F_FIXED) && /* FIXED, */ + ((MT_GET_FMT (uptr) == MTUF_F_ANSI) && + ((MT_GET_ANSI_TYP (uptr) != MTAT_F_VMS) && /* ANSI-VMS, */ + (MT_GET_ANSI_TYP (uptr) != MTAT_F_RSX11) && /* ANSI-RSX11, */ + (MT_GET_ANSI_TYP (uptr) != MTAT_F_VAR)))) { /* and ANSI-VAR only */ + sim_messagef (SCPE_ARG, "The -B option is ignored for %s format\n", _sim_tape_format_name (uptr)); + } + else { + uint32 recsize = (uint32) get_uint (gbuf, 10, MAX_RECORD_SIZE, &r); + if ((r != SCPE_OK) || (recsize < MIN_RECORD_SIZE)) + return sim_messagef (SCPE_ARG, "Invalid Tape Record Size: %s\n", gbuf); + uptr->recsize = recsize; + } sim_switches = sim_switches & ~(SWMASK ('B')); /* Record Blocking Factor */ } -else { - if ((MT_GET_FMT (uptr) == MTUF_F_TAR) && (uptr->recsize == 0)) - uptr->recsize = TAR_DFLT_RECSIZE; - } -if ((MT_GET_FMT (uptr) == MTUF_F_TPC) || - (MT_GET_FMT (uptr) == MTUF_F_TAR) || - (MT_GET_FMT (uptr) >= MTUF_F_ANSI)) - sim_switches |= SWMASK ('R'); /* Force ReadOnly attach for TPC, TAR and ANSI tapes */ -if (sim_switches & SWMASK ('X')) +if (sim_switches & SWMASK ('E')) /* On-disk tape image file must exist? */ + if (MT_GET_FMT (uptr) >= MTUF_F_ANSI) /* Does not apply to MEMORY_TAPE images */ + sim_messagef (SCPE_ARG, "The -E option is ignored for %s format\n", _sim_tape_format_name (uptr)); +if (fmts[MT_GET_FMT (uptr)].uflags & UNIT_RO) /* Force ReadOnly attach for TPC, */ + sim_switches |= SWMASK ('R'); /* TAR, ANSI, FIXED and DOS11 */ +if (sim_switches & SWMASK ('X')) /* Export as SIMH? */ cptr = get_glyph_nc (cptr, export_file, 0); /* get export file spec */ switch (MT_GET_FMT (uptr)) { @@ -711,6 +720,9 @@ switch (MT_GET_FMT (uptr)) { if ((tape->file_count > 0) && (file_errors == 0)) { r = SCPE_OK; memory_tape_add_block (tape, NULL, 0); /* Tape Mark */ + /* RT-11 and RSTS write three tape marks at the end of an ANSI volume */ + /* RSX-11 and VMS do not, but there is no harm in the extra tape mark */ + memory_tape_add_block (tape, NULL, 0); /* Tape Mark */ uptr->flags |= UNIT_ATT; uptr->filename = (char *)malloc (strlen (ocptr) + 1); strcpy (uptr->filename, ocptr); @@ -844,6 +856,8 @@ switch (MT_GET_FMT (uptr)) { if ((tape->file_count > 0) && (file_errors == 0)) { r = SCPE_OK; memory_tape_add_block (tape, NULL, 0); /* Tape Mark */ + /* RSX-11 and RSTS write three tape marks at the end of a DOS volume */ + /* VMS does not, but there is no harm in the extra tape mark */ memory_tape_add_block (tape, NULL, 0); /* Tape Mark */ uptr->flags |= UNIT_ATT; uptr->filename = (char *)malloc (strlen (ocptr) + 1); @@ -861,24 +875,20 @@ switch (MT_GET_FMT (uptr)) { case MTUF_F_TAR: if (uptr->recsize == 0) - uptr->recsize = TAR_DFLT_RECSIZE; /* Apply default block size */ + uptr->recsize = TAR_DFLT_RECSIZE; /* Apply default block size */ + if ((uptr->recsize % 512) != 0) + return sim_messagef (SCPE_ARG, "TAR format block size of %u is not a multiple of 512\n", uptr->recsize); + sim_switches |= SWMASK ('E'); /* The TAR file must exist */ /* fall through */ default: - r = attach_unit (uptr, (CONST char *)cptr); /* attach unit */ + r = attach_unit (uptr, (CONST char *)cptr); /* attach unit */ break; } if (r != SCPE_OK) { /* error? */ - switch (MT_GET_FMT (uptr)) { - case MTUF_F_ANSI: - case MTUF_F_TAR: - case MTUF_F_FIXED: - case MTUF_F_DOS11: - r = sim_messagef (r, "Error opening %s format internal tape image generated from: %s\n", _sim_tape_format_name (uptr), cptr); - break; - default: - r = sim_messagef (r, "Error opening %s format tape image: %s - %s\n", _sim_tape_format_name (uptr), cptr, strerror(errno)); - break; - } + if (MT_GET_FMT (uptr) >= MTUF_F_ANSI) + r = sim_messagef (r, "Error opening %s format internal tape image generated from: '%s'\n", _sim_tape_format_name (uptr), cptr); + else + r = sim_messagef (r, "Error opening %s format tape image: '%s' - %s\n", _sim_tape_format_name (uptr), cptr, strerror(errno)); if (auto_format) /* format was specified at attach time? */ sim_tape_set_fmt (uptr, 0, "SIMH", NULL); /* restore default format */ uptr->recsize = 0; @@ -3567,32 +3577,37 @@ while (r == SCPE_OK) { } } uptr->tape_eom = uptr->pos; -if ((!stop_cpu) && - ((r != MTSE_EOM) || (sim_switches & SWMASK ('V')) || (sim_switches & SWMASK ('L')) || - ((uint32)(sim_tape_size (uptr) - (t_offset)uptr->pos) > fmts[MT_GET_FMT (uptr)].eom_remnant) || - (unique_record_sizes > 2 * tapemark_total))) { +if (!stop_cpu) { /* if SIGINT didn't interrupt the scan */ + sim_messagef (SCPE_OK, "%s: Tape Image %s'%s' scanned as %s format\n", sim_uname (uptr), + ((MT_GET_FMT (uptr) >= MTUF_F_ANSI) ? "made from " : ""), uptr->filename, + _sim_tape_format_name (uptr)); remaining_data = (uint32)(sim_tape_size (uptr) - (t_offset)uptr->tape_eom); - sim_messagef (SCPE_OK, "Tape Image %s'%s' scanned as %s format.\n", ((MT_GET_FMT (uptr) == MTUF_F_ANSI) ? "made from " : ""), uptr->filename, (MT_GET_FMT (uptr) == MTUF_F_ANSI) ? ansi_args[MT_GET_ANSI_TYP (uptr)].name : fmts[MT_GET_FMT (uptr)].name); - sim_messagef (SCPE_OK, "%s %u bytes of tape data (%u records, %u tapemarks)\n", - (r != MTSE_EOM) ? "After processing" : "contains", data_total, record_total, tapemark_total); - if ((record_total > 0) && (sim_switches & SWMASK ('L'))) { - sim_messagef (SCPE_OK, "Comprising %d different sized records (in record size order):\n", unique_record_sizes); - for (bc = 0; bc <= max; bc++) { - if (rec_sizes[bc]) - sim_messagef (SCPE_OK, "%8u %u byte record%s\n", rec_sizes[bc], (uint32)bc, (rec_sizes[bc] != 1) ? "s" : ""); + if ((r != MTSE_EOM) || (sim_switches & SWMASK ('V')) || (sim_switches & SWMASK ('L')) || + (remaining_data > 0) || + (unique_record_sizes > 2 * tapemark_total)) { + sim_messagef (SCPE_OK, "%s %u bytes of tape data (%u record%s, %u tapemark%s)\n", + (r != MTSE_EOM) ? "After processing" : "contains", data_total, + record_total, (record_total == 1) ? "" : "s", + tapemark_total, (tapemark_total == 1) ? "" : "s"); + if ((record_total > 0) && (sim_switches & SWMASK ('L'))) { + sim_messagef (SCPE_OK, "Comprising %d different sized records (in record size order):\n", unique_record_sizes); + for (bc = 0; bc <= max; bc++) { + if (rec_sizes[bc]) + sim_messagef (SCPE_OK, "%8u %u byte record%s\n", rec_sizes[bc], (uint32)bc, (rec_sizes[bc] != 1) ? "s" : ""); + } + if (gaps) + sim_messagef (SCPE_OK, "%8u gap%s totalling %u bytes %s seen\n", gaps, (gaps != 1) ? "s" : "", gap_bytes, (gaps != 1) ? "were" : "was"); } - if (gaps) - sim_messagef (SCPE_OK, "%8u gap%s totalling %u bytes %s seen\n", gaps, (gaps != 1) ? "s" : "", gap_bytes, (gaps != 1) ? "were" : "was"); + if (r != MTSE_EOM) + sim_messagef (SCPE_OK, "Read Tape Record Returned Unexpected Status: %s\n", sim_tape_error_text (r)); + if (remaining_data > fmts[MT_GET_FMT (uptr)].eom_remnant) + sim_messagef (SCPE_OK, "%u %s of unexamined data remain in the tape image file\n", + remaining_data, (MT_GET_FMT (uptr) < MTUF_F_ANSI) ? "bytes" : "records"); + } + if (unique_record_sizes > 2 * tapemark_total) { + sim_messagef (SCPE_OK, "A potentially unreasonable number of record sizes(%u) vs tape marks (%u) have been found\n", unique_record_sizes, tapemark_total); + sim_messagef (SCPE_OK, "The tape format (%s) might not be correct for the '%s' tape image\n", _sim_tape_format_name (uptr), uptr->filename); } - if (r != MTSE_EOM) - sim_messagef (SCPE_OK, "Read Tape Record Returned Unexpected Status: %s\n", sim_tape_error_text (r)); - if (remaining_data > fmts[MT_GET_FMT (uptr)].eom_remnant) - sim_messagef (SCPE_OK, "%u bytes of unexamined data remain in the tape image file\n", remaining_data); - } -if ((!stop_cpu) && - (unique_record_sizes > 2 * tapemark_total)) { - sim_messagef (SCPE_OK, "A potentially unreasonable number of record sizes(%u) vs tape marks (%u) have been found\n", unique_record_sizes, tapemark_total); - sim_messagef (SCPE_OK, "The tape format (%s) might not be correct for the '%s' tape image\n", fmts[MT_GET_FMT (uptr)].name, uptr->filename); } free (buf_f); @@ -3827,7 +3842,7 @@ int32 saved_switches = sim_switches; srand (0); /* All devices use the same random sequence for file data */ if (max_size == 0) - max_size = 65535; + max_size = MAX_RECORD_SIZE; if (!p7b_parity_inited) { for (i=0; i < 64; i++) { int bit_count = 0; @@ -4457,8 +4472,6 @@ t_bool crlast = FALSE; int error = 0; size_t i, data_read, offset = 0; -memset (buf, 0, bufSize); - while (!feof (f) && !error) { data_read = fread (tmp, 1, sizeof (tmp), f); if (data_read > 0) @@ -4470,14 +4483,12 @@ while (!feof (f) && !error) { if (offset == bufSize) { error = memory_tape_add_block (tape, (uint8 *)buf, bufSize); offset = 0; - memset (buf, 0, bufSize); } } buf[offset++] = ch; if (offset == bufSize) { error = memory_tape_add_block (tape, (uint8 *)buf, bufSize); offset = 0; - memset (buf, 0, bufSize); } crlast = FALSE; } @@ -4488,13 +4499,18 @@ while (!feof (f) && !error) { if (offset == bufSize) { error = memory_tape_add_block (tape, (uint8 *)buf, bufSize); offset = 0; - memset (buf, 0, bufSize); } } } } - if (offset != 0) + if (offset > 0) { + /* RSTS COPY to a DOS volume pads the last block with zeros */ + /* VMS EXCHANGE COPY /RECORD_FORMAT=STREAM and RSX-11 FLX /FA */ + /* output to a DOS volume do not */ + /* DOS-11 ignores NULs in ASCII data transfer modes */ + memset (buf + offset, 0, bufSize - offset); error = memory_tape_add_block (tape, (uint8 *)buf, bufSize); + } return error; } @@ -4517,8 +4533,8 @@ DOS11_HDR hdr; char fname[9], ext[3]; const char *ptr; struct tm *tm; -time_t now = time (NULL); -uint16 today; +time_t filetime; +uint16 fileday; int year; /* @@ -4526,12 +4542,13 @@ int year; * same calendar as the current year but will be in the 20th century so that * DOS/BATCH-11 will be able to interpret it correctly. */ -tm = localtime (&now); +filetime = (time_t)filestat->st_ctime; +tm = localtime (&filetime); year = tm->tm_year + 1900; while (year >= 2000) year -= 28; -today = ((year - 70) * 1000) + tm->tm_yday + 1; +fileday = 1000 * ((year - 70) % 100) + tm->tm_yday + 1; sprintf (FullPath, "%s%s", directory, filename); f = tape_open_and_check_file (FullPath); @@ -4566,7 +4583,7 @@ hdr.ext = dos11_ascR50 (&ext[0]); hdr.prog = 1; hdr.proj = 1; hdr.prot = DOS11_PROT; -hdr.date = today; +hdr.date = fileday; hdr.fname3 = dos11_ascR50 (&fname[6]); memory_tape_add_block (tape, (uint8 *)&hdr, sizeof (hdr)); diff --git a/sim_tmxr.c b/sim_tmxr.c index cbf4290..4ccbdb7 100644 --- a/sim_tmxr.c +++ b/sim_tmxr.c @@ -2318,7 +2318,8 @@ tmxr_debug_trace_line (lp, "tmxr_putc_ln()"); if ((lp->xmte == 0) && (TXBUF_AVAIL(lp) > 1) && ((lp->txbps == 0) || (lp->txnexttime <= sim_gtime ()))) lp->xmte = 1; /* enable line transmit */ -if ((lp->txbfd && !lp->notelnet) || (TXBUF_AVAIL(lp) > 1)) {/* room for char (+ IAC)? */ +if ((lp->conn && (TXBUF_AVAIL(lp) > 1)) || /* connected and room for char (+ IAC)? OR */ + (!lp->conn && !lp->notelnet && lp->txbfd)) { /* not connected and buffered ? */ if ((TN_IAC == (u_char) chr) && (!lp->notelnet)) /* char == IAC in telnet session? */ TXBUF_CHAR (lp, TN_IAC); /* stuff extra IAC char */ TXBUF_CHAR (lp, chr); /* buffer char & adv pointer */