mirror of
https://github.com/rcornwell/sims.git
synced 2026-04-13 15:34:22 +00:00
SCP: Updated to current.
This commit is contained in:
222
scp.c
222
scp.c
@@ -1546,7 +1546,10 @@ static const char simh_help1[] =
|
||||
"+SET <unit> DISABLED disable unit\n"
|
||||
"+SET <unit> arg{,arg...} set unit parameters (see show modifiers)\n"
|
||||
"+HELP <dev> SET displays the device specific set commands\n"
|
||||
"++++++++ available\n";
|
||||
"++++++++ available\n"
|
||||
#define HLP_NOAUTOSIZE "*Commands SET NoAutosize"
|
||||
"3NoAutosize\n"
|
||||
"+SET NOAUTOSIZE disables disk autosizing for all disks\n";
|
||||
static const char simh_help2[] =
|
||||
/***************** 80 character line width template *************************/
|
||||
#define HLP_SHOW "*Commands SHOW"
|
||||
@@ -2597,6 +2600,7 @@ static CTAB set_glob_tab[] = {
|
||||
{ "PROMPT", &set_prompt, 0, HLP_SET_PROMPT },
|
||||
{ "RUNLIMIT", &set_runlimit, 1, HLP_RUNLIMIT },
|
||||
{ "NORUNLIMIT", &set_runlimit, 0, HLP_RUNLIMIT },
|
||||
{ "NOAUTOSIZE", &sim_disk_set_noautosize, 1, HLP_NOAUTOSIZE },
|
||||
{ NULL, NULL, 0 }
|
||||
};
|
||||
|
||||
@@ -5821,37 +5825,43 @@ if ((dptr = find_dev (gbuf))) { /* device match? */
|
||||
lvl = MTAB_VDV; /* device match */
|
||||
GET_SWITCHES (cptr); /* get more switches */
|
||||
}
|
||||
else if ((dptr = find_unit (gbuf, &uptr))) { /* unit match? */
|
||||
if (uptr == NULL) /* invalid unit */
|
||||
return SCPE_NXUN;
|
||||
ctbr = set_unit_tab; /* global table */
|
||||
lvl = MTAB_VUN; /* unit match */
|
||||
GET_SWITCHES (cptr); /* get more switches */
|
||||
}
|
||||
else if ((gcmdp = find_ctab (set_glob_tab, gbuf))) { /* global? */
|
||||
GET_SWITCHES (cptr); /* get more switches */
|
||||
return gcmdp->action (gcmdp->arg, cptr); /* do the rest */
|
||||
}
|
||||
else {
|
||||
if (sim_dflt_dev->modifiers) {
|
||||
if ((cvptr = strchr (gbuf, '='))) /* = value? */
|
||||
*cvptr++ = 0;
|
||||
for (mptr = sim_dflt_dev->modifiers; mptr->mask != 0; mptr++) {
|
||||
if (mptr->mstring && (MATCH_CMD (gbuf, mptr->mstring) == 0)) {
|
||||
dptr = sim_dflt_dev;
|
||||
cptr = svptr;
|
||||
while (sim_isspace(*cptr))
|
||||
++cptr;
|
||||
break;
|
||||
if ((dptr = find_unit (gbuf, &uptr))) { /* unit match? */
|
||||
if (uptr == NULL) /* invalid unit */
|
||||
return SCPE_NXUN;
|
||||
ctbr = set_unit_tab; /* global table */
|
||||
lvl = MTAB_VUN; /* unit match */
|
||||
GET_SWITCHES (cptr); /* get more switches */
|
||||
}
|
||||
else {
|
||||
if ((gcmdp = find_ctab (set_glob_tab, gbuf))) { /* global? */
|
||||
GET_SWITCHES (cptr); /* get more switches */
|
||||
return gcmdp->action (gcmdp->arg, cptr); /* do the rest */
|
||||
}
|
||||
else {
|
||||
if (sim_dflt_dev->modifiers) {
|
||||
if ((cvptr = strchr (gbuf, '='))) /* = value? */
|
||||
*cvptr++ = 0;
|
||||
for (mptr = sim_dflt_dev->modifiers; mptr->mask != 0; mptr++) {
|
||||
if (mptr->mstring && (MATCH_CMD (gbuf, mptr->mstring) == 0)) {
|
||||
dptr = sim_dflt_dev;
|
||||
cptr = svptr;
|
||||
while (sim_isspace(*cptr))
|
||||
++cptr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!dptr)
|
||||
return sim_messagef (SCPE_NXDEV, "Non-existent device: %s\n", gbuf);/* no match */
|
||||
lvl = MTAB_VDV; /* device match */
|
||||
uptr = dptr->units; /* first unit */
|
||||
}
|
||||
}
|
||||
if (!dptr)
|
||||
return sim_messagef (SCPE_NXDEV, "Non-existent device: %s\n", gbuf);/* no match */
|
||||
lvl = MTAB_VDV; /* device match */
|
||||
uptr = dptr->units; /* first unit */
|
||||
}
|
||||
if ((*cptr == 0) || (*cptr == ';') || (*cptr == '#')) /* must be more */
|
||||
if ((*cptr == 0) || /* must be more */
|
||||
(*cptr == ';') ||
|
||||
(*cptr == '#'))
|
||||
return SCPE_2FARG;
|
||||
GET_SWITCHES (cptr); /* get more switches */
|
||||
|
||||
@@ -6121,42 +6131,46 @@ if ((dptr = find_dev (gbuf))) { /* device match? */
|
||||
lvl = MTAB_VDV; /* device match */
|
||||
GET_SWITCHES (cptr); /* get more switches */
|
||||
}
|
||||
else if ((dptr = find_unit (gbuf, &uptr))) { /* unit match? */
|
||||
if (uptr == NULL) /* invalid unit */
|
||||
return sim_messagef (SCPE_NXUN, "Non-existent unit: %s\n", gbuf);
|
||||
if (uptr->flags & UNIT_DIS) /* disabled? */
|
||||
return sim_messagef (SCPE_UDIS, "Unit disabled: %s\n", gbuf);
|
||||
shtb = show_unit_tab; /* global table */
|
||||
lvl = MTAB_VUN; /* unit match */
|
||||
GET_SWITCHES (cptr); /* get more switches */
|
||||
}
|
||||
else if ((shptr = find_shtab (show_glob_tab, gbuf))) { /* global? */
|
||||
GET_SWITCHES (cptr); /* get more switches */
|
||||
return shptr->action (ofile, NULL, NULL, shptr->arg, cptr);
|
||||
}
|
||||
else {
|
||||
if (sim_dflt_dev->modifiers) {
|
||||
if ((cvptr = strchr (gbuf, '='))) /* = value? */
|
||||
*cvptr++ = 0;
|
||||
for (mptr = sim_dflt_dev->modifiers; mptr && (mptr->mask != 0); mptr++) {
|
||||
if ((((mptr->mask & MTAB_VDV) == MTAB_VDV) &&
|
||||
(mptr->pstring && (MATCH_CMD (gbuf, mptr->pstring) == 0))) ||
|
||||
(!(mptr->mask & MTAB_VDV) && (mptr->mstring && (MATCH_CMD (gbuf, mptr->mstring) == 0)))) {
|
||||
dptr = sim_dflt_dev;
|
||||
lvl = MTAB_VDV; /* device match */
|
||||
cptr = svptr;
|
||||
while (sim_isspace(*cptr))
|
||||
++cptr;
|
||||
break;
|
||||
if ((dptr = find_unit (gbuf, &uptr))) { /* unit match? */
|
||||
if (uptr == NULL) /* invalid unit */
|
||||
return sim_messagef (SCPE_NXUN, "Non-existent unit: %s\n", gbuf);
|
||||
if (uptr->flags & UNIT_DIS) /* disabled? */
|
||||
return sim_messagef (SCPE_UDIS, "Unit disabled: %s\n", gbuf);
|
||||
shtb = show_unit_tab; /* global table */
|
||||
lvl = MTAB_VUN; /* unit match */
|
||||
GET_SWITCHES (cptr); /* get more switches */
|
||||
}
|
||||
else {
|
||||
if ((shptr = find_shtab (show_glob_tab, gbuf))) {/* global? */
|
||||
GET_SWITCHES (cptr); /* get more switches */
|
||||
return shptr->action (ofile, NULL, NULL, shptr->arg, cptr);
|
||||
}
|
||||
else {
|
||||
if (sim_dflt_dev->modifiers) {
|
||||
if ((cvptr = strchr (gbuf, '='))) /* = value? */
|
||||
*cvptr++ = 0;
|
||||
for (mptr = sim_dflt_dev->modifiers; mptr && (mptr->mask != 0); mptr++) {
|
||||
if ((((mptr->mask & MTAB_VDV) == MTAB_VDV) &&
|
||||
(mptr->pstring && (MATCH_CMD (gbuf, mptr->pstring) == 0))) ||
|
||||
(!(mptr->mask & MTAB_VDV) && (mptr->mstring && (MATCH_CMD (gbuf, mptr->mstring) == 0)))) {
|
||||
dptr = sim_dflt_dev;
|
||||
lvl = MTAB_VDV; /* device match */
|
||||
cptr = svptr;
|
||||
while (sim_isspace(*cptr))
|
||||
++cptr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!dptr) {
|
||||
if ((shptr = find_shtab (show_dev_tab, gbuf))) /* global match? */
|
||||
return shptr->action (ofile, sim_dflt_dev, uptr, shptr->arg, cptr);
|
||||
else
|
||||
return sim_messagef (SCPE_NXDEV, "Non-existent device: %s\n", gbuf);/* no match */
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!dptr) {
|
||||
if ((shptr = find_shtab (show_dev_tab, gbuf))) /* global match? */
|
||||
return shptr->action (ofile, sim_dflt_dev, uptr, shptr->arg, cptr);
|
||||
else
|
||||
return sim_messagef (SCPE_NXDEV, "Non-existent device: %s\n", gbuf);/* no match */
|
||||
}
|
||||
}
|
||||
|
||||
if ((*cptr == 0) || (*cptr == ';') || (*cptr == '#')) { /* now eol? */
|
||||
@@ -6215,8 +6229,9 @@ return NULL;
|
||||
/* Show device and unit */
|
||||
|
||||
static size_t dev_name_len;
|
||||
static size_t unit_name_len;
|
||||
|
||||
const char *_sim_name_prefix (const char *name, const char *prefix)
|
||||
const char *_sim_name_prefix (const char *name, const char *prefix, size_t max_name_len)
|
||||
{
|
||||
static char nambuf[CBUFSIZE];
|
||||
size_t prefix_len = prefix ? strlen (prefix) : 0;
|
||||
@@ -6224,20 +6239,20 @@ size_t name_len = name ? strlen (name) : 0;
|
||||
size_t string_len = prefix_len + name_len;
|
||||
|
||||
snprintf (nambuf, sizeof (nambuf), "%s%*s", prefix ? prefix : "",
|
||||
((string_len <= 6) && (dev_name_len <= 6)) ? -((int)(8 - prefix_len)) :
|
||||
-((int)(dev_name_len + 2)),
|
||||
name ? name : "");
|
||||
((string_len <= 6) && (max_name_len <= 6)) ? -((int)(8 - prefix_len)) :
|
||||
-((int)(max_name_len + 2)),
|
||||
name ? name : "");
|
||||
return nambuf;
|
||||
}
|
||||
|
||||
const char *_sim_dname_prefix (DEVICE *dptr, const char *prefix)
|
||||
{
|
||||
return _sim_name_prefix (sim_dname (dptr), prefix);
|
||||
return _sim_name_prefix (sim_dname (dptr), prefix, dev_name_len);
|
||||
}
|
||||
|
||||
const char *_sim_uname_prefix (UNIT *uptr, const char *prefix)
|
||||
{
|
||||
return _sim_name_prefix (sim_uname (uptr), prefix);
|
||||
return _sim_name_prefix (sim_uname (uptr), prefix, unit_name_len);
|
||||
}
|
||||
|
||||
const char *_sim_dname (DEVICE *dptr)
|
||||
@@ -6255,12 +6270,32 @@ const char *_sim_dname_space (void)
|
||||
return _sim_dname_prefix (NULL, "");
|
||||
}
|
||||
|
||||
void _set_dname_len (DEVICE *dptr)
|
||||
{
|
||||
uint32 i;
|
||||
|
||||
if (dev_name_len < strlen (dptr->name))
|
||||
dev_name_len = strlen (dptr->name);
|
||||
for (i = 0; i < dptr->numunits; i++) {
|
||||
UNIT *uptr = &dptr->units[i];
|
||||
|
||||
if (((uptr->flags & UNIT_DIS) == 0) &&
|
||||
(unit_name_len < strlen (sim_uname (uptr))))
|
||||
unit_name_len = strlen (sim_uname (uptr));
|
||||
}
|
||||
}
|
||||
|
||||
t_stat show_device (FILE *st, DEVICE *dptr, int32 flag)
|
||||
{
|
||||
uint32 j, udbl, ucnt;
|
||||
UNIT *uptr;
|
||||
int32 toks = -1;
|
||||
t_bool did_set_dname_len = FALSE;
|
||||
|
||||
if (dev_name_len == 0) {
|
||||
_set_dname_len (dptr);
|
||||
did_set_dname_len = TRUE;
|
||||
}
|
||||
fprintf (st, "%s", _sim_dname (dptr)); /* print dev name */
|
||||
if ((flag == 2) && dptr->description) {
|
||||
fprintf (st, "%s\n", dptr->description(dptr));
|
||||
@@ -6309,6 +6344,8 @@ for (j = 0; j < dptr->numunits; j++) { /* loop thru units */
|
||||
if ((uptr->flags & UNIT_DIS) == 0)
|
||||
show_unit (st, dptr, uptr, ucnt + udbl);
|
||||
}
|
||||
if (did_set_dname_len)
|
||||
dev_name_len = unit_name_len = 0;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
@@ -6791,24 +6828,22 @@ t_bool only_enabled = (sim_switches & SWMASK ('E'));
|
||||
if (cptr && (*cptr != 0))
|
||||
return SCPE_2MARG;
|
||||
fprintf (st, "%s simulator configuration%s\n\n", sim_name, only_enabled ? " (enabled devices)" : "");
|
||||
for (i = dev_name_len = 0; (dptr = sim_devices[i]) != NULL; i++)
|
||||
for (i = dev_name_len = unit_name_len = 0; (dptr = sim_devices[i]) != NULL; i++)
|
||||
if (!only_enabled || !qdisable (dptr))
|
||||
if (dev_name_len < strlen (dptr->name))
|
||||
dev_name_len = strlen (dptr->name);
|
||||
_set_dname_len (dptr);
|
||||
for (i = 0; (dptr = sim_devices[i]) != NULL; i++)
|
||||
if (!only_enabled || !qdisable (dptr))
|
||||
show_device (st, dptr, flag);
|
||||
if (sim_switches & SWMASK ('I')) {
|
||||
for (i = dev_name_len = 0; sim_internal_device_count && (dptr = sim_internal_devices[i]); ++i)
|
||||
if (!only_enabled || !qdisable (dptr))
|
||||
if (dev_name_len < strlen (dptr->name))
|
||||
dev_name_len = strlen (dptr->name);
|
||||
_set_dname_len (dptr);
|
||||
fprintf (st, "\nInternal Devices%s\n\n", only_enabled ? " (enabled devices)" : "");
|
||||
for (i = 0; sim_internal_device_count && (dptr = sim_internal_devices[i]); ++i)
|
||||
if (!only_enabled || !qdisable (dptr))
|
||||
show_device (st, dptr, flag);
|
||||
}
|
||||
dev_name_len = 0;
|
||||
dev_name_len = unit_name_len = 0;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
@@ -8066,10 +8101,12 @@ if ((sim_switches & SWMASK ('R')) || /* read only? */
|
||||
((uptr->flags & UNIT_RO) != 0)) {
|
||||
if (((uptr->flags & UNIT_ROABLE) == 0) && /* allowed? */
|
||||
((uptr->flags & UNIT_RO) == 0))
|
||||
return attach_err (uptr, SCPE_NORO); /* no, error */
|
||||
return sim_messagef (attach_err (uptr, SCPE_NORO), "%s: Read Only operation not allowed\n", /* no, error */
|
||||
sim_uname (uptr));
|
||||
uptr->fileref = sim_fopen (cptr, "rb"); /* open rd only */
|
||||
if (uptr->fileref == NULL) /* open fail? */
|
||||
return attach_err (uptr, SCPE_OPENERR); /* yes, error */
|
||||
return sim_messagef (attach_err (uptr, SCPE_OPENERR), "%s: Can't open '%s': %s\n", /* yes, error */
|
||||
sim_uname (uptr), cptr, strerror (errno));
|
||||
if (!(uptr->flags & UNIT_RO))
|
||||
sim_messagef (SCPE_OK, "%s: unit is read only\n", sim_uname (uptr));
|
||||
uptr->flags = uptr->flags | UNIT_RO; /* set rd only */
|
||||
@@ -8078,7 +8115,8 @@ else {
|
||||
if (sim_switches & SWMASK ('N')) { /* new file only? */
|
||||
uptr->fileref = sim_fopen (cptr, "wb+"); /* open new file */
|
||||
if (uptr->fileref == NULL) /* open fail? */
|
||||
return attach_err (uptr, SCPE_OPENERR); /* yes, error */
|
||||
return sim_messagef (attach_err (uptr, SCPE_OPENERR), "%s: Can't open '%s': %s\n", /* yes, error */
|
||||
sim_uname (uptr), cptr, strerror (errno));
|
||||
sim_messagef (SCPE_OK, "%s: creating new file: %s\n", sim_uname (uptr), cptr);
|
||||
}
|
||||
else { /* normal */
|
||||
@@ -8090,19 +8128,23 @@ else {
|
||||
if ((errno == EROFS) || (errno == EACCES)) {/* read only? */
|
||||
#endif
|
||||
if ((uptr->flags & UNIT_ROABLE) == 0) /* allowed? */
|
||||
return attach_err (uptr, SCPE_NORO);/* no error */
|
||||
return sim_messagef (attach_err (uptr, SCPE_NORO), "%s: Read Only operation not allowed\n", /* no, error */
|
||||
sim_uname (uptr));
|
||||
uptr->fileref = sim_fopen (cptr, "rb"); /* open rd only */
|
||||
if (uptr->fileref == NULL) /* open fail? */
|
||||
return attach_err (uptr, SCPE_OPENERR); /* yes, error */
|
||||
return sim_messagef (attach_err (uptr, SCPE_OPENERR), "%s: Can't open '%s': %s\n", /* yes, error */
|
||||
sim_uname (uptr), cptr, strerror (errno));
|
||||
uptr->flags = uptr->flags | UNIT_RO; /* set rd only */
|
||||
sim_messagef (SCPE_OK, "%s: unit is read only\n", sim_uname (uptr));
|
||||
}
|
||||
else { /* doesn't exist */
|
||||
if (sim_switches & SWMASK ('E')) /* must exist? */
|
||||
return attach_err (uptr, SCPE_OPENERR); /* yes, error */
|
||||
return sim_messagef (attach_err (uptr, SCPE_OPENERR), "%s: Can't open '%s': %s\n", /* yes, error */
|
||||
sim_uname (uptr), cptr, strerror (errno));
|
||||
uptr->fileref = sim_fopen (cptr, "wb+");/* open new file */
|
||||
if (uptr->fileref == NULL) /* open fail? */
|
||||
return attach_err (uptr, SCPE_OPENERR); /* yes, error */
|
||||
return sim_messagef (attach_err (uptr, SCPE_OPENERR), "%s: Can't open '%s': %s\n", /* yes, error */
|
||||
sim_uname (uptr), cptr, strerror (errno));
|
||||
sim_messagef (SCPE_OK, "%s: creating new file\n", sim_uname (uptr));
|
||||
}
|
||||
} /* end if null */
|
||||
@@ -8112,13 +8154,24 @@ else {
|
||||
}
|
||||
if (uptr->flags & UNIT_BUFABLE) { /* buffer? */
|
||||
uint32 cap = ((uint32) uptr->capac) / dptr->aincr; /* effective size */
|
||||
if (uptr->flags & UNIT_MUSTBUF) /* dyn alloc? */
|
||||
uptr->filebuf = calloc (cap, SZ_D (dptr)); /* allocate */
|
||||
if (uptr->filebuf == NULL) /* no buffer? */
|
||||
|
||||
uptr->filebuf2 = calloc (cap, SZ_D (dptr)); /* allocate copy */
|
||||
if (uptr->filebuf2 == NULL)
|
||||
return attach_err (uptr, SCPE_MEM); /* error */
|
||||
if (uptr->flags & UNIT_MUSTBUF) { /* dyn alloc? */
|
||||
uptr->filebuf = calloc (cap, SZ_D (dptr)); /* allocate */
|
||||
if (uptr->filebuf == NULL) {
|
||||
free (uptr->filebuf);
|
||||
uptr->filebuf = NULL;
|
||||
free (uptr->filebuf2);
|
||||
uptr->filebuf2 = NULL;
|
||||
return attach_err (uptr, SCPE_MEM); /* error */
|
||||
}
|
||||
}
|
||||
sim_messagef (SCPE_OK, "%s: buffering file in memory\n", sim_uname (uptr));
|
||||
uptr->hwmark = (uint32)sim_fread (uptr->filebuf, /* read file */
|
||||
SZ_D (dptr), cap, uptr->fileref);
|
||||
memcpy (uptr->filebuf2, uptr->filebuf, cap * SZ_D (dptr));/* save initial contents */
|
||||
uptr->flags = uptr->flags | UNIT_BUF; /* set buffered */
|
||||
}
|
||||
uptr->flags = uptr->flags | UNIT_ATT;
|
||||
@@ -8237,7 +8290,8 @@ if ((dptr = find_dev_from_unit (uptr)) == NULL)
|
||||
return SCPE_OK;
|
||||
if ((uptr->flags & UNIT_BUF) && (uptr->filebuf)) {
|
||||
uint32 cap = (uptr->hwmark + dptr->aincr - 1) / dptr->aincr;
|
||||
if (uptr->hwmark && ((uptr->flags & UNIT_RO) == 0)) {
|
||||
if (((uptr->flags & UNIT_RO) == 0) &&
|
||||
(memcmp (uptr->filebuf, uptr->filebuf2, (size_t)(SZ_D (dptr) * (uptr->capac / dptr->aincr))) != 0)) {
|
||||
sim_messagef (SCPE_OK, "%s: writing buffer to file: %s\n", sim_uname (uptr), uptr->filename);
|
||||
rewind (uptr->fileref);
|
||||
sim_fwrite (uptr->filebuf, SZ_D (dptr), cap, uptr->fileref);
|
||||
@@ -8245,8 +8299,10 @@ if ((uptr->flags & UNIT_BUF) && (uptr->filebuf)) {
|
||||
sim_printf ("%s: I/O error - %s", sim_uname (uptr), strerror (errno));
|
||||
}
|
||||
if (uptr->flags & UNIT_MUSTBUF) { /* dyn alloc? */
|
||||
free (uptr->filebuf); /* free buf */
|
||||
free (uptr->filebuf); /* free buffers */
|
||||
uptr->filebuf = NULL;
|
||||
free (uptr->filebuf2);
|
||||
uptr->filebuf2 = NULL;
|
||||
}
|
||||
uptr->flags = uptr->flags & ~UNIT_BUF;
|
||||
}
|
||||
|
||||
@@ -579,6 +579,7 @@ struct UNIT {
|
||||
char *filename; /* open file name */
|
||||
FILE *fileref; /* file reference */
|
||||
void *filebuf; /* memory buffer */
|
||||
void *filebuf2; /* copy of initial memory buffer */
|
||||
uint32 hwmark; /* high water mark */
|
||||
int32 time; /* time out */
|
||||
uint32 flags; /* flags */
|
||||
@@ -899,7 +900,7 @@ struct MEMFILE {
|
||||
|
||||
*/
|
||||
|
||||
#define UDATA(act,fl,cap) NULL,act,NULL,NULL,NULL,0,0,(fl),0,(cap),0,NULL,0,0
|
||||
#define UDATA(act,fl,cap) NULL,act,NULL,NULL,NULL,NULL,0,0,(fl),0,(cap),0,NULL,0,0
|
||||
|
||||
/* Internal use ONLY (see below) Generic Register declaration for all fields */
|
||||
#define _REGDATANF(nm,loc,rdx,wd,off,dep,desc,flds,qptr,siz,elesiz,macro) \
|
||||
|
||||
111
sim_disk.c
111
sim_disk.c
@@ -516,6 +516,37 @@ AIO_CALL(DOP_IAVL, 0, NULL, NULL, 0, callback);
|
||||
return r;
|
||||
}
|
||||
|
||||
static t_bool sim_disk_no_autosize = FALSE;
|
||||
|
||||
t_stat sim_disk_set_noautosize (int32 flag, CONST char *cptr)
|
||||
{
|
||||
DEVICE *dptr;
|
||||
uint32 dev, unit, count = 0;
|
||||
|
||||
if (flag == sim_disk_no_autosize)
|
||||
return sim_messagef (SCPE_ARG, "Autosizing is already %sabled!\n",
|
||||
sim_disk_no_autosize ? "dis" : "en");
|
||||
for (dev = 0; (dptr = sim_devices[dev]) != NULL; dev++) {
|
||||
if ((DEV_TYPE (dptr) != DEV_DISK) ||
|
||||
(dptr->flags & DEV_DIS))
|
||||
continue;
|
||||
++count;
|
||||
for (unit = 0; unit < dptr->numunits; unit++) {
|
||||
char cmd[CBUFSIZE];
|
||||
int32 saved_sim_show_message = sim_show_message;
|
||||
|
||||
sim_show_message = FALSE;
|
||||
sprintf (cmd, "%s %sAUTOSIZE", sim_uname (&dptr->units[unit]), (flag != 0) ? "NO" : "");
|
||||
set_cmd (0, cmd);
|
||||
sim_show_message = saved_sim_show_message;
|
||||
}
|
||||
if (count == 0)
|
||||
return sim_messagef (SCPE_ARG, "No disk devices support autosizing\n");
|
||||
}
|
||||
sim_disk_no_autosize = flag;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Test for write protect */
|
||||
|
||||
t_bool sim_disk_wrp (UNIT *uptr)
|
||||
@@ -2421,6 +2452,10 @@ t_bool auto_format = FALSE;
|
||||
t_offset container_size, filesystem_size, current_unit_size;
|
||||
size_t tmp_size = 1;
|
||||
|
||||
if (sim_disk_no_autosize) {
|
||||
dontchangecapac = TRUE;
|
||||
drivetypes = NULL;
|
||||
}
|
||||
if (uptr->flags & UNIT_DIS) /* disabled? */
|
||||
return SCPE_UDIS;
|
||||
if (!(uptr->flags & UNIT_ATTABLE)) /* not attachable? */
|
||||
@@ -2719,10 +2754,12 @@ if ((sim_switches & SWMASK ('R')) || /* read only? */
|
||||
((uptr->flags & UNIT_RO) != 0)) {
|
||||
if (((uptr->flags & UNIT_ROABLE) == 0) && /* allowed? */
|
||||
((uptr->flags & UNIT_RO) == 0))
|
||||
return _err_return (uptr, SCPE_NORO); /* no, error */
|
||||
return sim_messagef (_err_return (uptr, SCPE_NORO), "%s: Read Only operation not allowed\n", /* no, error */
|
||||
sim_uname (uptr));
|
||||
uptr->fileref = open_function (cptr, "rb"); /* open rd only */
|
||||
if (uptr->fileref == NULL) /* open fail? */
|
||||
return _err_return (uptr, SCPE_OPENERR); /* yes, error */
|
||||
return sim_messagef (_err_return (uptr, SCPE_OPENERR), "%s: Can't open '%s': %s\n", /* yes, error */
|
||||
sim_uname (uptr), cptr, strerror (errno));
|
||||
uptr->flags = uptr->flags | UNIT_RO; /* set rd only */
|
||||
sim_messagef (SCPE_OK, "%s: Unit is read only\n", sim_uname (uptr));
|
||||
}
|
||||
@@ -2731,10 +2768,12 @@ else { /* normal */
|
||||
if (uptr->fileref == NULL) { /* open fail? */
|
||||
if ((errno == EROFS) || (errno == EACCES)) { /* read only? */
|
||||
if ((uptr->flags & UNIT_ROABLE) == 0) /* allowed? */
|
||||
return _err_return (uptr, SCPE_NORO); /* no error */
|
||||
return sim_messagef (_err_return (uptr, SCPE_NORO), "%s: Read Only operation not allowed\n", /* no, error */
|
||||
sim_uname (uptr));
|
||||
uptr->fileref = open_function (cptr, "rb"); /* open rd only */
|
||||
if (uptr->fileref == NULL) /* open fail? */
|
||||
return _err_return (uptr, SCPE_OPENERR);/* yes, error */
|
||||
return sim_messagef (_err_return (uptr, SCPE_OPENERR), "%s: Can't open '%s': %s\n", /* yes, error */
|
||||
sim_uname (uptr), cptr, strerror (errno));
|
||||
uptr->flags = uptr->flags | UNIT_RO; /* set rd only */
|
||||
sim_messagef (SCPE_OK, "%s: Unit is read only\n", sim_uname (uptr));
|
||||
}
|
||||
@@ -2796,7 +2835,7 @@ if ((DK_GET_FMT (uptr) == DKUF_F_VHD) || (ctx->footer)) {
|
||||
}
|
||||
else { /* Type already matches, Need to confirm compatibility */
|
||||
t_addr saved_capac = uptr->capac;
|
||||
t_lba current_unit_sectors = (t_lba)((uptr->capac*ctx->capac_factor)/(ctx->sector_size/((dptr->flags & DEV_SECTORS) ? 512 : 1)));
|
||||
t_lba current_unit_sectors = (t_lba)((dptr->flags & DEV_SECTORS) ? uptr->capac : (uptr->capac*ctx->capac_factor)/ctx->sector_size);
|
||||
|
||||
if ((container_sector_size != 0) && (sector_size != container_sector_size))
|
||||
r = sim_messagef (SCPE_OPENERR, "%s: Incompatible Container Sector Size %d\n", sim_uname (uptr), container_sector_size);
|
||||
@@ -2804,10 +2843,17 @@ if ((DK_GET_FMT (uptr) == DKUF_F_VHD) || (ctx->footer)) {
|
||||
if (dontchangecapac &&
|
||||
((((t_lba)(ctx->container_size/sector_size) > current_unit_sectors)) ||
|
||||
((container_sectors != 0) && (container_sectors != current_unit_sectors)))) {
|
||||
r = sim_messagef (SCPE_OK, "%s: Container has %u sectors, drive has: %u sectors\n", sim_uname (uptr), container_sectors, current_unit_sectors);
|
||||
if (container_sectors != 0)
|
||||
r = sim_messagef (SCPE_INCOMPDSK, "%s: %s container created by the %s simulator is incompatible with the %s device on the %s simulator\n", sim_uname (uptr), container_dtype, created_name, uptr->dptr->name, sim_name);
|
||||
else
|
||||
r = sim_messagef (SCPE_INCOMPDSK, "%s: disk container %s is incompatible with the %s device\n", sim_uname (uptr), uptr->filename, uptr->dptr->name);
|
||||
if ((uptr->flags & UNIT_RO) != 0)
|
||||
r = sim_messagef (SCPE_OK, "%s: Read Only access to incompatible %s container '%s' allowed\n", sim_uname (uptr), container_dtype, uptr->filename);
|
||||
if (container_sectors < current_unit_sectors) {
|
||||
r = sim_messagef (SCPE_BARE_STATUS (r), "%s: Since the container is smaller than the drive, this might be useful:\n", sim_uname (uptr));
|
||||
r = sim_messagef (SCPE_BARE_STATUS (r), "%s: sim> ATTACH %s -C New-%s %s\n", sim_uname (uptr), sim_uname (uptr), uptr->filename, uptr->filename);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (r == SCPE_OK) {
|
||||
@@ -2976,6 +3022,9 @@ filesystem_size = get_filesystem_size (uptr);
|
||||
if (filesystem_size != (t_offset)-1)
|
||||
filesystem_size += reserved_sectors * sector_size;
|
||||
container_size = sim_disk_size (uptr);
|
||||
if ((filesystem_size == (t_offset)-1) &&
|
||||
(ctx->footer != NULL)) /* The presence of metadata means we already */
|
||||
filesystem_size = ctx->container_size; /* know the interesting disk size */
|
||||
current_unit_size = ((t_offset)uptr->capac)*ctx->capac_factor*((dptr->flags & DEV_SECTORS) ? ctx->sector_size : 1);
|
||||
if (container_size && (container_size != (t_offset)-1)) {
|
||||
if (dontchangecapac) { /* autosize by changing drive type */
|
||||
@@ -3015,7 +3064,7 @@ if (container_size && (container_size != (t_offset)-1)) {
|
||||
autosized = TRUE;
|
||||
}
|
||||
else {
|
||||
if (!created) {
|
||||
if (!created && (ctx->footer == NULL)) {
|
||||
sim_messagef (SCPE_OK, "%s: Amount of data in use in disk container '%s' cannot be determined, skipping autosizing\n", sim_uname (uptr), cptr);
|
||||
if (container_size > current_unit_size) {
|
||||
t_stat r = SCPE_FSSIZE;
|
||||
@@ -3120,6 +3169,30 @@ sim_disk_set_async (uptr, completion_delay);
|
||||
#endif
|
||||
uptr->io_flush = _sim_disk_io_flush;
|
||||
|
||||
if (uptr->flags & UNIT_BUFABLE) { /* buffer in memory? */
|
||||
t_seccnt sectsread;
|
||||
t_stat r = SCPE_OK;
|
||||
|
||||
if (uptr->flags & UNIT_MUSTBUF) { /* dyn alloc? */
|
||||
uptr->filebuf = calloc ((size_t)(ctx->container_size / ctx->xfer_element_size),
|
||||
ctx->xfer_element_size); /* allocate */
|
||||
uptr->filebuf2 = calloc ((size_t)(ctx->container_size / ctx->xfer_element_size),
|
||||
ctx->xfer_element_size); /* allocate copy */
|
||||
if ((uptr->filebuf == NULL) || /* either failed? */
|
||||
(uptr->filebuf2 == NULL)) {
|
||||
sim_disk_detach (uptr);
|
||||
return SCPE_MEM; /* memory allocation error */
|
||||
}
|
||||
}
|
||||
sim_messagef (SCPE_OK, "%s: buffering file in memory\n", sim_uname (uptr));
|
||||
r = sim_disk_rdsect (uptr, 0, uptr->filebuf, §sread, (t_seccnt)(ctx->container_size / ctx->sector_size));
|
||||
if (r != SCPE_OK)
|
||||
return sim_disk_detach (uptr);
|
||||
uptr->hwmark = (sectsread * ctx->sector_size) / ctx->xfer_element_size;
|
||||
memcpy (uptr->filebuf2, uptr->filebuf, (size_t)ctx->container_size);/* save initial contents */
|
||||
uptr->flags |= UNIT_BUF; /* mark as buffered */
|
||||
}
|
||||
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
@@ -3160,6 +3233,21 @@ if (!(uptr->flags & UNIT_ATT)) /* attached? */
|
||||
if (NULL == find_dev_from_unit (uptr))
|
||||
return SCPE_OK;
|
||||
|
||||
if ((uptr->flags & UNIT_BUF) && (uptr->filebuf)) {
|
||||
uint32 cap = (uptr->hwmark + uptr->dptr->aincr - 1) / uptr->dptr->aincr;
|
||||
|
||||
if (((uptr->flags & UNIT_RO) == 0) &&
|
||||
(memcmp (uptr->filebuf, uptr->filebuf2, (size_t)ctx->container_size) != 0)) {
|
||||
sim_messagef (SCPE_OK, "%s: writing buffer to file: %s\n", sim_uname (uptr), uptr->filename);
|
||||
sim_disk_wrsect (uptr, 0, uptr->filebuf, NULL, (cap + ctx->sector_size - 1) / ctx->sector_size);
|
||||
}
|
||||
uptr->flags = uptr->flags & ~UNIT_BUF;
|
||||
}
|
||||
free (uptr->filebuf); /* free buffers */
|
||||
uptr->filebuf = NULL;
|
||||
free (uptr->filebuf2);
|
||||
uptr->filebuf2 = NULL;
|
||||
|
||||
update_disk_footer (uptr); /* Update meta data if highwater has changed */
|
||||
|
||||
auto_format = ctx->auto_format;
|
||||
@@ -3180,6 +3268,7 @@ uptr->disk_ctx = NULL;
|
||||
uptr->io_flush = NULL;
|
||||
if (auto_format)
|
||||
sim_disk_set_fmt (uptr, 0, "AUTO", NULL); /* restore file format */
|
||||
|
||||
if (close_function (fileref) == EOF)
|
||||
return SCPE_IOERR;
|
||||
return SCPE_OK;
|
||||
@@ -3990,8 +4079,6 @@ while (bytestoread) {
|
||||
if (sectsread)
|
||||
*sectsread += sectorbytes / ctx->sector_size;
|
||||
bytestoread -= sectorbytes;
|
||||
if (bytestoread == 0)
|
||||
break;
|
||||
buf += sectorbytes;
|
||||
addr += sectorbytes;
|
||||
}
|
||||
@@ -4192,8 +4279,6 @@ while (bytestoread) {
|
||||
if (sectsread)
|
||||
*sectsread += sectorbytes / ctx->sector_size;
|
||||
bytestoread -= sectorbytes;
|
||||
if ((bytestoread == 0) || (bytesread == 0))
|
||||
break;
|
||||
buf += sectorbytes;
|
||||
addr += sectorbytes;
|
||||
}
|
||||
@@ -6236,6 +6321,12 @@ return WriteVirtualDiskSectors(hVHD, buf, sects, sectswritten, ctx->sector_size,
|
||||
|
||||
t_stat sim_disk_init (void)
|
||||
{
|
||||
int32 saved_sim_show_message = sim_show_message;
|
||||
|
||||
sim_show_message = FALSE;
|
||||
sim_disk_no_autosize = TRUE;
|
||||
sim_disk_set_noautosize (FALSE, NULL);
|
||||
sim_show_message = saved_sim_show_message;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -48,10 +48,12 @@ typedef uint32 t_lba; /* disk logical block ad
|
||||
#define DKUF_F_STD 1 /* SIMH format */
|
||||
#define DKUF_F_RAW 2 /* Raw Physical Disk Access */
|
||||
#define DKUF_F_VHD 3 /* VHD format */
|
||||
#define DKUF_V_UF (DKUF_V_FMT + DKUF_W_FMT)
|
||||
#define DKUF_V_NOAUTOSIZE (DKUF_V_FMT + DKUF_W_FMT) /* Don't Autosize disk option */
|
||||
#define DKUF_V_UF (DKUF_V_NOAUTOSIZE + 1)
|
||||
#define DKUF_WLK UNIT_WLK
|
||||
#define DKUF_FMT (DKUF_M_FMT << DKUF_V_FMT)
|
||||
#define DKUF_WRP (DKUF_WLK | UNIT_RO)
|
||||
#define DKUF_NOAUTOSIZE (1 << DKUF_V_NOAUTOSIZE)
|
||||
|
||||
#define DK_F_STD (DKUF_F_STD << DKUF_V_FMT)
|
||||
#define DK_F_RAW (DKUF_F_RAW << DKUF_V_FMT)
|
||||
@@ -126,6 +128,7 @@ t_bool sim_disk_vhd_support (void);
|
||||
t_bool sim_disk_raw_support (void);
|
||||
void sim_disk_data_trace (UNIT *uptr, const uint8 *data, size_t lba, size_t len, const char* txt, int detail, uint32 reason);
|
||||
t_stat sim_disk_info_cmd (int32 flag, CONST char *ptr);
|
||||
t_stat sim_disk_set_noautosize (int32 flag, CONST char *cptr);
|
||||
t_stat sim_disk_test (DEVICE *dptr, const char *cptr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -70,7 +70,7 @@
|
||||
#define SCSI_V_NOAUTO ((DKUF_V_UF > MTUF_V_UF) ? DKUF_V_UF : MTUF_V_UF)/* noautosize */
|
||||
#define SCSI_V_UF (SCSI_V_NOAUTO + 1)
|
||||
#define SCSI_WLK (UNIT_WLK|UNIT_RO) /* hwre write lock */
|
||||
#define SCSI_NOAUTO (1 << SCSI_V_NOAUTO)
|
||||
#define SCSI_NOAUTO DKUF_NOAUTOSIZE
|
||||
|
||||
|
||||
struct scsi_dev_t {
|
||||
|
||||
@@ -1051,6 +1051,8 @@ fprintf (st, "Attach command switches\n");
|
||||
fprintf (st, " -R Attach Read Only.\n");
|
||||
fprintf (st, " -E Must Exist (if not specified, the default behavior is to\n");
|
||||
fprintf (st, " attempt to create the indicated virtual tape file).\n");
|
||||
fprintf (st, " -N Create a new empty tape container file.\n");
|
||||
fprintf (st, " -Q Suppress informative messages during attach activities.\n");
|
||||
fprintf (st, " -F Open the indicated tape container in a specific format\n");
|
||||
fprintf (st, " (default is SIMH, alternatives are E11, TPC, P7B, AWS, TAR,\n");
|
||||
fprintf (st, " ANSI-VMS, ANSI-RT11, ANSI-RSX11, ANSI-RSTS, ANSI-VAR, FIXED,\n");
|
||||
|
||||
Reference in New Issue
Block a user