SCP: Add optional write_callback to REGister structure called only on DEPOSIT

Add necessary macros to populate this field and cleanup all the
existing macros to be simpler.
This commit is contained in:
Mark Pizzolato 2017-11-19 08:18:02 -08:00
parent 8b1af8b862
commit 61679ed8f0
3 changed files with 97 additions and 87 deletions

Binary file not shown.

5
scp.c
View file

@ -7637,6 +7637,7 @@ void put_rval (REG *rptr, uint32 idx, t_value val)
{ {
size_t sz; size_t sz;
t_value mask; t_value mask;
t_value old_val;
uint32 *ptr; uint32 *ptr;
#define PUT_RVAL(sz,rp,id,v,m) \ #define PUT_RVAL(sz,rp,id,v,m) \
@ -7644,6 +7645,8 @@ uint32 *ptr;
(sz)((*(((sz *) rp->loc) + id) & \ (sz)((*(((sz *) rp->loc) + id) & \
~((m) << (rp)->offset)) | ((v) << (rp)->offset)) ~((m) << (rp)->offset)) | ((v) << (rp)->offset))
if (rptr->write_callback)
old_val = get_rval (rptr, idx);
if (rptr == sim_PC) if (rptr == sim_PC)
sim_brk_npc (0); sim_brk_npc (0);
sz = SZ_R (rptr); sz = SZ_R (rptr);
@ -7696,6 +7699,8 @@ else PUT_RVAL (t_uint64, rptr, idx, val, mask);
#else #else
else PUT_RVAL (uint32, rptr, idx, val, mask); else PUT_RVAL (uint32, rptr, idx, val, mask);
#endif #endif
if ((rptr->write_callback) && (!(sim_switches & SIM_SW_REST)))
rptr->write_callback (old_val, rptr, idx);
return; return;
} }

View file

@ -648,9 +648,12 @@ struct REG {
uint32 depth; /* save depth */ uint32 depth; /* save depth */
const char *desc; /* description */ const char *desc; /* description */
BITFIELD *fields; /* bit fields */ BITFIELD *fields; /* bit fields */
uint32 flags; /* flags */
uint32 qptr; /* circ q ptr */ uint32 qptr; /* circ q ptr */
size_t str_size; /* structure size */ size_t str_size; /* structure size */
void (*write_callback)(t_value old_value, REG *rptr, int idx);
/* called during DEPOSIT */
/* NOTE: Flags MUST always be last since it is initialized outside of macro definitions */
uint32 flags; /* flags */
}; };
/* Register flags */ /* Register flags */
@ -855,111 +858,113 @@ 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,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,cbak) \
nm, (loc), (rdx), (wd), (off), (dep), (desc), (flds), (qptr), (siz), (cbak)
/* Right Justified Octal Register Data */
#define ORDATA(nm,loc,wd) ORDATAD(nm,loc,wd,NULL)
/* Right Justified Decimal Register Data */
#define DRDATA(nm,loc,wd) DRDATAD(nm,loc,wd,NULL)
/* Right Justified Hexadecimal Register Data */
#define HRDATA(nm,loc,wd) HRDATAD(nm,loc,wd,NULL)
/* Right Justified Binary Register Data */
#define BINRDATA(nm,loc,wd) BINRDATAD(nm,loc,wd,NULL)
/* One-bit binary flag at an arbitrary offset in a 32-bit word Register */
#define FLDATA(nm,loc,pos) FLDATAD(nm,loc,pos,NULL)
/* Arbitrary location and Radix Register */
#define GRDATA(nm,loc,rdx,wd,pos) GRDATAD(nm,loc,rdx,wd,pos,NULL)
/* Arrayed register whose data is kept in a standard C array Register */
#define BRDATA(nm,loc,rdx,wd,dep) BRDATAD(nm,loc,rdx,wd,dep,NULL)
/* Arrayed register whose data is part of the UNIT structure */
#define URDATA(nm,loc,rdx,wd,off,dep,fl) URDATAD(nm,loc,rdx,wd,off,dep,fl,NULL)
/* Arrayed register whose data is part of an arbitrary structure */
#define STRDATA(nm,loc,rdx,wd,off,dep,siz,fl) STRDATAD(nm,loc,rdx,wd,off,dep,siz,fl,NULL)
/* Same as above, but with additional description initializer */
#define ORDATAD(nm,loc,wd,desc) ORDATADF(nm,loc,wd,desc,NULL)
#define DRDATAD(nm,loc,wd,desc) DRDATADF(nm,loc,wd,desc,NULL)
#define HRDATAD(nm,loc,wd,desc) HRDATADF(nm,loc,wd,desc,NULL)
#define BINRDATAD(nm,loc,wd,desc) BINRDATADF(nm,loc,wd,desc,NULL)
#define FLDATAD(nm,loc,pos,desc) FLDATADF(nm,loc,pos,desc,NULL)
#define GRDATAD(nm,loc,rdx,wd,pos,desc) GRDATADF(nm,loc,rdx,wd,pos,desc,NULL)
#define BRDATAD(nm,loc,rdx,wd,dep,desc) BRDATADF(nm,loc,rdx,wd,dep,desc,NULL)
#define URDATAD(nm,loc,rdx,wd,off,dep,fl,desc) URDATADF(nm,loc,rdx,wd,off,dep,fl,desc,NULL)
#define STRDATAD(nm,loc,rdx,wd,off,dep,siz,fl,desc) STRDATADF(nm,loc,rdx,wd,off,dep,siz,fl,desc,NULL)
/* Same as above, but with additional description initializer, and bitfields */
#define ORDATADF(nm,loc,wd,desc,flds) ORDATADFC(nm,loc,wd,desc,flds,NULL)
#define DRDATADF(nm,loc,wd,desc,flds) DRDATADFC(nm,loc,wd,desc,flds,NULL)
#define HRDATADF(nm,loc,wd,desc,flds) HRDATADFC(nm,loc,wd,desc,flds,NULL)
#define BINRDATADF(nm,loc,wd,desc,flds) BINRDATADFC(nm,loc,wd,desc,flds,NULL)
#define FLDATADF(nm,loc,pos,desc,flds) FLDATADFC(nm,loc,pos,desc,flds,NULL)
#define GRDATADF(nm,loc,rdx,wd,pos,desc,flds) GRDATADFC(nm,loc,rdx,wd,pos,desc,flds,NULL)
#define BRDATADF(nm,loc,rdx,wd,dep,desc,flds) BRDATADFC(nm,loc,rdx,wd,dep,desc,flds,NULL)
#define URDATADF(nm,loc,rdx,wd,off,dep,fl,desc,flds) URDATADFC(nm,loc,rdx,wd,off,dep,fl,desc,flds,NULL)
#define STRDATADF(nm,loc,rdx,wd,off,dep,siz,fl,desc,flds) STRDATADFC(nm,loc,rdx,wd,off,dep,siz,fl,desc,flds,NULL)
#if defined (__STDC__) || defined (_WIN32) /* Variants which depend on how macro arguments are convered to strings */ #if defined (__STDC__) || defined (_WIN32) /* Variants which depend on how macro arguments are convered to strings */
/* Generic Register declaration for all fields. /* Generic Register declaration for all fields.
If the register structure is extended, this macro will be retained and a If the register structure is extended, this macro will be retained and a
new macro will be provided that populates the new register structure */ new macro will be provided that populates the new register structure */
#define REGDATA(nm,loc,rdx,wd,off,dep,desc,flds,fl,qptr,siz) \ #define REGDATA(nm,loc,rdx,wd,off,dep,desc,flds,fl,qptr,siz) \
#nm, &(loc), (rdx), (wd), (off), (dep), (desc), (flds), (fl), (qptr), (siz) _REGDATANF(#nm,&(loc),rdx,wd,off,dep,desc,flds,qptr,siz,NULL),(fl)
/* Internal use ONLY (see below) Generic Register declaration for all fields */ /* Same as above, but with callback initializer */
#define _REGDATA(nm,loc,rdx,wd,off,dep,desc,flds,fl,qptr,siz) \ #define ORDATADFC(nm,loc,wd,desc,flds,cbk) \
nm, &(loc), (rdx), (wd), (off), (dep), (desc), (flds), (fl), (qptr), (siz) _REGDATANF(#nm,&(loc),8,wd,0,1,desc,flds,0,0,cbk)
/* Right Justified Octal Register Data */ #define DRDATADFC(nm,loc,wd,desc,flds,cbk) \
#define ORDATA(nm,loc,wd) #nm, &(loc), 8, (wd), 0, 1, NULL, NULL _REGDATANF(#nm,&(loc),10,wd,0,1,desc,flds,0,0,cbk)
/* Right Justified Decimal Register Data */ #define HRDATADFC(nm,loc,wd,desc,flds,cbk) \
#define DRDATA(nm,loc,wd) #nm, &(loc), 10, (wd), 0, 1, NULL, NULL _REGDATANF(#nm,&(loc),16,wd,0,1,desc,flds,0,0,cbk)
/* Right Justified Hexadecimal Register Data */ #define BINRDATADFC(nm,loc,wd,desc,flds,cbk) \
#define HRDATA(nm,loc,wd) #nm, &(loc), 16, (wd), 0, 1, NULL, NULL _REGDATANF(#nm,&(loc),2,wd,0,1,desc,flds,0,0,cbk)
/* Right Justified Binary Register Data */ #define FLDATADFC(nm,loc,pos,desc,flds,cbk) \
#define BINRDATA(nm,loc,wd) #nm, &(loc), 2, (wd), 0, 1, NULL, NULL _REGDATANF(#nm,&(loc),2,1,pos,1,desc,flds,0,0,cbk)
/* One-bit binary flag at an arbitrary offset in a 32-bit word Register */ #define GRDATADFC(nm,loc,rdx,wd,pos,desc,flds,cbk) \
#define FLDATA(nm,loc,pos) #nm, &(loc), 2, 1, (pos), 1, NULL, NULL _REGDATANF(#nm,&(loc),rdx,wd,pos,1,desc,flds,0,0,cbk)
/* Arbitrary location and Radix Register */ #define BRDATADFC(nm,loc,rdx,wd,dep,desc,flds,cbk) \
#define GRDATA(nm,loc,rdx,wd,pos) #nm, &(loc), (rdx), (wd), (pos), 1, NULL, NULL _REGDATANF(#nm,loc,rdx,wd,0,dep,desc,flds,0,0,cbk)
/* Arrayed register whose data is kept in a standard C array Register */ #define URDATADFC(nm,loc,rdx,wd,off,dep,fl,desc,flds,cbk) \
#define BRDATA(nm,loc,rdx,wd,dep) #nm, (loc), (rdx), (wd), 0, (dep), NULL, NULL _REGDATANF(#nm,&(loc),rdx,wd,off,dep,desc,flds,0,0,cbk),((fl) | REG_UNIT)
/* Same as above, but with additional description initializer */ #define STRDATADFC(nm,loc,rdx,wd,off,dep,siz,fl,desc,flds,cbk) \
#define ORDATAD(nm,loc,wd,desc) #nm, &(loc), 8, (wd), 0, 1, (desc), NULL _REGDATANF(#nm,&(loc),rdx,wd,off,dep,desc,flds,0,siz,cbk),((fl) | REG_STRUCT)
#define DRDATAD(nm,loc,wd,desc) #nm, &(loc), 10, (wd), 0, 1, (desc), NULL
#define HRDATAD(nm,loc,wd,desc) #nm, &(loc), 16, (wd), 0, 1, (desc), NULL
#define BINRDATAD(nm,loc,wd,desc) #nm, &(loc), 2, (wd), 0, 1, (desc), NULL
#define FLDATAD(nm,loc,pos,desc) #nm, &(loc), 2, 1, (pos), 1, (desc), NULL
#define GRDATAD(nm,loc,rdx,wd,pos,desc) #nm, &(loc), (rdx), (wd), (pos), 1, (desc), NULL
#define BRDATAD(nm,loc,rdx,wd,dep,desc) #nm, (loc), (rdx), (wd), 0, (dep), (desc), NULL
/* Same as above, but with additional description initializer, and bitfields */
#define ORDATADF(nm,loc,wd,desc,flds) #nm, &(loc), 8, (wd), 0, 1, (desc), (flds)
#define DRDATADF(nm,loc,wd,desc,flds) #nm, &(loc), 10, (wd), 0, 1, (desc), (flds)
#define HRDATADF(nm,loc,wd,desc,flds) #nm, &(loc), 16, (wd), 0, 1, (desc), (flds)
#define BINRDATADF(nm,loc,wd) #nm, &(loc), 2, (wd), 0, 1, NULL, NULL
#define FLDATADF(nm,loc,pos,desc,flds) #nm, &(loc), 2, 1, (pos), 1, (desc), (flds)
#define GRDATADF(nm,loc,rdx,wd,pos,desc,flds) #nm, &(loc), (rdx), (wd), (pos), 1, (desc), (flds)
#define BRDATADF(nm,loc,rdx,wd,dep,desc,flds) #nm, (loc), (rdx), (wd), 0, (dep), (desc), (flds)
#define BIT(nm) {#nm, 0xffffffff, 1} /* Single Bit definition */ #define BIT(nm) {#nm, 0xffffffff, 1} /* Single Bit definition */
#define BITNC {"", 0xffffffff, 1} /* Don't care Bit definition */ #define BITNC {"", 0xffffffff, 1} /* Don't care Bit definition */
#define BITF(nm,sz) {#nm, 0xffffffff, sz} /* Bit Field definition */ #define BITF(nm,sz) {#nm, 0xffffffff, sz} /* Bit Field definition */
#define BITNCF(sz) {"", 0xffffffff, sz} /* Don't care Bit Field definition */ #define BITNCF(sz) {"", 0xffffffff, sz} /* Don't care Bit Field definition */
#define BITFFMT(nm,sz,fmt) {#nm, 0xffffffff, sz, NULL, #fmt}/* Bit Field definition with Output format */ #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} /* Bit Field definition with value->name map */ #define BITFNAM(nm,sz,names) {#nm, 0xffffffff, sz, names} /* Bit Field definition with value->name map */
/* Arrayed register whose data is part of the UNIT structure */
#define URDATA(nm,loc,rdx,wd,off,dep,fl) \
_REGDATA(#nm,(loc),(rdx),(wd),(off),(dep),NULL,NULL,((fl) | REG_UNIT),0,0)
/* Arrayed register whose data is part of an arbitrary structure */
#define STRDATA(nm,loc,rdx,wd,off,dep,siz,fl) \
_REGDATA(#nm,(loc),(rdx),(wd),(off),(dep),NULL,NULL,((fl) | REG_STRUCT),0,(siz))
/* Same as above, but with additional description initializer */
#define URDATAD(nm,loc,rdx,wd,off,dep,fl,desc) \
_REGDATA(#nm,(loc),(rdx),(wd),(off),(dep),(desc),NULL,((fl) | REG_UNIT),0,0)
#define STRDATAD(nm,loc,rdx,wd,off,dep,siz,fl,desc) \
_REGDATA(#nm,(loc),(rdx),(wd),(off),(dep),(desc),NULL,((fl) | REG_STRUCT),0,(siz))
/* Same as above, but with additional description initializer, and bitfields */
#define URDATADF(nm,loc,rdx,wd,off,dep,fl,desc,flds) \
_REGDATA(#nm,(loc),(rdx),(wd),(off),(dep),(desc),(flds),((fl) | REG_UNIT),0,0)
#define STRDATADF(nm,loc,rdx,wd,off,dep,siz,fl,desc,flds) \
_REGDATA(#nm,(loc),(rdx),(wd),(off),(dep),(desc),(flds),((fl) | REG_STRUCT),0,(siz))
#else /* For non-STD-C compiler which can't stringify macro arguments with # */ #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) \ #define REGDATA(nm,loc,rdx,wd,off,dep,desc,flds,fl,qptr,siz) \
"nm", &(loc), (rdx), (wd), (off), (dep), (desc), (flds), (fl), (qptr), (siz) _REGDATANF("nm",&(loc),rdx,wd,off,dep,desc,flds,qptr,siz,NULL),(fl)
#define _REGDATA(nm,loc,rdx,wd,off,dep,desc,flds,fl,qptr,siz) \ /* Same as above, but with callback initializer */
nm, &(loc), (rdx), (wd), (off), (dep), (desc), (flds), (fl), (qptr), (siz) #define ORDATADFC(nm,loc,wd,desc,flds,cbk) \
#define ORDATA(nm,loc,wd) "nm", &(loc), 8, (wd), 0, 1, NULL, NULL _REGDATANF("nm",&(loc),8,wd,0,1,desc,flds,0,0,cbk)
#define DRDATA(nm,loc,wd) "nm", &(loc), 10, (wd), 0, 1, NULL, NULL #define DRDATADFC(nm,loc,wd,desc,flds,cbk) \
#define HRDATA(nm,loc,wd) "nm", &(loc), 16, (wd), 0, 1, NULL, NULL _REGDATANF("nm",&(loc),10,wd,0,1,desc,flds,0,0,cbk)
#define BINRDATA(nm,loc,wd) "nm", &(loc), 2, (wd), 0, 1, NULL, NULL #define HRDATADFC(nm,loc,wd,desc,flds,cbk) \
#define FLDATA(nm,loc,pos) "nm", &(loc), 2, 1, (pos), 1, NULL, NULL _REGDATANF("nm",&(loc),16,wd,0,1,desc,flds,0,0,cbk)
#define GRDATA(nm,loc,rdx,wd,pos) "nm", &(loc), (rdx), (wd), (pos), 1, NULL, NULL #define BINRDATADFC(nm,loc,wd,cbk) \
#define BRDATA(nm,loc,rdx,wd,dep) "nm", (loc), (rdx), (wd), 0, (dep), NULL, NULL _REGDATANF("nm",&(loc),2,wd,0,1,desc,flds,0,0,cbk)
#define ORDATAD(nm,loc,wd,desc) "nm", &(loc), 8, (wd), 0, 1, (desc), NULL #define FLDATADFC(nm,loc,pos,desc,flds,cbk) \
#define DRDATAD(nm,loc,wd,desc) "nm", &(loc), 10, (wd), 0, 1, (desc), NULL _REGDATANF("nm",&(loc),2,1,pos,1,desc,flds,0,0,cbk)
#define HRDATAD(nm,loc,wd,desc) "nm", &(loc), 16, (wd), 0, 1, (desc), NULL #define GRDATADFC(nm,loc,rdx,wd,pos,desc,flds,cbk) \
#define BINRDATAD(nm,loc,wd,desc) "nm", &(loc), 2, (wd), 0, 1, (desc), NULL _REGDATANF("nm",&(loc),rdx,wd,pos,1,desc,flds,0,0,cbk)
#define FLDATAD(nm,loc,pos,desc) "nm", &(loc), 2, 1, (pos), 1, (desc), NULL #define BRDATADFC(nm,loc,rdx,wd,dep,desc,flds,cbk) \
#define GRDATAD(nm,loc,rdx,wd,pos,desc) "nm", &(loc), (rdx), (wd), (pos), 1, (desc), NULL _REGDATANF("nm",loc,rdx,wd,0,dep,desc,flds,0,0,cbk)
#define BRDATAD(nm,loc,rdx,wd,dep,desc) "nm", (loc), (rdx), (wd), 0, (dep), (desc), NULL #define URDATADFC(nm,loc,rdx,wd,off,dep,fl,desc,flds,cbk) \
#define ORDATADF(nm,loc,wd,desc,flds) "nm", &(loc), 8, (wd), 0, 1, (desc), (flds) _REGDATANF("nm",&(loc),rdx,wd,off,dep,desc,flds,0,0,cbk),((fl) | REG_UNIT)
#define DRDATADF(nm,loc,wd,desc,flds) "nm", &(loc), 10, (wd), 0, 1, (desc), (flds) #define STRDATADFC(nm,loc,rdx,wd,off,dep,siz,fl,desc,flds,cbk) \
#define HRDATADF(nm,loc,wd,desc,flds) "nm", &(loc), 16, (wd), 0, 1, (desc), (flds) _REGDATANF("nm",&(loc),rdx,wd,off,dep,desc,flds,0,siz,cbk),((fl) | REG_STRUCT)
#define BINRDATADF(nm,loc,wd,desc,flds) "nm", &(loc), 2, (wd), 0, 1, (desc), (flds) #define REGDATA(nm,loc,rdx,wd,off,dep,desc,flds,fl,qptr,siz) \
#define FLDATADF(nm,loc,pos,desc,flds) "nm", &(loc), 2, 1, (pos), 1, (desc), (flds) "nm", &(loc), (rdx), (wd), (off), (dep), (desc), (flds), (qptr), (siz), NULL, (fl)
#define GRDATADF(nm,loc,rdx,wd,pos,desc,flds) "nm", &(loc), (rdx), (wd), (pos), 1, (desc), (flds)
#define BRDATADF(nm,loc,rdx,wd,dep,desc,flds) "nm", (loc), (rdx), (wd), 0, (dep), (desc), (flds)
#define BIT(nm) {"nm", 0xffffffff, 1} /* Single Bit definition */ #define BIT(nm) {"nm", 0xffffffff, 1} /* Single Bit definition */
#define BITNC {"", 0xffffffff, 1} /* Don't care Bit definition */ #define BITNC {"", 0xffffffff, 1} /* Don't care Bit definition */
#define BITF(nm,sz) {"nm", 0xffffffff, sz} /* Bit Field definition */ #define BITF(nm,sz) {"nm", 0xffffffff, sz} /* Bit Field definition */
#define BITNCF(sz) {"", 0xffffffff, sz} /* Don't care Bit Field definition */ #define BITNCF(sz) {"", 0xffffffff, sz} /* Don't care Bit Field definition */
#define BITFFMT(nm,sz,fmt) {"nm", 0xffffffff, sz, NULL, "fmt"}/* Bit Field definition with Output format */ #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} /* Bit Field definition with value->name map */ #define BITFNAM(nm,sz,names) {"nm", 0xffffffff, sz, names} /* Bit Field definition with value->name map */
#define URDATA(nm,loc,rdx,wd,off,dep,fl) \
_REGDATA("nm",(loc),(rdx),(wd),(off),(dep),NULL,NULL,((fl) | REG_UNIT),0,0)
#define STRDATA(nm,loc,rdx,wd,off,dep,siz,fl) \
_REGDATA("nm",(loc),(rdx),(wd),(off),(dep),NULL,NULL,((fl) | REG_STRUCT),0,(siz))
#define URDATAD(nm,loc,rdx,wd,off,dep,fl,desc) \
_REGDATA("nm",(loc),(rdx),(wd),(off),(dep),(desc),NULL,((fl) | REG_UNIT),0,0)
#define STRDATAD(nm,loc,rdx,wd,off,dep,siz,fl,desc) \
_REGDATA("nm",(loc),(rdx),(wd),(off),(dep),(desc),NULL,((fl) | REG_STRUCT),0,(siz))
#define URDATADF(nm,loc,rdx,wd,off,dep,fl,desc,flds) \
_REGDATA("nm",(loc),(rdx),(wd),(off),(dep),(desc),(flds),((fl) | REG_UNIT),0,0)
#define STRDATADF(nm,loc,rdx,wd,off,dep,siz,fl,desc,flds) \
_REGDATA("nm",(loc),(rdx),(wd),(off),(dep),(desc),(flds),((fl) | REG_STRUCT),0,(siz))
#endif #endif
#define ENDBITS {NULL} /* end of bitfield list */ #define ENDBITS {NULL} /* end of bitfield list */