1
0
mirror of https://github.com/rcornwell/sims.git synced 2026-01-11 23:52:48 +00:00

SCP: Updated to current.

This commit is contained in:
Richard Cornwell 2021-03-07 13:40:34 -05:00
parent d533322a6a
commit 692f7474e1
6 changed files with 140 additions and 44 deletions

72
scp.c
View File

@ -233,13 +233,9 @@
#include <time.h>
#include <math.h>
#if defined(_WIN32)
#include <direct.h>
#include <io.h>
#include <fcntl.h>
#else
#include <unistd.h>
#endif
#include <sys/stat.h>
#include <setjmp.h>
#if defined(HAVE_DLOPEN) /* Dynamic Readline support */
@ -451,6 +447,7 @@ void (*sim_vm_fprint_addr) (FILE *st, DEVICE *dptr, t_addr addr) = NULL;
t_addr (*sim_vm_parse_addr) (DEVICE *dptr, CONST char *cptr, CONST char **tptr) = NULL;
t_value (*sim_vm_pc_value) (void) = NULL;
t_bool (*sim_vm_is_subroutine_call) (t_addr **ret_addrs) = NULL;
void (*sim_vm_reg_update) (REG *rptr, uint32 idx, t_value prev_val, t_value new_val) = NULL;
t_bool (*sim_vm_fprint_stopped) (FILE *st, t_stat reason) = NULL;
const char *sim_vm_release = NULL;
const char *sim_vm_release_message = NULL;
@ -3148,11 +3145,13 @@ DEVICE *tdptr;
CONST char *tptr;
char *namebuf;
char rangebuf[32];
int side_effects = 0;
if (dptr->registers)
for (rptr = dptr->registers; rptr->name != NULL; rptr++) {
if (rptr->flags & REG_HIDDEN)
continue;
side_effects += ((rptr->flags & REG_DEPOSIT) != 0);
if (rptr->depth > 1)
sprintf (rangebuf, "[%d:%d]", 0, rptr->depth-1);
else
@ -3172,8 +3171,11 @@ else {
namebuf = (char *)calloc (max_namelen + 1, sizeof (*namebuf));
fprintf (st, "\nThe %s device implements these registers:\n\n", dptr->name);
for (rptr = dptr->registers; rptr->name != NULL; rptr++) {
char note[2];
if (rptr->flags & REG_HIDDEN)
continue;
strlcpy (note, (side_effects != 0) ? ((rptr->flags & REG_DEPOSIT) ? "+" : " ") : "", sizeof (note));
if (rptr->depth <= 1)
sprintf (namebuf, "%*s", -((int)max_namelen), rptr->name);
else {
@ -3181,16 +3183,22 @@ else {
sprintf (namebuf, "%s%*s", rptr->name, (int)(strlen(rptr->name))-((int)max_namelen), rangebuf);
}
if (all_unique) {
fprintf (st, " %s %4d %s\n", namebuf, rptr->width, rptr->desc ? rptr->desc : "");
fprintf (st, " %s %4d %s %s\n", namebuf, rptr->width, note, rptr->desc ? rptr->desc : "");
continue;
}
trptr = find_reg_glob (rptr->name, &tptr, &tdptr);
if ((trptr == NULL) || (tdptr != dptr))
fprintf (st, " %s %s %4d %s\n", dptr->name, namebuf, rptr->width, rptr->desc ? rptr->desc : "");
fprintf (st, " %s %s %4d %s %s\n", dptr->name, namebuf, rptr->width, note, rptr->desc ? rptr->desc : "");
else
fprintf (st, " %*s %s %4d %s\n", (int)strlen(dptr->name), "", namebuf, rptr->width, rptr->desc ? rptr->desc : "");
fprintf (st, " %*s %s %4d %s %s\n", (int)strlen(dptr->name), "", namebuf, rptr->width, note, rptr->desc ? rptr->desc : "");
}
free (namebuf);
if (side_effects)
fprintf (st, "\n + Deposits to %s register%s will have some additional\n"
" side effects which can be suppressed if the deposit is\n"
" done with the -Z switch specified\n",
(side_effects == 1) ? "this" : "these",
(side_effects == 1) ? "" : "s");
}
}
@ -3861,10 +3869,10 @@ for (nargs = 0; nargs < 10; ) { /* extract arguments */
if (do_arg [0] == NULL) /* need at least 1 */
return SCPE_2FARG;
if ((strcasecmp (do_arg[0], "<stdin>") != 0) &&
((fpin = fopen (do_arg[0], "r")) == NULL)) { /* file failed to open? */
((fpin = sim_fopen (do_arg[0], "r")) == NULL)) { /* file failed to open? */
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 ((fpin = sim_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]);
return SCPE_OPENERR; /* return failure */
@ -4624,8 +4632,8 @@ if (sim_switches & SWMASK ('F')) { /* File Compare? */
filename2[strlen (filename2) - 1] = '\0';
setenv ("_FILE_COMPARE_DIFF_OFFSET", "", 1); /* Remove previous environment variable */
f1 = fopen (filename1, "rb");
f2 = fopen (filename2, "rb");
f1 = sim_fopen (filename1, "rb");
f2 = sim_fopen (filename2, "rb");
free (filename1);
free (filename2);
if ((f1 == NULL) && (f2 == NULL)) /* Both can't open? */
@ -4848,7 +4856,7 @@ if (Exist || (*gbuf == '"') || (*gbuf == '\'')) { /* quoted string compari
result = !result;
}
else {
FILE *f = fopen (gbuf, "r");
FILE *f = sim_fopen (gbuf, "r");
if (!f) {
if (((gbuf[0] == '"') || (gbuf[0] == '\'')) && /* quoted? */
@ -4856,7 +4864,7 @@ if (Exist || (*gbuf == '"') || (*gbuf == '\'')) { /* quoted string compari
char *without_quotes = sim_filepath_parts (gbuf, "f");
if (without_quotes) {
f = fopen (without_quotes, "r");
f = sim_fopen (without_quotes, "r");
free (without_quotes);
}
}
@ -6858,7 +6866,7 @@ GET_SWITCHES (cptr); /* get switches */
gbuf[sizeof(gbuf)-1] = '\0';
strlcpy (gbuf, cptr, sizeof(gbuf));
sim_trim_endspc(gbuf);
if (chdir(gbuf) != 0)
if (sim_chdir(gbuf) != 0)
return sim_messagef(SCPE_IOERR, "Unable to directory change to: %s\n", gbuf);
return SCPE_OK;
}
@ -6950,9 +6958,9 @@ if (*cptr == '\0')
else {
if ((WildName[strlen (WildName) - 1] == '/') ||
(WildName[strlen (WildName) - 1] == '\\'))
WildName[strlen (WildName) - 1] = '\0';
strlcat (WildName, ".", sizeof (WildName));
}
if ((!stat (WildName, &filestat)) && (filestat.st_mode & S_IFDIR))
if ((!sim_stat (WildName, &filestat)) && (filestat.st_mode & S_IFDIR))
strlcat (WildName, "/*", sizeof (WildName));
r = sim_dir_scan (cptr, sim_dir_entry, &dir_state);
sim_dir_entry (NULL, NULL, 0, NULL, &dir_state); /* output summary */
@ -7117,7 +7125,7 @@ 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)) {
if ((!sim_stat (dname, &deststat)) && (deststat.st_mode & S_IFDIR)) {
const char *dslash = (strrchr (dname, '/') ? "/" : (strrchr (dname, '\\') ? "\\" : "/"));
dname[sizeof (dname) - 1] = '\0';
@ -7182,12 +7190,12 @@ 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))
if ((!sim_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';
if (!stat (path, &filestat)) {
if (!sim_stat (path, &filestat)) {
if (filestat.st_mode & S_IFDIR) {
*c = '/'; /* restore / */
++c;
@ -7195,24 +7203,12 @@ while ((c = strchr (c, '/'))) {
}
return sim_messagef (SCPE_ARG, "%s is not a directory\n", path);
}
if (
#if defined(_WIN32)
mkdir (path)
#else
mkdir (path, 0777)
#endif
)
if (sim_mkdir (path))
return sim_messagef (SCPE_ARG, "Can't create directory: %s - %s\n", path, strerror (errno));
*c = '/'; /* restore / */
++c;
}
if (
#if defined(_WIN32)
mkdir (path)
#else
mkdir (path, 0777)
#endif
)
if (sim_mkdir (path))
return sim_messagef (SCPE_ARG, "Can't create directory: %s - %s\n", path, strerror (errno));
return SCPE_OK;
}
@ -7222,7 +7218,7 @@ 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))
if (sim_rmdir (cptr))
return sim_messagef (SCPE_ARG, "Can't remove directory: %s - %s\n", cptr, strerror (errno));
return SCPE_OK;
}
@ -9441,6 +9437,11 @@ void put_rval_pcchk (REG *rptr, uint32 idx, t_value val, t_bool pc_chk)
size_t sz;
t_value mask;
uint32 *ptr;
t_value prev_val;
if ((!(sim_switches & SWMASK ('Z'))) &&
(rptr->flags & REG_DEPOSIT) && sim_vm_reg_update)
prev_val = get_rval (rptr, idx);
#define PUT_RVAL(sz,rp,id,v,m) \
*(((sz *) rp->loc) + id) = \
@ -9499,6 +9500,9 @@ else PUT_RVAL (t_uint64, rptr, idx, val, mask);
#else
else PUT_RVAL (uint32, rptr, idx, val, mask);
#endif
if ((!(sim_switches & SWMASK ('Z'))) &&
(rptr->flags & REG_DEPOSIT) && sim_vm_reg_update)
sim_vm_reg_update (rptr, idx, prev_val, val);
}
void put_rval (REG *rptr, uint32 idx, t_value val)

1
scp.h
View File

@ -371,6 +371,7 @@ extern t_addr (*sim_vm_parse_addr) (DEVICE *dptr, CONST char *cptr, CONST char *
extern t_bool (*sim_vm_fprint_stopped) (FILE *st, t_stat reason);
extern t_value (*sim_vm_pc_value) (void);
extern t_bool (*sim_vm_is_subroutine_call) (t_addr **ret_addrs);
extern void (*sim_vm_reg_update) (REG *rptr, uint32 idx, t_value prev_val, t_value new_val);
extern const char **sim_clock_precalibrate_commands;
extern int32 sim_vm_initial_ips; /* base estimate of simulated instructions per second */
extern const char *sim_vm_interval_units; /* Simulator can change this - default "instructions" */

View File

@ -710,6 +710,7 @@ struct REG {
#define REG_VMIO 00400 /* use VM data print/parse */
#define REG_VMAD 01000 /* use VM addr print/parse */
#define REG_FIT 02000 /* fit access to size */
#define REG_DEPOSIT 04000 /* call VM routine after update */
#define REG_HRO (REG_RO | REG_HIDDEN) /* hidden, read only */
#define REG_V_UF 16 /* device specific */

102
sim_fio.c
View File

@ -248,19 +248,90 @@ if ((0 != fstat (fileno (fp), &statb)) ||
return TRUE;
}
static void _sim_expand_homedir (const char *file, char *dest, size_t dest_size)
{
if (memcmp (file, "~/", 2) != 0)
strlcpy (dest, file, dest_size);
else {
char *cptr = getenv("HOME");
char *cptr2;
if (cptr == NULL) {
cptr = getenv("HOMEPATH");
cptr2 = getenv("HOMEDRIVE");
}
else
cptr2 = NULL;
if (cptr && (dest_size > strlen (cptr) + strlen (file) + 3))
snprintf(dest, dest_size, "%s%s%s%s", cptr2 ? cptr2 : "", cptr, strchr (cptr, '/') ? "/" : "\\", file + 2);
else
strlcpy (dest, file, dest_size);
while ((strchr (dest, '\\') != NULL) && ((cptr = strchr (dest, '/')) != NULL))
*cptr = '\\';
}
}
#if defined(_WIN32)
#include <direct.h>
#include <io.h>
#include <fcntl.h>
#else
#include <unistd.h>
#endif
int sim_stat (const char *fname, struct stat *stat_str)
{
char namebuf[PATH_MAX + 1];
_sim_expand_homedir (fname, namebuf, sizeof (namebuf));
return stat (namebuf, stat_str);
}
int sim_chdir(const char *path)
{
char pathbuf[PATH_MAX + 1];
_sim_expand_homedir (path, pathbuf, sizeof (pathbuf));
return chdir (pathbuf);
}
int sim_mkdir(const char *path)
{
char pathbuf[PATH_MAX + 1];
_sim_expand_homedir (path, pathbuf, sizeof (pathbuf));
#if defined(_WIN32)
return mkdir (pathbuf);
#else
return mkdir (pathbuf, 0777);
#endif
}
int sim_rmdir(const char *path)
{
char pathbuf[PATH_MAX + 1];
_sim_expand_homedir (path, pathbuf, sizeof (pathbuf));
return rmdir (pathbuf);
}
/* OS-dependent routines */
/* Optimized file open */
FILE *sim_fopen (const char *file, const char *mode)
{
char namebuf[PATH_MAX + 1];
_sim_expand_homedir (file, namebuf, sizeof (namebuf));
#if defined (VMS)
return fopen (file, mode, "ALQ=32", "DEQ=4096",
return fopen (namebuf, mode, "ALQ=32", "DEQ=4096",
"MBF=6", "MBC=127", "FOP=cbt,tef", "ROP=rah,wbh", "CTX=stm");
#elif (defined (__linux) || defined (__linux__) || defined (__hpux) || defined (_AIX)) && !defined (DONT_DO_LARGEFILE)
return fopen64 (file, mode);
return fopen64 (namebuf, mode);
#else
return fopen (file, mode);
return fopen (namebuf, mode);
#endif
}
@ -392,7 +463,11 @@ 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))
char sourcename[PATH_MAX + 1], destname[PATH_MAX + 1];
_sim_expand_homedir (source_file, sourcename, sizeof (sourcename));
_sim_expand_homedir (dest_file, destname, sizeof (destname));
if (CopyFileA (sourcename, destname, !overwrite_existing))
return SCPE_OK;
return sim_messagef (SCPE_ARG, "Error Copying '%s' to '%s': %s\n", source_file, dest_file, sim_get_os_error_text (GetLastError ()));
}
@ -540,7 +615,7 @@ if (fOut)
if (st == SCPE_OK) {
struct stat statb;
if (!stat (source_file, &statb)) {
if (!sim_stat (source_file, &statb)) {
struct utimbuf utim;
utim.actime = statb.st_atime;
@ -762,7 +837,9 @@ char chr;
const char *p;
char filesizebuf[32] = "";
char filedatetimebuf[32] = "";
char namebuf[PATH_MAX + 1];
/* Remove quotes if they're present */
if (((*filepath == '\'') || (*filepath == '"')) &&
(filepath[strlen (filepath) - 1] == *filepath)) {
size_t temp_size = 1 + strlen (filepath);
@ -774,6 +851,12 @@ if (((*filepath == '\'') || (*filepath == '"')) &&
tempfilepath[strlen (tempfilepath) - 1] = '\0';
filepath = tempfilepath;
}
/* Expand ~/ home directory */
_sim_expand_homedir (filepath, namebuf, sizeof (namebuf));
filepath = namebuf;
/* Check for full or current directory relative path */
if ((filepath[1] == ':') ||
(filepath[0] == '/') ||
(filepath[0] == '\\')){
@ -785,7 +868,7 @@ if ((filepath[1] == ':') ||
}
strcpy (fullpath, filepath);
}
else {
else { /* Need to prepend current directory */
char dir[PATH_MAX+1] = "";
char *wd = sim_getcwd(dir, sizeof (dir));
@ -837,7 +920,8 @@ if (ext == NULL)
tot_size = 0;
if (*parts == '\0') /* empty part specifier means strip only quotes */
tot_size = strlen (tempfilepath);
if (strchr (parts, 't') || strchr (parts, 'z')) {
if (strchr (parts, 't') || /* modification time or */
strchr (parts, 'z')) { /* or size requested? */
struct stat filestat;
struct tm *tm;
@ -919,7 +1003,7 @@ WIN32_FIND_DATAA File;
struct stat filestat;
char WildName[PATH_MAX + 1];
strlcpy (WildName, cptr, sizeof(WildName));
_sim_expand_homedir (cptr, WildName, sizeof (WildName));
cptr = WildName;
sim_trim_endspc (WildName);
if ((hFind = FindFirstFileA (cptr, &File)) != INVALID_HANDLE_VALUE) {
@ -982,7 +1066,7 @@ char DirName[PATH_MAX + 1], WholeName[PATH_MAX + 1], WildName[PATH_MAX + 1], Mat
memset (DirName, 0, sizeof(DirName));
memset (WholeName, 0, sizeof(WholeName));
memset (MatchName, 0, sizeof(MatchName));
strlcpy (WildName, cptr, sizeof(WildName));
_sim_expand_homedir (cptr, WildName, sizeof (WildName));
cptr = WildName;
sim_trim_endspc (WildName);
c = sim_filepath_parts (cptr, "f");

View File

@ -37,6 +37,8 @@
extern "C" {
#endif
#include <sys/stat.h>
#define FLIP_SIZE (1 << 16) /* flip buf size */
#define fxread(a,b,c,d) sim_fread (a, b, c, d)
#define fxwrite(a,b,c,d) sim_fwrite (a, b, c, d)
@ -70,6 +72,10 @@ 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);
int sim_stat (const char *fname, struct stat *stat_str);
int sim_chdir(const char *path);
int sim_mkdir(const char *path);
int sim_rmdir(const char *path);
t_stat sim_copyfile (const char *source_file, const char *dest_file, t_bool overwrite_existing);
char *sim_filepath_parts (const char *pathname, const char *parts);
char *sim_getcwd (char *buf, size_t buf_size);

View File

@ -2016,7 +2016,7 @@ if (0) while (SDL_PeepEvents (&event, 1, SDL_GETEVENT, SD
}
break;
case SDL_QUIT:
sim_debug (SIM_VID_DBG_VIDEO|SIM_VID_DBG_KEY|SIM_VID_DBG_MOUSE|SIM_VID_DBG_CURSOR, vptr->vid_dev, "vid_thread() - QUIT Event - %s\n", vid_quit_callback ? "Signaled" : "Ignored");
sim_debug (SIM_VID_DBG_VIDEO|SIM_VID_DBG_KEY|SIM_VID_DBG_MOUSE|SIM_VID_DBG_CURSOR, vptr0->vid_dev, "vid_thread() - QUIT Event - %s\n", vid_quit_callback ? "Signaled" : "Ignored");
if (vid_quit_callback)
vid_quit_callback ();
break;