diff --git a/scp.c b/scp.c index 8146f377..37de4158 100644 --- a/scp.c +++ b/scp.c @@ -1152,13 +1152,15 @@ static const char simh_help1[] = " diagnostic which didn't achieve explicit success or failure within\n" " some user specified time. The RUNLIMIT command provides ways to\n" " limit execution.\n\n" - "++RUNLIMIT n {%C|MICROSECONDS|SECONDS|MINUTES|HOURS}\n" - "++NORUNLIMIT\n\n" + "+RUNLIMIT n{K|M} {%C|MICROSECONDS|SECONDS|MINUTES|HOURS}\n" + "+NORUNLIMIT\n\n" " Equivalently:\n\n" - "++SET RUNLIMIT n {%C|MICROSECONDS|SECONDS|MINUTES|HOURS}\n" - "++SET NORUNLIMIT\n\n" + "+SET RUNLIMIT n{K|M} {%C|MICROSECONDS|SECONDS|MINUTES|HOURS}\n" + "+SET NORUNLIMIT\n\n" + " The value n can be expressed as a bare number or as nK or nM to represent\n" + " thousands or millions of the specified units.\n\n" " The run limit state can be examined with:\n\n" - "++SHOW RUNLIMIT\n\n" + "+SHOW RUNLIMIT\n\n" " If the units of the run limit are not specified, the default units are\n" " %C. Once an execution run limit has been reached, any subsequent\n" " GO, RUN, CONTINUE, STEP or BOOT commands will cause the simulator to\n" @@ -1750,75 +1752,92 @@ static const char simh_help2[] = " %%DATE_MONTH%%, %%DATE_DD%%, %%DATE_D%%, %%DATE_WYYYY%%, %%DATE_WW%%,\n" " %%TIME_HH%%, %%TIME_MM%%, %%TIME_SS%%, %%TIME_MSEC%%, %%STATUS%%, %%TSTATUS%%,\n" " %%SIM_VERIFY%%, %%SIM_QUIET%%, %%SIM_MESSAGE%% %%SIM_MESSAGE%%\n" - " %%SIM_NAME%%, %%SIM_BIN_NAME%%, %%SIM_BIN_PATH%%m %%SIM_OSTYPE%%\n\n" + " %%SIM_NAME%%, %%SIM_BIN_NAME%%, %%SIM_BIN_PATH%% %%SIM_OSTYPE%%,\n" + " %%SIM_RUNTIME%%, %%SIM_RUNTIME_UNITS%%\n\n" "+Token %%0 expands to the command file name.\n" "+Token %%n (n being a single digit) expands to the n'th argument\n" "+Token %%* expands to the whole set of arguments (%%1 ... %%9)\n\n" "+The input sequence \"%%%%\" represents a literal \"%%\". All other\n" "+character combinations are rendered literally.\n\n" "+Omitted parameters result in null-string substitutions.\n\n" - "+Tokens preceeded and followed by %% characters are expanded as environment\n" - "+variables, and if an environment variable isn't found then it can be one of\n" - "+several special variables:\n\n" - "++%%DATE%% yyyy-mm-dd\n" - "++%%TIME%% hh:mm:ss\n" - "++%%DATETIME%% yyyy-mm-ddThh:mm:ss\n" - "++%%LDATE%% mm/dd/yy (Locale Formatted)\n" - "++%%LTIME%% hh:mm:ss am/pm (Locale Formatted)\n" - "++%%CTIME%% Www Mmm dd hh:mm:ss yyyy (Locale Formatted)\n" - "++%%UTIME%% nnnn (Unix time - seconds since 1/1/1970)\n" - "++%%DATE_YYYY%% yyyy (0000-9999)\n" - "++%%DATE_YY%% yy (00-99)\n" - "++%%DATE_MM%% mm (01-12)\n" - "++%%DATE_MMM%% mmm (JAN-DEC)\n" - "++%%DATE_MONTH%% month (January-December)\n" - "++%%DATE_DD%% dd (01-31)\n" - "++%%DATE_WW%% ww (01-53) ISO 8601 week number\n" - "++%%DATE_WYYYY%% yyyy (0000-9999) ISO 8601 week year number\n" - "++%%DATE_D%% d (1-7) ISO 8601 day of week\n" - "++%%DATE_JJJ%% jjj (001-366) day of year\n" - "++%%DATE_19XX_YY%% yy A year prior to 2000 with the same\n" - "++++++++++ calendar days as the current year\n" - "++%%DATE_19XX_YYYY%% yyyy A year prior to 2000 with the same\n" - "++++++++++ calendar days as the current year\n" - "++%%TIME_HH%% hh (00-23)\n" - "++%%TIME_MM%% mm (00-59)\n" - "++%%TIME_SS%% ss (00-59)\n" - "++%%TIME_MSEC%% msec (000-999)\n" - "++%%STATUS%% Status value from the last command executed\n" - "++%%TSTATUS%% The text form of the last status value\n" - "++%%SIM_VERIFY%% The Verify/Verbose mode of the current Do command file\n" - "++%%SIM_VERBOSE%% The Verify/Verbose mode of the current Do command file\n" - "++%%SIM_QUIET%% The Quiet mode of the current Do command file\n" - "++%%SIM_MESSAGE%% The message display status of the current Do command file\n" - "++%%SIM_NAME%% The name of the current simulator\n" - "++%%SIM_BIN_NAME%% The program name of the current simulator\n" - "++%%SIM_BIN_PATH%% The program path that invoked the current simulator\n" - "++%%SIM_OSTYPE%% The Operating System running the current simulator\n\n" - "+Environment variable lookups are done first with the precise name between\n" - "+the %% characters and if that fails, then the name between the %% characters\n" - "+is upcased and a lookup of that valus is attempted.\n\n" - "+The first Space delimited token on the line is extracted in uppercase and\n" - "+then looked up as an environment variable. If found it the value is\n" - "+supstituted for the original string before expanding everything else. If\n" - "+it is not found, then the original beginning token on the line is left\n" - "+untouched.\n\n" + "+Tokens preceeded and followed by %% characters are expanded as\n" + "+environment variables, and if an environment variable isn't found then\n" + "+it can be one of several special variables:\n\n" + "++%%DATE%% yyyy-mm-dd\n" + "++%%TIME%% hh:mm:ss\n" + "++%%DATETIME%% yyyy-mm-ddThh:mm:ss\n" + "++%%LDATE%% mm/dd/yy (Locale Formatted)\n" + "++%%LTIME%% hh:mm:ss am/pm (Locale Formatted)\n" + "++%%CTIME%% Www Mmm dd hh:mm:ss yyyy (Locale\n" + "+++++++++++ Formatted)\n" + "++%%UTIME%% nnnn (Unix time - seconds since\n" + "+++++++++++ 1/1/1970)\n" + "++%%DATE_YYYY%% yyyy (0000-9999)\n" + "++%%DATE_YY%% yy (00-99)\n" + "++%%DATE_MM%% mm (01-12)\n" + "++%%DATE_MMM%% mmm (JAN-DEC)\n" + "++%%DATE_MONTH%% month (January-December)\n" + "++%%DATE_DD%% dd (01-31)\n" + "++%%DATE_WW%% ww (01-53) ISO 8601\n" + "+++++++++++ week number\n" + "++%%DATE_WYYYY%% yyyy (0000-9999) ISO 8601\n" + "+++++++++++ week year number\n" + "++%%DATE_D%% d (1-7) ISO 8601\n" + "+++++++++++ day of week\n" + "++%%DATE_JJJ%% jjj (001-366) day of year\n" + "++%%DATE_19XX_YY%% yy A year prior to 2000\n" + "+++++++++++ with the same calendar\n" + "+++++++++++ days as the current year\n" + "++%%DATE_19XX_YYYY%% yyyy A year prior to 2000\n" + "+++++++++++ with the same calendar days\n" + "+++++++++++ as the current year\n" + "++%%TIME_HH%% hh (00-23)\n" + "++%%TIME_MM%% mm (00-59)\n" + "++%%TIME_SS%% ss (00-59)\n" + "++%%TIME_MSEC%% msec (000-999)\n" + "++%%STATUS%% Status value from the last command executed\n" + "++%%TSTATUS%% The text form of the last status value\n" + "++%%SIM_VERIFY%% The Verify/Verbose mode of the current Do\n" + "++++++++ command file\n" + "++%%SIM_VERBOSE%% The Verify/Verbose mode of the current Do\n" + "++++++++ command file\n" + "++%%SIM_QUIET%% The Quiet mode of the current Do command\n" + "++++++++ file\n" + "++%%SIM_MESSAGE%% The message display status of the current\n" + "++++++++ Do command file\n" + "++%%SIM_NAME%% The name of the current simulator\n" + "++%%SIM_BIN_NAME%% The program name of the current simulator\n" + "++%%SIM_BIN_PATH%% The program path that invoked the current\n" + "++++++++ simulator\n" + "++%%SIM_OSTYPE%% The Operating System running the current\n" + "++++++++ simulator\n" + "++%%SIM_RUNTIME%% The Number simulated instructions or cycles\n" + "++++++++ performed\n" + "++%%SIM_RUNTIME_UNITS%% The units of the SIM_RUNTIME value\n\n" + "+Environment variable lookups are done first with the precise name\n" + "+between the %% characters and if that fails, then the name between\n" + "+the %% characters is upcased and a lookup of that valus is attempted.\n\n" + "+The first Space delimited token on a sim> command line is extracted\n" + "+in uppercase and then looked up as an environment variable. If found\n" + "+it the value is supstituted for the original string before expanding\n" + "+everything else. If it is not found, then the original beginning\n" + "+token on the line is left untouched.\n\n" "+Environment variable string substitution:\n\n" "++%%XYZ:str1=str2%%\n\n" "+would expand the XYZ environment variable, substituting each occurrence\n" "+of \"str1\" in the expanded result with \"str2\". \"str2\" can be the empty\n" - "+string to effectively delete all occurrences of \"str1\" from the expanded\n" - "+output. \"str1\" can begin with an asterisk, in which case it will match\n" - "+everything from the beginning of the expanded output to the first\n" - "+occurrence of the remaining portion of str1.\n\n" + "+string to effectively delete all occurrences of \"str1\" from the\n" + "+expanded output. \"str1\" can begin with an asterisk, in which case it\n" + "+will match everything from the beginning of the expanded output to the\n" + "+first occurrence of the remaining portion of str1.\n\n" "+May also specify substrings for an expansion.\n\n" "++%%XYZ:~10,5%%\n\n" "+would expand the XYZ environment variable, and then use only the 5\n" "+characters that begin at the 11th (offset 10) character of the expanded\n" "+result. If the length is not specified, then it defaults to the\n" - "+remainder of the variable value. If either number (offset or length) is\n" - "+negative, then the number used is the length of the environment variable\n" - "+value added to the offset or length specified.\n\n" + "+remainder of the variable value. If either number (offset or length)\n" + "+is negative, then the number used is the length of the environment\n" + "+variable value added to the offset or length specified.\n\n" "++%%XYZ:~-10%%\n\n" "+would extract the last 10 characters of the XYZ variable.\n\n" "++%%XYZ:~0,-2%%\n\n" @@ -1827,7 +1846,8 @@ static const char simh_help2[] = " The value of environment variables can be parsed as filenames\n" " and have their values be expanded to full paths and/or into pieces.\n" " Parsing and expansion of file names.\n\n" - "++%%~I%% - expands the value of %%I%% removing any surrounding quotes (\")\n" + "++%%~I%% - expands the value of %%I%% removing any surrounding\n" + "+++++ quotes (\")\n" "++%%~fI%% - expands the value of %%I%% to a fully qualified path name\n" "++%%~pI%% - expands the value of %%I%% to a path only\n" "++%%~nI%% - expands the value of %%I%% to a file name only\n" @@ -1836,7 +1856,8 @@ static const char simh_help2[] = "++%%~zI%% - expands the value of %%I%% to size of file\n\n" " The modifiers can be combined to get compound results:\n\n" "++%%~pnI%% - expands the value of %%I%% to a path and name only\n" - "++%%~nxI%% - expands the value of %%I%% to a file name and extension only\n\n" + "++%%~nxI%% - expands the value of %%I%% to a file name and extension\n" + "+++++ only\n\n" " In the above example above %%I%% can be replaced by other\n" " environment variables or numeric parameters to a DO command\n" " invokation.\n" @@ -4844,6 +4865,14 @@ if (!ap) { /* no environment variable found? */ sprintf (rbuf, "%s", sim_show_message ? "" : "-Q"); ap = rbuf; } + else if (!strcmp ("SIM_RUNTIME", gbuf)) { + sprintf (rbuf, "%s", sim_fmt_numeric (sim_gtime ())); + ap = rbuf; + } + else if (!strcmp ("SIM_RUNTIME_UNITS", gbuf)) { + sprintf (rbuf, "%s", sim_vm_interval_units); + ap = rbuf; + } } if (ap && fixup_needed) { /* substring/substituted needed? */ strlcpy (tgbuf, ap, tgbuf_size); @@ -8032,14 +8061,14 @@ if (sim_runlimit_switches & SWMASK ('T')) { sim_runlimit_d_initial = sim_runlimit_d = num * usec_factor * sim_host_speed_factor (); if (sim_host_speed_factor () > 1.0) sim_messagef (SCPE_OK, "Slow host - adjusting RUNLIMIT from %d %s to %.1f %s\n", num, units, num * sim_host_speed_factor (), units); - snprintf (runlimit, sizeof (runlimit), "%.f", num * sim_host_speed_factor ()); + snprintf (runlimit, sizeof (runlimit), "%s", sim_fmt_secs (num * sim_host_speed_factor ())); setenv ("SIM_RUNLIMIT", runlimit, 1); setenv ("SIM_RUNLIMIT_UNITS", units, 1); return sim_activate_after_d (&sim_runlimit_unit, sim_runlimit_d); } else { sim_runlimit_initial = sim_runlimit = num; - snprintf (runlimit, sizeof (runlimit), "%d", num); + snprintf (runlimit, sizeof (runlimit), "%s", sim_fmt_numeric ((double)num)); setenv ("SIM_RUNLIMIT", runlimit, 1); setenv ("SIM_RUNLIMIT_UNITS", units, 1); return sim_activate (&sim_runlimit_unit, sim_runlimit); @@ -8067,14 +8096,14 @@ if (sim_runlimit_enabled) { } else { if (sim_runlimit_initial != sim_runlimit) { - fprintf (st, "%d %s initially, ", sim_runlimit_initial, sim_vm_interval_units); + fprintf (st, "%s %s initially, ", sim_fmt_numeric ((double)sim_runlimit_initial), sim_vm_interval_units); if (sim_is_active (&sim_runlimit_unit)) - fprintf (st, "and %d %s remaining\n", sim_activate_time (&sim_runlimit_unit), sim_vm_interval_units); + fprintf (st, "and %s %s remaining\n", sim_fmt_numeric ((double)sim_activate_time (&sim_runlimit_unit)), sim_vm_interval_units); else fprintf (st, "expired now\n"); } else - fprintf (st, "%d %s\n", sim_runlimit_initial, sim_vm_interval_units); + fprintf (st, "%s %s\n", sim_fmt_numeric ((double)sim_runlimit_initial), sim_vm_interval_units); } } else @@ -10787,6 +10816,7 @@ return FALSE; t_value get_uint (const char *cptr, uint32 radix, t_value max, t_stat *status) { t_value val; +uint32 factor = 1; CONST char *tptr; *status = SCPE_OK; @@ -10796,17 +10826,18 @@ if ((cptr == tptr) || (val > max)) else { while (sim_isspace (*tptr)) tptr++; if (sim_toupper (*tptr) == 'K') { - val *= 1000; + factor = 1000; ++tptr; } else { if (sim_toupper (*tptr) == 'M') { - val *= 1000000; + factor = 1000000; ++tptr; } } - if ((*tptr != 0) || (val > max)) + if ((*tptr != 0) || (val > (max / factor))) *status = SCPE_ARG; + val *= factor; } return val; } @@ -12155,10 +12186,21 @@ const char *sim_fmt_numeric (double number) { static char buf[60]; char tmpbuf[60]; +const char *factor = ""; size_t len; uint32 c; char *p; +if (0 == (number - ((int)(number / 1000000.0)) * 1000000.0)) { + factor = "M"; + number /= 1000000.0; + } +else { + if (0 == (number - ((int)(number / 1000.0)) * 1000.0)) { + factor = "K"; + number /= 1000.0; + } + } sprintf (tmpbuf, "%.0f", number); len = strlen (tmpbuf); for (c=0, p=buf; c < len; c++) { @@ -12169,6 +12211,7 @@ for (c=0, p=buf; c < len; c++) { *(p++) = tmpbuf[c]; } *p = '\0'; +strlcat (buf, factor, sizeof (buf)); return buf; }