SCP: Updated REG macros and manipulation APIs
- Rewrote get_rval, put_rval to support fields within arrays of structures - REG "size" field now determines access size - REG "maxval" field now determines maximum allowed value Merge from v3.12
This commit is contained in:
parent
8bbec61483
commit
4dde5a69a4
2 changed files with 262 additions and 291 deletions
260
scp.c
260
scp.c
|
@ -24,6 +24,9 @@
|
|||
in this Software without prior written authorization from Robert M Supnik.
|
||||
|
||||
21-Oct-21 RMS Fixed bug in byte deposits if aincr > 1
|
||||
16-Feb-21 JDB Rewrote get_rval, put_rval to support arrays of structures
|
||||
25-Jan-21 JDB REG "size" field now determines access size
|
||||
REG "maxval" field now determines maximum allowed value
|
||||
08-Mar-16 RMS Added shutdown flag for detach_all
|
||||
20-Mar-12 MP Fixes to "SHOW <x> SHOW" commands
|
||||
06-Jan-12 JDB Fixed "SHOW DEVICE" with only one enabled unit (Dave Bryan)
|
||||
|
@ -8710,7 +8713,7 @@ void *mbuf = NULL;
|
|||
int32 j, blkcnt, limit, unitno, time, flg;
|
||||
uint32 us, depth;
|
||||
t_addr k, high, old_capac;
|
||||
t_value val, mask;
|
||||
t_value val, max;
|
||||
t_stat r;
|
||||
size_t sz;
|
||||
t_bool v40, v35, v32;
|
||||
|
@ -8979,10 +8982,13 @@ for ( ;; ) { /* device loop */
|
|||
if (depth > rptr->depth)
|
||||
depth = rptr->depth;
|
||||
}
|
||||
mask = width_mask[rptr->width]; /* get mask */
|
||||
if (rptr->maxval > 0) /* if a maximum value is defined */
|
||||
max = rptr->maxval; /* then use it */
|
||||
else /* otherwise */
|
||||
max = width_mask[rptr->width]; /* the mask defines the maximum value */
|
||||
for (us = 0; us < depth; us++) { /* loop thru values */
|
||||
READ_I (val); /* read value */
|
||||
if (val > mask) { /* value ok? */
|
||||
if (val > max) { /* value ok? */
|
||||
sim_printf ("Invalid register value: %s %s\n", sim_dname (dptr), buf);
|
||||
}
|
||||
else {
|
||||
|
@ -9133,7 +9139,9 @@ if ((flag == RU_RUN) || (flag == RU_GO)) { /* run or go */
|
|||
else
|
||||
new_pcv = strtotv (gbuf, &tptr, sim_PC->radix);/* parse PC */
|
||||
if ((tptr == gbuf) || (*tptr != 0) || /* error? */
|
||||
(new_pcv > width_mask[sim_PC->width]))
|
||||
(new_pcv > ((sim_PC->maxval > 0)
|
||||
? sim_PC->maxval
|
||||
: (width_mask[sim_PC->width]))))
|
||||
return SCPE_ARG;
|
||||
new_pc = TRUE;
|
||||
}
|
||||
|
@ -9822,53 +9830,50 @@ return SCPE_OK;
|
|||
idx = index
|
||||
Outputs:
|
||||
return = register value
|
||||
|
||||
Implementation notes:
|
||||
|
||||
1. The stride is the size of the element spacing for arrays, which is
|
||||
equivalent to the addressing increment for array subscripting. For
|
||||
scalar registers, the stride will be zero (as will the idx value), so the
|
||||
access pointer is same as the specified location pointer.
|
||||
|
||||
2. The size of the t_value type is determined by the USE_INT64 symbol and
|
||||
will be either a 32-bit or a 64-bit type. It represents the largest
|
||||
value that can be returned and so is the default if one of the smaller
|
||||
sizes is not indicated. If USE_INT64 is not defined, t_value will be
|
||||
identical to uint32. In this case, compilers are generally smart enough
|
||||
to eliminate the 32-bit size test and combine the two assignments into a
|
||||
single default assignment.
|
||||
*/
|
||||
|
||||
t_value get_rval (REG *rptr, uint32 idx)
|
||||
{
|
||||
size_t sz;
|
||||
t_value val;
|
||||
uint32 *ptr;
|
||||
void *ptr;
|
||||
|
||||
sz = SZ_R (rptr);
|
||||
if ((rptr->depth > 1) && (rptr->flags & REG_CIRC)) {
|
||||
idx = idx + rptr->qptr;
|
||||
if (idx >= rptr->depth) idx = idx - rptr->depth;
|
||||
if ((rptr->depth > 1) && (rptr->flags & REG_CIRC)) { /* if the register is a circular queue */
|
||||
idx = idx + rptr->qptr; /* then adjust the index relative to the queue */
|
||||
if (idx >= rptr->depth) /* if the index is beyond the end of the array */
|
||||
idx = idx - rptr->depth; /* then wrap it around */
|
||||
}
|
||||
if ((rptr->depth > 1) && (rptr->flags & REG_UNIT)) {
|
||||
ptr = (uint32 *)(((UNIT *) rptr->loc) + idx);
|
||||
#if defined (USE_INT64)
|
||||
if (sz <= sizeof (uint32))
|
||||
val = *ptr;
|
||||
else val = *((t_uint64 *) ptr);
|
||||
#else
|
||||
val = *ptr;
|
||||
#endif
|
||||
}
|
||||
else if ((rptr->depth > 1) && (rptr->flags & REG_STRUCT)) {
|
||||
ptr = (uint32 *)(((size_t) rptr->loc) + (idx * rptr->str_size));
|
||||
#if defined (USE_INT64)
|
||||
if (sz <= sizeof (uint32))
|
||||
val = *ptr;
|
||||
else val = *((t_uint64 *) ptr);
|
||||
#else
|
||||
val = *ptr;
|
||||
#endif
|
||||
}
|
||||
else if (((rptr->depth > 1) || (rptr->flags & REG_FIT)) &&
|
||||
(sz == sizeof (uint8)))
|
||||
val = *(((uint8 *) rptr->loc) + idx);
|
||||
else if (((rptr->depth > 1) || (rptr->flags & REG_FIT)) &&
|
||||
(sz == sizeof (uint16)))
|
||||
val = *(((uint16 *) rptr->loc) + idx);
|
||||
#if defined (USE_INT64)
|
||||
else if (sz <= sizeof (uint32))
|
||||
val = *(((uint32 *) rptr->loc) + idx);
|
||||
else val = *(((t_uint64 *) rptr->loc) + idx);
|
||||
#else
|
||||
else val = *(((uint32 *) rptr->loc) + idx);
|
||||
#endif
|
||||
val = (val >> rptr->offset) & width_mask[rptr->width];
|
||||
|
||||
ptr = ((char *) rptr->loc) + (idx * rptr->stride); /* point at the starting byte of the item */
|
||||
|
||||
if (rptr->size == sizeof (uint8)) /* get the value */
|
||||
val = *((uint8 *) ptr); /* using a size */
|
||||
/* appropriate to */
|
||||
else if (rptr->size == sizeof (uint16)) /* the size of */
|
||||
val = *((uint16 *) ptr); /* the underlying type */
|
||||
|
||||
else if (rptr->size == sizeof (uint32))
|
||||
val = *((uint32 *) ptr);
|
||||
|
||||
else /* if the element size is non-standard */
|
||||
val = *((t_value *) ptr); /* then access using the largest size permitted */
|
||||
|
||||
val = (val >> rptr->offset) & width_mask[rptr->width]; /* shift and mask to obtain the final value */
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
|
@ -9886,7 +9891,7 @@ return val;
|
|||
t_stat dep_reg (int32 flag, CONST char *cptr, REG *rptr, uint32 idx)
|
||||
{
|
||||
t_stat r;
|
||||
t_value val, mask;
|
||||
t_value val, max;
|
||||
int32 rdx;
|
||||
CONST char *tptr;
|
||||
char gbuf[CBUFSIZE];
|
||||
|
@ -9898,24 +9903,27 @@ if (rptr->flags & REG_RO)
|
|||
if (flag & EX_I) {
|
||||
cptr = read_line (gbuf, sizeof(gbuf), stdin);
|
||||
if (sim_log)
|
||||
fprintf (sim_log, "%s\n", cptr? cptr: "");
|
||||
fprintf (sim_log, "%s\n", cptr? cptr: ""); /* fix clang error */
|
||||
if (cptr == NULL) /* force exit */
|
||||
return 1;
|
||||
if (*cptr == 0) /* success */
|
||||
return SCPE_OK;
|
||||
}
|
||||
mask = width_mask[rptr->width];
|
||||
if (rptr->maxval > 0) /* if a maximum value is defined */
|
||||
max = rptr->maxval; /* then use it */
|
||||
else /* otherwise */
|
||||
max = width_mask[rptr->width]; /* the mask defines the maximum value */
|
||||
GET_RADIX (rdx, rptr->radix);
|
||||
if ((rptr->flags & REG_VMAD) && sim_vm_parse_addr) { /* address form? */
|
||||
val = sim_vm_parse_addr (sim_dflt_dev, cptr, &tptr);
|
||||
if ((tptr == cptr) || (*tptr != 0) || (val > mask))
|
||||
if ((tptr == cptr) || (*tptr != 0) || (val > max))
|
||||
return SCPE_ARG;
|
||||
}
|
||||
else
|
||||
if (!(rptr->flags & REG_VMFLAGS) || /* dont use sym? */
|
||||
(parse_sym ((CONST char *)cptr, (rptr->flags & REG_UFMASK) | rdx, NULL,
|
||||
&val, sim_switches | SIM_SW_REG) > SCPE_OK)) {
|
||||
val = get_uint (cptr, rdx, mask, &r);
|
||||
val = get_uint (cptr, rdx, max, &r);
|
||||
if (r != SCPE_OK)
|
||||
return SCPE_ARG;
|
||||
}
|
||||
|
@ -9934,76 +9942,59 @@ return SCPE_OK;
|
|||
mask = mask
|
||||
Outputs:
|
||||
none
|
||||
|
||||
|
||||
Implementation notes:
|
||||
|
||||
1. mask and val are of type t_value, so an explicit cast is not needed for
|
||||
that type of assignment.
|
||||
|
||||
2. See the notes for the get_rval routine for additional information
|
||||
regarding the stride calculation and the t_value default assignment,
|
||||
*/
|
||||
|
||||
void put_rval_pcchk (REG *rptr, uint32 idx, t_value val, t_bool pc_chk)
|
||||
{
|
||||
size_t sz;
|
||||
t_value mask;
|
||||
uint32 *ptr;
|
||||
void *ptr;
|
||||
t_value prev_val = 0;
|
||||
|
||||
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) = \
|
||||
(sz)((*(((sz *) rp->loc) + id) & \
|
||||
~((m) << (rp)->offset)) | ((v) << (rp)->offset))
|
||||
if (pc_chk && (rptr == sim_PC)) /* if the PC is changing */
|
||||
sim_brk_npc (0); /* then notify the breakpoint package */
|
||||
|
||||
if (pc_chk && (rptr == sim_PC))
|
||||
sim_brk_npc (0);
|
||||
sz = SZ_R (rptr);
|
||||
mask = width_mask[rptr->width];
|
||||
if ((rptr->depth > 1) && (rptr->flags & REG_CIRC)) {
|
||||
idx = idx + rptr->qptr;
|
||||
if (idx >= rptr->depth)
|
||||
idx = idx - rptr->depth;
|
||||
mask = ~(width_mask [rptr->width] << rptr->offset); /* set up a mask to produce a hole in the element */
|
||||
val = val << rptr->offset; /* and position the new value to fit the hole */
|
||||
|
||||
if ((rptr->depth > 1) && (rptr->flags & REG_CIRC)) { /* if the register is a circular queue */
|
||||
idx = idx + rptr->qptr; /* then adjust the index relative to the queue */
|
||||
if (idx >= rptr->depth) /* if the index is beyond the end of the array */
|
||||
idx = idx - rptr->depth; /* then wrap it around */
|
||||
}
|
||||
if ((rptr->depth > 1) && (rptr->flags & REG_UNIT)) {
|
||||
ptr = (uint32 *)(((UNIT *) rptr->loc) + idx);
|
||||
#if defined (USE_INT64)
|
||||
if (sz <= sizeof (uint32))
|
||||
*ptr = (*ptr &
|
||||
~(((uint32) mask) << rptr->offset)) |
|
||||
(((uint32) val) << rptr->offset);
|
||||
else *((t_uint64 *) ptr) = (*((t_uint64 *) ptr)
|
||||
& ~(mask << rptr->offset)) | (val << rptr->offset);
|
||||
#else
|
||||
*ptr = (*ptr &
|
||||
~(((uint32) mask) << rptr->offset)) |
|
||||
(((uint32) val) << rptr->offset);
|
||||
#endif
|
||||
}
|
||||
else if ((rptr->depth > 1) && (rptr->flags & REG_STRUCT)) {
|
||||
ptr = (uint32 *)(((size_t)rptr->loc) + (idx * rptr->str_size));
|
||||
#if defined (USE_INT64)
|
||||
if (sz <= sizeof (uint32))
|
||||
*((uint32 *) ptr) = (*((uint32 *) ptr) &
|
||||
~(((uint32) mask) << rptr->offset)) |
|
||||
(((uint32) val) << rptr->offset);
|
||||
else *((t_uint64 *) ptr) = (*((t_uint64 *) ptr)
|
||||
& ~(mask << rptr->offset)) | (val << rptr->offset);
|
||||
#else
|
||||
*ptr = (*ptr &
|
||||
~(((uint32) mask) << rptr->offset)) |
|
||||
(((uint32) val) << rptr->offset);
|
||||
#endif
|
||||
}
|
||||
else if (((rptr->depth > 1) || (rptr->flags & REG_FIT)) &&
|
||||
(sz == sizeof (uint8)))
|
||||
PUT_RVAL (uint8, rptr, idx, (uint32) val, (uint32) mask);
|
||||
else if (((rptr->depth > 1) || (rptr->flags & REG_FIT)) &&
|
||||
(sz == sizeof (uint16)))
|
||||
PUT_RVAL (uint16, rptr, idx, (uint32) val, (uint32) mask);
|
||||
#if defined (USE_INT64)
|
||||
else if (sz <= sizeof (uint32))
|
||||
PUT_RVAL (uint32, rptr, idx, (int32) val, (uint32) mask);
|
||||
else PUT_RVAL (t_uint64, rptr, idx, val, mask);
|
||||
#else
|
||||
else PUT_RVAL (uint32, rptr, idx, val, mask);
|
||||
#endif
|
||||
|
||||
ptr = ((char *) rptr->loc) + (idx * rptr->stride); /* point at the starting byte of the item */
|
||||
|
||||
if (rptr->size == sizeof (uint8)) /* store the value */
|
||||
*((uint8 *) ptr) = /* using a size */
|
||||
(uint8) (*((uint8 *) ptr) & mask | val); /* appropriate to */
|
||||
/* the size of */
|
||||
else
|
||||
if (rptr->size == sizeof (uint16)) /* the underlying type */
|
||||
*((uint16 *) ptr) =
|
||||
(uint16) (*((uint16 *) ptr) & mask | val);
|
||||
|
||||
else
|
||||
if (rptr->size == sizeof (uint32))
|
||||
*((uint32 *) ptr) =
|
||||
(uint32) (*((uint32 *) ptr) & mask | val);
|
||||
|
||||
else /* if the element size is non-standard */
|
||||
*((t_value *) ptr) = /* then access using the largest size permitted */
|
||||
*((t_value *) ptr) & mask | val;
|
||||
|
||||
if ((!(sim_switches & SWMASK ('Z'))) &&
|
||||
(rptr->flags & REG_DEPOSIT) && sim_vm_reg_update)
|
||||
sim_vm_reg_update (rptr, idx, prev_val, val);
|
||||
|
@ -16084,19 +16075,8 @@ for (i = 0; (dptr = devices[i]) != NULL; i++) {
|
|||
bytes <<= 1;
|
||||
|
||||
if (rptr->depth > 1)
|
||||
bytes = rptr->ele_size;
|
||||
bytes = rptr->size;
|
||||
|
||||
if (rptr->flags & REG_UNIT) {
|
||||
DEVICE **d;
|
||||
|
||||
for (d = devices; *d != NULL; d++) {
|
||||
if (((UNIT *)rptr->loc >= (*d)->units) &&
|
||||
((UNIT *)rptr->loc < (*d)->units + (*d)->numunits)) {
|
||||
udptr = *d;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (((rptr->width + rptr->offset + CHAR_BIT - 1) / CHAR_BIT) >= sizeof(size_map) / sizeof(size_map[0])) {
|
||||
Bad = TRUE;
|
||||
rsz = 0;
|
||||
|
@ -16107,10 +16087,10 @@ for (i = 0; (dptr = devices[i]) != NULL; i++) {
|
|||
}
|
||||
|
||||
if (sim_switches & SWMASK ('R')) /* Debug output */
|
||||
sim_printf ("%5s:%-9.9s %s(rdx=%u, wd=%u, off=%u, dep=%u, strsz=%u, objsz=%u, elesz=%u, rsz=%u, %s %s%s%s membytes=%u)\n", dptr->name, rptr->name, rptr->macro,
|
||||
rptr->radix, rptr->width, rptr->offset, rptr->depth, (uint32)rptr->str_size, (uint32)rptr->obj_size, (uint32)rptr->ele_size, rsz, rptr->desc ? rptr->desc : "",
|
||||
(rptr->flags & REG_FIT) ? "REG_FIT" : "", (rptr->flags & REG_VMIO) ? " REG_VMIO" : "", (rptr->flags & REG_STRUCT) ? " REG_STRUCT" : "",
|
||||
memsize);
|
||||
sim_printf ("%5s:%-9.9s %s(rdx=%u, wd=%u, off=%u, dep=%u, strsz=%u, objsz=%u, elesz=%u, rsz=%u, %s %s%s membytes=%u, macro=%s)\n", dptr->name, rptr->name, rptr->macro,
|
||||
rptr->radix, rptr->width, rptr->offset, rptr->depth, (uint32)rptr->stride, (uint32)rptr->obj_size, (uint32)rptr->size, rsz, rptr->desc ? rptr->desc : "",
|
||||
(rptr->flags & REG_FIT) ? "REG_FIT" : "", (rptr->flags & REG_VMIO) ? " REG_VMIO" : "",
|
||||
memsize, rptr->macro ? rptr->macro : "");
|
||||
|
||||
MFlush (f);
|
||||
if (rptr->depth == 1) {
|
||||
|
@ -16129,42 +16109,6 @@ for (i = 0; (dptr = devices[i]) != NULL; i++) {
|
|||
Bad = TRUE;
|
||||
Mprintf (f, "a 0 bit wide register is meaningless\n");
|
||||
}
|
||||
if ((rptr->obj_size != 0) && (rptr->ele_size != 0) && (rptr->depth != 0) && (rptr->macro != NULL)) {
|
||||
if (rptr->flags & REG_UNIT) {
|
||||
if (udptr == NULL) {
|
||||
Bad = TRUE;
|
||||
Mprintf (f, "\tthe indicated UNIT can't be found for this %u depth array\n", rptr->depth);
|
||||
}
|
||||
else {
|
||||
if (rptr->depth > udptr->numunits) {
|
||||
Bad = TRUE;
|
||||
Mprintf (f, "\tthe depth of the UNIT array exceeds the number of units on the %s device which is %u\n", dptr->name, udptr->numunits);
|
||||
}
|
||||
if (rptr->obj_size > sizeof (t_value)) {
|
||||
Bad = TRUE;
|
||||
Mprintf (f, "\t%u is larger than the size of the t_value type (%u)\n", (uint32)rptr->obj_size, (uint32)sizeof (t_value));
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
bytes *= rptr->depth;
|
||||
if (!Bad)
|
||||
if ((rsz * rptr->depth == rptr->obj_size) ||
|
||||
((rptr->flags & REG_STRUCT) && (rsz <= rptr->obj_size)) ||
|
||||
((rptr->depth == 1) &&
|
||||
((rptr->obj_size == sizeof (t_value)) || (rsz < rptr->obj_size))) ||
|
||||
((rptr->depth != 1) && (bytes == rptr->obj_size)) ||
|
||||
((rptr->depth != 1) && (rptr->offset == 0) && (rptr->width == 8) &&
|
||||
((rptr->depth == rptr->obj_size) || (rptr->depth == rptr->obj_size - 1))) ||
|
||||
((rptr->depth != 1) && (rptr->offset == 0) && (rptr->obj_size == rptr->ele_size)))
|
||||
continue;
|
||||
Bad = TRUE;
|
||||
Mprintf (f, "\ttherefore SAVE/RESTORE operations will affect %u byte%s of memory\n", bytes, (bytes != 1) ? "s" : "");
|
||||
Mprintf (f, "\twhile the variable lives in %u bytes of memory\n", (uint32)rptr->obj_size);
|
||||
}
|
||||
}
|
||||
else
|
||||
Mprintf (f, "\tthis register entry is not properly initialized\n");
|
||||
if (Bad) {
|
||||
FMwrite (stdout, f);
|
||||
stat = SCPE_IERR;
|
||||
|
|
293
sim_defs.h
293
sim_defs.h
|
@ -694,9 +694,9 @@ struct REG {
|
|||
const char *desc; /* description */
|
||||
BITFIELD *fields; /* bit fields */
|
||||
uint32 qptr; /* circ q ptr */
|
||||
size_t str_size; /* structure size */
|
||||
size_t stride; /* structure/object size (for indexing) */
|
||||
size_t obj_size; /* sizeof(*loc) */
|
||||
size_t ele_size; /* sizeof(**loc) or sizeof(*loc) if depth == 1 */
|
||||
size_t size; /* sizeof(**loc) or sizeof(*loc) if depth == 1 */
|
||||
const char *macro; /* Initializer Macro Name */
|
||||
/* NOTE: Flags and maxval MUST always be last since they are initialized outside of macro definitions */
|
||||
uint32 flags; /* flags */
|
||||
|
@ -709,12 +709,10 @@ struct REG {
|
|||
#define REG_RO 00004 /* read only */
|
||||
#define REG_HIDDEN 00010 /* hidden */
|
||||
#define REG_NZ 00020 /* must be non-zero */
|
||||
#define REG_UNIT 00040 /* in unit struct */
|
||||
#define REG_STRUCT 00100 /* in structure array */
|
||||
#define REG_CIRC 00200 /* circular array */
|
||||
#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_FIT 00000 /* fit access to size (obsolete) */
|
||||
#define REG_DEPOSIT 04000 /* call VM routine after update */
|
||||
#define REG_HRO (REG_RO | REG_HIDDEN) /* hidden, read only */
|
||||
|
||||
|
@ -893,6 +891,7 @@ struct MEMFILE {
|
|||
size_t size; /* size */
|
||||
size_t pos; /* data used */
|
||||
};
|
||||
|
||||
/*
|
||||
The following macros exist to help populate structure contents
|
||||
|
||||
|
@ -903,91 +902,208 @@ struct MEMFILE {
|
|||
|
||||
#define UDATA(act,fl,cap) NULL,act,NULL,NULL,NULL,NULL,0,0,(fl),0,(cap),0,NULL,0,0
|
||||
|
||||
/* Register initialization macros.
|
||||
|
||||
The following macros should be used to initialize the elements of a
|
||||
simulator's register array. The macros provide simplified initialization,
|
||||
ensure that unspecified fields are set appropriately, and insulate the
|
||||
simulator writer from changes in the underlying REG structure.
|
||||
|
||||
The macros take varying numbers of parameters with the following meanings:
|
||||
|
||||
Param Meaning
|
||||
----- ------------------------------------------
|
||||
nm Register symbolic name
|
||||
loc Location of the associated variable
|
||||
aloc Location of the associated array
|
||||
floc Location of the associated structure field
|
||||
rdx Display and entry radix
|
||||
wd Field width in bits
|
||||
off Field offset in bits from LSB
|
||||
dep Number of array elements
|
||||
siz Element size in bytes
|
||||
str Array element spacing in bytes
|
||||
|
||||
The macros have the following uses:
|
||||
|
||||
Macro Use with
|
||||
-------- ---------------------------------------------------------------
|
||||
ORDATA Scalar with octal display/entry
|
||||
DRDATA Scalar with decimal display/entry
|
||||
HRDATA Scalar with hexadecimal display/entry
|
||||
BINRDATA Scalar with binary display/entry
|
||||
FLDATA Scalar with single bit display/entry
|
||||
GRDATA Scalar with with specification of radix/width/offset parameters
|
||||
|
||||
BRDATA Singly-subscripted array
|
||||
CRDATA Doubly-subscripted array
|
||||
|
||||
SRDATA Singly-subscripted array of general structure fields
|
||||
URDATA Singly-subscripted array of UNIT structure fields
|
||||
|
||||
XRDATA Generic type with specification of all parameters
|
||||
SAVEDATA Generic type used only for persistence across SAVE/RESTORE
|
||||
|
||||
Normally, scalar and array locations specify the variable name; the names are
|
||||
converted internally to pointers as needed. However, the starting point of
|
||||
a partial array may be specified by passing a pointer to the desired element.
|
||||
For example:
|
||||
|
||||
BRDATA (SYM, array, ...)
|
||||
|
||||
...specifies a register starting with array element zero, while:
|
||||
|
||||
BRDATA (SYM, &array[3], ...)
|
||||
|
||||
...specifies a register starting with array element three.
|
||||
|
||||
For arrays of general structures, the names of the array and selected field
|
||||
are given:
|
||||
|
||||
SRDATA (SYM, array, field, ...)
|
||||
|
||||
This specifies a arrayed register whose elements are array[0].field,
|
||||
array[1].field, etc.
|
||||
|
||||
All above macro names from ORDATA through XRDATA have two additional
|
||||
precisely related macros. The first it the above name with D appended and
|
||||
has an additional parameter which is a quoted string describing the purpose
|
||||
of the register which is visible when displaying HELP about a device's
|
||||
registers. The second related macro has the above name with DF appended
|
||||
and has two additional parameters. The first parameter is the register
|
||||
description, and the second is the name of a BITFIELD array which describes
|
||||
the fields in the register's contents. This info is used to display the
|
||||
register contents (via EXAMINE) along with the detailed bitfield data.
|
||||
For example:
|
||||
|
||||
{ HRDATA (KSP, KSP, 32) },
|
||||
{ HRDATAD (KSP, KSP, 32, "kernel stack pointer") },
|
||||
{ HRDATADF(PSL, PSL, 32, "processor status longword", cpu_psl_bits) },
|
||||
or
|
||||
{ ORDATA (PSW, PSW, 16) },
|
||||
{ ORDATAD (PSW, PSW, 16, "Processor Status Word") },
|
||||
{ ORDATADF(PSW, PSW, 16, "Processor Status Word", psw_bits) },
|
||||
|
||||
|
||||
Implementation notes:
|
||||
|
||||
1. The "_RegCheck" macro is used to ensure that each of the user macros has
|
||||
the correct number of parameters. This improves maintenance reliability,
|
||||
as changes to the REG structure need to be reflected only in the
|
||||
"_RegCheck" macro.
|
||||
|
||||
2. "Stringization" must occur at the first macro call level to support
|
||||
register names that are themselves macros. Otherwise, macro expansion
|
||||
will occur before stringization, resulting in the wrong register name.
|
||||
|
||||
3. Additional REG initialization values may be supplied after a macro
|
||||
invocation. If present, these begin with the "flags" field which is,
|
||||
for the most part, not specified as a macro parameter.
|
||||
|
||||
4. The URDATA macro is obsolescent and present for backward-compatibility.
|
||||
It is a special case of the generic SRDATA macro, which provides the same
|
||||
functionality. Note also that URDATA requires a "flags" parameter value,
|
||||
which is optional for all other macros.
|
||||
|
||||
5. The SAVEDATA macro is useful to indicate global variables whose values
|
||||
must persist across a SAVE and RESTORE. Such data is hidden from the
|
||||
register user interface.
|
||||
*/
|
||||
|
||||
/* 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) \
|
||||
#define _RegCheck(nm,loc,rdx,wd,off,dep,desc,flds,qptr,siz,elesiz,macro) \
|
||||
nm, (loc), (rdx), (wd), (off), (dep), (desc), (flds), (qptr), (siz), sizeof(*(loc)), (elesiz), #macro
|
||||
|
||||
#if defined (__STDC__) || defined (_WIN32) /* Variants which depend on how macro arguments are convered to strings */
|
||||
/* Generic Register declaration for all fields.
|
||||
If the register structure is extended, this macro will be retained and a
|
||||
new internal macro will be provided that populates the new register structure */
|
||||
#define REGDATA(nm,loc,rdx,wd,off,dep,desc,flds,fl,qptr,siz) \
|
||||
_REGDATANF(#nm,&(loc),rdx,wd,off,dep,desc,flds,qptr,siz,sizeof((loc)),REGDATA),(fl)
|
||||
#define REGDATAC(nm,loc,rdx,wd,off,dep,desc,flds,fl,qptr,siz) \
|
||||
_REGDATANF(#nm,&(loc),rdx,wd,off,dep,desc,flds,qptr,siz,sizeof((loc)),REGDATAC),(fl)
|
||||
_RegCheck(#nm,&(loc),rdx,wd,off,dep,desc,flds,qptr,siz,sizeof((loc)),REGDATA),(fl)
|
||||
/* v3 compatible macro */
|
||||
#define XRDATA(nm,loc,rdx,wd,off,dep,siz,str) \
|
||||
_RegCheck(#nm,loc,rdx,wd,off,dep,NULL,NULL,0,siz,sizeof((loc)),XRDATA),(fl)
|
||||
|
||||
/* Right Justified Octal Register Data */
|
||||
#define ORDATA(nm,loc,wd) \
|
||||
_REGDATANF(#nm,&(loc),8,wd,0,1,NULL,NULL,0,0,sizeof((loc)),ORDATA)
|
||||
_RegCheck(#nm,&(loc),8,wd,0,1,NULL,NULL,0,0,sizeof((loc)),ORDATA)
|
||||
#define ORDATAD(nm,loc,wd,desc) \
|
||||
_REGDATANF(#nm,&(loc),8,wd,0,1,desc,NULL,0,0,sizeof((loc)),ORDATAD)
|
||||
_RegCheck(#nm,&(loc),8,wd,0,1,desc,NULL,0,0,sizeof((loc)),ORDATAD)
|
||||
#define ORDATADF(nm,loc,wd,desc,flds) \
|
||||
_REGDATANF(#nm,&(loc),8,wd,0,1,desc,flds,0,0,sizeof((loc)),ORDATADF)
|
||||
_RegCheck(#nm,&(loc),8,wd,0,1,desc,flds,0,0,sizeof((loc)),ORDATADF)
|
||||
/* Right Justified Decimal Register Data */
|
||||
#define DRDATA(nm,loc,wd) \
|
||||
_REGDATANF(#nm,&(loc),10,wd,0,1,NULL,NULL,0,0,sizeof((loc)),DRDATA)
|
||||
_RegCheck(#nm,&(loc),10,wd,0,1,NULL,NULL,0,0,sizeof((loc)),DRDATA)
|
||||
#define DRDATAD(nm,loc,wd,desc) \
|
||||
_REGDATANF(#nm,&(loc),10,wd,0,1,desc,NULL,0,0,sizeof((loc)),DRDATAD)
|
||||
_RegCheck(#nm,&(loc),10,wd,0,1,desc,NULL,0,0,sizeof((loc)),DRDATAD)
|
||||
#define DRDATADF(nm,loc,wd,desc,flds) \
|
||||
_REGDATANF(#nm,&(loc),10,wd,0,1,desc,flds,0,0,sizeof((loc)),DRDATADF)
|
||||
_RegCheck(#nm,&(loc),10,wd,0,1,desc,flds,0,0,sizeof((loc)),DRDATADF)
|
||||
/* Right Justified Hexadecimal Register Data */
|
||||
#define HRDATA(nm,loc,wd) \
|
||||
_REGDATANF(#nm,&(loc),16,wd,0,1,NULL,NULL,0,0,sizeof((loc)),HRDATA)
|
||||
_RegCheck(#nm,&(loc),16,wd,0,1,NULL,NULL,0,0,sizeof((loc)),HRDATA)
|
||||
#define HRDATAD(nm,loc,wd,desc) \
|
||||
_REGDATANF(#nm,&(loc),16,wd,0,1,desc,NULL,0,0,sizeof((loc)),HRDATAD)
|
||||
_RegCheck(#nm,&(loc),16,wd,0,1,desc,NULL,0,0,sizeof((loc)),HRDATAD)
|
||||
#define HRDATADF(nm,loc,wd,desc,flds) \
|
||||
_REGDATANF(#nm,&(loc),16,wd,0,1,desc,flds,0,0,sizeof((loc)),HRDATADF)
|
||||
_RegCheck(#nm,&(loc),16,wd,0,1,desc,flds,0,0,sizeof((loc)),HRDATADF)
|
||||
/* Right Justified Binary Register Data */
|
||||
#define BINRDATA(nm,loc,wd) \
|
||||
_REGDATANF(#nm,&(loc),2,wd,0,1,NULL,NULL,0,0,sizeof((loc)),BINRDATA)
|
||||
_RegCheck(#nm,&(loc),2,wd,0,1,NULL,NULL,0,0,sizeof((loc)),BINRDATA)
|
||||
#define BINRDATAD(nm,loc,wd,desc) \
|
||||
_REGDATANF(#nm,&(loc),2,wd,0,1,desc,NULL,0,0,sizeof((loc)),BINRDATAD)
|
||||
_RegCheck(#nm,&(loc),2,wd,0,1,desc,NULL,0,0,sizeof((loc)),BINRDATAD)
|
||||
#define BINRDATADF(nm,loc,wd,desc,flds) \
|
||||
_REGDATANF(#nm,&(loc),2,wd,0,1,desc,flds,0,0,sizeof((loc)),BINRDATADF)
|
||||
_RegCheck(#nm,&(loc),2,wd,0,1,desc,flds,0,0,sizeof((loc)),BINRDATADF)
|
||||
/* One-bit binary flag at an arbitrary offset in a 32-bit word Register */
|
||||
#define FLDATA(nm,loc,pos) \
|
||||
_REGDATANF(#nm,&(loc),2,1,pos,1,NULL,NULL,0,0,sizeof((loc)),FLDATA)
|
||||
_RegCheck(#nm,&(loc),2,1,pos,1,NULL,NULL,0,0,sizeof((loc)),FLDATA)
|
||||
#define FLDATAD(nm,loc,pos,desc) \
|
||||
_REGDATANF(#nm,&(loc),2,1,pos,1,desc,NULL,0,0,sizeof((loc)),FLDATAD)
|
||||
_RegCheck(#nm,&(loc),2,1,pos,1,desc,NULL,0,0,sizeof((loc)),FLDATAD)
|
||||
#define FLDATADF(nm,loc,pos,desc,flds) \
|
||||
_REGDATANF(#nm,&(loc),2,1,pos,1,desc,flds,0,0,sizeof((loc)),FLDATADF)
|
||||
_RegCheck(#nm,&(loc),2,1,pos,1,desc,flds,0,0,sizeof((loc)),FLDATADF)
|
||||
/* Arbitrary location and Radix Register */
|
||||
#define GRDATA(nm,loc,rdx,wd,pos) \
|
||||
_REGDATANF(#nm,&(loc),rdx,wd,pos,1,NULL,NULL,0,0,sizeof((loc)),GRDATA)
|
||||
_RegCheck(#nm,&(loc),rdx,wd,pos,1,NULL,NULL,0,0,sizeof((loc)),GRDATA)
|
||||
#define GRDATAD(nm,loc,rdx,wd,pos,desc) \
|
||||
_REGDATANF(#nm,&(loc),rdx,wd,pos,1,desc,NULL,0,0,sizeof((loc)),GRDATAD)
|
||||
_RegCheck(#nm,&(loc),rdx,wd,pos,1,desc,NULL,0,0,sizeof((loc)),GRDATAD)
|
||||
#define GRDATADF(nm,loc,rdx,wd,pos,desc,flds) \
|
||||
_REGDATANF(#nm,&(loc),rdx,wd,pos,1,desc,flds,0,0,sizeof((loc)),GRDATADF)
|
||||
_RegCheck(#nm,&(loc),rdx,wd,pos,1,desc,flds,0,0,sizeof((loc)),GRDATADF)
|
||||
/* Arrayed register whose data is kept in a standard C array Register */
|
||||
#define BRDATA(nm,loc,rdx,wd,dep) \
|
||||
_REGDATANF(#nm,&(loc),rdx,wd,0,dep,NULL,NULL,0,0,sizeof(*(loc)),BRDATA)
|
||||
#define BRDATAD(nm,loc,rdx,wd,dep,desc) \
|
||||
_REGDATANF(#nm,&(loc),rdx,wd,0,dep,desc,NULL,0,0,sizeof(*(loc)),BRDATAD)
|
||||
#define BRDATADF(nm,loc,rdx,wd,dep,desc,flds) \
|
||||
_REGDATANF(#nm,&(loc),rdx,wd,0,dep,desc,flds,0,0,sizeof(*(loc)),BRDATADF)
|
||||
#define BRDATA(nm,aloc,rdx,wd,dep) \
|
||||
_RegCheck(#nm,aloc,rdx,wd,0,dep,NULL,NULL,0,0,sizeof(*(aloc)),BRDATA)
|
||||
#define BRDATAD(nm,aloc,rdx,wd,dep,desc) \
|
||||
_RegCheck(#nm,aloc,rdx,wd,0,dep,desc,NULL,0,0,sizeof(*(aloc)),BRDATAD)
|
||||
#define BRDATADF(nm,aloc,rdx,wd,dep,desc,flds) \
|
||||
_RegCheck(#nm,aloc,rdx,wd,0,dep,desc,flds,0,0,sizeof(*(aloc)),BRDATADF)
|
||||
/* Arrayed register whose data is kept in a standard C array Register */
|
||||
#define CRDATA(nm,aloc,rdx,wd,dep) \
|
||||
_RegCheck(#nm,aloc,rdx,wd,0,dep,NULL,NULL,0,0,sizeof(**(aloc)),CRDATA)
|
||||
#define CRDATAD(nm,aloc,rdx,wd,dep,desc) \
|
||||
_RegCheck(#nm,aloc,rdx,wd,0,dep,desc,NULL,0,0,sizeof(**(aloc)),CRDATAD)
|
||||
#define CRDATADF(nm,aloc,rdx,wd,dep,desc,flds) \
|
||||
_RegCheck(#nm,aloc,rdx,wd,0,dep,desc,flds,0,0,sizeof(**(aloc)),CRDATADF)
|
||||
|
||||
/* Range of memory whose data is successive scalar values accessed like an array Register */
|
||||
#define VBRDATA(nm,loc,rdx,wd,dep) \
|
||||
_REGDATANF(#nm,&(loc),rdx,wd,0,dep,NULL,NULL,0,0,sizeof(loc),VBRDATA)
|
||||
_RegCheck(#nm,&(loc),rdx,wd,0,dep,NULL,NULL,0,0,sizeof(loc),VBRDATA)
|
||||
#define VBRDATAD(nm,loc,rdx,wd,dep,desc) \
|
||||
_REGDATANF(#nm,&(loc),rdx,wd,0,dep,desc,NULL,0,0,sizeof(loc),VBRDATAD)
|
||||
_RegCheck(#nm,&(loc),rdx,wd,0,dep,desc,NULL,0,0,sizeof(loc),VBRDATAD)
|
||||
#define VBRDATADF(nm,loc,rdx,wd,dep,desc,flds) \
|
||||
_REGDATANF(#nm,&(loc),rdx,wd,0,dep,desc,flds,0,0,sizeof(loc),VBRDATADF)
|
||||
_RegCheck(#nm,&(loc),rdx,wd,0,dep,desc,flds,0,0,sizeof(loc),VBRDATADF)
|
||||
/* Arrayed register whose data is part of the UNIT structure */
|
||||
#define URDATA(nm,loc,rdx,wd,off,dep,fl) \
|
||||
_REGDATANF(#nm,&(loc),rdx,wd,off,dep,NULL,NULL,0,0,sizeof((loc)),URDATA),((fl) | REG_UNIT)
|
||||
_RegCheck(#nm,&(loc),rdx,wd,off,dep,NULL,NULL,0,sizeof(UNIT),sizeof((loc)),URDATA),(fl)
|
||||
#define URDATAD(nm,loc,rdx,wd,off,dep,fl,desc) \
|
||||
_REGDATANF(#nm,&(loc),rdx,wd,off,dep,desc,NULL,0,0,sizeof((loc)),URDATAD),((fl) | REG_UNIT)
|
||||
_RegCheck(#nm,&(loc),rdx,wd,off,dep,desc,NULL,0,sizeof(UNIT),sizeof((loc)),URDATAD),(fl)
|
||||
#define URDATADF(nm,loc,rdx,wd,off,dep,fl,desc,flds) \
|
||||
_REGDATANF(#nm,&(loc),rdx,wd,off,dep,desc,flds,0,0,sizeof((loc)),URDATADF),((fl) | REG_UNIT)
|
||||
_RegCheck(#nm,&(loc),rdx,wd,off,dep,desc,flds,0,sizeof(UNIT),sizeof((loc)),URDATADF),(fl)
|
||||
/* Arrayed register whose data is part of an arbitrary structure */
|
||||
#define STRDATA(nm,loc,rdx,wd,off,dep,siz,fl) \
|
||||
_REGDATANF(#nm,&(loc),rdx,wd,off,dep,NULL,NULL,0,siz,sizeof((loc)),STRDATA),((fl) | REG_STRUCT)
|
||||
_RegCheck(#nm,&(loc),rdx,wd,off,dep,NULL,NULL,0,siz,sizeof((loc)),STRDATA),(fl)
|
||||
#define STRDATAD(nm,loc,rdx,wd,off,dep,siz,fl,desc) \
|
||||
_REGDATANF(#nm,&(loc),rdx,wd,off,dep,desc,NULL,0,siz,sizeof((loc)),STRDATAD),((fl) | REG_STRUCT)
|
||||
_RegCheck(#nm,&(loc),rdx,wd,off,dep,desc,NULL,0,siz,sizeof((loc)),STRDATAD),(fl)
|
||||
#define STRDATADF(nm,loc,rdx,wd,off,dep,siz,fl,desc,flds) \
|
||||
_REGDATANF(#nm,&(loc),rdx,wd,off,dep,desc,flds,0,siz,sizeof((loc)),STRDATADF),((fl) | REG_STRUCT)
|
||||
_RegCheck(#nm,&(loc),rdx,wd,off,dep,desc,flds,0,siz,sizeof((loc)),STRDATADF),(fl)
|
||||
/* Hidden Blob of Data - Only used for SAVE/RESTORE */
|
||||
#define SAVEDATA(nm,loc) \
|
||||
_REGDATANF(#nm,&(loc),0,8,0,1,NULL,NULL,0,sizeof(loc),sizeof(loc),SAVEDATA),(REG_HRO)
|
||||
_RegCheck(#nm,&(loc),0,8,0,1,NULL,NULL,0,sizeof(loc),sizeof(loc),SAVEDATA),(REG_HRO)
|
||||
#define STARTBIT {"", 0x00000000, 0, NULL, NULL} /* Start at beginning bit */
|
||||
#define BIT(nm) {#nm, 0xffffffff, 1, NULL, NULL} /* Single Bit definition */
|
||||
#define BITNC {"", 0xffffffff, 1, NULL, NULL} /* Don't care Bit definition */
|
||||
|
@ -995,95 +1111,6 @@ struct MEMFILE {
|
|||
#define BITNCF(sz) {"", 0xffffffff, sz, NULL, NULL} /* Don't care Bit Field definition */
|
||||
#define BITFFMT(nm,sz,fmt) {#nm, 0xffffffff, sz, NULL, #fmt} /* Bit Field definition with Output format */
|
||||
#define BITFNAM(nm,sz,names) {#nm, 0xffffffff, sz, names,NULL} /* Bit Field definition with value->name map */
|
||||
#else /* For non-STD-C compiler which can't stringify macro arguments with # */
|
||||
/* Generic Register declaration for all fields.
|
||||
If the register structure is extended, this macro will be retained and a
|
||||
new macro will be provided that populates the new register structure */
|
||||
#define REGDATA(nm,loc,rdx,wd,off,dep,desc,flds,fl,qptr,siz) \
|
||||
_REGDATANF("nm",&(loc),rdx,wd,off,dep,desc,flds,qptr,siz,sizeof((loc)),REGDATA),(fl)
|
||||
#define REGDATAC(nm,loc,rdx,wd,off,dep,desc,flds,fl,qptr,siz) \
|
||||
_REGDATANF("nm",&(loc),rdx,wd,off,dep,desc,flds,qptr,siz,sizeof((loc)),REGDATAC),(fl)
|
||||
/* Right Justified Octal Register Data */
|
||||
#define ORDATA(nm,loc,wd) \
|
||||
_REGDATANF("nm",&(loc),8,wd,0,1,NULL,NULL,0,0,sizeof((loc)),ORDATA)
|
||||
#define ORDATAD(nm,loc,wd,desc) \
|
||||
_REGDATANF("nm",&(loc),8,wd,0,1,desc,NULL,0,0,sizeof((loc)),ORDATAD)
|
||||
#define ORDATADF(nm,loc,wd,desc,flds) \
|
||||
_REGDATANF("nm",&(loc),8,wd,0,1,desc,flds,0,0,sizeof((loc)),ORDATADF)
|
||||
/* Right Justified Decimal Register Data */
|
||||
#define DRDATA(nm,loc,wd) \
|
||||
_REGDATANF("nm",&(loc),10,wd,0,1,NULL,NULL,0,0,sizeof((loc)),DRDATA)
|
||||
#define DRDATAD(nm,loc,wd,desc) \
|
||||
_REGDATANF("nm",&(loc),10,wd,0,1,desc,NULL,0,0,sizeof((loc)),DRDATAD)
|
||||
#define DRDATADF(nm,loc,wd,desc,flds) \
|
||||
_REGDATANF("nm",&(loc),10,wd,0,1,desc,flds,0,0,sizeof((loc)),DRDATADF)
|
||||
/* Right Justified Hexadecimal Register Data */
|
||||
#define HRDATA(nm,loc,wd) \
|
||||
_REGDATANF("nm",&(loc),16,wd,0,1,NULL,NULL,0,0,sizeof((loc)),HRDATA)
|
||||
#define HRDATAD(nm,loc,wd,desc) \
|
||||
_REGDATANF("nm",&(loc),16,wd,0,1,desc,NULL,0,0,sizeof((loc)),HRDATAD)
|
||||
#define HRDATADF(nm,loc,wd,desc,flds) \
|
||||
_REGDATANF("nm",&(loc),16,wd,0,1,desc,flds,0,0,sizeof((loc)),HRDATADF)
|
||||
/* Right Justified Binary Register Data */
|
||||
#define BINRDATA(nm,loc,wd) \
|
||||
_REGDATANF("nm",&(loc),2,wd,0,1,NULL,NULL,0,0,sizeof((loc)),BINRDATA)
|
||||
#define BINRDATAD(nm,loc,wd,desc) \
|
||||
_REGDATANF("nm",&(loc),2,wd,0,1,desc,NULL,0,0,sizeof((loc)),BINRDATAD)
|
||||
#define BINRDATADF(nm,loc,wd,desc,flds) \
|
||||
_REGDATANF("nm",&(loc),2,wd,0,1,desc,flds,0,0,sizeof((loc)),BINRDATADF)
|
||||
/* One-bit binary flag at an arbitrary offset in a 32-bit word Register */
|
||||
#define FLDATA(nm,loc,pos) \
|
||||
_REGDATANF("nm",&(loc),2,1,pos,1,NULL,NULL,0,0,sizeof((loc)),FLDATA)
|
||||
#define FLDATAD(nm,loc,pos,desc) \
|
||||
_REGDATANF("nm",&(loc),2,1,pos,1,desc,NULL,0,0,sizeof((loc)),FLDATAD)
|
||||
#define FLDATADF(nm,loc,pos,desc,flds) \
|
||||
_REGDATANF("nm",&(loc),2,1,pos,1,desc,flds,0,0,sizeof((loc)),FLDATADF)
|
||||
/* Arbitrary location and Radix Register */
|
||||
#define GRDATA(nm,loc,rdx,wd,pos) \
|
||||
_REGDATANF("nm",&(loc),rdx,wd,pos,1,NULL,NULL,0,0,sizeof((loc)),GRDATA)
|
||||
#define GRDATAD(nm,loc,rdx,wd,pos,desc) \
|
||||
_REGDATANF("nm",&(loc),rdx,wd,pos,1,desc,NULL,0,0,sizeof((loc)),GRDATAD)
|
||||
#define GRDATADF(nm,loc,rdx,wd,pos,desc,flds) \
|
||||
_REGDATANF("nm",&(loc),rdx,wd,pos,1,desc,flds,0,0,sizeof((loc)),GRDATADF)
|
||||
/* Arrayed register whose data is kept in a standard C array Register */
|
||||
#define BRDATA(nm,loc,rdx,wd,dep) \
|
||||
_REGDATANF("nm",&(loc),rdx,wd,0,dep,NULL,NULL,0,0,sizeof(*(loc)),BRDATA)
|
||||
#define BRDATAD(nm,loc,rdx,wd,dep,desc) \
|
||||
_REGDATANF("nm",&(loc),rdx,wd,0,dep,desc,NULL,0,0,sizeof(*(loc)),BRDATAD)
|
||||
#define BRDATADF(nm,loc,rdx,wd,dep,desc,flds) \
|
||||
_REGDATANF("nm",&(loc),rdx,wd,0,dep,desc,flds,0,0,sizeof(*(loc)),BRDATADF)
|
||||
/* Range of memory whose data is successive scalar values accessed like an array Register */
|
||||
#define VBRDATA(nm,loc,rdx,wd,dep) \
|
||||
_REGDATANF("nm",&(loc),rdx,wd,0,dep,NULL,NULL,0,0,sizeof(loc),VBRDATA)
|
||||
#define VBRDATAD(nm,loc,rdx,wd,dep,desc) \
|
||||
_REGDATANF("nm",&(loc),rdx,wd,0,dep,desc,NULL,0,0,sizeof(loc),VBRDATAD)
|
||||
#define VBRDATADF(nm,loc,rdx,wd,dep,desc,flds) \
|
||||
_REGDATANF("nm",&(loc),rdx,wd,0,dep,desc,flds,0,0,sizeof(loc),VBRDATADF)
|
||||
/* Arrayed register whose data is part of the UNIT structure */
|
||||
#define URDATA(nm,loc,rdx,wd,off,dep,fl) \
|
||||
_REGDATANF("nm",&(loc),rdx,wd,off,dep,NULL,NULL,0,0,sizeof((loc)),URDATA),((fl) | REG_UNIT)
|
||||
#define URDATAD(nm,loc,rdx,wd,off,dep,fl,desc) \
|
||||
_REGDATANF("nm",&(loc),rdx,wd,off,dep,desc,NULL,0,0,sizeof((loc)),URDATAD),((fl) | REG_UNIT)
|
||||
#define URDATADF(nm,loc,rdx,wd,off,dep,fl,desc,flds) \
|
||||
_REGDATANF("nm",&(loc),rdx,wd,off,dep,desc,flds,0,0,sizeof((loc)),URDATADF),((fl) | REG_UNIT)
|
||||
/* Arrayed register whose data is part of an arbitrary structure */
|
||||
#define STRDATA(nm,loc,rdx,wd,off,dep,siz,fl) \
|
||||
_REGDATANF("nm",&(loc),rdx,wd,off,dep,NULL,NULL,0,siz,sizeof((loc)),STRDATA),((fl) | REG_STRUCT)
|
||||
#define STRDATAD(nm,loc,rdx,wd,off,dep,siz,fl,desc) \
|
||||
_REGDATANF("nm",&(loc),rdx,wd,off,dep,desc,NULL,0,siz,sizeof((loc)),STRDATAD),((fl) | REG_STRUCT)
|
||||
#define STRDATADF(nm,loc,rdx,wd,off,dep,siz,fl,desc,flds) \
|
||||
_REGDATANF("nm",&(loc),rdx,wd,off,dep,desc,flds,0,siz,sizeof((loc)),STRDATADF),((fl) | REG_STRUCT)
|
||||
/* Hidden Blob of Data - Only used for SAVE/RESTORE */
|
||||
#define SAVEDATA(nm,loc) \
|
||||
_REGDATANF("nm",&(loc),0,8,0,1,NULL,NULL,0,sizeof(loc),sizeof(loc)),SAVEDATA),(REG_HRO)
|
||||
#define STARTBIT {"", 0x00000000, 0, NULL, NULL} /* Start at beginning bit */
|
||||
#define BIT(nm) {"nm", 0xffffffff, 1, NULL, NULL} /* Single Bit definition */
|
||||
#define BITNC {"", 0xffffffff, 1, NULL, NULL} /* Don't care Bit definition */
|
||||
#define BITF(nm,sz) {"nm", 0xffffffff, sz, NULL, NULL} /* Bit Field definition */
|
||||
#define BITNCF(sz) {"", 0xffffffff, sz, NULL, NULL} /* Don't care Bit Field definition */
|
||||
#define BITFFMT(nm,sz,fmt) {"nm", 0xffffffff, sz, NULL, "fmt"}/* Bit Field definition with Output format */
|
||||
#define BITFNAM(nm,sz,names) {"nm", 0xffffffff, sz, names,NULL} /* Bit Field definition with value->name map */
|
||||
#endif
|
||||
#define ENDBITS {NULL} /* end of bitfield list */
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue