diff --git a/src/frontend/outitf.c b/src/frontend/outitf.c index 2ca77f5a1..75f7f4cfd 100644 --- a/src/frontend/outitf.c +++ b/src/frontend/outitf.c @@ -83,7 +83,7 @@ int fixme_inoise_type = SV_NOTYPE; static clock_t lastclock, currclock; static double *rowbuf; -static size_t column, rowbuflen; +static size_t column, rowbuflen, doornroosje = 0; static bool shouldstop = FALSE; /* Tell simulator to stop next time it asks. */ @@ -175,6 +175,7 @@ beginPlot(JOB *analysisPtr, CKTcircuit *circuitPtr, char *cktName, char *analNam run->type = copy(analName); run->windowed = windowed; run->numData = 0; + run->spindex = -1; // mhx an_name = spice_analysis_get_name(analysisPtr->JOBtype); ft_curckt->ci_last_an = an_name; @@ -508,13 +509,14 @@ OUTpData(runDesc *plotPtr, IFvalue *refValue, IFvalue *valuePtr) every quarter of a second, to give some feedback without using too much CPU time */ #ifndef HAS_WINGUI - if (!orflag) { + if (!orflag && (doornroosje == 0)) { currclock = clock(); if ((currclock-lastclock) > (0.25*CLOCKS_PER_SEC)) { fprintf(stderr, " Reference value : % 12.5e\r", refValue->cValue.real); lastclock = currclock; } + else doornroosje--; } #endif } else { @@ -523,7 +525,7 @@ OUTpData(runDesc *plotPtr, IFvalue *refValue, IFvalue *valuePtr) fileAddRealValue(run->fp, run->binary, refValue->rValue); #ifndef HAS_WINGUI - if (!orflag) { + if (!orflag && (doornroosje == 0)) { currclock = clock(); if ((currclock-lastclock) > (0.25*CLOCKS_PER_SEC)) { fprintf(stderr, " Reference value : % 12.5e\r", @@ -531,6 +533,7 @@ OUTpData(runDesc *plotPtr, IFvalue *refValue, IFvalue *valuePtr) lastclock = currclock; } } + else doornroosje--; #endif } } @@ -606,7 +609,7 @@ OUTpData(runDesc *plotPtr, IFvalue *refValue, IFvalue *valuePtr) variable just the same */ #ifndef HAS_WINGUI - if (!orflag) { + if (!orflag && (doornroosje == 0)) { currclock = clock(); if ((currclock-lastclock) > (0.25*CLOCKS_PER_SEC)) { if (run->isComplex) { @@ -619,6 +622,7 @@ OUTpData(runDesc *plotPtr, IFvalue *refValue, IFvalue *valuePtr) lastclock = currclock; } } + else doornroosje--; #endif for (i = 0; i < run->numData; i++) { @@ -942,7 +946,7 @@ fileStartPoint(FILE *fp, bool bin, int num) column = 0; } - +/* This code is used when one does RUN aap.raw but *not* when doing RUN. */ static void fileAddRealValue(FILE *fp, bool bin, double value) { @@ -1056,6 +1060,8 @@ plotInit(runDesc *run) } } +/* mhx: minimize the number of REALLOCs */ +#define OUTSIZE (256*4096) static void plotAddRealValue(dataDesc *desc, double value) @@ -1063,11 +1069,11 @@ plotAddRealValue(dataDesc *desc, double value) struct dvec *v = desc->vec; if (isreal(v)) { - v->v_realdata = TREALLOC(double, v->v_realdata, v->v_length + 1); + if ((v->v_dims[0] & (OUTSIZE - 1)) == 0) v->v_realdata = TREALLOC(double, v->v_realdata, v->v_length + OUTSIZE); v->v_realdata[v->v_length] = value; } else { /* a real parading as a VF_COMPLEX */ - v->v_compdata = TREALLOC(ngcomplex_t, v->v_compdata, v->v_length + 1); + if ((v->v_dims[0] & (OUTSIZE - 1)) == 0) v->v_compdata = TREALLOC(ngcomplex_t, v->v_compdata, v->v_length + OUTSIZE); v->v_compdata[v->v_length].cx_real = value; v->v_compdata[v->v_length].cx_imag = 0.0; } @@ -1082,7 +1088,7 @@ plotAddComplexValue(dataDesc *desc, IFcomplex value) { struct dvec *v = desc->vec; - v->v_compdata = TREALLOC(ngcomplex_t, v->v_compdata, v->v_length + 1); + if ((v->v_dims[0] & (OUTSIZE - 1)) == 0) v->v_compdata = TREALLOC(ngcomplex_t, v->v_compdata, v->v_length + OUTSIZE); v->v_compdata[v->v_length].cx_real = value.real; v->v_compdata[v->v_length].cx_imag = value.imag; diff --git a/src/frontend/outitf.h b/src/frontend/outitf.h index be45a69f6..e0cd968ba 100644 --- a/src/frontend/outitf.h +++ b/src/frontend/outitf.h @@ -8,7 +8,6 @@ #include "ngspice/typedefs.h" - typedef struct dataDesc { char *name; /* The name of the vector. */ int type; /* The type. */ @@ -24,7 +23,6 @@ typedef struct dataDesc { struct dvec *vec; } dataDesc; - struct runDesc { void *analysis; CKTcircuit *circuit; @@ -38,13 +36,13 @@ struct runDesc { bool binary; struct plot *runPlot; FILE *fp; - long pointPos; /* where to write pointCount */ + long pointPos; /* where to write pointCount */ int pointCount; int isComplex; int windowCount; + int spindex; /* mhx */ }; - int OUTpBeginPlot(CKTcircuit *circuitPtr, JOB *analysisPtr, IFuid analName, IFuid refName, int refType, @@ -64,11 +62,4 @@ int OUTattributes(runDesc *plotPtr, IFuid varName, int param, IFvalue *value); int OUTstopnow(void); void OUTerror(int flags, char *format, IFuid *names); -#ifdef __GNUC__ -void OUTerrorf(int, const char *fmt, ...) __attribute__ ((format (__printf__, 2, 3))); -#else -void OUTerrorf(int, const char *fmt, ...); -#endif - - #endif diff --git a/src/include/ngspice/inpdefs.h b/src/include/ngspice/inpdefs.h index b4623f77b..04b334e4f 100644 --- a/src/include/ngspice/inpdefs.h +++ b/src/include/ngspice/inpdefs.h @@ -89,6 +89,7 @@ int IFnewUid(CKTcircuit *, IFuid *, IFuid, char *, int, CKTnode **); int IFdelUid(CKTcircuit *, IFuid, int); int INPaName(char *, IFvalue *, CKTcircuit *, int *, char *, GENinstance **, IFsimulator *, int *, IFvalue *); +int INPaSpecName(char *, IFvalue *, CKTcircuit *, int *, char *, GENinstance **, IFsimulator *, int *, IFvalue *, int *); int INPapName(CKTcircuit *, int, JOB *, char *, IFvalue *); void INPcaseFix(char *); char *INPdevParse(char **, CKTcircuit *, int, GENinstance *, double *, int *, INPtables *); diff --git a/src/spicelib/devices/cap/Makefile.am b/src/spicelib/devices/cap/Makefile.am index 4205040ae..2ad748d9d 100644 --- a/src/spicelib/devices/cap/Makefile.am +++ b/src/spicelib/devices/cap/Makefile.am @@ -28,6 +28,7 @@ libcap_la_SOURCES = \ capsset.c \ capsupd.c \ captemp.c \ + capfindbr.c \ captrunc.c diff --git a/src/spicelib/devices/cap/capdefs.h b/src/spicelib/devices/cap/capdefs.h index fbf860f9a..b5affc6fc 100644 --- a/src/spicelib/devices/cap/capdefs.h +++ b/src/spicelib/devices/cap/capdefs.h @@ -26,6 +26,7 @@ typedef struct sCAPinstance { int CAPstate; /* pointer to start of capacitor state vector */ int CAPposNode; /* number of positive node of capacitor */ int CAPnegNode; /* number of negative node of capacitor */ + int CAPbrEq; /* mhx: store node number */ double CAPtemp; /* temperature at which this capacitor operates */ double CAPdtemp; /* delta-temperature of this instance */ @@ -47,6 +48,7 @@ typedef struct sCAPinstance { * (positive,negative) */ double *CAPnegPosptr; /* pointer to sparse matrix offdiagonal at * (negative,positive) */ + double *CAPbrptr; /* mhx: to get I(Cx), pointer to sparse matrix diagonal */ unsigned CAPcapGiven : 1; /* flag to indicate capacitance was specified */ unsigned CAPicGiven : 1; /* flag to indicate init. cond. was specified */ unsigned CAPwidthGiven : 1; /* flag to indicate capacitor width given */ diff --git a/src/spicelib/devices/cap/capext.h b/src/spicelib/devices/cap/capext.h index d128959c4..c4af5cdab 100644 --- a/src/spicelib/devices/cap/capext.h +++ b/src/spicelib/devices/cap/capext.h @@ -23,4 +23,5 @@ extern int CAPsetup(SMPmatrix*,GENmodel*,CKTcircuit*,int*); extern int CAPtemp(GENmodel*,CKTcircuit*); extern int CAPtrunc(GENmodel*,CKTcircuit*,double*); extern int CAPsoaCheck(CKTcircuit *, GENmodel *); +extern int CAPfindBr(CKTcircuit*, GENmodel*, IFuid); diff --git a/src/spicelib/devices/cap/capinit.c b/src/spicelib/devices/cap/capinit.c index 1c8bb5126..3a122bc3e 100644 --- a/src/spicelib/devices/cap/capinit.c +++ b/src/spicelib/devices/cap/capinit.c @@ -47,7 +47,7 @@ SPICEdev CAPinfo = { /* DEVpzSetup */ CAPsetup, /* DEVtemperature*/ CAPtemp, /* DEVtrunc */ CAPtrunc, - /* DEVfindBranch */ NULL, + /* DEVfindBranch */ CAPfindBr, /* DEVacLoad */ CAPacLoad, /* DEVaccept */ NULL, /* DEVdestroy */ CAPdestroy, diff --git a/src/spicelib/devices/cap/capload.c b/src/spicelib/devices/cap/capload.c index d6796d5b2..b341ac422 100644 --- a/src/spicelib/devices/cap/capload.c +++ b/src/spicelib/devices/cap/capload.c @@ -77,6 +77,11 @@ CAPload(GENmodel *inModel, CKTcircuit *ckt) *(here->CAPnegPosptr) -= m * geq; *(ckt->CKTrhs+here->CAPposNode) -= m * ceq; *(ckt->CKTrhs+here->CAPnegNode) += m * ceq; + /* mhx: to access I(Cx) */ + if (here->CAPbrptr != NULL) { + *(ckt->CKTrhs + here->CAPbrEq) = *(ckt->CKTstate0 + here->CAPccap); + *(here->CAPbrptr) += 1.0; + } } else *(ckt->CKTstate0+here->CAPqcap) = here->CAPcapac * vcap; } diff --git a/src/spicelib/devices/cap/capsetup.c b/src/spicelib/devices/cap/capsetup.c index 6d2bbdc55..4cff404ce 100644 --- a/src/spicelib/devices/cap/capsetup.c +++ b/src/spicelib/devices/cap/capsetup.c @@ -115,6 +115,8 @@ do { if((here->ptr = SMPmakeElt(matrix, here->first, here->second)) == NULL){\ TSTALLOC(CAPnegNegptr,CAPnegNode,CAPnegNode); TSTALLOC(CAPposNegptr,CAPposNode,CAPnegNode); TSTALLOC(CAPnegPosptr,CAPnegNode,CAPposNode); + if (here->CAPbrEq & (here->CAPbrptr == NULL)) + TSTALLOC(CAPbrptr, CAPbrEq, CAPbrEq); /* mhx: to access I(Cx) */ } } return(OK); diff --git a/src/spicelib/devices/ind/Makefile.am b/src/spicelib/devices/ind/Makefile.am index 5a05ee97b..102fa0e31 100644 --- a/src/spicelib/devices/ind/Makefile.am +++ b/src/spicelib/devices/ind/Makefile.am @@ -22,6 +22,7 @@ libind_la_SOURCES = \ indsacl.c \ indsetup.c \ indsload.c \ + indfindbr.c \ indsprt.c \ indsset.c \ indsupd.c \ diff --git a/src/spicelib/devices/ind/indext.h b/src/spicelib/devices/ind/indext.h index 8d2fa035c..5d134d90e 100644 --- a/src/spicelib/devices/ind/indext.h +++ b/src/spicelib/devices/ind/indext.h @@ -24,7 +24,7 @@ extern int INDsetup(SMPmatrix*,GENmodel*,CKTcircuit*,int*); extern int INDunsetup(GENmodel*,CKTcircuit*); extern int INDtemp(GENmodel*, CKTcircuit*); extern int INDtrunc(GENmodel*,CKTcircuit*,double*); - +extern int INDfindBr(CKTcircuit*, GENmodel*, IFuid); // mhx: find inductor branch extern int MUTacLoad(GENmodel*,CKTcircuit*); extern int MUTask(CKTcircuit*,GENinstance*,int,IFvalue*,IFvalue*); extern int MUTdelete(GENmodel*,IFuid,GENinstance**); diff --git a/src/spicelib/devices/ind/indinit.c b/src/spicelib/devices/ind/indinit.c index 8148abde8..2900dd244 100644 --- a/src/spicelib/devices/ind/indinit.c +++ b/src/spicelib/devices/ind/indinit.c @@ -47,7 +47,7 @@ SPICEdev INDinfo = { /* DEVpzSetup */ INDsetup, /* DEVtemperature*/ INDtemp, /* DEVtrunc */ INDtrunc, - /* DEVfindBranch */ NULL, + /* DEVfindBranch */ INDfindBr, // mhx /* DEVacLoad */ INDacLoad, /* DEVaccept */ NULL, /* DEVdestroy */ INDdestroy, diff --git a/src/spicelib/devices/res/Makefile.am b/src/spicelib/devices/res/Makefile.am index ab746263d..9b5e75959 100644 --- a/src/spicelib/devices/res/Makefile.am +++ b/src/spicelib/devices/res/Makefile.am @@ -25,6 +25,7 @@ libres_la_SOURCES = \ ressload.c \ ressprt.c \ ressset.c \ + resfindbr.c \ restemp.c diff --git a/src/spicelib/devices/res/resdefs.h b/src/spicelib/devices/res/resdefs.h index a8f0578a2..6789590b9 100644 --- a/src/spicelib/devices/res/resdefs.h +++ b/src/spicelib/devices/res/resdefs.h @@ -27,6 +27,7 @@ typedef struct sRESinstance { int RESstate; /* not used but needed for sructure consistency */ int RESposNode; /* number of positive node of resistor */ int RESnegNode; /* number of negative node of resistor */ + int RESbrEq; /* mhx: number of the node that stores I(Rx) */ double REStemp; /* temperature at which this resistor operates */ double RESdtemp; /* delta-temperature of a particular instance */ @@ -53,6 +54,7 @@ typedef struct sRESinstance { * (positive,negative) */ double *RESnegPosptr; /* pointer to sparse matrix offdiagonal at * (negative,positive) */ + double *RESbrptr; /* mhx: to get I(Rx), pointer to sparse matrix diagonal */ unsigned RESresGiven : 1; /* flag to indicate resistance was specified */ unsigned RESwidthGiven : 1; /* flag to indicate width given */ unsigned RESlengthGiven : 1; /* flag to indicate length given */ diff --git a/src/spicelib/devices/res/resext.h b/src/spicelib/devices/res/resext.h index 148d1d222..5a4e636ca 100644 --- a/src/spicelib/devices/res/resext.h +++ b/src/spicelib/devices/res/resext.h @@ -21,3 +21,4 @@ extern int RESsetup(SMPmatrix*,GENmodel*,CKTcircuit*,int*); extern int REStemp(GENmodel*,CKTcircuit*); extern int RESnoise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*); extern int RESsoaCheck(CKTcircuit *, GENmodel *); +extern int RESfindBr(CKTcircuit*, GENmodel*, IFuid); // mhx diff --git a/src/spicelib/devices/res/resinit.c b/src/spicelib/devices/res/resinit.c index d4096de8d..bf87369e4 100644 --- a/src/spicelib/devices/res/resinit.c +++ b/src/spicelib/devices/res/resinit.c @@ -48,7 +48,7 @@ SPICEdev RESinfo = { /* DEVpzSetup */ RESsetup, /* DEVtemperature*/ REStemp, /* DEVtrunc */ NULL, - /* DEVfindBranch */ NULL, + /* DEVfindBranch */ RESfindBr, /* DEVacLoad */ RESacload, /* ac load and normal load are identical */ /* DEVaccept */ NULL, /* DEVdestroy */ RESdestroy, diff --git a/src/spicelib/devices/res/resload.c b/src/spicelib/devices/res/resload.c index ff6e5d66f..6fe7fc3d4 100644 --- a/src/spicelib/devices/res/resload.c +++ b/src/spicelib/devices/res/resload.c @@ -10,9 +10,9 @@ Modified: Apr 2000 - Paolo Nenzi #include "ngspice/sperror.h" -/* actually load the current resistance value into the sparse matrix +/* actually load the current resistance value into the sparse matrix * previously provided */ -int +int RESload(GENmodel *inModel, CKTcircuit *ckt) { RESmodel *model = (RESmodel *)inModel; @@ -23,14 +23,20 @@ RESload(GENmodel *inModel, CKTcircuit *ckt) RESinstance *here; /* loop through all the instances of the model */ - for (here = model->RESinstances; here != NULL ; - here = here->RESnextInstance) { + for (here = model->RESinstances; here != NULL ; + here = here->RESnextInstance) { - here->REScurrent = (*(ckt->CKTrhsOld+here->RESposNode) - + here->REScurrent = (*(ckt->CKTrhsOld+here->RESposNode) - *(ckt->CKTrhsOld+here->RESnegNode)) * here->RESconduct; m = (here->RESm); + /* mhx: access current like I(Rx) */ + if (here->RESbrptr != NULL) { + *(ckt->CKTrhs + here->RESbrEq) = m * here->REScurrent; + *(here->RESbrptr) += 1.0; + } + *(here->RESposPosptr) += m * here->RESconduct; *(here->RESnegNegptr) += m * here->RESconduct; *(here->RESposNegptr) -= m * here->RESconduct; @@ -41,10 +47,10 @@ RESload(GENmodel *inModel, CKTcircuit *ckt) } -/* actually load the current resistance value into the sparse matrix +/* actually load the current resistance value into the sparse matrix * previously provided */ -int -RESacload(GENmodel *inModel, CKTcircuit *ckt) +int +RESacload(GENmodel *inModel, CKTcircuit *ckt) { RESmodel *model = (RESmodel *)inModel; double m; @@ -56,7 +62,7 @@ RESacload(GENmodel *inModel, CKTcircuit *ckt) RESinstance *here; /* loop through all the instances of the model */ - for (here = model->RESinstances; here != NULL ; + for (here = model->RESinstances; here != NULL ; here = here->RESnextInstance) { m = (here->RESm); diff --git a/src/spicelib/devices/res/ressetup.c b/src/spicelib/devices/res/ressetup.c index 44c75ea5f..910ebeaef 100644 --- a/src/spicelib/devices/res/ressetup.c +++ b/src/spicelib/devices/res/ressetup.c @@ -86,7 +86,9 @@ do { if((here->ptr = SMPmakeElt(matrix, here->first, here->second)) == NULL){\ TSTALLOC(RESnegNegptr, RESnegNode, RESnegNode); TSTALLOC(RESposNegptr, RESposNode, RESnegNode); TSTALLOC(RESnegPosptr, RESnegNode, RESposNode); - } + if (here->RESbrEq & (here->RESbrptr == NULL)) + TSTALLOC(RESbrptr, RESbrEq, RESbrEq); + } } return(OK); } diff --git a/src/spicelib/parser/inpaname.c b/src/spicelib/parser/inpaname.c index c9d294b46..b6d31340d 100644 --- a/src/spicelib/parser/inpaname.c +++ b/src/spicelib/parser/inpaname.c @@ -19,20 +19,18 @@ Author: 1985 Thomas L. Quarles #include "ngspice/iferrmsg.h" #include "inpxx.h" -int -INPaName(char *parm, IFvalue * val, CKTcircuit *ckt, int *dev, char *devnam, - GENinstance **fast, IFsimulator * sim, int *dataType, IFvalue * selector) - /* the name of the parameter to set */ - /* the parameter union containing the value to set */ - /* the circuit this device is a member of */ - /* the device type code to the device being parsed */ - /* the name of the device */ - /* direct pointer to device being parsed */ - /* the simulator data structure */ - /* the datatype of the returned value structure */ - /* data sub-selector for questions */ +int +INPaName ( char *parm, // the name of the parameter to set, + IFvalue *val, // the parameter union containing the value to set, + CKTcircuit *ckt, // the circuit this device is a member of, + int *dev, // the device type code to the device being parsed, + char *devnam, // the name of the device, + GENinstance **fast, // direct pointer to device being parsed, + IFsimulator *sim, // the simulator data structure, + int *dataType, // the datatype of the returned value structure, + IFvalue *selector) // data sub-selector for questions. { - int error; /* int to store evaluate error return codes in */ + int error; /* int to store evaluate error return codes in */ int i; /* find the instance - don't know about model, so use null there, @@ -43,7 +41,7 @@ INPaName(char *parm, IFvalue * val, CKTcircuit *ckt, int *dev, char *devnam, if (*fast == NULL) *fast = sim->findInstance (ckt, devnam); if (*fast == NULL) - return (E_NODEV); + return (E_NODEV); *dev = (*fast)->GENmodPtr->GENmodType; @@ -52,20 +50,76 @@ INPaName(char *parm, IFvalue * val, CKTcircuit *ckt, int *dev, char *devnam, * parameter. */ for (i = 0; i < *(sim->devices[*dev]->numInstanceParms); i++) { - if (strcmp(parm, sim->devices[*dev]->instanceParms[i].keyword) == 0 - && (sim->devices[*dev]->instanceParms[i].dataType & IF_ASK)) { - /* found it, so we ask the question using the device info we got - * above and put the results in the IFvalue structure our caller - * gave us originally - */ - error = sim->askInstanceQuest (ckt, *fast, + if (strcmp(parm, sim->devices[*dev]->instanceParms[i].keyword) == 0 + && (sim->devices[*dev]->instanceParms[i].dataType & IF_ASK)) { + /* found it, so we ask the question using the device info we got + * above and put the results in the IFvalue structure our caller + * gave us originally + */ + error = sim->askInstanceQuest (ckt, *fast, sim->devices[*dev]->instanceParms[i].id, val, - selector); - if (dataType) - *dataType = - sim->devices[*dev]->instanceParms[i].dataType; - return (error); - } + selector); + if (dataType) + *dataType = + sim->devices[*dev]->instanceParms[i].dataType; + return (error); + } } return (E_BADPARM); } + +// mhx: specialized (faster) version that directly returns/uses the index of the parameter we seek +int INPaSpecName ( + char *parm, // the name of the parameter to set, + IFvalue *val, // the parameter union containing the value to set, + CKTcircuit *ckt, // the circuit this device is a member of, + int *dev, // the device type code to the device being parsed, + char *devnam, // the name of the device, + GENinstance **fast, // direct pointer to device being parsed, + IFsimulator *sim, // the simulator data structure, + int *dataType, // the datatype of the returned value structure, + IFvalue *selector, // data sub-selector for questions. + int *spindex) // special index +{ + int error; // int to store evaluate error return codes in + int i; + + /* + * find the instance - don't know about model, so use null there, + * otherwise pass on as much info as we have about the device + * (name, type, direct pointer) - the type and direct pointer + * WILL be set on return unless error is not OK + */ + if (*fast == NULL) + *fast = sim->findInstance(ckt, devnam); + if (*fast == NULL) + return (E_NODEV); + + *dev = (*fast)->GENmodPtr->GENmodType; + + /* now find the parameter - hunt through the parameter tables for + * this device type and look for a name match of an 'ask'able + * parameter. + */ + if (*spindex != -1) { // mhx: shortcut for repeated question + error = sim->askInstanceQuest(ckt, *fast, sim->devices[*dev]->instanceParms[*spindex].id, val, selector); + if (dataType) *dataType = sim->devices[*dev]->instanceParms[*spindex].dataType; + return error; + } + + for (i = 0; i < *(sim->devices[*dev]->numInstanceParms); i++) { + if (strcmp(parm, sim->devices[*dev]->instanceParms[i].keyword) == 0 + && (sim->devices[*dev]->instanceParms[i].dataType & IF_ASK)) { + /* + * found it, so we ask the question using the device info we got + * above and put the results in the IFvalue structure our caller gave us originally + */ + *spindex = i; /* mhx: shortcut for repeated questioning */ + error = sim->askInstanceQuest(ckt, *fast, sim->devices[*dev]->instanceParms[i].id, val, selector); + if (dataType) + *dataType = sim->devices[*dev]->instanceParms[i].dataType; // probably double + return error; + } + } + return E_BADPARM; +}