home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1993 #3 / NN_1993_3.iso / spool / alt / sources / 3111 < prev    next >
Encoding:
Text File  |  1993-01-28  |  57.3 KB  |  1,995 lines

  1. Path: sparky!uunet!ferkel.ucsb.edu!taco!rock!stanford.edu!ames!haven.umd.edu!darwin.sura.net!ukma!cs.widener.edu!dsinc!ub!galileo.cc.rochester.edu!ee.rochester.edu!rbc!al
  2. From: al@rbc.uucp (Al Davis)
  3. Newsgroups: alt.sources
  4. Subject: ACS  circuit simulator  part 11/20
  5. Message-ID: <1993Jan27.040710.11435@rbc.uucp>
  6. Date: 27 Jan 93 04:07:10 GMT
  7. Sender: al@rbc.uucp (Al Davis)
  8. Organization: Huh?
  9. Lines: 1984
  10.  
  11. #! /bin/sh
  12. # This is a shell archive, meaning:
  13. # 1. Remove everything above the #! /bin/sh line.
  14. # 2. Save the resulting text in a file.
  15. # 3. Execute the file with /bin/sh (not csh) to create the files:
  16. #    src/branch.c
  17. #    src/cmath.c
  18. #    src/crtset.c
  19. #    src/ctof.c
  20. #    src/ctoi.c
  21. #    src/ctostr.c
  22. #    src/dc.c
  23. #    src/dc_setup.c
  24. #    src/dc_sweep.c
  25. #    src/dealloc.c
  26. #    src/delete.c
  27. #    src/dev.c
  28. #    src/d_admit.c
  29. # This archive created: Tue Jan 26 22:51:00 1993
  30. export PATH; PATH=/bin:$PATH
  31. if test -f 'src/branch.c'
  32. then
  33.     echo shar: will not over-write existing file "'src/branch.c'"
  34. else
  35. cat << \SHAR_EOF > 'src/branch.c'
  36. /* branch  04/18/92
  37.  * Copyright 1983-1992   Albert Davis
  38.  * accesses branch array.
  39.  */
  40. #include "ecah.h"
  41. #include "branch.h"
  42. #include "error.h"
  43. #include "declare.h"
  44. /*--------------------------------------------------------------------------*/
  45.     branch_t *firstbranch_dev(void);
  46.     branch_t *firstbranch_all(void);
  47.     branch_t *nextbranch_dev(const branch_t*);
  48.     branch_t *nextbranch_all(const branch_t*);
  49.     branch_t *lastbranch_dev(void);
  50.     branch_t *lastbranch_all(void);
  51.     branch_t *insertbranch(branch_t*);
  52.     int     deletebranch(branch_t*);
  53. static    void     freelist(generic_t**);
  54. /*--------------------------------------------------------------------------*/
  55. extern const char e_int[];
  56. static branch_t ends = {(generic_t*)NULL, sizeof(branch_t),
  57.     (functions_t*)NULL, &ends, &ends, &ends, &ends, /*more*/};
  58. /*--------------------------------------------------------------------------*/
  59. /* firstbranch_dev: return pointer to first device in the parts list
  60.  *               pointer to ends if empty list, or no devices
  61.  */
  62. branch_t *firstbranch_dev()
  63. {
  64.  branch_t *x;
  65.  for (x = ends.next;  exists(x) && !isdevice(x);  x = x->next)
  66.     /* skip */;
  67.  return x;
  68. }
  69. /*--------------------------------------------------------------------------*/
  70. /* firstbranch_all: return pointer to first item in the parts list
  71.  *               pointer to ends if empty list
  72.  */
  73. branch_t *firstbranch_all()
  74. {
  75.  return ends.next;
  76. }
  77. /*--------------------------------------------------------------------------*/
  78. /* nextbranch_dev: return pointer to next non-comment branch in list
  79.  */
  80. branch_t *nextbranch_dev(x)
  81. const branch_t *x;
  82. {
  83.  branch_t *y;
  84.  if (!x)
  85.     return &ends;
  86.  while (y = x->next,  !isdevice(y))
  87.     x = y;;
  88.  return y;
  89. }
  90. /*--------------------------------------------------------------------------*/
  91. /* nextbranch_all: return pointer to next line in netlist (incl comments)
  92.  *              pointer to ends if at end of list or null arg
  93.  */
  94. branch_t *nextbranch_all(x)
  95. const branch_t *x;
  96. {
  97.  return (x) ? x->next : &ends;
  98. }
  99. /*--------------------------------------------------------------------------*/
  100. /* lastbranch_dev: return pointer to last device in the parts list
  101.  *              pointer to ends if empty list, or no devices
  102.  */
  103. branch_t *lastbranch_dev()
  104. {
  105.  branch_t *x;
  106.  for (x = ends.prev;  exists(x) && !isdevice(x);  x = x->prev)
  107.     /* skip */;
  108.  return x;
  109. }
  110. /*--------------------------------------------------------------------------*/
  111. /* lastbranch_all: return pointer to last item in the parts list
  112.  *              pointer to ends if empty list
  113.  */
  114. branch_t *lastbranch_all()
  115. {
  116.  return ends.prev;
  117. }
  118. /*--------------------------------------------------------------------------*/
  119. /* insertbranch: insert a branch into the parts list
  120.  * either pre or post inserts, depending....
  121.  *   specify after, inserts after that one (post)
  122.  *   specify before, inserts before that one (pre)
  123.  *   specify both (bad.  don't do it) after wins.
  124.  *   specify neither, makes self link, for a new list.
  125.  * then set up same-type links
  126.  *   if one of the links is done, fill in the others
  127.  *   else make same type point to self
  128.  * actually inserts the branch passed in into the list.  no copies.
  129.  * links are never null, after this returns
  130.  * returns pointer to actual new element
  131.  */
  132. branch_t *insertbranch(brh)
  133. branch_t *brh;
  134. {
  135.  if (brh->prev  &&  brh->next)
  136.     error(bERROR, e_int, "bad branch link");
  137.  else if (brh->prev)
  138.     brh->next = brh->prev->next;
  139.  else if (brh->next)
  140.     brh->prev = brh->next->prev;
  141.  else /* make self link */
  142.     brh->prev = brh->next = brh;
  143.  
  144.  brh->next->prev = brh->prev->next = brh;
  145.  
  146.  if (brh->stprev  &&  brh->stnext){
  147.     if (brh->stprev != brh  ||  brh->stnext != brh)
  148.        error(bERROR, e_int, "bad st link");
  149.  }else if (brh->stprev){
  150.     brh->stnext = brh->stprev->stnext;
  151.  }else if (brh->stnext){
  152.     brh->stprev = brh->stnext->stprev;
  153.  }else{ /* make self link */
  154.     brh->stprev = brh->stnext = brh;
  155.  }
  156.  
  157.  brh->stnext->stprev = brh->stprev->stnext = brh;
  158.  return brh;
  159. }    
  160. /*--------------------------------------------------------------------------*/
  161. /* deletebranch: delete a branch from parts list
  162.  * returns count actually deleted (either 1 or 0)
  163.  * updates pointers, first, last, etc.
  164.  * so list is consistent on return
  165.  */
  166. int deletebranch(brh)        /* delete a branch.                */
  167. branch_t *brh;            /* return count actually deleted        */
  168. {
  169.  if (exists(brh)){
  170.     brh->next->prev = brh->prev;
  171.     brh->prev->next = brh->next;
  172.     brh->stnext->stprev = brh->stprev;
  173.     brh->stprev->stnext = brh->stnext;
  174.     freelist((generic_t**)&brh);
  175.     return 1;
  176.  }else{
  177.     return 0;
  178.  }
  179. }
  180. /*--------------------------------------------------------------------------*/
  181. /* freelist: free a (singly linked) list of structures   (recursive)
  182.  * struct generic is an attempt to tame type clashes
  183.  */
  184. static void freelist(x)
  185. generic_t **x;
  186. {
  187.  if ((*x)->x  &&  (*x)->x != (*x)->x->x)
  188.     freelist(&((*x)->x));
  189.  qfree((void**)x);
  190. }
  191. /*--------------------------------------------------------------------------*/
  192. /*--------------------------------------------------------------------------*/
  193. SHAR_EOF
  194. fi # end of overwriting check
  195. if test -f 'src/cmath.c'
  196. then
  197.     echo shar: will not over-write existing file "'src/cmath.c'"
  198. else
  199. cat << \SHAR_EOF > 'src/cmath.c'
  200. /* cmath  12/31/92
  201.  * Copyright 1983-1992   Albert Davis
  202.  * complex math
  203.  */
  204. #include "ecah.h"
  205. #include "declare.h"
  206. /*LINTLIBRARY*/
  207. /*--------------------------------------------------------------------------*/
  208.     complex_t cxadd(double,double,double,double);
  209.     complex_t cxsub(double,double,double,double);
  210.     complex_t cxmul(double,double,double,double);
  211.     complex_t cxdiv(double,double,double,double);
  212.     complex_t cxflip(double,double);
  213.     complex_t cadd(complex_t,complex_t);
  214.     complex_t csub(complex_t,complex_t);
  215.     complex_t cmul(complex_t,complex_t);
  216.     complex_t ccmul(complex_t,complex_t);
  217.     complex_t cdiv(complex_t,complex_t);
  218.     complex_t cflip(complex_t);
  219. /*--------------------------------------------------------------------------*/
  220. complex_t cxadd(x1,y1,x2,y2)
  221. double x1,y1,x2,y2;
  222. {
  223.  complex_t z;
  224.  z.x = x1 + x2;
  225.  z.y = y1 + y2;
  226.  return z;
  227. }
  228. /*--------------------------------------------------------------------------*/
  229. complex_t cxsub(x1,y1,x2,y2)
  230. double x1,y1,x2,y2;
  231. {
  232.  complex_t z;
  233.  z.x = x1 - x2;
  234.  z.y = y1 - y2;
  235.  return z;
  236. }
  237. /*--------------------------------------------------------------------------*/
  238. complex_t cxmul(x1,y1,x2,y2)
  239. double x1,y1,x2,y2;
  240. {
  241.  complex_t z;
  242.  z.x = x1*x2 - y1*y2 ;
  243.  z.y = x1*y2 + y1*x2 ;
  244.  return z;
  245. }
  246. /*--------------------------------------------------------------------------*/
  247. complex_t cxdiv(x1,y1,x2,y2)
  248. double x1,y1,x2,y2;
  249. {
  250.  complex_t z;
  251.  double  d;
  252.  d   =  x2*x2 + y2*y2;
  253.  z.x = (x1*x2 + y1*y2) / d;
  254.  z.y = (y1*x2 - x1*y2) / d;
  255.  return z;
  256. }
  257. /*--------------------------------------------------------------------------*/
  258. complex_t cxflip(x2,y2)
  259. double x2,y2;
  260. {
  261.  complex_t z;
  262.  double  d;
  263.  d = x2*x2 + y2*y2;
  264.  z.x =  x2 / d;
  265.  z.y = -y2 / d;
  266.  return z;
  267. }
  268. /*--------------------------------------------------------------------------*/
  269.  
  270. complex_t cadd(a,b)
  271. complex_t a,b;
  272. {
  273.  complex_t z;
  274.  z.x = a.x + b.x;
  275.  z.y = a.y + b.y;
  276.  return z;
  277. }
  278. /*--------------------------------------------------------------------------*/
  279. complex_t csub(a,b)
  280. complex_t a,b;
  281. {
  282.  complex_t z;
  283.  z.x = a.x - b.x;
  284.  z.y = a.y - b.y;
  285.  return z;
  286. }
  287. /*--------------------------------------------------------------------------*/
  288. complex_t cmul(a,b)
  289. complex_t a,b;
  290. {
  291.  complex_t z;
  292.  z.x = a.x*b.x - a.y*b.y ;
  293.  z.y = a.x*b.y + a.y*b.x ;
  294.  return z;
  295. }
  296. /*--------------------------------------------------------------------------*/
  297. complex_t ccmul(a,b)    /* conjugate multiply */
  298. complex_t a,b;
  299. {
  300.  complex_t z;
  301.  z.x = a.x*b.x + a.y*b.y ;
  302.  z.y = a.y*b.x - a.x*b.y ;
  303.  return z;
  304. }
  305. /*--------------------------------------------------------------------------*/
  306. complex_t cdiv(a,b)
  307. complex_t a,b;
  308. {
  309.  complex_t z;
  310.  double  d;
  311.  d   =  b.x*b.x + b.y*b.y;
  312.  z.x = (a.x*b.x + a.y*b.y) / d;
  313.  z.y = (a.y*b.x - a.x*b.y) / d;
  314.  return z;
  315. }
  316. /*--------------------------------------------------------------------------*/
  317. complex_t cflip(b)
  318. complex_t b;
  319. {
  320.  complex_t z;
  321.  double  d;
  322.  d = b.x*b.x + b.y*b.y;
  323.  z.x =  b.x / d;
  324.  z.y = -b.y / d;
  325.  return z;
  326. }
  327. /*--------------------------------------------------------------------------*/
  328. /*--------------------------------------------------------------------------*/
  329. SHAR_EOF
  330. fi # end of overwriting check
  331. if test -f 'src/crtset.c'
  332. then
  333.     echo shar: will not over-write existing file "'src/crtset.c'"
  334. else
  335. cat << \SHAR_EOF > 'src/crtset.c'
  336. /* crtset  10/08/91
  337.  * Copyright 1983-1992   Albert Davis
  338.  * set up crt plotting parameters
  339.  */
  340. #include "ecah.h"
  341. #include "error.h"
  342. #include "io.h"
  343. #include "pixelh.h"
  344. #include "declare.h"
  345. /*--------------------------------------------------------------------------*/
  346.     void        cmd_crtset(const char*,int*);
  347. static    void        setq(const char*,int*,int*);
  348.     int        testcrt(void);
  349.     struct graph    *initcrt(void);
  350. /*--------------------------------------------------------------------------*/
  351. extern const struct ioctrl io;
  352.  
  353. extern struct graph *initsun();
  354. extern struct graph *initibm();
  355. extern struct graph *initherc();
  356. extern struct graph *initz100();
  357. extern struct graph *initbasic();
  358. extern struct graph *initpostscript();
  359. extern struct graph *initunix();
  360. extern struct graph *initx();
  361. static int crttype;
  362. static struct graph d;
  363. /*--------------------------------------------------------------------------*/
  364. void cmd_crtset(cmd,cnt)
  365. const char *cmd;
  366. int  *cnt;
  367. {
  368. static int sw_c, sh_c;
  369. static int beenhere = NO;
  370.  
  371. if (!beenhere)
  372.     {
  373.     d.sw    = 640;
  374.     d.sh    = 200;
  375.     sw_c    = 80;
  376.     sh_c    = 25;
  377.     d.ppc   = d.sw / sw_c;
  378.     d.lpc   = d.sh / sh_c;
  379.     d.gmode = 6;
  380.     d.tmode = 2;
  381.     d.pri   = 1;
  382.     d.sec   = -2;
  383.     d.grid  = -8;
  384.     d.back  = 0;
  385.     d.palette = 0;
  386.     }
  387. beenhere = YES;
  388.  
  389. if (pmatch(cmd,cnt,"Ascii"))
  390.     crttype = '\0';
  391. else if (pmatch(cmd,cnt,"None"))
  392.     crttype = '\0';
  393. else if (pmatch(cmd,cnt,"Basic"))
  394.     crttype = 'b';
  395. else if (pmatch(cmd,cnt,"Hercules"))
  396.     crttype = 'h';
  397. else if (pmatch(cmd,cnt,"Ibm"))
  398.     crttype = 'i';
  399. else if (pmatch(cmd,cnt,"Postscript"))
  400.     crttype = 'p';
  401. else if (pmatch(cmd,cnt,"Sun"))
  402.     crttype = 's';
  403. else if (pmatch(cmd,cnt,"Unix"))
  404.     crttype = 'u';
  405. else if (pmatch(cmd,cnt,"X"))
  406.     crttype = 'x';
  407. else if (pmatch(cmd,cnt,"Zenith"))
  408.     crttype = 'z';
  409. else if (!cmd[*cnt])
  410.     {
  411.     mprintf(io.mstdout,"%c\n", crttype);
  412.     mprintf(io.mstdout,"%dx%d, %dx%d\n", d.sw, d.sh, sw_c, sh_c);
  413.     mprintf(io.mstdout,"%d, %d\n", d.gmode, d.tmode);
  414.     mprintf(io.mstdout,"%d, %d, %d, %d\n", d.pri, d.sec, d.grid, d.back);
  415.     mprintf(io.mstdout,"%d\n", d.palette);
  416.     return ;
  417.     }
  418. else
  419.     syntax(cmd,cnt,bERROR);
  420.  
  421. setq(cmd,cnt,&d.sw);
  422. setq(cmd,cnt,&d.sh);
  423. setq(cmd,cnt,&sw_c);
  424. setq(cmd,cnt,&sh_c);
  425. d.ppc = d.sw / sw_c;
  426. d.lpc = d.sh / sh_c;
  427. setq(cmd,cnt,&d.gmode);
  428. setq(cmd,cnt,&d.tmode);
  429. setq(cmd,cnt,&d.pri);
  430. setq(cmd,cnt,&d.sec);
  431. setq(cmd,cnt,&d.grid);
  432. setq(cmd,cnt,&d.back);
  433. setq(cmd,cnt,&d.palette);
  434. }
  435. /*--------------------------------------------------------------------------*/
  436. static void setq(cmd,cnt,value)
  437. const char *cmd;
  438. int  *cnt;
  439. int  *value;
  440. {
  441. skipbl(cmd,cnt);
  442. if (isdigit(cmd[*cnt]) || cmd[*cnt]=='-')
  443.     *value = (int)ctof(cmd,cnt);
  444. else
  445.     skiparg(cmd,cnt);
  446. }
  447. /*--------------------------------------------------------------------------*/
  448. int testcrt()
  449. {
  450. return crttype;
  451. }
  452. /*--------------------------------------------------------------------------*/
  453. struct graph *initcrt()
  454. {
  455. switch (crttype)
  456.     {
  457.     case 'b':
  458.         return initbasic(&d);
  459. #ifdef MSDOS
  460.     case 'i':
  461.     return initibm(&d);
  462. #endif
  463. #ifdef HERCULES
  464.     case 'h':
  465.     return initherc(&d);
  466. #endif
  467.     case 'p':
  468.         return initpostscript(&d);
  469. #ifdef SUNVIEW
  470.     case 's':
  471.         return initsun(&d);
  472. #endif
  473.     case 'u':
  474.         return initunix(&d);
  475.     case 'x':
  476.         return initx(&d);
  477. #ifdef MSDOS
  478.     case 'z':
  479.     return initz100(&d);
  480. #endif
  481.     default:
  482.         return (struct graph*)NULL;
  483.     }
  484. }
  485. /*--------------------------------------------------------------------------*/
  486. /*--------------------------------------------------------------------------*/
  487. SHAR_EOF
  488. fi # end of overwriting check
  489. if test -f 'src/ctof.c'
  490. then
  491.     echo shar: will not over-write existing file "'src/ctof.c'"
  492. else
  493. cat << \SHAR_EOF > 'src/ctof.c'
  494. /* ctof     04/02/92
  495.  * Copyright 1983-1992   Albert Davis
  496.  * get double from string
  497.  * update string pointer
  498.  * return double number if got, else 0
  499.  * supports letter multipliers (spice style)
  500.  * skips trailing letters (10uhenries == 10u)
  501.  * skips trailing spaces and one comma
  502.  * pointer points to char following comma
  503.  * or first non-space following number just got
  504.  * or first non-space (if non-number)
  505.  */
  506. #include "ecah.h"
  507. #include "declare.h"
  508. /*--------------------------------------------------------------------------*/
  509.     double    ctof(const char*,int*);
  510.     double    x10(int);
  511. /*--------------------------------------------------------------------------*/
  512. double ctof(cmd,cnt)
  513. const char *cmd;
  514. int  *cnt;
  515. {
  516.  double val, power;
  517.  int    sign;
  518.  char   pc;
  519.  
  520.  skipbl(cmd,cnt);
  521.  if (!isfloat(cmd[*cnt])){
  522.     skipcom(cmd,cnt);
  523.     return 0.;
  524.  }
  525.  
  526.  sign = 1;                    /* sign */
  527.  if (cmd[*cnt]=='+'){
  528.     (*cnt)++;
  529.  }else if (cmd[*cnt]=='-'){
  530.     sign = -1;
  531.     (*cnt)++;
  532.  }
  533.  
  534.  for (val=0.0;  isdigit(cmd[*cnt]);  (*cnt)++)    /* up to dec pt */
  535.     val = 10.0 * val + (cmd[*cnt]-'0');
  536.  
  537.  if (cmd[*cnt] == '.')                /* dec pt */
  538.     (*cnt)++;
  539.  
  540.  for (power=1.; isdigit(cmd[*cnt]); (*cnt)++){    /* after dec pt */
  541.     val = 10.0 * val + (cmd[*cnt]-'0');
  542.     power *= .1;
  543.  }
  544.  
  545.  pc = to_upper(cmd[*cnt]);
  546.  (*cnt)++;
  547.  if (pc == 'E'){                /* exponent: E form */
  548.     int es, expo;
  549.     es = 1;
  550.     if (cmd[*cnt]=='+'){
  551.        (*cnt)++;
  552.     }else if (cmd[*cnt]=='-'){
  553.        (*cnt)++;
  554.        es = -1;
  555.     }
  556.     for (expo=0;  isdigit(cmd[*cnt]);  (*cnt)++)
  557.     expo = 10 * expo + (cmd[*cnt]-'0');
  558.     expo *= es;
  559.     power *= x10(expo);
  560.  }else if (pc == 'M'){                /* M is special */
  561.     int pc2;
  562.     pc2 = to_upper(cmd[*cnt]);
  563.     (*cnt)++;
  564.     if (pc2 == 'E'){                /* meg */
  565.         power *= 1e6;
  566.     }else if (pc2 == 'I'){            /* mil */
  567.         power *= 25.4e-6;
  568.     }else{                    /* plain m (milli) */
  569.        power *= 1e-3;
  570.        (*cnt)--;
  571.     }
  572.  }else if (pc == 'U'){                /* other letters */
  573.     power *= 1e-6;
  574.  }else if (pc == 'N'){
  575.     power *= 1e-9;
  576.  }else if (pc == 'P'){
  577.     power *= 1e-12;
  578.  }else if (pc == 'F'){
  579.     power *= 1e-15;
  580.  }else if (pc == 'K'){
  581.     power *= 1e3;
  582.  }else if (pc == 'G'){
  583.     power *= 1e9;
  584.  }else if (pc == 'T'){
  585.     power *= 1e12;
  586.  }else{
  587.     (*cnt)--;
  588.  }
  589.  while (isalpha(cmd[*cnt]))            /* skip letters */
  590.     (*cnt)++;
  591.  
  592.  skipcom(cmd,cnt);
  593.  return (sign*val*power);
  594. }
  595. /*--------------------------------------------------------------------------*/
  596. double x10(ex)
  597. int ex;
  598. {
  599. double r;
  600. r = 1.;
  601. for (; ex>0; ex-- )
  602.     r *= 10.0;
  603. for (; ex<0; ex++ )
  604.     r *= .1;
  605. return r;
  606. }
  607. /*--------------------------------------------------------------------------*/
  608. /*--------------------------------------------------------------------------*/
  609. SHAR_EOF
  610. fi # end of overwriting check
  611. if test -f 'src/ctoi.c'
  612. then
  613.     echo shar: will not over-write existing file "'src/ctoi.c'"
  614. else
  615. cat << \SHAR_EOF > 'src/ctoi.c'
  616. /* ctoi  04/02/92
  617.  * Copyright 1983-1992   Albert Davis
  618.  * get integer from string
  619.  * update string pointer
  620.  * return integer if got, else 0
  621.  * pointer points to char following number just got
  622.  * or first non-space
  623.  */
  624. #include "ecah.h"
  625. #include "declare.h"
  626. /*--------------------------------------------------------------------------*/
  627.     int ctoi(const char*,int*);
  628. /*--------------------------------------------------------------------------*/
  629. /* ctoi: character input to integer
  630.  * Returns signed integer, or 0 if the string is not a number.
  631.  * Input must be integer: no multipliers, no decimal point.
  632.  * Dot or letter belongs to the next token.
  633.  */
  634. int ctoi(cmd,cnt)
  635. const char *cmd  ;
  636. int  *cnt  ;
  637. {
  638.  int val, sign ;
  639.  
  640.  skipbl(cmd,cnt) ;
  641.  
  642.  sign = 1 ;                    /* sign */
  643.  if (cmd[*cnt]=='+'){
  644.     (*cnt)++ ;
  645.  }else if (cmd[*cnt]=='-'){
  646.     sign = -1 ;
  647.     (*cnt)++ ;
  648.  }
  649.  
  650.  for ( val=0 ; isdigit(cmd[*cnt]) ; (*cnt)++ )
  651.     val = 10 * val + (cmd[*cnt]-'0') ;
  652.  
  653.  skipcom(cmd,cnt) ;
  654.  return val * sign ;
  655. }
  656. /*--------------------------------------------------------------------------*/
  657. /*--------------------------------------------------------------------------*/
  658. SHAR_EOF
  659. fi # end of overwriting check
  660. if test -f 'src/ctostr.c'
  661. then
  662.     echo shar: will not over-write existing file "'src/ctostr.c'"
  663. else
  664. cat << \SHAR_EOF > 'src/ctostr.c'
  665. /* ctostr.c  04/02/92
  666.  * Copyright 1983-1992   Albert Davis
  667.  * get string from string
  668.  */
  669. #include "ecah.h"
  670. #include "declare.h"
  671. /*--------------------------------------------------------------------------*/
  672.     char    *ctostr(const char*,int*,char*,int);
  673. /*--------------------------------------------------------------------------*/
  674. /* ctostr: character input to string
  675.  * scan (and eat) an input string (cmd) using index (cnt).
  676.  * result in (des)  (null terminated).
  677.  * max length (actual char count) is (len).
  678.  * (des) must be at least (len)+1 characters long.
  679.  * (cmd) unchanged.  (*cnt) updated to point to next argument.
  680.  * skips leading whitespace.  skips trailing whitespace and comma
  681.  * skips parts of input word too big for destination
  682.  */
  683. char *ctostr(cmd,cnt,des,len)
  684. const char *cmd;
  685. int *cnt;
  686. char *des;
  687. int len;
  688. {
  689.  char chr;
  690.  int dind;
  691.  
  692.  skipbl(cmd,cnt);
  693.  for (dind = 0;  dind < len;  (*cnt)++, dind++){
  694.     chr = cmd[*cnt];
  695.     if (isterm(chr))
  696.        break;
  697.     des[dind] = chr;
  698.  }
  699.  des[dind] = '\0';
  700.  
  701.  while (!isterm(cmd[*cnt]))
  702.     (*cnt)++;
  703.  skipcom(cmd,cnt);
  704.  return des;
  705. }
  706. /*--------------------------------------------------------------------------*/
  707. /*--------------------------------------------------------------------------*/
  708. SHAR_EOF
  709. fi # end of overwriting check
  710. if test -f 'src/dc.c'
  711. then
  712.     echo shar: will not over-write existing file "'src/dc.c'"
  713. else
  714. cat << \SHAR_EOF > 'src/dc.c'
  715. /* dc  03/26/92
  716.  * Copyright 1983-1992   Albert Davis
  717.  * dc analysis top
  718.  */
  719. #include "ecah.h"
  720. #include "branch.h"
  721. #include "dc.h"
  722. #include "mode.h"
  723. #include "options.h"
  724. #include "status.h"
  725. #include "declare.h"
  726. /*--------------------------------------------------------------------------*/
  727.     void    cmd_dc(const char*,int*);
  728.     void    cmd_op(const char*,int*);
  729. /*--------------------------------------------------------------------------*/
  730. extern const struct options opt;
  731. extern          struct status stats;
  732.  
  733. extern int run_mode;    /* variations on handling of dot cmds            */
  734. extern int sim_mode;    /* simulation type (AC, DC, ...)            */
  735. extern double trtime;    /* transient analysis time, -1 means dc            */
  736. /*--------------------------------------------------------------------------*/
  737. void cmd_dc(cmd,cnt)
  738. const char *cmd;
  739. int  *cnt;
  740. {
  741.  static dc_t dc;
  742.  
  743.  sim_mode = sDC;
  744.  time_zstart(&(stats.total));
  745.  time_zstart(&(stats.dc));
  746.  stats.iter[sim_mode] = 0;
  747.  stats.iter[iPRINTSTEP] = 0;
  748.  
  749.  trtime = -1.;
  750.  
  751.  allocate(sim_mode);
  752.  dc_setup(cmd,cnt,&dc);
  753.  if (run_mode != rEXECUTE)
  754.     return;
  755.  dc_sweep(&dc);
  756.  
  757.  time_stop(&(stats.dc));
  758.  time_stop(&(stats.total));
  759. }
  760. /*--------------------------------------------------------------------------*/
  761. void cmd_op(cmd,cnt)
  762. const char *cmd;
  763. int  *cnt;
  764. {
  765.  static dc_t op;
  766.  
  767.  sim_mode = sOP;
  768.  time_zstart(&(stats.total));
  769.  time_zstart(&(stats.op));
  770.  stats.iter[sim_mode] = 0;
  771.  stats.iter[iPRINTSTEP] = 0;
  772.  
  773.  trtime = -1.;
  774.  
  775.  allocate(sim_mode);
  776.  op_setup(cmd,cnt,&op);
  777.  if (run_mode != rEXECUTE)
  778.     return;
  779.  dc_sweep(&op);
  780.  
  781.  time_stop(&(stats.op));
  782.  time_stop(&(stats.total));
  783. }
  784. /*--------------------------------------------------------------------------*/
  785. /*--------------------------------------------------------------------------*/
  786. SHAR_EOF
  787. fi # end of overwriting check
  788. if test -f 'src/dc_setup.c'
  789. then
  790.     echo shar: will not over-write existing file "'src/dc_setup.c'"
  791. else
  792. cat << \SHAR_EOF > 'src/dc_setup.c'
  793. /* dc_setup  12/29/92
  794.  * Copyright 1983-1992   Albert Davis
  795.  * dc analysis setup
  796.  */
  797. #include "ecah.h"
  798. #include "argparse.h"
  799. #include "branch.h"
  800. #include "dc.h"
  801. #include "dev.h"
  802. #include "error.h"
  803. #include "io.h"
  804. #include "mode.h"
  805. #include "options.h"
  806. #include "worst.h"
  807. #include "declare.h"
  808. /*--------------------------------------------------------------------------*/
  809.     void    dc_finish(void);
  810.     void    op_setup(const char*,int*,dc_t*);
  811.     void    dc_setup(const char*,int*,dc_t*);
  812. static    void    dc_options(const char*,int*,dc_t*);
  813. static    void    dcoptby(const char*,int*);
  814. static    void    dcoptdecade(const char*,int*);
  815. static    void    dcopttimes(const char*,int*);
  816. /*--------------------------------------------------------------------------*/
  817. extern       struct ioctrl io;
  818. extern const struct options opt;
  819. extern int sim_mode;    /* simulation type (AC, DC, ...)            */
  820. extern int worstcase;    /* worst case, monte carlo mode    (enum type, worst.h)*/
  821. extern double temp;    /* actual ambient temperature, kelvin            */
  822. extern double genout;    /* output of signal generator (ckt input)        */
  823. static dc_t *par;    /* latest parameters for arg passing and "finish"   */
  824. static branch_t stash[DCNEST];    /* store std values of elements being swept */
  825. /*--------------------------------------------------------------------------*/
  826. void dc_finish()
  827. {
  828.  int ii;
  829.  for (ii = 0;  ii < DCNEST;  ii++){
  830.     if (par && exists(par->zap[ii])){
  831.        par->zap[ii]->subckt = stash[ii].subckt;
  832.        par->zap[ii]->x = stash[ii].x;
  833.        par->zap[ii]->val = stash[ii].val;
  834.        expand_branch(par->zap[ii]);
  835.     }
  836.  }
  837. }
  838. /*--------------------------------------------------------------------------*/
  839. void op_setup(cmd,cnt,dc)
  840. const char *cmd;
  841. int  *cnt;
  842. dc_t *dc;
  843. {
  844.  dc->zap[0] = (branch_t*)NULL;
  845.  dc->sweep[0] = &temp;
  846.  dc->start[0] = (isfloat(cmd[*cnt])) ? ctof(cmd,cnt)-ABS_ZERO : opt.tempamb;
  847.  dc->stop[0] = (isfloat(cmd[*cnt])) ? ctof(cmd,cnt)-ABS_ZERO : dc->start[0];
  848.  dc->step[0] = 0.;
  849.  genout = 0.;
  850.  dc_options(cmd,cnt,dc);
  851.  if (dc->step[0] == 0.){
  852.     dc->step[0] = dc->stop[0] - dc->start[0];
  853.     dc->linswp[0] = YES;
  854.  }
  855. }
  856. /*--------------------------------------------------------------------------*/
  857. void dc_setup(cmd,cnt,dc)
  858. const char *cmd;
  859. int  *cnt;
  860. dc_t *dc;
  861. {
  862.  branch_t *target;
  863.  
  864.  target = findbranch(cmd,cnt,firstbranch_all(),lastbranch_all());
  865.  if (exists(target)){
  866.     dc->zap[0] = target;
  867.     stash[0] = *(dc->zap[0]);
  868.     dc->zap[0]->x = (generic_t*)NULL;
  869.     dc->zap[0]->subckt = (branch_t*)NULL;
  870.     if (isfloat(cmd[*cnt])){
  871.        dc->sweep[0] = &(dc->zap[0]->val);
  872.        dc->start[0] = ctof(cmd,cnt);
  873.        dc->stop[0] = (isfloat(cmd[*cnt])) ? ctof(cmd,cnt) : dc->start[0];
  874.        dc->step[0] = 0.;
  875.     }else{
  876.        dc->sweep[0] = (double*)NULL;
  877.        syntax(cmd,cnt,bERROR);
  878.     }
  879.  }else if (isfloat(cmd[*cnt])){
  880.     dc->zap[0] = (branch_t*)NULL;
  881.     dc->sweep[0] = &genout;
  882.     dc->start[0] = ctof(cmd,cnt);
  883.     dc->stop[0] = (isfloat(cmd[*cnt])) ? ctof(cmd,cnt) : dc->start[0];
  884.     dc->step[0] = 0.;
  885.  }
  886.  if (!dc->sweep[0])
  887.     error(bERROR, "dc: nothing to sweep\n");
  888.  
  889.  genout = 0.;
  890.  temp = opt.tempamb;
  891.  dc_options(cmd,cnt,dc);
  892.  if (dc->step[0] == 0.){
  893.     dc->step[0] = dc->stop[0] - dc->start[0];
  894.     dc->linswp[0] = YES;
  895.  }
  896. }
  897. /*--------------------------------------------------------------------------*/
  898. static void dc_options(cmd,cnt,dc)
  899. const char *cmd;
  900. int  *cnt;
  901. dc_t *dc;
  902. {
  903.  par = dc;
  904.  io.where |= io.mstdout;
  905.  io.ploton = io.plotset;
  906.  dc->loop = dc->reverse = dc->cont = dc->watch = worstcase = NO;
  907.  for (;;){
  908.     if (argparse(cmd,cnt,REPEAT,
  909.     "*",        aFUNCTION,  dcopttimes,
  910.         "ACMAx",    aENUM,        &worstcase,      wMAXAC,
  911.     "ACMIn",    aENUM,        &worstcase,      wMINAC,
  912.     "Ambient",    aODOUBLE,   &temp,      opt.tempamb,
  913.     "By",        aFUNCTION,  dcoptby,
  914.     "Continue",    aENUM,        &dc->cont,      YES,
  915.         "DCMAx",    aENUM,        &worstcase,      wMAXDC,
  916.     "DCMIn",    aENUM,        &worstcase,      wMINDC,
  917.     "Decade",    aFUNCTION,  dcoptdecade,
  918.     "LAg",        aENUM,        &worstcase,   wLAG,
  919.     "LEad",        aENUM,        &worstcase,   wLEAD,
  920.     "LOop",        aENUM,        &dc->loop,      YES,
  921.     "MAx",        aENUM,        &worstcase,   wMAXDC,
  922.     "MIn",        aENUM,        &worstcase,   wMINDC,
  923.     "NOPlot",    aENUM,        &io.ploton,   NO,
  924.     "PLot",        aENUM,        &io.ploton,   YES,
  925.     "Reftemp",    aODOUBLE,   &temp,      opt.tnom,
  926.     "REverse",    aENUM,        &dc->reverse, YES,
  927.     "SEnsitivity",    aENUM,        &worstcase,   wSENS,
  928.     "Temperature",    aODOUBLE,   &temp,      -ABS_ZERO,
  929.     "TImes",    aFUNCTION,  dcopttimes,
  930.     "WAtch",    aENUM,        &dc->watch,      YES,
  931.     ""))
  932.     ;    
  933.     else if (isfloat(cmd[*cnt]))
  934.         dcoptby(cmd,cnt);
  935.     else if (outset(cmd,cnt,(char*)NULL,((sim_mode==sOP)?"bi ":"dc ")))
  936.     ;
  937.     else{
  938.        syntax(cmd,cnt,bWARNING);
  939.        break;
  940.     }
  941.  }
  942.  initio(io.where,(FILE*)NULL);
  943.  if (worstcase == wRAND   ||   worstcase == wWORST)
  944.     io.ploton = NO;
  945. }
  946. /*--------------------------------------------------------------------------*/
  947. static void dcoptby(cmd,cnt)
  948. const char *cmd;
  949. int *cnt;
  950. {
  951.  par->step[0] = ctof(cmd,cnt);
  952.  par->linswp[0] = YES;
  953.  if (par->step[0] == 0.)
  954.      par->step[0] = par->stop[0] - par->start[0];
  955. }
  956. /*--------------------------------------------------------------------------*/
  957. static void dcoptdecade(cmd,cnt)
  958. const char *cmd;
  959. int *cnt;
  960. {
  961.  double junk;
  962.  junk = fabs(ctof(cmd,cnt));
  963.  if (junk == 0.)
  964.     junk = 1.;
  965.  junk = pow(10., 1./junk);
  966.  par->step[0] = junk;
  967.  par->linswp[0] = NO;
  968. }
  969. /*--------------------------------------------------------------------------*/
  970. static void dcopttimes(cmd,cnt)
  971. const char *cmd;
  972. int *cnt;
  973. {
  974.  par->step[0] = fabs(ctof(cmd,cnt));
  975.  par->linswp[0] = NO;
  976.  if (par->step[0] == 0.  &&  par->start[0] != 0.)
  977.     par->step[0] = par->stop[0] / par->start[0];
  978. }
  979. /*--------------------------------------------------------------------------*/
  980. /*--------------------------------------------------------------------------*/
  981. SHAR_EOF
  982. fi # end of overwriting check
  983. if test -f 'src/dc_sweep.c'
  984. then
  985.     echo shar: will not over-write existing file "'src/dc_sweep.c'"
  986. else
  987. cat << \SHAR_EOF > 'src/dc_sweep.c'
  988. /* dc_sweep  12/29/92
  989.  * Copyright 1983-1992   Albert Davis
  990.  * dc analysis sweep
  991.  */
  992. #include "ecah.h"
  993. #include "branch.h"
  994. #include "convstat.h"
  995. #include "dev.h"
  996. #include "dc.h"
  997. #include "error.h"
  998. #include "io.h"
  999. #include "mode.h"
  1000. #include "options.h"
  1001. #include "status.h"
  1002. #include "declare.h"
  1003. /*--------------------------------------------------------------------------*/
  1004.     void    dc_sweep(dc_t*);
  1005. static    void    dc_first(dc_t*,int);
  1006. static    int    dc_next(dc_t*,int);
  1007. /*--------------------------------------------------------------------------*/
  1008. extern       struct ioctrl io;
  1009. extern const struct options opt;
  1010. extern          struct status stats;
  1011. extern const int sim_mode;    /* simulation type (AC, DC, ...)        */
  1012. extern int currents_bad;
  1013. /*--------------------------------------------------------------------------*/
  1014. void dc_sweep(dc)
  1015. dc_t *dc;
  1016. {
  1017.  int conv;
  1018.  
  1019.  tr_head(dc->start[0], dc->stop[0], dc->linswp[0], " ");
  1020.  currents_bad = YES;
  1021.  if (dc->cont){
  1022.     trestor();
  1023.  }
  1024.  
  1025.  dc_first(dc,0);
  1026.  io.suppresserrors = !dc->watch;
  1027.  conv = tr_solve(opt.itl[1]);
  1028.  if (conv != cGOOD)
  1029.     error(bWARNING, "did not converge\n");
  1030.  dc_out(dc);
  1031.  
  1032.  while (dc_next(dc,0)){
  1033.     io.suppresserrors = !dc->watch;
  1034.     conv = tr_solve(opt.itl[2]);
  1035.     if (conv != cGOOD)
  1036.        error(bWARNING, "did not converge\n");
  1037.     dc_out(dc);
  1038.  }
  1039. }
  1040. /*--------------------------------------------------------------------------*/
  1041. static void dc_first(dc,ii)
  1042. dc_t *dc;
  1043. int ii;
  1044. {
  1045.  *dc->sweep[ii] = dc->start[ii];
  1046.  expand_branch(dc->zap[ii]);
  1047.  
  1048.  if (dc->reverse){
  1049.     dc->reverse = NO;
  1050.     while (dc_next(dc,ii))
  1051.        /* nothing */;
  1052.     dc->reverse = YES;
  1053.     dc_next(dc,ii);
  1054.  }
  1055.  dc->printnow = YES;
  1056. }
  1057. /*--------------------------------------------------------------------------*/
  1058. static int dc_next(dc,ii)
  1059. dc_t *dc;
  1060. int ii;
  1061. {
  1062.  int ok = NO;
  1063.  if (dc->linswp[ii]){
  1064.     double fudge = dc->step[ii] / 10.;
  1065.     if (dc->step[ii] == 0.){
  1066.        ok = NO;
  1067.     }else{
  1068.        if (!dc->reverse){
  1069.       *(dc->sweep[ii]) += dc->step[ii];
  1070.       ok=inorder(dc->start[ii]-fudge,*(dc->sweep[ii]),dc->stop[ii]+fudge);
  1071.       if (!ok  &&  dc->loop)
  1072.          dc->reverse = YES;
  1073.        }
  1074.        if (dc->reverse){
  1075.       *(dc->sweep[ii]) -= dc->step[ii];
  1076.       ok=inorder(dc->start[ii]-fudge,*(dc->sweep[ii]),dc->stop[ii]+fudge);
  1077.        }
  1078.     }
  1079.  }else{
  1080.     double fudge = pow(dc->step[ii], .1);
  1081.     if (dc->step[ii] == 1.){
  1082.        ok = NO;
  1083.     }else{
  1084.        if (!dc->reverse){
  1085.       *(dc->sweep[ii]) *= dc->step[ii];
  1086.       ok=inorder(dc->start[ii]/fudge,*(dc->sweep[ii]),dc->stop[ii]*fudge);
  1087.       if (!ok  &&  dc->loop)
  1088.          dc->reverse = YES;       
  1089.        }
  1090.        if (dc->reverse){
  1091.       *(dc->sweep[ii]) /= dc->step[ii];
  1092.       ok=inorder(dc->start[ii]/fudge,*(dc->sweep[ii]),dc->stop[ii]*fudge);
  1093.        }
  1094.     }
  1095.  }
  1096.  expand_branch(dc->zap[ii]);
  1097.  dc->printnow = YES;
  1098.  return ok;
  1099. }
  1100. /*--------------------------------------------------------------------------*/
  1101. /*--------------------------------------------------------------------------*/
  1102. SHAR_EOF
  1103. fi # end of overwriting check
  1104. if test -f 'src/dealloc.c'
  1105. then
  1106.     echo shar: will not over-write existing file "'src/dealloc.c'"
  1107. else
  1108. cat << \SHAR_EOF > 'src/dealloc.c'
  1109. /* dealloc  12/30/92
  1110.  * Copyright 1983-1992   Albert Davis
  1111.  * Deallocates all heap space except the main parts list
  1112.  */
  1113. #include "ecah.h"
  1114. #include "branch.h"
  1115. #include "error.h"
  1116. #include "nodestat.h"
  1117. #include "declare.h"
  1118. /*--------------------------------------------------------------------------*/
  1119.     void    dealloc(int);
  1120. /*--------------------------------------------------------------------------*/
  1121. extern double last_time;
  1122. extern double *volts;
  1123. extern int *basnode;            /* lowest node connected to this node*/
  1124. extern int *nm;                /* node map table            */
  1125. extern double **rerow, **imrow;        /* array of row pointers        */
  1126. extern double **recol, **imcol;        /* array of column pointers        */
  1127. extern double *recon,*imcon,*oldcon,*fwcon;/* constant terms            */
  1128. extern double *reals, *imags;        /* big array allocation bases        */
  1129. extern complex_t *fodata;        /* for fourier analysis            */
  1130. extern struct nodestat *nstat;            /* node status flags            */
  1131. /*--------------------------------------------------------------------------*/
  1132. void dealloc(all)
  1133. int all;
  1134. {
  1135.  if (all){
  1136.     last_time = 0.;
  1137.     qfree((void**)&volts);
  1138.     qfree((void**)&basnode);
  1139.     qfree((void**)&nm);
  1140.  }
  1141.  qfree((void**)&rerow);
  1142.  qfree((void**)&imrow);
  1143.  qfree((void**)&recol);
  1144.  qfree((void**)&imcol);
  1145.  qfree((void**)&reals);
  1146.  qfree((void**)&imags);
  1147.  qfree((void**)&recon);
  1148.  qfree((void**)&imcon);
  1149.  qfree((void**)&fwcon);
  1150.  qfree((void**)&nstat);
  1151.  qfree((void**)&oldcon);
  1152.  qfree((void**)&fodata);
  1153. }
  1154. /*--------------------------------------------------------------------------*/
  1155. /*--------------------------------------------------------------------------*/
  1156. SHAR_EOF
  1157. fi # end of overwriting check
  1158. if test -f 'src/delete.c'
  1159. then
  1160.     echo shar: will not over-write existing file "'src/delete.c'"
  1161. else
  1162. cat << \SHAR_EOF > 'src/delete.c'
  1163. /* delete  01/11/93
  1164.  * Copyright 1983-1992   Albert Davis
  1165.  * delete and clear commands
  1166.  * (for now, also unexpand)
  1167.  */
  1168. #include "ecah.h"
  1169. #include "branch.h"
  1170. #include "error.h"
  1171. #include "declare.h"
  1172. /*--------------------------------------------------------------------------*/
  1173.     void    cmd_clear(void);
  1174.     void    cmd_delete(const char*,int*);
  1175. static    void    bylabel(const char*,int*);
  1176. static    void    all(void);
  1177. /*--------------------------------------------------------------------------*/
  1178. #ifndef MAXINT
  1179. #define MAXINT 32000
  1180. #endif
  1181. /*--------------------------------------------------------------------------*/
  1182. /* cmd_clear: clear the whole circuit, including faults, etc
  1183.  *   equivalent to unfault; unkeep; delete all; title = (blank)
  1184.  */
  1185. void cmd_clear()
  1186. {
  1187.  volatile int dummy = 0;
  1188.  
  1189.  cmd_unfault();
  1190.  cmd_unkeep();
  1191.  dummy = 0;
  1192.  cmd_ic("clear",&dummy);
  1193.  dummy = 0;
  1194.  cmd_nodeset("clear",&dummy);
  1195.  dummy = 0;
  1196.  cmd_print("clear",&dummy);
  1197.  dummy = 0;
  1198.  cmd_delete("all",&dummy);
  1199.  dummy = 0;
  1200.  cmd_title("'",&dummy);
  1201. }
  1202. /*--------------------------------------------------------------------------*/
  1203. /* cmd_delete:  delete command
  1204.  */
  1205. void cmd_delete(cmd,cnt)
  1206. const char *cmd;    /* command string                    */
  1207. int  *cnt;        /* pointer to cmd string counter            */
  1208. {
  1209.  dealloc(YES);
  1210.  if (pmatch(cmd,cnt,"ALL")){
  1211.     all();
  1212.  }else{
  1213.     while (isalpha(cmd[*cnt]))
  1214.        bylabel(cmd,cnt);
  1215.  }
  1216. }
  1217. /*--------------------------------------------------------------------------*/
  1218. /* bylabel: delete circuit element by label
  1219.  *     all lines with matching label (with wild cards * and ?) deleted.
  1220.  *    syntax warning if no match
  1221.  */
  1222. static void bylabel(cmd,cnt)
  1223. const char *cmd;
  1224. int  *cnt;
  1225. {
  1226.  branch_t *brh;        /* scanning branch                    */
  1227.  /*volatile*/ int idx;    /* temporary string index                */
  1228.  int count = 0;        /* deleted line counter                    */
  1229.  int x = 0;        /* fudge: place to stash new index            */
  1230.  
  1231.  for (brh = firstbranch_all();
  1232.     idx= *cnt,  brh = findbranch(cmd,&idx,brh,lastbranch_all()),  exists(brh);
  1233.      brh=nextbranch_all(brh)){
  1234.     x = idx;
  1235.     count += deletebranch(brh);
  1236.  }
  1237.  
  1238.  if (count != 0){
  1239.     *cnt = x;
  1240.  }else{
  1241.     syntax(cmd,cnt,bWARNING);
  1242.     skiparg(cmd,cnt);
  1243.  }
  1244. }
  1245. /*--------------------------------------------------------------------------*/
  1246. /* all: delete all parts of a circuit, line by line
  1247.  */
  1248. static void all()                /* the whole circuit        */
  1249. {
  1250.  branch_t *brh;
  1251.  for (brh=firstbranch_all();  exists(brh);  brh=nextbranch_all(brh))
  1252.     (void)deletebranch(brh);
  1253. }
  1254. /*--------------------------------------------------------------------------*/
  1255. /*--------------------------------------------------------------------------*/
  1256. SHAR_EOF
  1257. fi # end of overwriting check
  1258. if test -f 'src/dev.c'
  1259. then
  1260.     echo shar: will not over-write existing file "'src/dev.c'"
  1261. else
  1262. cat << \SHAR_EOF > 'src/dev.c'
  1263. /* dev.c  01/18/93
  1264.  * Copyright 1983-1992   Albert Davis
  1265.  * generic functions to be used as part of specific devices
  1266.  */
  1267. #include "ecah.h"
  1268. #include "branch.h"
  1269. #include "error.h"
  1270. #include "expr.h"
  1271. #include "declare.h"
  1272. /*--------------------------------------------------------------------------*/
  1273.     branch_t*  createbranch(
  1274.                const branch_t*,const generic_t*,const functions_t*);
  1275. static    generic_t* create_extra_stuff(const branch_t*,const generic_t*);
  1276.     void       parsegeneric(branch_t*,const char*,int*,int);
  1277. static    void       parseexpr(branch_t*,const char*,int*);
  1278. static    void       getkey(int*,int*,const char*,int*);
  1279.     void       parselabel(branch_t*,const char*,int*);
  1280.     void       printgeneric(const branch_t*,int,int);
  1281. static    void       printexpr(const branch_t*,int);
  1282.     char*       printlabel(const branch_t*,int);
  1283.     double       trprobegeneric(const branch_t*,const char*);
  1284.     double       acprobegeneric(const branch_t*,const char*);
  1285.     double       trprobe_branch(branch_t*,const char*);
  1286.     double       acprobe_branch(branch_t*,const char*);
  1287.     void       expandgeneric(branch_t*, const branch_t*);
  1288. /*--------------------------------------------------------------------------*/
  1289. extern const double *recon, *imcon;
  1290. extern const char e_om[], e_int[];
  1291. /*--------------------------------------------------------------------------*/
  1292. /* createbranch: create an empty branch structure, or copy a prototype
  1293.  * returns pointer to it.
  1294.  * doesn't actually copy extra stuff, up to caller to do it
  1295.  */
  1296. branch_t *createbranch(proto,xproto,func)
  1297. const branch_t *proto;
  1298. const generic_t *xproto;
  1299. const functions_t *func;
  1300. {
  1301.  branch_t *brh;
  1302.  
  1303.  if (proto){
  1304.     brh = (branch_t*)calloc(1,proto->ssize);
  1305.     if (!brh)
  1306.        error(bERROR, e_om, "createbranch");
  1307.     (void)memcpy((void*)brh, (void*)proto, proto->ssize);
  1308.  }else if (func){
  1309.     int ii;
  1310.     brh = (branch_t*)calloc(1, func->ssize);
  1311.     if (!brh)
  1312.        error(bERROR, e_om, "createbranch");
  1313.     for (ii = 0;  ii <= NODESPERBRANCH;  ii++)
  1314.        brh->nodes[ii].e = brh->nodes[ii].t = brh->nodes[ii].m = INVALIDNODE;
  1315.     brh->f = func;
  1316.     brh->ssize = func->ssize;
  1317.  }else{
  1318.     brh = (branch_t*)NULL;
  1319.     error(bERROR, e_int, "nothing to create");
  1320.  }
  1321.  brh->n = brh->nodes;
  1322.  brh->subckt = (branch_t*)NULL;
  1323.  brh->x = create_extra_stuff(brh,((brh->x)?(const generic_t*)brh->x:xproto));
  1324.  
  1325.  brh->prev = brh->next = (branch_t*)NULL;
  1326.  brh->stprev = brh->stnext = (branch_t*)NULL;
  1327.  brh->parent = (branch_t*)NULL;
  1328.  brh->wcg = brh->wcd = brh->wcp = 2;
  1329.  
  1330.  return brh;
  1331. }
  1332. /*--------------------------------------------------------------------------*/
  1333. /* create_extra_stuff: copy the extra info for special parts (mosfets, etc)
  1334.  */
  1335. static generic_t *create_extra_stuff(brh,proto)
  1336. const branch_t  *brh;
  1337. const generic_t *proto;
  1338. {
  1339.  if (proto){
  1340.     generic_t *x;
  1341.     x = (generic_t*)calloc(1,proto->ssize);
  1342.     if (!x)
  1343.        error(bERROR, e_om, "extra_stuff");
  1344.     (void)memcpy((void*)x, (void*)proto, proto->ssize);
  1345.     x->x = create_extra_stuff(brh, x->x);
  1346.     return x;
  1347.  }else{
  1348.     return (generic_t*)NULL;
  1349.  }
  1350. }
  1351. /*--------------------------------------------------------------------------*/
  1352. /* parsegeneric: parse most ordinary elements (resistor, vccs, cap, etc.)
  1353.  *     called mostly by functions that parse particular elements
  1354.  */
  1355. void parsegeneric(brh,cmd,cnt,nodecount)
  1356. branch_t *brh;
  1357. const char *cmd;
  1358. int *cnt;
  1359. int nodecount;
  1360. {
  1361.  parselabel(brh,cmd,cnt);
  1362.  (void)parsenodes(brh,cmd,cnt,nodecount);
  1363.  parseexpr(brh,cmd,cnt);
  1364. }
  1365. /*--------------------------------------------------------------------------*/
  1366. /* parseexpr: parse ureca style expressions.
  1367.  */
  1368. static void parseexpr(brh,cmd,cnt)
  1369. branch_t *brh;
  1370. const char *cmd;
  1371. int *cnt;
  1372. {
  1373.  double numbers[EXPRSIZE];    /* there are two dynamic arrays            */
  1374.  int keys[EXPRSIZE];        /* one for the keys                */
  1375.  int numcount;            /* other for arguments (doubles)        */
  1376.  int keycount;            /* keys are first.                */
  1377.                 /* Initially, they are unknown size, so        */
  1378.  brh->val = ctof(cmd,cnt);
  1379.  numcount = keycount = 0;    /* use local fixed allocation.  Then copy   */
  1380.  for (;;){            /* in appropriate size to malloc space,        */
  1381.     int key;            /* with links to parent branch struct.        */
  1382.     int args;
  1383.     int arg;
  1384.     int paren = 0;
  1385.     getkey(&key, &args, cmd, cnt);
  1386.     if (!key)
  1387.        break;
  1388.     if ((keycount + 1 >= EXPRSIZE) || (numcount + args > EXPRSIZE))
  1389.        error(bERROR, "expression too long\n");
  1390.     keys[keycount++] = key;
  1391.     if (args == aVARIABLE){            /* variable # of args        */
  1392.        double *argcount;            /* 1st arg is count        */
  1393.        paren += skiplparen(cmd,cnt);
  1394.        argcount = &(numbers[numcount++]);
  1395.        *argcount = 1.;
  1396.        while (isfloat(cmd[*cnt])){
  1397.        numbers[numcount++] = ctof(cmd,cnt);
  1398.        (*argcount)++;
  1399.        }
  1400.        paren -= skiprparen(cmd,cnt);
  1401.     }else if (args == aASSIGN){
  1402.        skipequal(cmd,cnt);
  1403.        numbers[numcount++] = ctof(cmd,cnt);
  1404.     }else if (args > 0){
  1405.        paren += skiplparen(cmd,cnt);
  1406.        for (arg = 1;  arg <= args;  arg++)
  1407.        numbers[numcount++] = ctof(cmd,cnt);
  1408.        paren -= skiprparen(cmd,cnt);
  1409.     }else{
  1410.        /* no args, do nothing */
  1411.     }
  1412.     if (paren != 0)
  1413.        syntax(cmd,cnt,bWARNING);
  1414.  }
  1415.  
  1416.  if (keycount != 0){        /* allocate mem to save this stuff,        */
  1417.     struct expr *x;        /* then copy.                    */
  1418.     size_t ssize;
  1419.  
  1420.     brh->x = (generic_t*)calloc(1,sizeof(struct expr));
  1421.     if (!brh->x)
  1422.        error(bERROR, e_om, "partslist (expression)");
  1423.     x = (struct expr*)brh->x;
  1424.     x->ssize = sizeof(struct expr);
  1425.  
  1426.     keys[keycount++] = eEND;
  1427.  
  1428.     ssize = sizeof(generic_t) + keycount*sizeof(int);
  1429.     x->x = (generic_t*)calloc(1, ssize);
  1430.     if (!x->x)
  1431.        error(bERROR, e_om, "partslist (expression)");
  1432.     x->x->ssize = ssize;
  1433.     x->keys = (struct ints*)x->x;
  1434.  
  1435.     ssize = sizeof(generic_t) + numcount*sizeof(double);
  1436.     x->x->x = (generic_t*)calloc(1, ssize);
  1437.     if (!x->x->x)
  1438.        error(bERROR, e_om, "partslist (expression)");
  1439.     x->x->x->ssize = ssize;
  1440.     x->args = (struct dbls*)x->x->x;
  1441.  
  1442.     x->x->x->x = (generic_t*)NULL;
  1443.  
  1444.     (void)memcpy((void*)x->keys->args,(void*)keys,   keycount*sizeof(int));
  1445.     (void)memcpy((void*)x->args->args,(void*)numbers,numcount*sizeof(double));
  1446.  }else{
  1447.     brh->x = (generic_t*)NULL;
  1448.  }
  1449. }
  1450. /*--------------------------------------------------------------------------*/
  1451. /* getkey: scan for a keyword. Return its key and desired arg count.
  1452.  * returns key == eNO if no match.
  1453.  */
  1454. static void getkey(key,args,cmd,cnt)
  1455. int *key;
  1456. int *args;
  1457. const char *cmd;
  1458. int *cnt;
  1459. {
  1460.  setmatch(cmd,cnt);
  1461.       if (rematch("AC"        )) { *key = eAC;     *args = aAC; }
  1462.  else if (rematch("DC"        )) { *key = eDC;     *args = aDC; }
  1463.  else if (rematch("DCTran"    )) { *key = eDCTRAN;    *args = aDCTRAN; }
  1464.  else if (rematch("Frequency"    )) { *key = eFREQUENCY;    *args = aFREQUENCY; }
  1465.  else if (rematch("PEriod"    )) { *key = ePERIOD;    *args = aPERIOD; }
  1466.  else if (rematch("Ramp"    )) { *key = eRAMP;    *args = aRAMP; }
  1467.  else if (rematch("TIme"    )) { *key = eTIME;    *args = aTIME; }
  1468.  else if (rematch("TRansient"    )) { *key = eTRAN;    *args = aTRAN; }
  1469.  
  1470.  else if (rematch("BAndwidth"    )) { *key = eBANDWIDTH;    *args = aBANDWIDTH; }
  1471.  else if (rematch("COMplex"    )) { *key = eCOMPLEX;    *args = aCOMPLEX; }
  1472.  else if (rematch("CORNERDown"    )) { *key = eCORNERDOWN;*args = aCORNERDOWN; }
  1473.  else if (rematch("CORNERUp"    )) { *key = eCORNERUP;    *args = aCORNERUP; }
  1474.  else if (rematch("DElay"    )) { *key = eDELAY;    *args = aDELAY; }
  1475.  else if (rematch("EXP"        )) { *key = eEXP;    *args = aEXP; }
  1476.  else if (rematch("EXPTerm"    )) { *key = eEXPTERM;    *args = aEXPTERM; }
  1477.  else if (rematch("Generator"    )) { *key = eGENERATOR;    *args = aGENERATOR; }
  1478.  else if (rematch("Max"        )) { *key = eMAX;    *args = aMAX; }
  1479.  else if (rematch("NEtfunction" )) { *key = eNETFUNC;    *args = aNETFUNC; }
  1480.  else if (rematch("NOtch"    )) { *key = eNOTCH;    *args = aNOTCH; }
  1481.  else if (isfloat(cmd[*cnt]    )) { *key = eNUMERIC;    *args = aNUMERIC; }
  1482.  else if (rematch("Offset"    )) { *key = eOFFSET;    *args = aOFFSET; }
  1483.  else if (rematch("POLAr"    )) { *key = ePOLAR;    *args = aPOLAR; }
  1484.  else if (rematch("POLYTerm"    )) { *key = ePOLYTERM;    *args = aPOLYTERM; }
  1485.  else if (rematch("PUlse"    )) { *key = ePULSE;    *args = aPULSE; }
  1486.  else if (rematch("PWl"        )) { *key = ePWL;    *args = aPWL;}
  1487.  else if (rematch("SFfm"    )) { *key = eSFFM;    *args = aSFFM; }
  1488.  else if (rematch("SIn"        )) { *key = eSIN;    *args = aSIN; }
  1489.  else if (rematch("Tanh"    )) { *key = eTANH;    *args = aTANH; }
  1490.  
  1491.  else if (rematch("IC"        )) { *key = eIC;     *args = aIC; }
  1492.  else if (rematch("II"        )) { *key = eII;     *args = aII; }
  1493.  else if (rematch("IV"        )) { *key = eIV;     *args = aIV; }
  1494.  else if (rematch("TEmpco"    )) { *key = eTEMPCO;    *args = aTEMPCO; }
  1495.  else     { syntax(cmd,cnt,bWARNING);  *key = eNO;    *args = 0; }
  1496. }
  1497. /*--------------------------------------------------------------------------*/
  1498. /* parselabel: parse element label from input string
  1499.  * result in brh.
  1500.  */
  1501. void parselabel(brh,cmd,cnt)
  1502. branch_t *brh;
  1503. const char *cmd;
  1504. int *cnt;
  1505. {
  1506.  (void)ctostr(cmd, cnt, brh->label, LABELEN);
  1507.  brh->label[0] = to_upper(brh->label[0]);
  1508. }
  1509. /*--------------------------------------------------------------------------*/
  1510. void printgeneric(brh,where,detail)
  1511. const branch_t *brh;
  1512. int where;
  1513. int detail;
  1514. {
  1515.  (void)printlabel(brh,where);
  1516.  printnodes(brh,where);
  1517.  printexpr(brh,where);
  1518.  mputc('\n', where);
  1519. }
  1520. /*--------------------------------------------------------------------------*/
  1521. static void printexpr(brh,where)
  1522. const branch_t *brh;
  1523. int where;
  1524. {
  1525.  if (!brh->x  ||  brh->val != 0.){
  1526.     mprintf(where, "%s", ftos(brh->val, "", 7, 0));
  1527.  }
  1528.  
  1529.  if (brh->x){
  1530.     struct expr *x;
  1531.     double *arg;
  1532.     int *key;
  1533.     char *fname;
  1534.     int terms;
  1535.  
  1536.     x = (struct expr*)brh->x;
  1537.     arg = x->args->args;
  1538.     for (key = x->keys->args;  *key;  key++){
  1539.        switch (*key){
  1540.      case eAC:      fname = "ac";           terms = aAC;        break;
  1541.      case eDC:      fname = "dc";           terms = aDC;        break;
  1542.      case eDCTRAN:    fname = "dctran";    terms = aDCTRAN;    break;
  1543.      case eFREQUENCY: fname = "freq";    terms = aFREQUENCY;    break;
  1544.      case ePERIOD:    fname = "period";    terms = aPERIOD;    break;
  1545.      case eRAMP:      fname = "ramp";    terms = aRAMP;        break;
  1546.      case eTIME:      fname = "time";    terms = aTIME;        break;
  1547.      case eTRAN:      fname = "tran";    terms = aTRAN;        break;
  1548.  
  1549.      case eBANDWIDTH: fname = "bandwidth";  terms = aBANDWIDTH;    break;
  1550.      case eCOMPLEX:   fname = "complex";    terms = aCOMPLEX;    break;
  1551.      case eCORNERDOWN:fname = "cornerdown"; terms = aCORNERDOWN;    break;
  1552.      case eCORNERUP:  fname = "cornerup";    terms = aCORNERUP;    break;
  1553.      case eDELAY:     fname = "delay";    terms = aDELAY;        break;
  1554.      case eEXP:      fname = "exp";    terms = aEXP;        break;
  1555.      case eEXPTERM:   fname = "expterm";    terms = aEXPTERM;    break;
  1556.      case eGENERATOR: fname = "generator";  terms = aGENERATOR;    break;
  1557.      case eMAX:      fname = "max";    terms = aMAX;        break;
  1558.      case eNOTCH:     fname = "notch";    terms = aNOTCH;        break;
  1559.      case eNETFUNC:   fname = "netfunction";terms = aNETFUNC;    break;
  1560.      case eNUMERIC:   fname = "";           terms = aNUMERIC;    break;
  1561.      case eOFFSET:    fname = "offset";    terms = aOFFSET;    break;
  1562.      case ePOLAR:     fname = "polar";    terms = aPOLAR;        break;
  1563.      case ePOLYTERM:  fname = "polyterm";   terms = aPOLYTERM;    break;
  1564.      case ePULSE:     fname = "pulse";    terms = aPULSE;        break;
  1565.      case ePWL:      fname = "pwl";    terms = aPWL;        break;
  1566.      case eSFFM:      fname = "sffm";    terms = aSFFM;        break;
  1567.      case eSIN:      fname = "sin";    terms = aSIN;        break;
  1568.      case eTANH:      fname = "tanh";    terms = aTANH;        break;
  1569.  
  1570.      case eIC:      fname = "ic";           terms = aIC;        break;
  1571.      case eII:      fname = "ii";           terms = aII;        break;
  1572.      case eIV:      fname = "iv";           terms = aIV;        break;
  1573.      case eTEMPCO:    fname = "tempco";    terms = aTEMPCO;    break;
  1574.      default:      fname = "\n+ ERROR";  terms = 0;        break;
  1575.        }
  1576.        mprintf(where, " %s", fname);
  1577.        if (*key == eNUMERIC){
  1578.       mprintf(where,"%s ",ftos(*(arg++), "", 7, 0));
  1579.        }else if (terms == aVARIABLE){
  1580.           int i;
  1581.       terms = (int)(*(arg++)) - 1;
  1582.       mprintf(where, "(", fname);
  1583.       for (i = 1;   i <= terms;   i++){
  1584.          mprintf(where,"%s ",ftos(*(arg++), "", 7, 0));
  1585.       }
  1586.       mprintf(where, ") ");
  1587.        }else if (terms == aASSIGN){
  1588.       mprintf(where, "=", fname);
  1589.       mprintf(where,"%s ",ftos(*(arg++), "", 7, 0));
  1590.        }else if (terms > 0){
  1591.           int i;
  1592.       mprintf(where, "(", fname);
  1593.       for (i = 1;   i <= terms;   i++){
  1594.          mprintf(where,"%s ",ftos(*(arg++), "", 7, 0));
  1595.       }
  1596.       mprintf(where, ") ");
  1597.        }
  1598.     }
  1599.  }
  1600. }
  1601. /*--------------------------------------------------------------------------*/
  1602. char* printlabel(brh,where)
  1603. const branch_t *brh;
  1604. int where;
  1605. {
  1606.  static char label[BUFLEN];/* CAUTION: static area overwritten every call */
  1607.  
  1608.  strcpy(label, brh->label);
  1609.  while (brh = brh->parent, exists(brh)){
  1610.     strcat(label, ".");
  1611.     strncat(label, brh->label, BUFLEN-strlen(label)-2);
  1612.  }
  1613.  strcpy(&(label[BUFLEN-3]), "++");
  1614.  if (where)
  1615.     mprintf(where, "%s  ", label);
  1616.  return label;
  1617. }
  1618. /*--------------------------------------------------------------------------*/
  1619. double trprobegeneric(brh,what)
  1620. const branch_t *brh;
  1621. const char *what;
  1622. {
  1623.  double volts;
  1624.  int dummy = 0;
  1625.  
  1626.  volts = tr_volts(brh->n[OUT1],brh->n[OUT2]);
  1627.  
  1628.  setmatch(what,&dummy);
  1629.  if (rematch("V")){
  1630.     return volts;
  1631.  }else if (rematch("I")){
  1632.     return brh->m0.f1 * volts + brh->m0.c0;
  1633.  }else if (rematch("P")){
  1634.     return (brh->m0.f1 * volts + brh->m0.c0) * volts;
  1635.  }else if (rematch("EV")){
  1636.     return brh->ev;
  1637.  }else if (rematch("Y")){
  1638.     return brh->m0.f1;
  1639.  }else if (rematch("R")){
  1640.     return (brh->m0.f1!=0.) ? 1/brh->m0.f1 : MAXDOUBLE;
  1641.  }else if (rematch("Z")){
  1642.     return trz(brh->n[OUT1],brh->n[OUT2],0.);
  1643.  }else{ /* bad parameter */
  1644.     return NOT_VALID;
  1645.  }
  1646. }
  1647. /*--------------------------------------------------------------------------*/
  1648. double acprobegeneric(brh,what)
  1649. const branch_t *brh;
  1650. const char *what;
  1651. {
  1652.  complex_t xvolts;
  1653.  int dummy = 0;
  1654.  
  1655.  xvolts.x = recon[brh->n[OUT1].m] - recon[brh->n[OUT2].m];
  1656.  xvolts.y = imcon[brh->n[OUT1].m] - imcon[brh->n[OUT2].m];
  1657.  
  1658.  setmatch(what,&dummy);
  1659.  if (rematch("V") || rematch("VM")){        /* volts, magnitude */
  1660.     return cabs(xvolts);
  1661.  }else if (rematch("VDB")){            /* volts, db re 1v */
  1662.     double v = cabs(xvolts);
  1663.     return (v > VMIN)  ?  20. * log10(v)  :  DBVMIN;
  1664.  }else if (rematch("VP")){            /* voltage phase */
  1665.     return phase(xvolts.x,xvolts.y);
  1666.  
  1667.  }else if (rematch("I") || rematch("IM")){    /* amps, magnitude */
  1668.     return cabs(cmul(xvolts,brh->acg));
  1669.  }else if (rematch("IDB")){            /* amps, db re 1a */
  1670.     double i = cabs(cmul(xvolts,brh->acg));
  1671.     return (i > VMIN)  ?  20. * log10(i)  :  DBVMIN;
  1672.  }else if (rematch("IP")){            /* current phase */
  1673.     complex_t xamps;
  1674.     xamps = cmul(xvolts,brh->acg);
  1675.     return phase(xamps.x,xamps.y);
  1676.  
  1677.  }else if (rematch("P")){            /* real power */
  1678.     complex_t va;
  1679.     va = ccmul(ccmul(xvolts,xvolts),brh->acg);
  1680.     return va.x;
  1681.  }else if (rematch("PDB")){            /* real pwr db re 1w */
  1682.     complex_t va;
  1683.     double x;
  1684.     va = ccmul(ccmul(xvolts,xvolts),brh->acg);
  1685.     x = fabs(va.x);
  1686.     return (x > PMIN)  ?  10. * log10(x)  :  DBPMIN;
  1687.  }else if (rematch("PX")){            /* volt amp reactive */
  1688.     complex_t va;
  1689.     va = ccmul(ccmul(xvolts,xvolts),brh->acg);
  1690.     return va.y;
  1691.  }else if (rematch("PXDB")){            /* var db re 1 va */
  1692.     complex_t va;
  1693.     double y;
  1694.     va = ccmul(ccmul(xvolts,xvolts),brh->acg);
  1695.     y = fabs(va.y);
  1696.     return (y > PMIN)  ?  10. * log10(y)  :  DBPMIN;
  1697.  }else if (rematch("PM")){            /* volt amp magnitude */
  1698.     return cabs(ccmul(ccmul(xvolts,xvolts),brh->acg));
  1699.  }else if (rematch("PMDB")){            /* va db re 1 va */
  1700.     double pm = cabs(ccmul(ccmul(xvolts,xvolts),brh->acg));
  1701.     return (pm > PMIN)  ?  10. * log10(pm)  :  DBPMIN;
  1702.  }else if (rematch("PP")){            /* va phase */
  1703.     complex_t va;
  1704.     va = ccmul(ccmul(xvolts,xvolts),brh->acg);
  1705.     return phase(va.x,va.y);
  1706.  }else if (rematch("PF")){            /* power factor */
  1707.     complex_t va;
  1708.     va = ccmul(ccmul(xvolts,xvolts),brh->acg);
  1709.     return va.x / cabs(va);
  1710.  
  1711.  }else if (rematch("EV")){            /* effective value */
  1712.     return brh->ev;
  1713.  
  1714.  }else if (rematch("Y") || rematch("YM")){    /* admittance magnitude */
  1715.     return cabs(brh->acg);
  1716.  }else if (rematch("YP")){            /* admittance phase */
  1717.     return phase(brh->acg.x,brh->acg.y);
  1718.  }else if (rematch("YR")){            /* admittance real part */
  1719.     return brh->acg.x;
  1720.  }else if (rematch("YI")){            /* admittance imag part */
  1721.     return brh->acg.y;
  1722.  
  1723.  }else if (rematch("R") || rematch("RM")){    /* "resistance" magnitude */
  1724.     double r = cabs(brh->acg);
  1725.     return (r==0.) ? MAXDOUBLE : 1./r;
  1726.  }else if (rematch("RP")){            /* "resistance" phase */
  1727.     return phase(brh->acg.x,brh->acg.y);
  1728.  }else if (rematch("RR")){            /* "resistance" real part */
  1729.     return (brh->acg.x==0.) ? MAXDOUBLE : 1./brh->acg.x;
  1730.  }else if (rematch("RI")){            /* "resistance" imag part */
  1731.     return (brh->acg.y==0.) ? MAXDOUBLE : 1./brh->acg.y;
  1732.  
  1733.  }else if (rematch("Z") || rematch("ZM")){    /* port impedance magnitude */
  1734.     complex_t zz;
  1735.     zz = acz(brh->n[OUT1].m,brh->n[OUT2].m,brh->acg);
  1736.     return cabs(zz);
  1737.  }else if (rematch("ZP")){            /* port impedance phase */
  1738.     complex_t zz;
  1739.     zz = acz(brh->n[OUT1].m,brh->n[OUT2].m,brh->acg);
  1740.     return phase(zz.x,zz.y);
  1741.  }else if (rematch("ZR")){            /* port impedance real part */
  1742.     complex_t zz;
  1743.     zz = acz(brh->n[OUT1].m,brh->n[OUT2].m,brh->acg);
  1744.     return zz.x;
  1745.  }else if (rematch("ZI")){            /* port impedance imag part */
  1746.     complex_t zz;
  1747.     zz = acz(brh->n[OUT1].m,brh->n[OUT2].m,brh->acg);
  1748.     return zz.y;
  1749.  
  1750.  }else{ /* bad parameter */
  1751.     return NOT_VALID;
  1752.  }
  1753. }
  1754. /*--------------------------------------------------------------------------*/
  1755. double trprobe_branch(brh,what)
  1756. branch_t *brh;
  1757. const char *what;
  1758. {
  1759.  return  (exists(brh) && brh->f->trprobe)
  1760.       ? (*(brh->f->trprobe))(brh,what)
  1761.       : 0.0;
  1762. }
  1763. /*--------------------------------------------------------------------------*/
  1764. double acprobe_branch(brh,what)
  1765. branch_t *brh;
  1766. const char *what;
  1767. {
  1768.  return  (exists(brh) && brh->f->acprobe)
  1769.       ? (*(brh->f->acprobe))(brh,what)
  1770.       : 0.0;
  1771. }
  1772. /*--------------------------------------------------------------------------*/
  1773. void expandgeneric(brh,modellist)
  1774. branch_t *brh;
  1775. const branch_t *modellist;
  1776. {
  1777.  if (!brh->subckt){
  1778.     error(bTRACE, "%s: expanding\n", printlabel(brh,NO));
  1779.  }else{
  1780.     error(bTRACE, "%s: re-expanding\n", printlabel(brh,NO));
  1781.     brh->subckt = (branch_t*)NULL;  /* detach subckt */
  1782.  }
  1783.  
  1784.  if (brh->x){
  1785.     if (!brh->x->m){
  1786.       const branch_t *model;
  1787.       model = modellist;    
  1788.        for (;;){                /* search for thing to copy */
  1789.       model = model->stnext;
  1790.       if (wmatch(brh->x->modelname, model->label)){
  1791.          break;                /* found it */
  1792.       }else if (model == modellist){
  1793.          error(bERROR, "%s: can't find model: %s\n",
  1794.               printlabel(brh,NO),   brh->x->modelname);
  1795.       }
  1796.        }
  1797.        brh->x->m = model->x;                /* link device to model */
  1798.     }
  1799.  }
  1800. }
  1801. /*--------------------------------------------------------------------------*/
  1802. /*--------------------------------------------------------------------------*/
  1803. SHAR_EOF
  1804. fi # end of overwriting check
  1805. if test -f 'src/d_admit.c'
  1806. then
  1807.     echo shar: will not over-write existing file "'src/d_admit.c'"
  1808. else
  1809. cat << \SHAR_EOF > 'src/d_admit.c'
  1810. /* devadmit.c  12/30/92
  1811.  * Copyright 1983-1992   Albert Davis
  1812.  * functions for admittance (type 'Y')
  1813.  * does not exist in spice
  1814.  * x = volts, y.f0 = amps, ev = y.f1 = mhos.
  1815.  */
  1816. #include "ecah.h"
  1817. #include "branch.h"
  1818. #include "convstat.h"
  1819. #include "mode.h"
  1820. #include "status.h"
  1821. #include "declare.h"
  1822. /*--------------------------------------------------------------------------*/
  1823. static     branch_t *create_admittance(const branch_t*);
  1824. static    void    parse_admittance(branch_t*,const char*,int*);
  1825. static    void    print_admittance(const branch_t*,int,int);
  1826. static    void    expand_admittance(branch_t*);
  1827. static    double    trprobe_admittance(const branch_t*,const char*);
  1828. static    double    acprobe_admittance(const branch_t*,const char*);
  1829. static    int    tr_admittance_lin(branch_t*);
  1830. static    int    tr_admittance_nl(branch_t*);
  1831. static    void    un_admittance(branch_t*);
  1832. static    void    ac_admittance_lin(branch_t*);
  1833. static    void    ac_admittance_nl(branch_t*);
  1834. /*--------------------------------------------------------------------------*/
  1835. functions_t dev_admittance_lin = {
  1836.    sizeof(branch_t),
  1837.    create_admittance,
  1838.    parse_admittance,
  1839.    print_admittance,
  1840.    expand_admittance,
  1841.    trprobe_admittance,
  1842.    acprobe_admittance,
  1843.    tr_admittance_lin,
  1844.    un_admittance,
  1845.    ac_admittance_lin,
  1846.    (void(*)())NULL,    /* trfun1 */
  1847.    (void(*)())NULL,    /* trfun0 */
  1848.    (complex_t(*)())NULL,/* acfun */
  1849.    (void(*)())NULL,    /* tr_guess */
  1850.    (void(*)())NULL,    /* tr_advance */
  1851.    (double(*)())NULL    /* tr_review */
  1852. };
  1853. functions_t dev_admittance = {
  1854.    sizeof(branch_t),
  1855.    create_admittance,
  1856.    parse_admittance,
  1857.    print_admittance,
  1858.    expand_admittance,
  1859.    trprobe_admittance,
  1860.    acprobe_admittance,
  1861.    tr_admittance_nl,
  1862.    un_admittance,
  1863.    ac_admittance_nl,
  1864.    trfix1,
  1865.    trfix0,
  1866.    acfix,
  1867.    (void(*)())NULL,    /* tr_guess */
  1868.    (void(*)())NULL,    /* tr_advance */
  1869.    (double(*)())NULL    /* tr_review */
  1870. };
  1871. /*--------------------------------------------------------------------------*/
  1872. extern const struct status stats;
  1873. /*--------------------------------------------------------------------------*/
  1874. static branch_t *create_admittance(proto)
  1875. const branch_t *proto;
  1876. {
  1877.  return createbranch(proto,(generic_t*)NULL,&dev_admittance);
  1878. }
  1879. /*--------------------------------------------------------------------------*/
  1880. static void parse_admittance(brh,cmd,cnt)
  1881. branch_t *brh;
  1882. const char *cmd;
  1883. int *cnt;
  1884. {
  1885.  parsegeneric(brh,cmd,cnt,2);
  1886.  brh->f = &dev_admittance;
  1887. }
  1888. /*--------------------------------------------------------------------------*/
  1889. static void print_admittance(brh,where,detail)
  1890. const branch_t *brh;
  1891. int where;
  1892. int detail;
  1893. {
  1894.  printgeneric(brh,where,detail);
  1895. }
  1896. /*--------------------------------------------------------------------------*/
  1897. static void expand_admittance(brh)
  1898. branch_t *brh;
  1899. {
  1900.  if (!brh->x){
  1901.     brh->f = &dev_admittance_lin;
  1902.     brh->ev = brh->val;
  1903.     brh->y0.f1 = brh->val;
  1904.     brh->y0.f0 = LINEAR;
  1905.     brh->m0.x  = brh->y0.x;
  1906.     brh->m0.c0 = 0.;
  1907.     brh->m0.f1 = brh->y0.f1;
  1908.  }
  1909. }
  1910. /*--------------------------------------------------------------------------*/
  1911. static double trprobe_admittance(brh,what)
  1912. const branch_t *brh;
  1913. const char *what;
  1914. {
  1915.  return trprobegeneric(brh,what);
  1916. }
  1917. /*--------------------------------------------------------------------------*/
  1918. static double acprobe_admittance(brh,what)
  1919. const branch_t *brh;
  1920. const char *what;
  1921. {
  1922.  return acprobegeneric(brh,what);
  1923. }
  1924. /*--------------------------------------------------------------------------*/
  1925. static int tr_admittance_lin(brh)
  1926. branch_t *brh;
  1927. {
  1928.  if (brh->iter == stats.iter[iTOTAL]){
  1929.     return brh->status;
  1930.  }else{
  1931.     brh->iter = stats.iter[iTOTAL];
  1932.  }
  1933.  trloadpassive(brh);
  1934.  return brh->status = cGOOD;
  1935. }
  1936. /*--------------------------------------------------------------------------*/
  1937. static int tr_admittance_nl(brh)
  1938. branch_t *brh;
  1939. {
  1940.  if (brh->iter == stats.iter[iTOTAL]){
  1941.     return brh->status;
  1942.  }else{
  1943.     brh->iter = stats.iter[iTOTAL];
  1944.  }
  1945.  trsetup(brh);
  1946.  brh->m0.x = tr_volts_limited(brh->n[OUT1],brh->n[OUT2]);
  1947.  brh->y0.x = brh->m0.x;
  1948.  if (brh->f->trfun1){
  1949.     (*brh->f->trfun1)(brh);
  1950.  }else{
  1951.     brh->y0.f1 = brh->val;
  1952.     brh->y0.f0 = LINEAR;
  1953.  }
  1954.  brh->ev = brh->y0.f1;
  1955.  brh->m0.x  = brh->y0.x;
  1956.  brh->m0.c0 = brh->y0.f0 - brh->y0.x * brh->y0.f1;
  1957.  brh->m0.f1 = brh->y0.f1;
  1958.  trloadpassive(brh);
  1959.  return brh->status = conv_check(brh);
  1960. }
  1961. /*--------------------------------------------------------------------------*/
  1962. static void un_admittance(brh)
  1963. branch_t *brh;
  1964. {
  1965.  unloadpassive(brh);
  1966. }
  1967. /*--------------------------------------------------------------------------*/
  1968. static void ac_admittance_lin(brh)
  1969. branch_t *brh;
  1970. {
  1971.  brh->acg.x = brh->m0.f1;
  1972.  brh->acg.y = 0.;
  1973.  acloadpassivereal(brh);
  1974. }
  1975. /*--------------------------------------------------------------------------*/
  1976. static void ac_admittance_nl(brh)
  1977. branch_t *brh;
  1978. {
  1979.  if (brh->f->acfun){
  1980.     brh->acbias = dc_volts(brh->n[OUT1],brh->n[OUT2]);
  1981.     brh->acg = (*brh->f->acfun)(brh);
  1982.     acloadpassive(brh);
  1983.  }else{
  1984.     brh->acg.x = brh->ev;
  1985.     brh->acg.y = 0.;
  1986.     acloadpassivereal(brh);
  1987.  }
  1988. }
  1989. /*--------------------------------------------------------------------------*/
  1990. /*--------------------------------------------------------------------------*/
  1991. SHAR_EOF
  1992. fi # end of overwriting check
  1993. #    End of shell archive
  1994. exit 0
  1995.