1
0
mirror of https://github.com/simh/simh.git synced 2026-03-09 12:16:13 +00:00

SCP: Add support for REGisters containing double values

This commit is contained in:
Mark Pizzolato
2023-11-02 06:56:45 -10:00
parent 3ac5062c12
commit 67ec597696
2 changed files with 66 additions and 9 deletions

60
scp.c
View File

@@ -9194,8 +9194,13 @@ for (i = 0; i < (device_count + sim_internal_device_count); i++) {/* loop thru d
fputc ('\n', sfile);
WRITE_I (rptr->depth); /* [V2.10] depth */
for (j = 0; j < rptr->depth; j++) { /* loop thru values */
val = get_rval (rptr, j); /* get value */
WRITE_I (val); /* store */
if ((rptr->macro != NULL) && (memcmp (rptr->macro, "DBRDATA", 7) == 0)) {
fprintf (sfile, "%f\n", *(((double *)(rptr->loc)) + j));
}
else {
val = get_rval (rptr, j); /* get value */
WRITE_I (val); /* store */
}
}
}
fputc ('\n', sfile); /* end registers */
@@ -9517,6 +9522,11 @@ for ( ;; ) { /* device loop */
else /* otherwise */
max = width_mask[rptr->width]; /* the mask defines the maximum value */
for (us = 0; us < depth; us++) { /* loop thru values */
if ((rptr->macro != NULL) && (memcmp (rptr->macro, "DBRDATA", 7) == 0)) {
READ_S (buf);
sscanf(buf, "%lf", (((double *)rptr->loc) + us));
continue;
}
READ_I (val); /* read value */
if (val > max) { /* value ok? */
sim_printf ("Invalid register value: %s %s\n", sim_dname (dptr), buf);
@@ -10354,7 +10364,8 @@ if ((rptr->flags & REG_VMAD) && sim_vm_fprint_addr)
sim_vm_fprint_addr (ofile, sim_dflt_dev, (t_addr) val);
else {
sim_snprint_sym (sim_last_val, sizeof (sim_last_val), !(rptr->flags & REG_VMFLAGS),
(t_addr)((rptr->flags & REG_UFMASK) | rdx), sim_eval,
(t_addr)((rptr->flags & REG_UFMASK) | rdx),
((rptr->flags & REG_DOUBLE) == 0) ? sim_eval : (t_value *)rptr->loc,
NULL, sim_switches | SIM_SW_REG, 0, rdx, rptr->width,
rptr->flags & REG_FMT);
fprintf (ofile, "%s", sim_last_val);
@@ -12247,6 +12258,24 @@ t_bool negative = FALSE;
int32 d, digit, ndigits, commas = 0;
char dbuf[MAX_WIDTH + 1];
if ((format & REG_DOUBLE) != 0) {
double dvalue = *((double *)&val);
snprintf (dbuf, sizeof (dbuf), "%f", dvalue);
if ((strrchr (dbuf, 'E') == NULL) && (strrchr (dbuf, 'e') == NULL) && (strchr (dbuf, '.') != NULL)) {
while (dbuf[strlen (dbuf) - 1] == '0')
dbuf[strlen (dbuf) - 1] = '\0';
if (dbuf[strlen (dbuf) - 1] == '.')
dbuf[strlen (dbuf) - 1] = '\0';
}
if (!buffer)
return strlen(dbuf);
*buffer = '\0';
if (width < strlen(dbuf))
return sim_messagef (SCPE_IOERR, "Invalid width (%u) for buffer size (%u)\n", width, (uint32)strlen(dbuf));
strcpy(buffer, dbuf);
return SCPE_OK;
}
if (((format == PV_LEFTSIGN) || (format == PV_RCOMMASIGN)) &&
(0 > (t_svalue)val)) {
val = (t_value)(-((t_svalue)val));
@@ -16686,6 +16715,7 @@ for (i = 0; (dptr = devices[i]) != NULL; i++) {
int reg_entry = -1;
for (rptr = dptr->registers; (rptr != NULL) && (rptr->name != NULL); rptr++) {
uint32 format = rptr->flags & REG_FMT;
uint32 bytes = 1;
uint32 rsz = SZ_R(rptr);
uint32 memsize = (rptr->depth >= 1) ? rptr->depth * rsz : rsz;
@@ -16730,13 +16760,27 @@ for (i = 0; (dptr = devices[i]) != NULL; i++) {
}
if (sim_switches & SWMASK ('R')) /* Debug output */
sim_printf ("%5s:%-9.9s %s%s%s(rdx=%u, wd=%u, off=%u, dep=%u, strsz=%u, objsz=%u, oobjsz=%u, elesz=%u, rsz=%u, %s%s%s membytes=%u)\n",
sim_printf ("%5s:%-9.9s %s%s%s(rdx=%u, wd=%u, off=%u, dep=%u, strsz=%u, objsz=%u, oobjsz=%u, elesz=%u, rsz=%u, %s%s%s%s membytes=%u)\n",
dptr->name, rptr->name, rptr->desc ? rptr->desc : "", rptr->desc ? "\n\t" : "", rptr->macro ? rptr->macro : "",
rptr->radix, rptr->width, rptr->offset, rptr->depth, (uint32)rptr->stride, (uint32)rptr->obj_size, (uint32)rptr->pobj_size, (uint32)rptr->size, rsz,
(rptr->flags & REG_VMAD) ? " REG_VMAD" : "", (rptr->flags & REG_VMIO) ? " REG_VMIO" : "",
(rptr->flags & REG_DEPOSIT) ? " REG_DEPOSIT" : "", memsize);
(rptr->flags & REG_DEPOSIT) ? " REG_DEPOSIT" : "", (rptr->flags & REG_DEPOSIT) ? " REG_DOUBLE" : "", memsize);
MFlush (f);
if (rptr->flags & REG_DOUBLE) {
Mprintf (f, "%s %s:%s used the %s macro but had REG_DOUBLE flag bit set\n", sim_name, dptr->name, rptr->name, rptr->macro);
Mprintf (f, "%s %s:%s REG_DOUBLE shoule never be specified as a register flag bit\n", sim_name, dptr->name, rptr->name, rptr->macro);
Bad = TRUE;
}
if ((rptr->macro != NULL) && (0 == memcmp (rptr->macro, "DBRDATA", 7))) {
if (rptr->flags != 0) {
Mprintf (f, "%s %s:%s used the %s macro but had flags bit set\n", sim_name, dptr->name, rptr->name, rptr->macro);
Mprintf (f, "%s %s:%s No flags should be specified for %s registers\n", sim_name, dptr->name, rptr->name, rptr->macro);
Bad = TRUE;
}
else
rptr->flags |= REG_DOUBLE|REG_RO;
}
if (rptr->depth == 1) {
if (rptr->offset)
Mprintf (f, "%s %s:%s used the %s macro to describe a %u bit%s wide field at offset %u\n", sim_name, dptr->name, rptr->name, rptr->macro, rptr->width, (rptr->width == 1) ? "" : "s", rptr->offset);
@@ -16836,6 +16880,12 @@ for (i = 0; (dptr = devices[i]) != NULL; i++) {
}
}
MClose (f);
if (devices == sim_devices) { /* Testing defaulted to simulator's DEVICEs? */
t_stat int_stat = sim_sanity_check_register_declarations (sim_internal_devices); /* Also test simulator's Internal Devices */
if (int_stat != SCPE_OK)
return int_stat;
}
return stat;
}

View File

@@ -702,10 +702,11 @@ struct REG {
/* Register flags */
#define REG_FMT 00003 /* see PV_x */
#define REG_RO 00004 /* read only */
#define REG_HIDDEN 00010 /* hidden */
#define REG_NZ 00020 /* must be non-zero */
#define REG_FMT 00017 /* see PV_x */
#define REG_DOUBLE 00010 /* Double Precision Value */
#define REG_RO 00020 /* read only */
#define REG_HIDDEN 00040 /* hidden */
#define REG_NZ 00100 /* must be non-zero */
#define REG_CIRC 00200 /* circular array */
#define REG_VMIO 00400 /* use VM data print/parse */
#define REG_VMAD 01000 /* use VM addr print/parse */
@@ -886,6 +887,7 @@ struct MEMFILE {
HRDATA Scalar with hexadecimal display/entry
BINRDATA Scalar with binary display/entry
FLDATA Scalar with single bit display/entry
DBRDATA Scalar double precision floating display (no entry)
GRDATA Scalar with with specification of radix/width/offset parameters
BRDATA Singly-subscripted array of scalars
@@ -1018,6 +1020,11 @@ struct MEMFILE {
_RegCheck(#nm,&(loc),2,1,pos,1,desc,NULL,0,0,sizeof((loc)),FLDATAD)
#define FLDATADF(nm,loc,pos,desc,flds) \
_RegCheck(#nm,&(loc),2,1,pos,1,desc,flds,0,0,sizeof((loc)),FLDATADF)
/* Double Precision Floating Register Data */
#define DBRDATA(nm,loc) \
_RegCheck(#nm,&(loc),10,16,0,1,NULL,NULL,0,0,sizeof((loc)),DBRDATA)
#define DBRDATAD(nm,loc,desc) \
_RegCheck(#nm,&(loc),10,16,0,1,desc,NULL,0,0,sizeof((loc)),DBRDATAD)
/* Arbitrary location and Radix Register */
#define GRDATA(nm,loc,rdx,wd,pos) \
_RegCheck(#nm,&(loc),rdx,wd,pos,1,NULL,NULL,0,0,sizeof((loc)),GRDATA)