diff --git a/Visual Studio Projects/BESM6.vcproj b/Visual Studio Projects/BESM6.vcproj index 83f2c96..e457e16 100644 --- a/Visual Studio Projects/BESM6.vcproj +++ b/Visual Studio Projects/BESM6.vcproj @@ -41,7 +41,7 @@ + + diff --git a/Visual Studio Projects/BuildROMs.vcproj b/Visual Studio Projects/BuildROMs.vcproj index 64c9512..5e088ba 100644 --- a/Visual Studio Projects/BuildROMs.vcproj +++ b/Visual Studio Projects/BuildROMs.vcproj @@ -95,6 +95,8 @@ /> diff --git a/Visual Studio Projects/FrontPanelTest.vcproj b/Visual Studio Projects/FrontPanelTest.vcproj index e684a37..70ae79e 100644 --- a/Visual Studio Projects/FrontPanelTest.vcproj +++ b/Visual Studio Projects/FrontPanelTest.vcproj @@ -126,7 +126,7 @@ EnableIntrinsicFunctions="true" FavorSizeOrSpeed="1" OmitFramePointers="true" - WholeProgramOptimization="true" + WholeProgramOptimization="false" AdditionalIncludeDirectories="./;../;../VAX/;../pdp11/;"../../windows-build/winpcap/Wpdpack/Include";"../../windows-build/PCRE/include/";"../../windows-build/pthreads"" PreprocessorDefinitions="_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;PTW32_STATIC_LIB" StringPooling="true" diff --git a/Visual Studio Projects/HP3000.vcproj b/Visual Studio Projects/HP3000.vcproj index 6d81a85..628d072 100644 --- a/Visual Studio Projects/HP3000.vcproj +++ b/Visual Studio Projects/HP3000.vcproj @@ -204,6 +204,10 @@ RelativePath="..\HP3000\hp3000_cpu_base.c" > + + @@ -216,6 +220,14 @@ RelativePath="..\HP3000\hp3000_iop.c" > + + + + @@ -313,6 +325,10 @@ RelativePath="..\HP3000\hp3000_io.h" > + + diff --git a/Visual Studio Projects/MicroVAX1.vcproj b/Visual Studio Projects/MicroVAX1.vcproj index b0f1ad5..e32311f 100644 --- a/Visual Studio Projects/MicroVAX1.vcproj +++ b/Visual Studio Projects/MicroVAX1.vcproj @@ -41,7 +41,7 @@ diff --git a/Visual Studio Projects/MicroVAX2.vcproj b/Visual Studio Projects/MicroVAX2.vcproj index 87e24f6..1829383 100644 --- a/Visual Studio Projects/MicroVAX2.vcproj +++ b/Visual Studio Projects/MicroVAX2.vcproj @@ -41,7 +41,7 @@ diff --git a/Visual Studio Projects/PDP1.vcproj b/Visual Studio Projects/PDP1.vcproj index ef20bc8..569e6ab 100644 --- a/Visual Studio Projects/PDP1.vcproj +++ b/Visual Studio Projects/PDP1.vcproj @@ -41,7 +41,7 @@ + + + + diff --git a/Visual Studio Projects/PDP10-KI.vcproj b/Visual Studio Projects/PDP10-KI.vcproj index 7b467e7..c7761a7 100644 --- a/Visual Studio Projects/PDP10-KI.vcproj +++ b/Visual Studio Projects/PDP10-KI.vcproj @@ -244,10 +244,18 @@ RelativePath="..\PDP10\ka10_rp.c" > + + + + diff --git a/Visual Studio Projects/PDP10.vcproj b/Visual Studio Projects/PDP10.vcproj index 7665a58..f9d1b02 100644 --- a/Visual Studio Projects/PDP10.vcproj +++ b/Visual Studio Projects/PDP10.vcproj @@ -42,7 +42,7 @@ Name="VCCLCompilerTool" Optimization="0" AdditionalIncludeDirectories="./;../;../PDP10/;../PDP11/;../VAX/;../../windows-build/PCRE/include/;../../windows-build/winpcap/Wpdpack/Include;../../windows-build/pthreads;../slirp;../slirp_glue;../slirp_glue/qemu;../slirp_glue/qemu/win32/include" - PreprocessorDefinitions="USE_INT64;VM_PDP10;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;SIM_NEED_GIT_COMMIT_ID;HAVE_PCREPOSIX_H;PCRE_STATIC;USE_SHARED;PTW32_STATIC_LIB;USE_READER_THREAD;HAVE_SLIRP_NETWORK;USE_SIMH_SLIRP_DEBUG" + PreprocessorDefinitions="USE_INT64;VM_PDP10;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;SIM_NEED_GIT_COMMIT_ID;HAVE_PCREPOSIX_H;PCRE_STATIC;USE_SHARED;PTW32_STATIC_LIB;USE_READER_THREAD;SIM_ASYNCH_IO;HAVE_SLIRP_NETWORK;USE_SIMH_SLIRP_DEBUG" KeepComments="false" MinimalRebuild="true" BasicRuntimeChecks="0" @@ -126,7 +126,7 @@ OmitFramePointers="true" WholeProgramOptimization="true" AdditionalIncludeDirectories="./;../;../PDP10/;../PDP11/;../VAX/;../../windows-build/PCRE/include/;../../windows-build/winpcap/Wpdpack/Include;../../windows-build/pthreads;../slirp;../slirp_glue;../slirp_glue/qemu;../slirp_glue/qemu/win32/include" - PreprocessorDefinitions="USE_INT64;VM_PDP10;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;SIM_NEED_GIT_COMMIT_ID;HAVE_PCREPOSIX_H;PCRE_STATIC;USE_SHARED;PTW32_STATIC_LIB;USE_READER_THREAD;HAVE_SLIRP_NETWORK;USE_SIMH_SLIRP_DEBUG" + PreprocessorDefinitions="USE_INT64;VM_PDP10;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;SIM_NEED_GIT_COMMIT_ID;HAVE_PCREPOSIX_H;PCRE_STATIC;USE_SHARED;PTW32_STATIC_LIB;USE_READER_THREAD;SIM_ASYNCH_IO;HAVE_SLIRP_NETWORK;USE_SIMH_SLIRP_DEBUG" StringPooling="true" RuntimeLibrary="0" EnableFunctionLevelLinking="true" @@ -275,6 +275,7 @@ diff --git a/Visual Studio Projects/PDP11.vcproj b/Visual Studio Projects/PDP11.vcproj index 15308d5..948b462 100644 --- a/Visual Studio Projects/PDP11.vcproj +++ b/Visual Studio Projects/PDP11.vcproj @@ -41,8 +41,8 @@ diff --git a/Visual Studio Projects/TX-0.vcproj b/Visual Studio Projects/TX-0.vcproj index ff8826f..80c1401 100644 --- a/Visual Studio Projects/TX-0.vcproj +++ b/Visual Studio Projects/TX-0.vcproj @@ -41,7 +41,7 @@ diff --git a/Visual Studio Projects/VAX730.vcproj b/Visual Studio Projects/VAX730.vcproj index a19a0ec..3136767 100644 --- a/Visual Studio Projects/VAX730.vcproj +++ b/Visual Studio Projects/VAX730.vcproj @@ -266,6 +266,7 @@ diff --git a/Visual Studio Projects/VAX750.vcproj b/Visual Studio Projects/VAX750.vcproj index 2425dfb..47f90fa 100644 --- a/Visual Studio Projects/VAX750.vcproj +++ b/Visual Studio Projects/VAX750.vcproj @@ -274,6 +274,7 @@ diff --git a/Visual Studio Projects/VAX780.vcproj b/Visual Studio Projects/VAX780.vcproj index 556ee4e..9c9b565 100644 --- a/Visual Studio Projects/VAX780.vcproj +++ b/Visual Studio Projects/VAX780.vcproj @@ -279,6 +279,7 @@ diff --git a/Visual Studio Projects/VAX8600.vcproj b/Visual Studio Projects/VAX8600.vcproj index 75edf38..5e65c70 100644 --- a/Visual Studio Projects/VAX8600.vcproj +++ b/Visual Studio Projects/VAX8600.vcproj @@ -279,6 +279,7 @@ diff --git a/Visual Studio Projects/isys8010.vcproj b/Visual Studio Projects/isys8010.vcproj index b5558a1..fddc6bd 100644 --- a/Visual Studio Projects/isys8010.vcproj +++ b/Visual Studio Projects/isys8010.vcproj @@ -212,12 +212,20 @@ RelativePath="..\Intel-Systems\common\isbc064.c" > + + + + + + + + + + + + diff --git a/makefile b/makefile index d152520..72d7af7 100644 --- a/makefile +++ b/makefile @@ -1172,7 +1172,8 @@ KA10 = ${KA10D}/ka10_cpu.c ${KA10D}/ka10_sys.c ${KA10D}/ka10_df.c \ ${KA10D}/ka10_dp.c ${KA10D}/ka10_mt.c ${KA10D}/ka10_cty.c \ ${KA10D}/ka10_lp.c ${KA10D}/ka10_pt.c ${KA10D}/ka10_dc.c \ ${KA10D}/ka10_rp.c ${KA10D}/ka10_rc.c ${KA10D}/ka10_dt.c \ - ${KA10D}/ka10_dk.c ${KA10D}/ka10_cr.c ${KA10D}/ka10_cp.c + ${KA10D}/ka10_dk.c ${KA10D}/ka10_cr.c ${KA10D}/ka10_cp.c \ + ${KA10D}/ka10_tu.c ${KA10D}/ka10_rs.c KA10_OPT = -DKA=1 -DUSE_INT64 -I $(KA10D) -DUSE_SIM_CARD @@ -1181,7 +1182,8 @@ KI10 = ${KA10D}/ka10_cpu.c ${KA10D}/ka10_sys.c ${KA10D}/ka10_df.c \ ${KA10D}/ka10_dp.c ${KA10D}/ka10_mt.c ${KA10D}/ka10_cty.c \ ${KA10D}/ka10_lp.c ${KA10D}/ka10_pt.c ${KA10D}/ka10_dc.c \ ${KA10D}/ka10_rp.c ${KA10D}/ka10_rc.c ${KA10D}/ka10_dt.c \ - ${KA10D}/ka10_dk.c ${KA10D}/ka10_cr.c ${KA10D}/ka10_cp.c + ${KA10D}/ka10_dk.c ${KA10D}/ka10_cr.c ${KA10D}/ka10_cp.c \ + ${KA10D}/ka10_tu.c ${KA10D}/ka10_rs.c KI10_OPT = -DKI=1 -DUSE_INT64 -I $(KA10D) -DUSE_SIM_CARD diff --git a/scp.c b/scp.c index 8aeb5a6..0cda26d 100644 --- a/scp.c +++ b/scp.c @@ -1029,16 +1029,24 @@ static const char simh_help[] = "2Displaying Files\n" #define HLP_TYPE "*Commands Displaying_Files TYPE" "3TYPE\n" - "++TYPE {file} display a file contents\n" + "++TYPE file display a file contents\n" #define HLP_CAT "*Commands Displaying_Files CAT" "3CAT\n" - "++CAT {file} display a file contents\n" + "++CAT file display a file contents\n" + "2Removing Files\n" #define HLP_DELETE "*Commands Removing_Files DEL" "3DELETE\n" - "++DEL{ete} {file} deletes a file\n" + "++DEL{ete} file deletes a file\n" #define HLP_RM "*Commands Removing_Files RM" "3RM\n" - "++RM {file} deletes a file\n" + "++RM file deletes a file\n" + "2Copying Files\n" +#define HLP_COPY "*Commands Copying_Files COPY" + "3COPY\n" + "++COPY sfile dfile copies a file\n" +#define HLP_CP "*Commands Copying_Files CP" + "3CP\n" + "++CP sfile dfile copies a file\n" #define HLP_SET "*Commands SET" "2SET\n" /***************** 80 character line width template *************************/ @@ -1839,6 +1847,8 @@ static CTAB cmd_table[] = { { "CAT", &type_cmd, 0, HLP_CAT }, { "DELETE", &delete_cmd, 0, HLP_DELETE }, { "RM", &delete_cmd, 0, HLP_RM }, + { "COPY", ©_cmd, 0, HLP_COPY }, + { "CP", ©_cmd, 0, HLP_CP }, { "SET", &set_cmd, 0, HLP_SET }, { "SHOW", &show_cmd, 0, HLP_SHOW }, { "DO", &do_cmd, 1, HLP_DO }, @@ -2027,7 +2037,7 @@ for (i = 1; i < argc; i++) { /* loop thru args */ return 0; } if (*cbuf) /* concat args */ - strcat (cbuf, " "); + sim_strlcat (cbuf, " ", sizeof(cbuf)); sprintf(&cbuf[strlen(cbuf)], "%s%s%s", strchr(argv[i], ' ') ? "\"" : "", argv[i], strchr(argv[i], ' ') ? "\"" : ""); lookswitch = FALSE; /* no more switches */ } @@ -2113,7 +2123,7 @@ else if (*argv[0]) { /* sim name arg? */ strncpy (nbuf + 1, argv[0], PATH_MAX + 1); /* copy sim name */ if ((np = (char *)match_ext (nbuf, "EXE"))) /* remove .exe */ *np = 0; - strcat (nbuf, ".ini\""); /* add .ini" */ + strlcat (nbuf, ".ini\"", sizeof(nbuf)); /* add .ini" */ stat = do_cmd (-1, nbuf) & ~SCPE_NOMESSAGE; /* proc default cmd file */ if (stat == SCPE_OPENERR) { /* didn't exist/can't open? */ np = strrchr (nbuf, '/'); /* stript path and try again in cwd */ @@ -2906,7 +2916,8 @@ for (nargs = 0; nargs < 10; ) { /* extract arguments */ if (do_arg [0] == NULL) /* need at least 1 */ return SCPE_2FARG; if ((fpin = fopen (do_arg[0], "r")) == NULL) { /* file failed to open? */ - strcat (strcpy (cbuf, do_arg[0]), ".sim"); /* try again with .sim extension */ + strlcpy (cbuf, do_arg[0], sizeof (cbuf)); /* try again with .sim extension */ + strlcat (cbuf, ".sim", sizeof (cbuf)); if ((fpin = fopen (cbuf, "r")) == NULL) { /* failed a second time? */ if (flag == 0) /* cmd line file? */ fprintf (stderr, "Can't open file %s\n", do_arg[0]); @@ -2937,7 +2948,8 @@ if (flag >= 0) { /* Only bump nesting fro } } -strcpy( sim_do_filename[sim_do_depth], do_arg[0]); /* stash away do file name for possible use by 'call' command */ +sim_strlcpy( sim_do_filename[sim_do_depth], do_arg[0], + sizeof (sim_do_filename[sim_do_depth])); /* stash away do file name for possible use by 'call' command */ sim_do_label[sim_do_depth] = label; /* stash away do label for possible use in messages */ sim_goto_line[sim_do_depth] = 0; if (label) { @@ -3738,8 +3750,11 @@ int32 saved_goto_line = sim_goto_line[sim_do_depth]; if (NULL == sim_gotofile) return SCPE_UNK; /* only valid inside of do_cmd */ get_glyph (fcptr, gbuf1, 0); -if ('\0' == gbuf1[0]) return SCPE_ARG; /* unspecified goto target */ +if ('\0' == gbuf1[0]) /* unspecified goto target */ + return sim_messagef (SCPE_ARG, "Missing goto target\n"); fpos = ftell(sim_gotofile); /* Save start position */ +if (fpos < 0) + return sim_messagef (SCPE_IERR, "goto ftell error: %s\n", strerror (errno)); rewind(sim_gotofile); /* start search for label */ sim_goto_line[sim_do_depth] = 0; /* reset line number */ sim_do_echo = 0; /* Don't echo while searching for label */ @@ -3751,7 +3766,7 @@ while (1) { if (*cptr != ':') continue; /* ignore non-labels */ ++cptr; /* skip : */ while (sim_isspace (*cptr)) ++cptr; /* skip blanks */ - cptr = get_glyph (cptr, gbuf, 0); /* get label glyph */ + get_glyph (cptr, gbuf, 0); /* get label glyph */ if (0 == strcmp(gbuf, gbuf1)) { sim_brk_clract (); /* goto defangs current actions */ sim_do_echo = saved_do_echo; /* restore echo mode */ @@ -3761,9 +3776,10 @@ while (1) { } } sim_do_echo = saved_do_echo; /* restore echo mode */ -fseek(sim_gotofile, fpos, SEEK_SET); /* restore start position */ sim_goto_line[sim_do_depth] = saved_goto_line; /* restore start line number */ -return SCPE_ARG; +if (fseek(sim_gotofile, fpos, SEEK_SET)) /* restore start position */ + return sim_messagef (SCPE_IERR, "goto seek error: %s\n", strerror (errno)); +return sim_messagef (SCPE_ARG, "goto target '%s' not found\n", gbuf1); } /* Return command */ @@ -5072,23 +5088,25 @@ struct stat filestat; char *c; char DirName[PATH_MAX + 1], WholeName[PATH_MAX + 1], WildName[PATH_MAX + 1]; -strcpy (WildName, cptr); +memset (DirName, 0, sizeof(DirName)); +memset (WholeName, 0, sizeof(WholeName)); +sim_strlcpy (WildName, cptr, sizeof(WildName)); cptr = WildName; sim_trim_endspc (WildName); if ((!stat (WildName, &filestat)) && (filestat.st_mode & S_IFDIR)) - strcat (WildName, "/*"); + strlcat (WildName, "/*", sizeof(WildName)); if ((*cptr != '/') || (0 == memcmp (cptr, "./", 2)) || (0 == memcmp (cptr, "../", 3))) { #if defined (VMS) - getcwd (WholeName, PATH_MAX, 0); + getcwd (WholeName, sizeof(WholeName)-1, 0); #else - getcwd (WholeName, PATH_MAX); + getcwd (WholeName, sizeof(WholeName)-1); #endif - strcat (WholeName, "/"); - strcat (WholeName, cptr); + strlcat (WholeName, "/", sizeof(WholeName)); + strlcat (WholeName, cptr, sizeof(WholeName)); sim_trim_endspc (WholeName); } else - strcpy (WholeName, cptr); + sim_strlcpy (WholeName, cptr, sizeof(WholeName)); while ((c = strstr (WholeName, "/./"))) memmove (c + 1, c + 3, 1 + strlen (c + 3)); while ((c = strstr (WholeName, "//"))) @@ -5109,9 +5127,9 @@ if (c) { } else { #if defined (VMS) - getcwd (WholeName, PATH_MAX, 0); + getcwd (WholeName, sizeof(WholeName)-1, 0); #else - getcwd (WholeName, PATH_MAX); + getcwd (WholeName, sizeof(WholeName)-1); #endif } cptr = WholeName; @@ -5146,7 +5164,8 @@ if (dir) { sprintf (FileName, "%s/%s", DirName, ent->d_name); #endif p_name = FileName + strlen (DirName); - stat (FileName, &filestat); + memset (&filestat, 0, sizeof (filestat)); + (void)stat (FileName, &filestat); FileSize = (t_offset)((filestat.st_mode & S_IFDIR) ? 0 : sim_fsize_name_ex (FileName)); entry (DirName, p_name, FileSize, &filestat, context); } @@ -5333,6 +5352,62 @@ if (stat == SCPE_OK) return sim_messagef (SCPE_ARG, "No such file or directory: %s\n", cptr); } +typedef struct { + t_stat stat; + int count; + char destname[CBUFSIZE]; + } COPY_CTX; + +static void sim_copy_entry (const char *directory, + const char *filename, + t_offset FileSize, + const struct stat *filestat, + void *context) +{ +COPY_CTX *ctx = (COPY_CTX *)context; +struct stat deststat; +char FullPath[PATH_MAX + 1]; +char dname[CBUFSIZE];\ +t_stat st; + +sim_strlcpy (dname, ctx->destname, sizeof (dname)); + +sprintf (FullPath, "%s%s", directory, filename); + +if ((dname[strlen (dname) - 1] == '/') || (dname[strlen (dname) - 1] == '\\')) + dname[strlen (dname) - 1] = '\0'; +if ((!stat (dname, &deststat)) && (deststat.st_mode & S_IFDIR)) { + const char *dslash = (strrchr (dname, '/') ? "/" : (strrchr (dname, '\\') ? "\\" : "/")); + + dname[sizeof (dname) - 1] = '\0'; + snprintf (&dname[strlen (dname)], sizeof (dname) - strlen (dname), "%s%s", dslash, filename); + } +st = sim_copyfile (FullPath, dname, TRUE); +if (SCPE_OK == st) + ++ctx->count; +else + ctx->stat = st; +} + +t_stat copy_cmd (int32 flg, CONST char *cptr) +{ +char sname[CBUFSIZE]; +COPY_CTX copy_state; +t_stat stat; + +memset (©_state, 0, sizeof (copy_state)); +if ((!cptr) || (*cptr == 0)) + return SCPE_2FARG; +cptr = get_glyph_quoted (cptr, sname, 0); +if ((!cptr) || (*cptr == 0)) + return SCPE_2FARG; +cptr = get_glyph_quoted (cptr, copy_state.destname, 0); +stat = sim_dir_scan (sname, sim_copy_entry, ©_state); +if ((stat == SCPE_OK) && (copy_state.count)) + return sim_messagef (SCPE_OK, " %3d file(s) copied\n", copy_state.count); +return copy_state.stat; +} + /* Breakpoint commands */ t_stat brk_cmd (int32 flg, CONST char *cptr) @@ -6150,7 +6225,10 @@ sim_switches &= ~(SWMASK ('F') | SWMASK ('D') | SWMASK ('Q')); /* remove digest goto Cleanup_Return; \ } -fstat (fileno (rfile), &rstat); +if (fstat (fileno (rfile), &rstat)) { + r = SCPE_IOERR; + goto Cleanup_Return; + } READ_S (buf); /* [V2.5+] read version */ v40 = v35 = v32 = FALSE; if (strcmp (buf, save_ver40) == 0) /* version 4.0? */ @@ -6603,7 +6681,8 @@ for (i = 1; (dptr = sim_devices[i]) != NULL; i++) { /* reposition all */ for (j = 0; j < dptr->numunits; j++) { /* seq devices */ uptr = dptr->units + j; if ((uptr->flags & (UNIT_ATT + UNIT_SEQ)) == (UNIT_ATT + UNIT_SEQ)) - sim_fseek (uptr->fileref, uptr->pos, SEEK_SET); + if (sim_fseek (uptr->fileref, uptr->pos, SEEK_SET)) + return sim_messagef (SCPE_IERR, "Can't seek to %u in %s for %s\n", (unsigned)uptr->pos, uptr->filename, sim_uname (uptr)); } } stop_cpu = 0; @@ -6789,8 +6868,10 @@ fputc ('\n', st); /* start on a new line * if (v >= SCPE_BASE) /* SCP error? */ fputs (sim_error_text (v), st); /* print it from the SCP list */ else { /* VM error */ - fputs (sim_stop_messages [v], st); /* print the VM-specific message */ - + if (sim_stop_messages [v]) + fputs (sim_stop_messages [v], st); /* print the VM-specific message */ + else + fprintf (st, "Unknown %s simulator stop code %d", sim_name, v); if ((sim_vm_fprint_stopped != NULL) && /* if a VM-specific stop handler is defined */ (!sim_vm_fprint_stopped (st, v))) /* call it; if it returned FALSE, */ return; /* we're done */ @@ -6818,7 +6899,6 @@ if ((dptr != NULL) && (dptr->examine != NULL)) { } } fprintf (st, "\n"); -return; } void fprint_stopped (FILE *st, t_stat v) @@ -7407,7 +7487,11 @@ for (i = 0, j = addr; i < sim_emax; i++, j = j + dptr->aincr) { SZ_LOAD (sz, sim_eval[i], uptr->filebuf, loc); } else { - sim_fseek (uptr->fileref, (t_addr)(sz * loc), SEEK_SET); + if (sim_fseek (uptr->fileref, (t_addr)(sz * loc), SEEK_SET)) { + clearerr (uptr->fileref); + reason = SCPE_IOERR; + break; + } sim_fread (&sim_eval[i], sz, 1, uptr->fileref); if ((feof (uptr->fileref)) && !(uptr->flags & UNIT_FIX)) { @@ -7498,7 +7582,10 @@ for (i = 0, j = addr; i < count; i++, j = j + dptr->aincr) { uptr->hwmark = (uint32) loc + 1; } else { - sim_fseek (uptr->fileref, (t_addr)(sz * loc), SEEK_SET); + if (sim_fseek (uptr->fileref, (t_addr)(sz * loc), SEEK_SET)) { + clearerr (uptr->fileref); + return SCPE_IOERR; + } sim_fwrite (&sim_eval[i], sz, 1, uptr->fileref); if (ferror (uptr->fileref)) { clearerr (uptr->fileref); @@ -7816,7 +7903,7 @@ return 0; } /* strcasecmp() is not available on all platforms */ -int sim_strcasecmp (const char* string1, const char* string2) +int sim_strcasecmp (const char *string1, const char *string2) { size_t i = 0; unsigned char s1, s2; @@ -7842,6 +7929,71 @@ while (1) { return 0; } +/* strlcat() and strlcpy() are not available on all platforms */ +/* Copyright (c) 1998 Todd C. Miller */ +/* + * Appends src to string dst of size siz (unlike strncat, siz is the + * full size of dst, not space left). At most siz-1 characters + * will be copied. Always NUL terminates (unless siz <= strlen(dst)). + * Returns strlen(src) + MIN(siz, strlen(initial dst)). + * If retval >= siz, truncation occurred. + */ +size_t sim_strlcat(char *dst, const char *src, size_t size) +{ +char *d = dst; +const char *s = src; +size_t n = size; +size_t dlen; + +/* Find the end of dst and adjust bytes left but don't go past end */ +while (n-- != 0 && *d != '\0') + d++; +dlen = d - dst; +n = size - dlen; + +if (n == 0) + return (dlen + strlen(s)); +while (*s != '\0') { + if (n != 1) { + *d++ = *s; + n--; + } + s++; + } +*d = '\0'; + +return (dlen + (s - src)); /* count does not include NUL */ +} + +/* + * Copy src to string dst of size siz. At most siz-1 characters + * will be copied. Always NUL terminates (unless siz == 0). + * Returns strlen(src); if retval >= siz, truncation occurred. + */ +size_t sim_strlcpy (char *dst, const char *src, size_t size) +{ +char *d = dst; +const char *s = src; +size_t n = size; + +/* Copy as many bytes as will fit */ +if (n != 0) { + while (--n != 0) { + if ((*d++ = *s++) == '\0') + break; + } + } + + /* Not enough room in dst, add NUL and traverse rest of src */ + if (n == 0) { + if (size != 0) + *d = '\0'; /* NUL-terminate dst */ + while (*s++) + ; + } +return (s - src - 1); /* count does not include NUL */ +} + /* get_yn yes/no question Inputs: @@ -8174,6 +8326,7 @@ while (size--) { case '\'': if (quote == *iptr) *tptr++ = '\\'; + /* fall through */ default: if (sim_isprint (*iptr)) *tptr++ = *iptr; @@ -10889,7 +11042,8 @@ while (1) { /* format passed string, arg break; } -if (sim_do_ocptr[sim_do_depth]) { +if ((sim_do_ocptr[sim_do_depth]) && + ((stat & ~SCPE_NOMESSAGE) != SCPE_OK)) { if (!sim_do_echo && !sim_quiet && !inhibit_message) sim_printf("%s> %s\n", do_position(), sim_do_ocptr[sim_do_depth]); else { diff --git a/scp.h b/scp.h index 5484599..0b3228c 100644 --- a/scp.h +++ b/scp.h @@ -91,6 +91,7 @@ t_stat pwd_cmd (int32 flg, CONST char *cptr); t_stat dir_cmd (int32 flg, CONST char *cptr); t_stat type_cmd (int32 flg, CONST char *cptr); t_stat delete_cmd (int32 flg, CONST char *cptr); +t_stat copy_cmd (int32 flg, CONST char *cptr); t_stat brk_cmd (int32 flag, CONST char *ptr); t_stat do_cmd (int32 flag, CONST char *ptr); t_stat goto_cmd (int32 flag, CONST char *ptr); @@ -147,6 +148,7 @@ const char *sim_dname (DEVICE *dptr); const char *sim_uname (UNIT *dptr); const char *sim_set_uname (UNIT *uptr, const char *uname); t_stat get_yn (const char *ques, t_stat deflt); +char *sim_trim_endspc (char *cptr); int sim_isspace (char c); int sim_islower (char c); int sim_isalpha (char c); @@ -156,6 +158,12 @@ int sim_isgraph (char c); int sim_isalnum (char c); int sim_strncasecmp (const char *string1, const char *string2, size_t len); int sim_strcasecmp (const char *string1, const char *string2); +size_t sim_strlcat (char *dst, const char *src, size_t size); +size_t sim_strlcpy (char *dst, const char *src, size_t size); +#define strlcpy(dst, src, size) sim_strlcpy((dst), (src), (size)) +#define strlcat(dst, src, size) sim_strlcat((dst), (src), (size)) +#define strncasecmp(str1, str2, len) sim_strncasecmp((str1), (str2), (len)) +#define strcasecmp(str1, str2) sim_strcasecmp ((str1), (str2)) CONST char *get_sim_opt (int32 opt, CONST char *cptr, t_stat *st); const char *put_switches (char *buf, size_t bufsize, uint32 sw); CONST char *get_glyph (const char *iptr, char *optr, char mchar); @@ -304,10 +312,10 @@ void sim_aio_activate (ACTIVATE_API caller, UNIT *uptr, int32 event_time); /* VM interface */ -extern char sim_name[]; +extern char sim_name[64]; extern DEVICE *sim_devices[]; extern REG *sim_PC; -extern const char *sim_stop_messages[]; +extern const char *sim_stop_messages[SCPE_BASE]; extern t_stat sim_instr (void); extern t_stat sim_load (FILE *ptr, CONST char *cptr, CONST char *fnam, int flag); extern int32 sim_emax; diff --git a/sim_console.c b/sim_console.c index 47f9f50..5bb132a 100644 --- a/sim_console.c +++ b/sim_console.c @@ -815,7 +815,7 @@ CTAB *cmdp = NULL; t_stat stat_nomessage = stat & SCPE_NOMESSAGE; /* extract possible message supression flag */ cmdp = find_cmd (cmd); -stat = SCPE_BARE_STATUS(stat); /* remove possible flag */ +stat = SCPE_BARE_STATUS(stat); /* remove possible flag */ if (!stat_nomessage) { if (cmdp && (cmdp->message)) /* special message handler? */ cmdp->message (NULL, stat); /* let it deal with display */ @@ -861,7 +861,7 @@ CONST char *cptr; int32 saved_switches = sim_switches; t_stat stat; -strcpy (cbuf, sim_rem_command_buf); +strlcpy (cbuf, sim_rem_command_buf, sizeof (cbuf)); while (isspace(cbuf[0])) memmove (cbuf, cbuf+1, strlen(cbuf+1)+1); /* skip leading whitespace */ sim_sub_args (cbuf, sizeof(cbuf), argv); @@ -1666,7 +1666,7 @@ for (i=(was_active_command ? sim_rem_cmd_active_line : 0); sim_quiet = 1; sim_set_logoff (0, NULL); sim_quiet = save_quiet; - remove (sim_rem_con_temp_name); + (void)remove (sim_rem_con_temp_name); sim_log_temp = FALSE; } else { @@ -1936,7 +1936,7 @@ if (sim_rem_master_mode) { sim_quiet = 1; sim_set_logoff (0, NULL); sim_quiet = save_quiet; - remove (sim_rem_con_temp_name); + (void)remove (sim_rem_con_temp_name); sim_log_temp = FALSE; } stat |= stat_nomessage; @@ -3598,8 +3598,8 @@ static t_stat sim_os_ttinit (void) { SIOUXSettings.toppixel = 42; SIOUXSettings.leftpixel = 6; iBeamCursorH = GetCursor(iBeamCursor); - strcat(title, sim_name); - strcat(title, " Simulator"); + strlcat(title, sim_name, sizeof(title)); + strlcat(title, " Simulator", sizeof(title)); title[0] = strlen(title) - 1; /* Pascal string done */ for (i = 0; i <= title[0]; i++) { /* copy to unsigned char */ ptitle[i] = title[i]; diff --git a/sim_defs.h b/sim_defs.h index 0730cad..6037ffd 100644 --- a/sim_defs.h +++ b/sim_defs.h @@ -1,6 +1,6 @@ /* sim_defs.h: simulator definitions - Copyright (c) 1993-2008, Robert M Supnik + Copyright (c) 1993-2016, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -23,6 +23,9 @@ used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from Robert M Supnik. + 25-Sep-16 RMS Removed KBD_WAIT and friends + 08-Mar-16 RMS Added shutdown invisible switch + 24-Dec-14 JDB Added T_ADDR_FMT 05-Jan-11 MP Added Asynch I/O support 18-Jan-11 MP Added log file reference count support 21-Jul-08 RMS Removed inlining support @@ -396,12 +399,9 @@ typedef uint32 t_addr; /* Default timing parameters */ #define KBD_POLL_WAIT 5000 /* keyboard poll */ -#define KBD_MAX_WAIT 500000 #define SERIAL_IN_WAIT 100 /* serial in time */ #define SERIAL_OUT_WAIT 100 /* serial output */ #define NOQUEUE_WAIT 1000000 /* min check time */ -#define KBD_LIM_WAIT(x) (((x) > KBD_MAX_WAIT)? KBD_MAX_WAIT: (x)) -#define KBD_WAIT(w,s) ((w)? w: KBD_LIM_WAIT (s)) /* Convert switch letter to bit mask */ diff --git a/sim_disk.c b/sim_disk.c index fc66745..6f5838a 100644 --- a/sim_disk.c +++ b/sim_disk.c @@ -1086,7 +1086,7 @@ ODS2_FileHeader Header; ODS2_Retreval *Retr; ODS2_SCB Scb; uint16 CheckSum1, CheckSum2; -uint32 ScbLbn; +uint32 ScbLbn = 0; t_offset ret_val = (t_offset)-1; if ((dptr = find_dev_from_unit (uptr)) == NULL) @@ -1379,7 +1379,7 @@ if (sim_switches & SWMASK ('C')) { /* create vhd disk & cop if (!copy_buf) { sim_vhd_disk_close(vhd); - remove (gbuf); + (void)remove (gbuf); return SCPE_MEM; } for (lba = 0; (lba < total_sectors) && (r == SCPE_OK); lba += sects) { @@ -1411,7 +1411,7 @@ if (sim_switches & SWMASK ('C')) { /* create vhd disk & cop if (!verify_buf) { sim_vhd_disk_close(vhd); - remove (gbuf); + (void)remove (gbuf); free (copy_buf); return SCPE_MEM; } @@ -1623,7 +1623,7 @@ if ((created) && (!copied)) { free (secbuf); if (r != SCPE_OK) { sim_disk_detach (uptr); /* report error now */ - remove (cptr); /* remove the create file */ + (void)remove (cptr); /* remove the created file */ return SCPE_OPENERR; } if (sim_switches & SWMASK ('I')) { /* Initialize To Sector Address */ @@ -1636,7 +1636,7 @@ if ((created) && (!copied)) { if (!init_buf) { sim_disk_detach (uptr); /* report error now */ - remove (cptr); + (void)remove (cptr); return SCPE_MEM; } for (lba = 0; (lba < total_sectors) && (r == SCPE_OK); lba += sects) { @@ -1652,7 +1652,7 @@ if ((created) && (!copied)) { if (r != SCPE_OK) { free (init_buf); sim_disk_detach (uptr); /* report error now */ - remove (cptr); /* remove the create file */ + (void)remove (cptr); /* remove the created file */ return SCPE_OPENERR; } if (!sim_quiet) @@ -2605,7 +2605,8 @@ t_offset pos, size; pos = (t_offset)lseek ((int)((long)f), (off_t)0, SEEK_CUR); size = (t_offset)lseek ((int)((long)f), (off_t)0, SEEK_END); -lseek ((int)((long)f), (off_t)pos, SEEK_SET); +if (pos != (t_offset)-1) + (void)lseek ((int)((long)f), (off_t)pos, SEEK_SET); return size; } @@ -3169,15 +3170,15 @@ static uint32 NtoHl(uint32 value) { uint8 *l = (uint8 *)&value; -return l[3] | (l[2]<<8) | (l[1]<<16) | (l[0]<<24); +return (uint32)l[3] | ((uint32)l[2]<<8) | ((uint32)l[1]<<16) | ((uint32)l[0]<<24); } static uint64 NtoHll(uint64 value) { uint8 *l = (uint8 *)&value; -uint64 highresult = l[3] | (l[2]<<8) | (l[1]<<16) | (l[0]<<24); -uint32 lowresult = l[7] | (l[6]<<8) | (l[5]<<16) | (l[4]<<24); +uint64 highresult = (uint64)l[3] | ((uint64)l[2]<<8) | ((uint64)l[1]<<16) | ((uint64)l[0]<<24); +uint32 lowresult = (uint64)l[7] | ((uint64)l[6]<<8) | ((uint64)l[5]<<16) | ((uint64)l[4]<<24); return (highresult << 32) | lowresult; } #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ @@ -3234,8 +3235,7 @@ int Return = 0; VHD_Footer sHeader; struct stat statb; -if (sFooter) - memset(sFooter, '\0', sizeof(*sFooter)); +memset(sFooter, '\0', sizeof(*sFooter)); if (sDynamic) memset(sDynamic, '\0', sizeof(*sDynamic)); if (aBAT) @@ -3652,7 +3652,7 @@ static FILE *sim_vhd_disk_merge (const char *szVHDPath, char **ParentVHD) continue; ++NeededBlock; BlockOffset = SectorSize*((uint64)(NtoHl (hVHD->BAT[BlockNumber]) + BitMapSectors)); - if ((BlockNumber*SectorsPerBlock + BlockSectors) > ((uint64)NtoHll (hVHD->Footer.CurrentSize))/SectorSize) + if (((uint64)BlockNumber*SectorsPerBlock + BlockSectors) > ((uint64)NtoHll (hVHD->Footer.CurrentSize))/SectorSize) BlockSectors = (uint32)(((uint64)NtoHll (hVHD->Footer.CurrentSize))/SectorSize - (BlockNumber*SectorsPerBlock)); if (ReadFilePosition(hVHD->File, BlockData, @@ -3680,7 +3680,7 @@ static FILE *sim_vhd_disk_merge (const char *szVHDPath, char **ParentVHD) sim_printf ("Merged %dMB. 100%% complete.\n", (int)((((float)NeededBlock)*SectorsPerBlock)*SectorSize/1000000)); fclose (hVHD->File); hVHD->File = NULL; - remove (szVHDPath); + (void)remove (szVHDPath); *ParentVHD = (char*) malloc (strlen (hVHD->ParentVHDPath)+1); strcpy (*ParentVHD, hVHD->ParentVHDPath); } @@ -3958,7 +3958,7 @@ if (File) fclose (File); if (Status) { if (Status != EEXIST) - remove (szVHDPath); + (void)remove (szVHDPath); } else { hVHD = (VHDHANDLE)sim_vhd_disk_open (szVHDPath, "rb+"); @@ -4225,7 +4225,7 @@ sim_vhd_disk_close ((FILE *)hVHD); hVHD = NULL; if (Status) { if ((EEXIST != Status) && (ENOENT != Status)) - remove (szVHDPath); + (void)remove (szVHDPath); } else { hVHD = (VHDHANDLE)sim_vhd_disk_open (szVHDPath, "rb+"); diff --git a/sim_ether.c b/sim_ether.c index 4b7b25d..47cf978 100644 --- a/sim_ether.c +++ b/sim_ether.c @@ -907,7 +907,7 @@ void ethq_insert_data(ETH_QUE* que, int32 type, const uint8 *data, int used, siz item->packet.len = len; item->packet.used = used; item->packet.crc_len = crc_len; - if (MAX (len, crc_len) <= sizeof (item->packet.msg) - ETH_CRC_SIZE) { + if (MAX (len, crc_len) <= sizeof (item->packet.msg)) { memcpy(item->packet.msg, data, ((len > crc_len) ? len : crc_len)); if (crc_data && (crc_len > len)) memcpy(&item->packet.msg[len], crc_data, ETH_CRC_SIZE); @@ -1144,7 +1144,7 @@ int load_pcap(void) { char npcap_path[512] = ""; if (p_GetSystemDirectory (npcap_path, sizeof(npcap_path) - 7)) - strcat (npcap_path, "\\Npcap"); + strlcat (npcap_path, "\\Npcap", sizeof(npcap_path)); if (p_SetDllDirectory(npcap_path)) hLib = LoadLibraryA(lib_name); p_SetDllDirectory (NULL); diff --git a/sim_fio.c b/sim_fio.c index 258178d..38a1926 100644 --- a/sim_fio.c +++ b/sim_fio.c @@ -375,6 +375,34 @@ return sim_fseeko (st, (t_offset)offset, whence); } #if defined(_WIN32) +static const char * +GetErrorText(DWORD dwError) +{ +static char szMsgBuffer[2048]; +DWORD dwStatus; + +dwStatus = FormatMessageA (FORMAT_MESSAGE_FROM_SYSTEM| + FORMAT_MESSAGE_IGNORE_INSERTS, // __in DWORD dwFlags, + NULL, // __in_opt LPCVOID lpSource, + dwError, // __in DWORD dwMessageId, + 0, // __in DWORD dwLanguageId, + szMsgBuffer, // __out LPTSTR lpBuffer, + sizeof (szMsgBuffer) -1, // __in DWORD nSize, + NULL); // __in_opt va_list *Arguments +if (0 == dwStatus) + snprintf(szMsgBuffer, sizeof(szMsgBuffer) - 1, "Error Code: 0x%X", dwError); +while (sim_isspace (szMsgBuffer[strlen (szMsgBuffer)-1])) + szMsgBuffer[strlen (szMsgBuffer) - 1] = '\0'; +return szMsgBuffer; +} + +t_stat sim_copyfile (const char *source_file, const char *dest_file, t_bool overwrite_existing) +{ +if (CopyFileA (source_file, dest_file, !overwrite_existing)) + return SCPE_OK; +return sim_messagef (SCPE_ARG, "Error Copying '%s' to '%s': %s\n", source_file, dest_file, GetErrorText (GetLastError ())); +} + #include int sim_set_fsize (FILE *fptr, t_addr size) { @@ -439,6 +467,54 @@ return ftruncate(fileno(fptr), (off_t)size); #include #include +#if HAVE_UTIME +#include +#endif + +t_stat sim_copyfile (const char *source_file, const char *dest_file, t_bool overwrite_existing) +{ +FILE *fIn = NULL, *fOut = NULL; +t_stat st = SCPE_OK; +char *buf = NULL; +size_t bytes; + +fIn = sim_fopen (source_file, "rb"); +if (!fIn) { + st = sim_messagef (SCPE_ARG, "Can't open '%s' for input: %s\n", source_file, strerror (errno)); + goto Cleanup_Return; + } +fOut = sim_fopen (dest_file, "wb"); +if (!fOut) { + st = sim_messagef (SCPE_ARG, "Can't open '%s' for output: %s\n", dest_file, strerror (errno)); + goto Cleanup_Return; + } +buf = (char *)malloc (BUFSIZ); +while ((bytes = fread (buf, 1, BUFSIZ, fIn))) + fwrite (buf, 1, bytes, fOut); +Cleanup_Return: +free (buf); +if (fIn) + fclose (fIn); +if (fOut) + fclose (fOut); +#if defined(HAVE_UTIME) +if (st == SCPE_OK) { + struct stat statb; + + if (!stat (source_file, &statb)) { + struct utimbuf utim; + + utim.actime = statb.st_atime; + utim.modtime = statb.st_mtime; + if (utime (dest_file, &utim)) + st = SCPE_IOERR; + } + else + st = SCPE_IOERR; + } +#endif +return st; +} int sim_set_fifo_nonblock (FILE *fptr) { diff --git a/sim_fio.h b/sim_fio.h index 32d5ce8..e372aba 100644 --- a/sim_fio.h +++ b/sim_fio.h @@ -66,6 +66,7 @@ uint32 sim_fsize_name (const char *fname); t_offset sim_ftell (FILE *st); t_offset sim_fsize_ex (FILE *fptr); t_offset sim_fsize_name_ex (const char *fname); +t_stat sim_copyfile (const char *source_file, const char *dest_file, t_bool overwrite_existing); void sim_buf_swap_data (void *bptr, size_t size, size_t count); void sim_buf_copy_swapped (void *dptr, const void *bptr, size_t size, size_t count); typedef struct SHMEM SHMEM; diff --git a/sim_frontpanel.c b/sim_frontpanel.c index 30ef6f2..2f3b0e5 100644 --- a/sim_frontpanel.c +++ b/sim_frontpanel.c @@ -235,7 +235,7 @@ return p; #endif static void __panel_debug (PANEL *p, int dbits, const char *fmt, const char *buf, int bufsize, ...) GCC_FMT_ATTR(3, 6); -#define _panel_debug(p, dbits, fmt, buf, bufsize, ...) do { if (p && p->Debug && (dbits & p->debug)) __panel_debug (p, dbits, fmt, buf, bufsize, ##__VA_ARGS__);} while (0) +#define _panel_debug(p, dbits, fmt, buf, bufsize, ...) do { if (p && p->Debug && ((dbits) & p->debug)) __panel_debug (p, dbits, fmt, buf, bufsize, ##__VA_ARGS__);} while (0) static void __panel_debug (PANEL *p, int dbits, const char *fmt, const char *buf, int bufsize, ...) { @@ -714,6 +714,7 @@ if (debug_file) { free (buf); buf = NULL; fclose (fIn); + fIn = NULL; } if (!simulator_panel) { #if defined(_WIN32) @@ -1942,9 +1943,9 @@ while ((p->sock != INVALID_SOCKET) && data = strtoull (e, NULL, 16); if (little_endian) - memcpy (p->regs[i].addr, &data, p->regs[i].size); + memcpy (r->addr, &data, r->size); else - memcpy (p->regs[i].addr, ((char *)&data) + sizeof(data)-p->regs[i].size, p->regs[i].size); + memcpy (r->addr, ((char *)&data) + sizeof(data)-r->size, r->size); r = NULL; } s = eol; @@ -2002,6 +2003,7 @@ while ((p->sock != INVALID_SOCKET) && if (p->callback) { pthread_mutex_unlock (&p->io_lock); p->callback (p, p->simulation_time, p->callback_context); + pthread_mutex_lock (&p->io_lock); } } if (!strcmp (s + strlen (sim_prompt), register_get_echo)) { @@ -2137,7 +2139,8 @@ while ((p->sock != INVALID_SOCKET) && for (c = strchr (repeat, '\r'); c != NULL; c = strchr (c, '\r')) *c = ';'; /* replace carriage returns with semicolons */ c = strstr (repeat, register_get_echo); /* remove register_done_echo string and */ - strcpy (c, register_repeat_echo); /* replace it with the register_repeat_echo string */ + if (c) /* always true */ + strcpy (c, register_repeat_echo); /* replace it with the register_repeat_echo string */ if (_panel_sendf (p, &cmd_stat, NULL, "%s", repeat)) { pthread_mutex_lock (&p->io_lock); free (repeat); diff --git a/sim_sock.c b/sim_sock.c index 8a2dbd7..858a74b 100644 --- a/sim_sock.c +++ b/sim_sock.c @@ -1127,9 +1127,9 @@ FD_ZERO (er_p); FD_SET (sock, rw_p); FD_SET (sock, er_p); if (rd) - select ((int) sock + 1, rw_p, NULL, er_p, &zero); + (void)select ((int) sock + 1, rw_p, NULL, er_p, &zero); else - select ((int) sock + 1, NULL, rw_p, er_p, &zero); + (void)select ((int) sock + 1, NULL, rw_p, er_p, &zero); if (FD_ISSET (sock, er_p)) return -1; if (FD_ISSET (sock, rw_p)) { @@ -1200,8 +1200,8 @@ if (socknamebuf) *socknamebuf = (char *)calloc(1, NI_MAXHOST+NI_MAXSERV+4); if (peernamebuf) *peernamebuf = (char *)calloc(1, NI_MAXHOST+NI_MAXSERV+4); -getsockname (sock, (struct sockaddr *)&sockname, &socknamesize); -getpeername (sock, (struct sockaddr *)&peername, &peernamesize); +(void)getsockname (sock, (struct sockaddr *)&sockname, &socknamesize); +(void)getpeername (sock, (struct sockaddr *)&peername, &peernamesize); if (socknamebuf != NULL) { _sim_getaddrname ((struct sockaddr *)&sockname, (size_t)socknamesize, hostbuf, portbuf); sprintf(*socknamebuf, "[%s]:%s", hostbuf, portbuf); diff --git a/sim_tape.c b/sim_tape.c index b2085fd..c238655 100644 --- a/sim_tape.c +++ b/sim_tape.c @@ -129,6 +129,8 @@ static t_stat sim_tape_simh_check (UNIT *uptr); static t_stat sim_tape_e11_check (UNIT *uptr); static t_addr sim_tape_tpc_fnd (UNIT *uptr, t_addr *map); static void sim_tape_data_trace (UNIT *uptr, const uint8 *data, size_t len, const char* txt, int detail, uint32 reason); +static t_stat tape_erase_fwd (UNIT *uptr, t_mtrlnt gap_size); +static t_stat tape_erase_rev (UNIT *uptr, t_mtrlnt gap_size); struct tape_context { @@ -527,13 +529,14 @@ return SCPE_OK; t_stat sim_tape_detach (UNIT *uptr) { struct tape_context *ctx; -uint32 f = MT_GET_FMT (uptr); +uint32 f; t_stat r; t_bool auto_format = FALSE; if (uptr == NULL) return SCPE_IERR; ctx = (struct tape_context *)uptr->tape_ctx; +f = MT_GET_FMT (uptr); if ((ctx == NULL) || !(uptr->flags & UNIT_ATT)) return SCPE_IERR; @@ -1620,6 +1623,44 @@ AIO_CALL(TOP_RDRR, NULL, NULL, NULL, 0, 0, gaplen, 0, NULL, callback); return r; } +/* Erase a record forward. + + An erase gap is written in the forward direction on the tape unit specified + by "uptr" for a length corresponding to a record containing the number of + bytes specified by "bc", and the status of the operation is returned. The + resulting gap will occupy "bc" bytes plus the size of the record length + metadata. This function may be used to erase a record of length "n" in place + by requesting a gap of length "n". After erasure, the tape will be + positioned at the end of the gap. +*/ + +t_stat sim_tape_errecf (UNIT *uptr, t_mtrlnt bc) +{ +const t_mtrlnt meta_size = sizeof (t_mtrlnt); /* the number of bytes per metadatum */ +const t_mtrlnt gap_size = bc + 2 * meta_size; /* the requested gap size in bytes */ + +return MTSE_IOERR; /* stub return */ +} + +/* Erase a record reverse. + + An erase gap is written in the reverse direction on the tape unit specified + by "uptr" for a length corresponding to a record containing the number of + bytes specified by "bc", and the status of the operation is returned. The + resulting gap will occupy "bc" bytes plus the size of the record length + metadata. This function may be used to erase a record of length "n" in place + by requesting a gap of length "n". After erasure, the tape will be + positioned at the start of the gap. +*/ + +t_stat sim_tape_errecr (UNIT *uptr, t_mtrlnt bc) +{ +const t_mtrlnt meta_size = sizeof (t_mtrlnt); /* the number of bytes per metadatum */ +const t_mtrlnt gap_size = bc + 2 * meta_size; /* the requested gap size in bytes */ + +return MTSE_IOERR; /* stub return */ +} + /* Space record forward Inputs: diff --git a/sim_tape.h b/sim_tape.h index c1cf6a0..9c5fc88 100644 --- a/sim_tape.h +++ b/sim_tape.h @@ -23,6 +23,11 @@ used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from Robert M Supnik. + 18-Jul-16 JDB Added sim_tape_errecf, sim_tape_errecr functions + 15-Dec-14 JDB Added tape density validity flags + 04-Nov-14 JDB Added tape density flags + 11-Oct-14 JDB Added reverse read half gap, set/show density + 22-Sep-14 JDB Added tape runaway support 23-Jan-12 MP Added support for Logical EOT detection while positioning 05-Feb-11 MP Add Asynch I/O support 30-Aug-06 JDB Added erase gap support @@ -170,6 +175,8 @@ t_stat sim_tape_wreomrw (UNIT *uptr); t_stat sim_tape_wreomrw_a (UNIT *uptr, TAPE_PCALLBACK callback); t_stat sim_tape_wrgap (UNIT *uptr, uint32 gaplen); t_stat sim_tape_wrgap_a (UNIT *uptr, uint32 gaplen, TAPE_PCALLBACK callback); +t_stat sim_tape_errecf (UNIT *uptr, t_mtrlnt bc); +t_stat sim_tape_errecr (UNIT *uptr, t_mtrlnt bc); t_stat sim_tape_sprecf (UNIT *uptr, t_mtrlnt *bc); t_stat sim_tape_sprecf_a (UNIT *uptr, t_mtrlnt *bc, TAPE_PCALLBACK callback); t_stat sim_tape_sprecsf (UNIT *uptr, uint32 count, uint32 *skipped);