diff --git a/Visual Studio Projects/Pre-Build-Event.cmd b/Visual Studio Projects/Pre-Build-Event.cmd index a5c02bb..1261014 100644 --- a/Visual Studio Projects/Pre-Build-Event.cmd +++ b/Visual Studio Projects/Pre-Build-Event.cmd @@ -29,6 +29,7 @@ rem rem Everything implicitly requires BUILD to also be set to have rem any meaning, it always gets set. set _X_BUILD=BUILD +set _X_REQUIRED_WINDOWS_BUILD=20191213 call :FindVCVersion _VC_VER set _PDB=%~dpn1.pdb @@ -127,7 +128,7 @@ if not exist ..\..\windows-build goto _notice1 if not exist ..\..\windows-build/lib goto _notice2 set _X_WINDOWS_BUILD= for /F "usebackq tokens=2" %%i in (`findstr /C:"WINDOWS-BUILD" ..\..\windows-build\Windows-Build_Versions.txt`) do SET _X_WINDOWS_BUILD=%%i -if "%_X_WINDOWS_BUILD%" LSS "20190815" goto _notice2 +if "%_X_WINDOWS_BUILD%" LSS "%_X_REQUIRED_WINDOWS_BUILD%" goto _notice2 set _X_LAST_WINDOWS_BUILD= if exist Pre-Build-Event.last-windows-build-version.txt for /F "usebackq tokens=2" %%i in (`findstr /C:"WINDOWS-BUILD" Pre-Build-Event.last-windows-build-version.txt`) do SET _X_LAST_WINDOWS_BUILD=%%i if "%_X_WINDOWS_BUILD%" EQU "%_X_LAST_WINDOWS_BUILD%" goto _new_or_same_windows_build diff --git a/makefile b/makefile index bd21b40..3a4c9c6 100644 --- a/makefile +++ b/makefile @@ -554,6 +554,13 @@ ifeq ($(WIN32),) #*nix Environments (&& cygwin) OS_CCDEFS += -DHAVE_LIBPNG OS_LDFLAGS += -lpng $(info using libpng: $(call find_lib,png) $(call find_include,png)) + ifneq (,$(call find_include,zlib)) + ifneq (,$(call find_lib,z)) + OS_CCDEFS += -DHAVE_ZLIB + OS_LDFLAGS += -lz + $(info using zlib: $(call find_lib,z) $(call find_include,zlib)) + endif + endif endif endif ifneq (,$(call find_include,glob)) diff --git a/scp.c b/scp.c index 762e7eb..ac8921c 100644 --- a/scp.c +++ b/scp.c @@ -1186,6 +1186,15 @@ static const char simh_help[] = #define HLP_CP "*Commands Copying_Files CP" "3CP\n" "++CP sfile dfile copies a file\n" + "2Renaming Files\n" +#define HLP_RENAME "*Commands Renaming_Files RENAME" + "3RENAME\n" + "++RENAME origname newname renames a file\n" +#define HLP_MOVE "*Commands Renaming_Files MOVE" + "3MOVE\n" + "++MOVE origname newname renames a file\n" + "+or\n" + "++MV origname newname renames a file\n" "2Creating Directories\n" #define HLP_MKDIR "*Commands Creating_Directories MKDIR" "3MKDIR\n" @@ -1966,6 +1975,8 @@ static const char simh_help[] = " which don't specify an explicit DELAY parameter along with a string\n" " If a SEND command is processed and no DELAY value has been specified,\n" " the default value of the delay parameter is 1000.\n" + " The value n can be specified with a suffix of k or m which indicates\n" + " a multiplier of 1000 or 1000000 respectively\n" /***************** 80 character line width template *************************/ "4After\n" " Specifies an integer (>=0) representing a minimal number of instructions\n" @@ -1976,6 +1987,8 @@ static const char simh_help[] = " which don't specify an explicit AFTER parameter along with a string\n" " If a SEND command is processed and no AFTER value has been specified,\n" " the default value of the delay parameter is the DELAY parameter value.\n" + " The value n can be specified with a suffix of k or m which indicates\n" + " a multiplier of 1000 or 1000000 respectively\n" "4Escaping String Data\n" " The following character escapes are explicitly supported:\n" "++\\r Sends the ASCII Carriage Return character (Decimal value 13)\n" @@ -2025,7 +2038,9 @@ static const char simh_help[] = " Data which is output prior to the definition of an expect rule is not\n" " eligible to be matched against.\n\n" " The NOEXPECT command removes a previously defined EXPECT command for the\n" - " console or a specific multiplexer line.\n\n" + " console or a specific multiplexer line. A NOEXPECT command, without a\n" + " specific mention of a particular EXPECT match string, will remove all\n" + " currently defined EXPECT match rules.\n\n" " The SHOW EXPECT command displays all of the pending EXPECT state for\n" " the console or a specific multiplexer line.\n" /***************** 80 character line width template *************************/ @@ -2109,6 +2124,8 @@ static const char simh_help[] = " enough for more than one expect rule to match before an earlier haltafter\n" " delay has expired, only a single EXPECT rule can be defined if a non-zero\n" " HaltAfter parameter has been set.\n" + " The value n can be specified with a suffix of k or m which indicates\n" + " a multiplier of 1000 or 1000000 respectively\n" /***************** 80 character line width template *************************/ #define HLP_SLEEP "*Commands Executing_Command_Files Pausing_Command_Execution" "3Pausing Command Execution\n" @@ -2344,6 +2361,9 @@ static CTAB cmd_table[] = { { "RM", &delete_cmd, 0, HLP_RM, NULL, NULL }, { "COPY", ©_cmd, 0, HLP_COPY, NULL, NULL }, { "CP", ©_cmd, 0, HLP_CP, NULL, NULL }, + { "RENAME", &rename_cmd, 0, HLP_RENAME, NULL, NULL }, + { "MOVE", &rename_cmd, 0, HLP_MOVE, NULL, NULL }, + { "MV", &rename_cmd, 0, HLP_MOVE, NULL, NULL }, { "MKDIR", &mkdir_cmd, 0, HLP_MKDIR, NULL, NULL }, { "RMDIR", &rmdir_cmd, 0, HLP_RMDIR, NULL, NULL }, { "SET", &set_cmd, 0, HLP_SET, NULL, NULL }, @@ -3410,6 +3430,7 @@ return SCPE_OK; t_stat spawn_cmd (int32 flag, CONST char *cptr) { t_stat status; + if ((cptr == NULL) || (strlen (cptr) == 0)) cptr = getenv("SHELL"); if ((cptr == NULL) || (strlen (cptr) == 0)) @@ -4728,9 +4749,9 @@ delay = get_default_env_parameter (dev_name, "SIM_SEND_DELAY", SEND_DEFAULT_DELA after = get_default_env_parameter (dev_name, "SIM_SEND_AFTER", delay); while (*cptr) { if ((!strncmp(gbuf, "DELAY=", 6)) && (gbuf[6])) { - delay = (uint32)get_uint (&gbuf[6], 10, 10000000, &r); + delay = (uint32)get_uint (&gbuf[6], 10, 2000000000, &r); if (r != SCPE_OK) - return sim_messagef (SCPE_ARG, "Invalid Delay Value\n"); + return sim_messagef (SCPE_ARG, "Invalid Delay Value: %s\n", &gbuf[6]); cptr = tptr; tptr = get_glyph (cptr, gbuf, ','); delay_set = TRUE; @@ -4739,9 +4760,9 @@ while (*cptr) { continue; } if ((!strncmp(gbuf, "AFTER=", 6)) && (gbuf[6])) { - after = (uint32)get_uint (&gbuf[6], 10, 10000000, &r); + after = (uint32)get_uint (&gbuf[6], 10, 2000000000, &r); if (r != SCPE_OK) - return sim_messagef (SCPE_ARG, "Invalid After Value\n"); + return sim_messagef (SCPE_ARG, "Invalid After Value: %s\n", &gbuf[6]); cptr = tptr; tptr = get_glyph (cptr, gbuf, ','); after_set = TRUE; @@ -6574,17 +6595,39 @@ if ((stat == SCPE_OK) && (copy_state.count)) return copy_state.stat; } +t_stat rename_cmd (int32 flg, CONST char *cptr) +{ +char sname[CBUFSIZE], dname[CBUFSIZE]; + +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, dname, 0); +if (0 == rename (sname, dname)) + return SCPE_OK; +return sim_messagef (SCPE_ARG, "Can't rename '%s' to '%s': %s\n\n", sname, dname, strerror (errno)); +} + t_stat mkdir_cmd (int32 flg, CONST char *cptr) { char path[CBUFSIZE]; char *c; struct stat filestat; +GET_SWITCHES (cptr); /* get switches */ if ((!cptr) || (*cptr == '\0')) return sim_messagef (SCPE_2FARG, "Must specify a directory path\n"); strlcpy (path, cptr, sizeof (path)); while ((c = strchr (path, '\\'))) *c = '/'; +if (path[strlen (path) - 1] == '/') /* trim any trailing / from the path */ + path[strlen (path) - 1] = '\0'; +while ((c = strstr (path, "//"))) + memmove (c, c + 1, strlen (c + 1) + 1); /* clean out any empty directories // */ +if ((!stat (path, &filestat)) && (filestat.st_mode & S_IFDIR)) + return sim_messagef (SCPE_OK, "directory %s already exists\n", path); c = path; while ((c = strchr (c, '/'))) { *c = '\0'; @@ -6620,6 +6663,7 @@ return SCPE_OK; t_stat rmdir_cmd (int32 flg, CONST char *cptr) { +GET_SWITCHES (cptr); /* get switches */ if ((!cptr) || (*cptr == '\0')) return sim_messagef (SCPE_2FARG, "Must specify a directory\n"); if (rmdir (cptr)) @@ -7325,8 +7369,10 @@ if (*cptr == 0) /* must be more */ gbuf[sizeof(gbuf)-1] = '\0'; strlcpy (gbuf, cptr, sizeof(gbuf)); sim_trim_endspc (gbuf); -if ((sfile = sim_fopen (gbuf, "wb")) == NULL) - return SCPE_OPENERR; +if ((sfile = sim_fopen (gbuf, "r+b")) == NULL) { /* try existing file */ + if ((sfile = sim_fopen (gbuf, "wb")) == NULL) /* create new empty file */ + return SCPE_OPENERR; + } r = sim_save (sfile); fclose (sfile); return r; @@ -7463,6 +7509,8 @@ for (i = 0; i < (device_count + sim_internal_device_count); i++) {/* loop thru d fputc ('\n', sfile); /* end registers */ } fputc ('\n', sfile); /* end devices */ +if (!ferror (sfile)) + sim_set_fsize (sfile, (t_addr)sim_ftell (sfile)); /* truncate the save file */ return (ferror (sfile))? SCPE_IOERR: SCPE_OK; /* error during save? */ } @@ -9398,7 +9446,17 @@ if ((cptr == tptr) || (val > max)) *status = SCPE_ARG; else { while (sim_isspace (*tptr)) tptr++; - if (*tptr != 0) + if (sim_toupper (*tptr) == 'K') { + val *= 1000; + ++tptr; + } + else { + if (sim_toupper (*tptr) == 'M') { + val *= 1000000; + ++tptr; + } + } + if ((*tptr != 0) || (val > max)) *status = SCPE_ARG; } return val; @@ -11779,9 +11837,9 @@ if (*cptr == '[') { } tptr = get_glyph (cptr, gbuf, ','); if ((!strncmp(gbuf, "HALTAFTER=", 10)) && (gbuf[10])) { - after = (uint32)get_uint (&gbuf[10], 10, 100000000, &r); + after = (uint32)get_uint (&gbuf[10], 10, 2000000000, &r); if (r != SCPE_OK) - return sim_messagef (SCPE_ARG, "Invalid Halt After Value\n"); + return sim_messagef (SCPE_ARG, "Invalid Halt After Value: %s\n", &gbuf[10]); cptr = tptr; after_set = TRUE; } @@ -12277,6 +12335,12 @@ memcpy(snd->buffer+snd->insoff, data, size); snd->insoff += size; snd->delay = (sim_switches & SWMASK ('T')) ? (uint32)((sim_timer_inst_per_sec()*delay)/1000000.0) : delay; snd->after = (sim_switches & SWMASK ('T')) ? (uint32)((sim_timer_inst_per_sec()*after)/1000000.0) : after; +if (sim_switches & SWMASK ('T')) + sim_debug (snd->dbit, snd->dptr, "%d bytes queued for input. Delay %d usecs = %d insts, After %d usecs = %d insts\n", + (int)size, (int)delay, (int)snd->delay, (int)after, (int)snd->after); +else + sim_debug (snd->dbit, snd->dptr, "%d bytes queued for input. Delay=%d, After=%d\n", + (int)size, (int)delay, (int)after); snd->next_time = sim_gtime() + snd->after; return SCPE_OK; } diff --git a/scp.h b/scp.h index b2966d1..8beaa05 100644 --- a/scp.h +++ b/scp.h @@ -95,6 +95,7 @@ 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 rename_cmd (int32 flg, CONST char *cptr); t_stat mkdir_cmd (int32 flg, CONST char *cptr); t_stat rmdir_cmd (int32 flg, CONST char *cptr); t_stat brk_cmd (int32 flag, CONST char *ptr); diff --git a/sim_console.c b/sim_console.c index 41558b2..6a0674b 100644 --- a/sim_console.c +++ b/sim_console.c @@ -182,6 +182,13 @@ int32 sim_del_char = '\b'; /* delete character */ #else int32 sim_del_char = 0177; #endif +t_bool sim_signaled_int_char /* WRU character detected by signal while running */ +#if defined (_WIN32) || defined (_VMS) || defined (__CYGWIN__) + = FALSE; +#else + = TRUE; +#endif +uint32 sim_last_poll_kbd_time; /* time when sim_poll_kbd was called */ extern TMLN *sim_oline; /* global output socket */ static t_stat sim_con_poll_svc (UNIT *uptr); /* console connection poll routine */ @@ -2835,6 +2842,7 @@ t_stat sim_poll_kbd (void) { t_stat c; +sim_last_poll_kbd_time = sim_os_msec (); /* record when this poll happened */ if (sim_send_poll_data (&sim_con_send, &c)) /* injected input characters available? */ return c; if (!sim_rem_master_mode) { diff --git a/sim_console.h b/sim_console.h index 6f27d99..37a1fe0 100644 --- a/sim_console.h +++ b/sim_console.h @@ -127,12 +127,14 @@ int32 sim_tt_outcvt (int32 c, uint32 mode); t_stat sim_tt_settabs (UNIT *uptr, int32 val, CONST char *cptr, void *desc); t_stat sim_tt_showtabs (FILE *st, UNIT *uptr, int32 val, CONST void *desc); -extern int32 sim_rem_cmd_active_line; /* command in progress on line # */ +extern int32 sim_rem_cmd_active_line; /* command in progress on line # */ -extern int32 sim_int_char; /* interrupt character */ -extern int32 sim_brk_char; /* break character */ -extern int32 sim_tt_pchar; /* printable character mask */ -extern int32 sim_del_char; /* delete character */ +extern int32 sim_int_char; /* interrupt character */ +extern int32 sim_brk_char; /* break character */ +extern int32 sim_tt_pchar; /* printable character mask */ +extern int32 sim_del_char; /* delete character */ +extern t_bool sim_signaled_int_char; /* WRU character detected by signal while running */ +extern uint32 sim_last_poll_kbd_time; /* time when sim_poll_kbd was called */ #ifdef __cplusplus } diff --git a/sim_serial.c b/sim_serial.c index 86ae870..74bdfb3 100644 --- a/sim_serial.c +++ b/sim_serial.c @@ -362,7 +362,7 @@ if (serial_open_device_count) { for (i=0; imp->dptr->name, (int)(serial_open_devices[i].line->mp->ldsc-serial_open_devices[i].line), - serial_open_devices[i].line->destination, d ? " {" : "", d ? d : "", d ? ")" : "", serial_open_devices[i].line->serconfig); + serial_open_devices[i].line->destination, ((d != NULL) && (*d != '\0')) ? " (" : "", ((d != NULL) && (*d != '\0')) ? d : "", ((d != NULL) && (*d != '\0')) ? ")" : "", serial_open_devices[i].line->serconfig); } } return SCPE_OK; diff --git a/sim_timer.c b/sim_timer.c index 8c77303..b120716 100644 --- a/sim_timer.c +++ b/sim_timer.c @@ -987,6 +987,11 @@ if (sim_calb_tmr != tmr) { return rtc->currd; } new_rtime = sim_os_msec (); /* wall time */ +if (!sim_signaled_int_char && + ((new_rtime - sim_last_poll_kbd_time) > 500)) { + sim_debug (DBG_CAL, &sim_timer_dev, "sim_rtcn_calb(tmr=%d) gratuitious keyboard poll after %d msecs\n", tmr, (int)(new_rtime - sim_last_poll_kbd_time)); + (void)sim_poll_kbd (); + } ++rtc->calibrations; /* count calibrations */ sim_debug (DBG_TRC, &sim_timer_dev, "sim_rtcn_calb(ticksper=%d, tmr=%d)\n", ticksper, tmr); if (new_rtime < rtc->rtime) { /* time running backwards? */ diff --git a/sim_video.c b/sim_video.c index d0b0488..fe9d6cb 100644 --- a/sim_video.c +++ b/sim_video.c @@ -1871,9 +1871,13 @@ if (1) { snprintf(&SDLVersion[strlen (SDLVersion)], sizeof (SDLVersion) - (strlen (SDLVersion) + 1), ", PNG Version %s", PNG_LIBPNG_VER_STRING); png_destroy_read_struct(&png, NULL, NULL); -#if defined (HAVE_ZLIB) - snprintf(&SDLVersion[strlen (SDLVersion)], sizeof (SDLVersion) - (strlen (SDLVersion) + 1), - ", zlib: %s", zlibVersion()); +#if defined (ZLIB_VERSION) + if (strcmp (ZLIB_VERSION, zlibVersion ())) + snprintf(&SDLVersion[strlen (SDLVersion)], sizeof (SDLVersion) - (strlen (SDLVersion) + 1), + ", zlib: (Compiled: %s, Runtime: %s)", ZLIB_VERSION, zlibVersion ()); + else + snprintf(&SDLVersion[strlen (SDLVersion)], sizeof (SDLVersion) - (strlen (SDLVersion) + 1), + ", zlib: %s", ZLIB_VERSION); #endif } #endif