#include "defs.h" /* * arot arrow blotch show showa showh showname showshape wwtext */ /* * adjust 'a' entries for rotated environment * * p1 and p2 are 'a' entries * dir is rotation * c is point of rotation */ LOC arot(p1, p2, dir) REG DL p1, p2; INT dir; { REG INT pt; switch(dir){ case 0: break; case 1: case 2: pt = p1->x; p1->x = p2->x; p2->x = pt; if (dir == 1) break; case 3: pt = p1->y; p1->y = p2->y; p2->y = pt; } } /* * Draw input/output pin arrow. * * pe = position * dir = direction * cp = name */ LOC arrow(pe, dir, cp) REG DL pe; REG INT dir; STRING cp; { REG DL p; DL1 p1, p2; INT inv, dx, dy; inv = (*cp++ =='<'); if (*cp) { switch(dir){ case 0: dx = 256, dy = -64; break; case 1: dx = -48 * upbstr(cp); dy = 256; break; case 2: dx = (-128 * upbstr(cp)) - 256; dy = -64; break; case 3: dx = -48 * upbstr(cp), dy = -384; } wwtext(offset(pe, dx, dy), cp); } p = findname('L', (inv ? "<" : ">" )); copypt(pe, p1); copypt(p1, p2); p1->flag = dir; cchip(p1, p2, p, dir, 'a'); showshape(p1, p2, p, nil(DL)); } /* * Draw a solder dot. * * p = position of dot */ LOC blotch(p) DL p; { DL1 p1, p2; copypt(offset(p, -24, -24), p1); copypt(offset(p, 24, 24), p2); box(p1, p2); wvec(p); } /* * Display a text, point, or label entry. * * p = entry ('h', 'o', 'e', 'V', or 'v') * h = header entry, or zero */ show(h, p) REG DL p, h; { switch(p->type){ case 'o': if(p->flag&START) circle(p,succa(p)); break; case 'h': { REG INT cp = p->styl; if (cp == 0 && gscale) cp = 8; style(cp << gscale, -1, 0); wtext(offset(p, 0, 32), p->tag); } break; case 'e': if(p->flag&START){ style(-1, 0, (destyl)? destyl : p->styl); mode(GRAPH); } wvec(p); break; case 'v': case 'V': { REG STRING cp; if (h->type == 'c' || h->type == 'L'){ showname(h, p); } else { cp = dln(h)->name; switch(p->flag&DIR){ case 0: case 2: wwtext(offset(p, 0, 32), cp); break; case 1: case 3: vtext(offset(p, -160, 0), cp); } } } break; } } /* * Draw a chip instance. * * p1 = first (START) chip instance ('a') entry * v is 'c' item if label to be printed */ showa(p1, v) REG DL p1; DL v; { REG DL p2; DL th; char *cp; if(p1->flag&END) return; p2 = succa(p1); cp = p1->tag; th = findname('L', cp); showshape(p1, p2, th, v); } /* * display one major item. * * h = item entry ('J', 'c', or 'w') * ds = 0 if full display, = 1 if faint display * * return addr of next item in list */ DL showh(h, ds) REG DL h; { REG DL p; DL vprt; vprt = h; p=h; while(p=succa(p)) { switch(p->type){ case 'J': case 'L': case 'M': case 'c': case 'w': case 'Z': return(p); case 'v': case 'V': vprt = nil(DL); default: break; } if (ds == 0){ destyl = 0; switch(p->type){ case 'a': showa(p, vprt); break; case 'h': case 'v': case 'V': case 'o': show(h, p); break; case 'p': showp(h, p); break; case 'e': shows(h, p); } } else { destyl = 2; switch(p->type){ case 'a': showa(p, nil(DL)); break; case 'e': shows(nil(DL), p); break; case 'o': show(nil(DL),p); break; } } } return(junk(DL)); } /* * Draw name and type and boardposn of chip * * h = chip item entry 'c' * p = 'v', 'V' or 'a' entry */ LOC showname(h, p) REG DL h, p; { DL1 pp; INT i; STRING bn[3]; if (p->type != 'a'){ copypt(p, pp); } else { REG DL sp; if(p->flag&END) return; sp = succa(p); copypt(point((p->x + sp->x) / 2, (p->y + sp->y) / 2), pp); } if (h->type == 'L'){ CHAR v[2]; v[0]=p->type; v[1]=0; wwtext(roffset(pp, -48, -64), v); } else { REG STRING cp; i = 0; if( (dln(h)->name[0] != '$') || (p->type=='V') ) { bn[i++] = dln(h)->name; } if (cp = bdpos(h)) bn[i++] = cp; if (cp = ctype(h)) bn[i++] = cp; else{ /* use shape name for type */ REG DL sp=succa(h); if(sp && sp->type=='a') bn[i++]=sp->tag; } pp->y -= (i + 1) * 96; pp->x += 32; while(--i >= 0){ cp = bn[i]; pp->y += 192; wwtext(offset(pp, -64*upbstr(cp), -64), cp); } } } /* * Draw the endpoint text. * * h = wire item entry ('w') * p = endpoint ('p') entry */ showp(h, p) DL h; REG DL p; { REG DL q; REG STRING cp; INT dir; dir = p->flag&DIR; cp = p->tag; /* pin number display */ if(*cp) switch(dir){ case 0: wwtext(offset(p, -128*upbstr(cp)-48, -160), cp); break; case 1: wwtext(offset(p, 16, -160), cp); break; case 2: wwtext(offset(p, 48, -160), cp); break; case 3: wwtext(offset(p, 16, 48), cp); } cp += upbstr(cp)+1; /* pin name */ if (*cp) if((*cp == '>') || (*cp == '<')) arrow(p, dir, cp); else{ switch(dir){ case 0: q = offset(p, 32, -64); break; case 1: q = offset(p, -48*upbstr(cp), 64); break; case 2: q = offset(p, -128*upbstr(cp)-48, -64); break; case 3: q = offset(p, -48*upbstr(cp), -192); } wwtext(q, cp); } if(!findxact('e', h, p)) wchar(p, '*'); } /* * Draw a segment point. * * A solder dot is also drawn for T-junctions of wires. * * h = header item * p = point ('e') entry */ LOC shows(h, p) REG DL h, p; { REG DL q; if(!(p->flag&START)) show(h, p); if(solder(h,p)) blotch(p); if(p->flag&START) show(h, p); } solder(h, p) REG DL h, p; { REG DL q; if(h && (h->type == 'w') && (q = another(h, 'e', p)) && (!(q->flag&(START|END))) && p->styl == 0 && q->styl == 0) return(1); else return(0); } /* * draw shape * * p1 and p2 are the 'a' entries * h is addr of the shape header, or zero for box * v is 'c' item if label to be printed */ showshape(p1, p2, h, v) REG DL p1, p2; DL h, v; { DL1 ap1, ap2; DL tx, ah; REG DL q; INT ostyl; if ((ostyl = destyl) == 0) destyl = p1->styl; if(h) { tx = succ('x', h); q = h; while(q=nexta('L', q)) switch(q->type){ case 'a': ah = findname('L', q->tag); if(ah) { if(ah->flag&MARKS) { ah->flag &= ~MARKS; error("recursion in shape"); } ah->flag |= MARKS; } ap1->flag = ((p1->flag & DIR) + (q->flag & DIR)) & DIR; ap1->styl = q->styl; ap1->type = 'a'; copypt(shift(p1, p2, q, tx), ap1); copypt(shift(p1, p2, q = succa(q), tx), ap2); ap2->type = 'A'; arot(ap1, ap2, p1->flag & DIR); showshape(ap1, ap2, ah, nil(DL)); if(ah) { ah->flag &= ~MARKS; } break; case 'h': case 'e': show(h, shift(p1, p2, q, tx)); break; case 'o': if (!(q->flag & START)) break; ap1->flag = p1->flag & DIR; ap1->styl = q->styl; copypt(shift(p1, p2, q, tx), ap1); copypt(shift(p1, p2, q = succa(q), tx), ap2); arot(ap1, ap2, p1->flag & DIR); circle(ap1, ap2); break; case 'v': case 'V': if (v) show(v, shift(p1, p2, q, tx)); break; case 'x': break; case 'X': if (v && v->type == 'L') wchar(shift(p1, p2, q, tx), 'X'); break; } } else{ style(-1, 0, destyl & 7); box(p1, p2); if (v) showname(v, p1); } destyl = ostyl; } /* * Draw a circle. * * p1 and p2 are the two 'o' entries */ LOC circle(p1, p2) REG DL p1, p2; { INT dx, dy; INT ostyl; if ((ostyl = destyl) == 0) destyl = p1->styl; dx = p2->x - p1->x; dy = p2->y - p1->y; if (dx > dy) dx = dy; wcirc(midpt(p1, p2), dx / 2); destyl = ostyl; } /* * Compute scaled and rotated coordinates of a point of a chip instance. * * p1, p2 = the START and END chip instance ('a') entries * tp = entry of shape definition to be scaled and rotated * tx = extent ('x') entry of the shape * return = new position * * note: scale(a, b, c) computes (a * b)/c */ LOC DL shift(p1, p2, tp, tx) REG DL p1, p2, tx; DL tp; { LOC DL1 sp; copy(tp, sp); switch(p1->flag&DIR){ case 0: sp->x = scale(tp->x, p2->x - p1->x, tx->x); sp->y = scale(tp->y, p2->y - p1->y, tx->y); break; case 1: sp->x = scale(tx->y - tp->y, p2->x - p1->x, tx->y); sp->y = scale(tp->x, p2->y - p1->y, tx->x); break; case 2: sp->x = scale(tx->x - tp->x, p2->x - p1->x, tx->x); sp->y = scale(tx->y - tp->y, p2->y - p1->y, tx->y); break; case 3: sp->x = scale(tp->y, p2->x - p1->x, tx->y); sp->y = scale(tx->x - tp->x, p2->y - p1->y, tx->x); } sp->x += p1->x; sp->y += p1->y; return(sp); }