agn@cmu-cs-unh.ARPA (Andreas Nowatzyk) (08/10/85)
# # type sh /usru0/agn/pcb/distr/../usenet/part5 to unpack this archive. # echo extracting pcif.c... cat >pcif.c <<'!E!O!F!' /***************************************************************\ * * * PCB program * * * * CIF output routines * * * * (c) 1985 A. Nowatzyk * * * \***************************************************************/ #include <stdio.h> #include "pparm.h" #include "pcdst.h" extern FILE *fwantread(), *fwantwrite(); extern int rot_m[4][4]; /* rotation matrix (in pplace) */ extern int pdr[8]; /* direction offsets (for ptrs) */ FILE *icf, *ocf; /* Cif - I/O */ #define pinsym 1 /* ordinary pin symbol */ #define viasym 2 /* via - symbol */ #define pwrsym 3 /* power plane connection */ #define gndsym 4 /* ground plane connection */ #define tlhsym 5 /* tool hole symbol */ #define sigsym 6 /* signal pin: no pwr/gnd conn. */ #define pn1sym 7 /* pin #1 marking */ #define algsym 8 /* alignment symbol */ /**********************************************************\ * * * A note on coordinates: * * internally: 1 unit = 100mil/rsun * * CIF output: 1 unit = 0.5 mil for the main section * * = 1 mil for the symbol definition * * * \**********************************************************/ #define almoff 32 /* offset for alignment marks */ #define ucf 25 /* unit conversion factor */ #define pgd 9 /* pin guard zone displacement */ #define cmww 100 /* crop mark wire width */ #define coww 40 /* component outline wire width */ #define gzww 400 /* guard zone wire width */ #define sgww0 16 /* signal wire width (near hole) */ #define sgww1 26 /* signal wire width (elsewhere) */ #define min_dst 16 /* min distance between wires */ #define cpsb 1000 /* base for component symbols > ex_cifH */ #define chhgh 128 /* character hight */ #define chwdf 4 /* character width factor */ #define clm_off 50 /* offset of clm-s to boarder */ #define max_wcp 7 /* max. wire coordinate pairs in a line */ /********************************************************************\ * * * Some obsolete stuff: * * dynamic labeling was used to generate the silk-screen lable for * * a component based on its instantiation name. People prefered * * the type definition name. * * * * Alignment marks are no longer required by mossis. * * * * (the code for tooling holes was entirely ripped out: external * * cif symbols can do as well if required) * * * \********************************************************************/ /* #define dyna_lab */ /* dynamic labeling */ /* #define align_mrk */ /* alignment marks */ static int chdst[128][2]; /* character descriptor table */ cifout() /* output a cif file */ { char buf[82]; int i, c1, c2, s, w, c; printf ("Start writing CIF-file\n"); icf = fwantread (".", "/usr/agn/pcb/pcbsdef.CIF", buf, "Symbol definition file:"); ocf = fwantwrite (".", "pcb.cif", buf, "CIF output file:", 1); if (!ocf) err("-NO CIF output file written", 0, 0, 0, 0); c1 = c2 = 0; for (i = 0; i < 128; ++i) chdst[i][0] = (-1); while (fgets (buf, 82, icf)) { if (buf[0] == '%') { switch (buf[1]) { case 'c': /* character descriptor */ i = sscanf (&buf[2], "%d%d%d", &c, &w, &s); if ((i != 3) || (c<=0) || (c>127) || (w<0) || (w>300)) { printf ("Illegal character descriptor -- ignored\n"); break; }; if (chdst[c][0] >= 0) { printf ( "Multiple character descriptor (%d) -- ignored\n", c); break; }; chdst[c][0] = s; chdst[c][1] = w * chwdf; break; case 's': /* insert component symbols */ if (c1) err ("invalid pcbsdef.CIF - multiple %s", c1, 0, 0, 0); c1 = 1; ocps (); /* output component symbols */ break; case 'p': /* insert PC-board symbol */ if (c2) err ("invalid pcbsdef.CIF - multiple %p", c2, 0, 0, 0); c2 = 1; ofps (); /* output frame and components */ opgc (); /* output pwr / gnd connections */ osws (); /* output signal wires */ ohfs (); /* output hole 'fillet'-s */ oclm (); /* output cmpnt location marks */ clean_up (); /* remove temp. marks */ break; default: err ("invalid pcbsdef.CIF - unknown escape", (int)buf[1] & 255, 0, 0, 0); }; } else fputs (buf, ocf); }; if (!c1 || !c2) err ("invalid pcbsdef.CIF - missing %s or %p", c1, c2, 0, 0); fclose (icf); fclose (ocf); } ofps() /* output frame components */ { int i; #ifdef align_mrk scall (-almoff, -almoff, algsym); /* alignment marks */ scall (V.BSX + almoff, -almoff, algsym); scall (-almoff, V.BSY + almoff, algsym); scall (V.BSX + almoff, V.BSY + almoff, algsym); #endif cmrk (-2, 18, -2, -2, 18, -2); /* crop - marks */ cmrk (V.BSX - 18, -2, V.BSX + 2, -2, V.BSX + 2, 18); cmrk (V.BSX + 2, V.BSY - 18, V.BSX + 2, V.BSY + 2, V.BSX - 18, V.BSY + 2); cmrk (18, V.BSY + 2, -2, V.BSY + 2, -2, V.BSY - 18); fputs (" L PN2;\n", ocf); /* guard zone for inner layers */ cwire_S ( 0, 0, 0, 0, gzww); cwire_C (V.BSX, 0, 0, 0); cwire_C (V.BSX, V.BSY, 0, 0); cwire_C ( 0, V.BSY, 0, 0); cwire_E ( 0, 0, 0, 0); fputs (" L PN3;\n", ocf); cwire_S ( 0, 0, 0, 0, gzww); cwire_C (V.BSX, 0, 0, 0); cwire_C (V.BSX, V.BSY, 0, 0); cwire_C ( 0, V.BSY, 0, 0); cwire_E ( 0, 0, 0, 0); for (i = 0; i < V.ncp; ++i) /* scan components to call sym */ if (strcmp (CP[i].name, DELETED)) dcp (&CP[i]); } ocps () /* output component symbols */ { register int i, j, k, x, y; int ext = 0; register struct pin *pp; char buf[inp_lnl], fname[80]; FILE *ex_cif; for (j = 0; j < V.nty; ++j) { if (!strcmp (TY[j].name, DELETED)) continue; /* skip deleted entries */ if (TY[j].cif) { /* skip external components */ ext = 1; continue; } fprintf (ocf, "DS %d 1270 1;\n", j + cpsb); pp = TY[j].p; for (i = 0; i < TY[j].np; ++i) { x = pp -> x; y = pp -> y; if (!i) scall (x, y, pn1sym); switch (pp -> p) { case 0: scall (x, y, pinsym); break; case 1: scall (x, y, pinsym); scall (x, y, gndsym); break; case 2: case 3: case 4: scall (x, y, pinsym); scall (x, y, pwrsym); break; default: err ("illegal pin type", pp -> p, i, 0, 0); }; pp++; }; fputs (" L PSSC;\n", ocf); /* outline component */ cwire_S ( -3, -3, 0, 0, coww); cwire_C (TY[j].x + 3, -3, 0, 0); cwire_C (TY[j].x + 3, TY[j].y + 3, 0, 0); cwire_C ( -3, TY[j].y + 3, 0, 0); cwire_E ( -3, -3, 0, 0); if (TY[j].y >= rsun * 3 && TY[j].x >= rsun * 3) /* add an IC mark */ fprintf (ocf, " B 200 200 -50 %d;\n", (TY[j].y >> 1) * ucf); fputs (" L PF;\n", ocf); cwire_S ( -3, -3, 0, 0, coww); cwire_C (TY[j].x + 3, -3, 0, 0); cwire_C (TY[j].x + 3, TY[j].y + 3, 0, 0); cwire_C ( -3, TY[j].y + 3, 0, 0); cwire_E ( -3, -3, 0, 0); if (TY[j].y >= rsun * 3 && TY[j].x >= rsun * 3) /* add an IC mark */ fprintf (ocf, " B 200 200 -50 %d;\n", (TY[j].y >> 1) * ucf); #ifndef dyna_lab for (i = nmmax; i; i--) /* truncate string if necessary */ if ((k = txt_len (TY[j].name, i)) <= (TY[j].x + 4) * ucf) break; x = ((TY[j].x + 4) * ucf - k) / 2 - 2 * ucf;/* center text */ y = ((TY[j].y + 4) * ucf - chhgh) / 2 - 2 * ucf; ctxt (x, y, 0, TY[j].name, i); #endif fputs ("DF;\n", ocf); } if (ext) { /* external components present */ printf ("List of external components:\n"); for (i = 0; i < V.nty; i++) if (TY[i].cif) printf ("\t'%s':\tcif-symbol#=%d\n", TY[i].name, CIF[TY[i].cif-1].symn); ex_cif = fwantread (".", "", fname, "External CIF-symbol file:"); if (!ex_cif) err ("Could not open external CIF-symbol file", 0, 0, 0, 0); while (fgets (buf, inp_lnl, ex_cif)) fputs (buf, ocf); fclose (ex_cif); } } dcp (C) /* call a component symbol */ struct comp *C; { static int rm[4][4] = { { 1, 1, 0, 1}, {-1, 1, 1, 0}, {-1, -1, 0, -1}, { 1, -1, -1, 0} }; union ptr_int { /* allow arithmetic on pointer */ unsigned i; struct type *ty; } p1, p2; register int i, r, x, y; x = C -> x; y = C -> y; r = C -> r; i = C -> ty -> cif; if (i) /* external symbol */ i = CIF[i - 1].symn; else { /* internal symbol */ p1.ty = C -> ty; p2.ty = V.ty; i = (p1.i - p2.i) / sizeof (TY[0]) + cpsb; } fprintf (ocf, "C %d R%d %d T%d %d;\n", i, rm[r][3], rm[r][2], x * ucf, y * ucf); #ifdef dyna_lab i = (C -> ty -> y * ucf - chhgh) / 2; ctxt (C -> x * ucf + i * rm[C -> r][0], C -> y * ucf + i * rm[C -> r][1], C -> r, C -> name, nmmax); #endif } ctxt (x, y, r, s, l) /* create text */ int x, y, r, l; char *s; { while (*s && l--) { *s &= 127; if (chdst[*s][0] > 0) { switch (r) { case 1: fprintf (ocf, "C %d R 0 1 T %d %d;\n", chdst[*s][0], x, y); y += chdst[*s][1]; break; case 2: fprintf (ocf, "C %d R -1 0 T %d %d;\n", chdst[*s][0], x, y); x -= chdst[*s][1]; break; case 3: fprintf (ocf, "C %d R 0 -1 T %d %d;\n", chdst[*s][0], x, y); y -= chdst[*s][1]; break; default: fprintf (ocf, "C %d T %d %d;\n", chdst[*s][0], x, y); x += chdst[*s][1]; break; }; }; s++; }; } txt_len (s, l) /* text length function */ char *s; int l; { register int i = 0; while (*(s++) && l--) i += chdst[*s & 127][1]; return i; } cmrk (x1, y1, x2, y2, x3, y3) /* crop mark */ int x1, y1, x2, y2, x3, y3; { fputs (" L PC1;\n", ocf); cwire_S (x1, y1, 0, 0, cmww); cwire_C (x2, y2, 0, 0); cwire_E (x3, y3, 0, 0); fputs (" L PC4;\n", ocf); cwire_S (x1, y1, 0, 0, cmww); cwire_C (x2, y2, 0, 0); cwire_E (x3, y3, 0, 0); fputs (" L PSSC;\n", ocf); cwire_S (x1, y1, 0, 0, cmww); cwire_C (x2, y2, 0, 0); cwire_E (x3, y3, 0, 0); fputs (" L PSMC;\n", ocf); cwire_S (x1, y1, 0, 0, cmww); cwire_C (x2, y2, 0, 0); cwire_E (x3, y3, 0, 0); fputs (" L PD;\n", ocf); cwire_S (x1, y1, 0, 0, cmww); cwire_C (x2, y2, 0, 0); cwire_E (x3, y3, 0, 0); fputs (" L PF;\n", ocf); cwire_S (x1, y1, 0, 0, cmww); cwire_C (x2, y2, 0, 0); cwire_E (x3, y3, 0, 0); } scall (x, y, t) /* symbol call */ int x, y, t; { fprintf (ocf, "C %d T %d,%d;\n", t, x * ucf, y * ucf); } #ifdef simple /* simple wire routines */ osws () /* output signal wire stuff */ { int i, chplt (), cvplt (); wtvf = cvplt; wthf = chplt; for (i = 0; i < V.nnh; ++i) /* trace all nets */ if (NH[i].l > 1) wtrace (NH[i].lp -> c -> x, NH[i].lp -> c -> y, vec); } #else osws () /* output signal wire stuff */ { int chplt (), cvplt (), mrk_hole (), umrk_hole (); register int i, x, y; for (i = 0; i < V.nnh; ++i) /* trace all nets */ if (NH[i].l > 1) { wtvf = nil; /* mark all holes of this net */ wthf = mrk_hole; x = NH[i].lp -> c -> x; y = NH[i].lp -> c -> y; wtrace (x, y, vec); wtvf = cvplt; /* plot the net */ wthf = chplt; wtrace (x, y, vec); wtvf = nil; /* remove the hole marks */ wthf = umrk_hole; wtrace (x, y, vec); } } #endif #ifdef simple /* simple wire routines */ cvplt (x1, y1, x2, y2) /* output a wire segment */ int x1, y1, x2, y2; /******************************************************************\ * * * Plot part of a signal wire from <x1,y1> to <x2,y2>. This draws * * just a straight line on the desired side of the board. * * * \******************************************************************/ { static int s = 0; if (s != wtsb) { /* side check */ if (wtsb == s1b) fputs (" L PC1;\n", ocf); else fputs (" L PC4;\n", ocf); s = wtsb; }; cwire_S (x1, y1, 0, 0, sgww1); cwire_E (x2, y2, 0, 0); } #else /* conservative wire routine */ cvplt (x1, y1, x2, y2) /* output a wire segment */ int x1, y1, x2, y2; /**********************************************************************\ * * * A wire is drawn from <x1,y1> to <x2,y2> on the desired board side. * * A minimal distance to holes is maintained. This calles for bends * * in the wire path if it 1 raster unit apart from a hole. * * * \**********************************************************************/ { register int i, j, t; register char *p; static int s = 0; if (s != wtsb) { /* side check */ if (wtsb == s1b) fputs (" L PC1;\n", ocf); else fputs (" L PC4;\n", ocf); s = wtsb; } p = &pcb[(y1 + y2) >> 1][(x1 + x2) >> 1]; for (i = 0, j = 0; i < 8; i++) /* wide wire locator */ if (*(p + pdr[i]) & wtsb) j++; /* count adjacent points */ if (j > 6) wwb_trc ((x1 + x2) >> 1, (y1 + y2) >> 1, wtsb); if ((y2 < y1) || ((y2 == y1) && (x2 < x1))) { t = x1; /* direction confined 0 to 3 */ x1 = x2; x2 = t; t = y1; y1 = y2; y2 = t; } if (x2 > x1) { if (y2 > y1) plt_d1wire (x1, y1, x2, y2); /* dir = 1 */ else plt_hwire (x1, y1, x2, y2);} /* dir = 0 */ else { if (x2 < x1) plt_d2wire (x1, y1, x2, y2); /* dir = 3 */ else plt_vwire (x1, y1, x2, y2); /* dir = 2 */ } } plt_d1wire (x1, y1, x2, y2) /* plot diag. wire */ int x1, y1, x2, y2; /***********************************************************\ * * * Plot a diagonal wire from <x1,y1> to <x2,y2>. The slope * * is dx = 1, dy = 1. * * * \***********************************************************/ { register int enable, nh1, nh2; nh1 = near_hl (x1, y1); nh2 = near_hl (x2, y2); enable = 3 <= (!nh1 + !nh2 + y2 - y1); /* attn: trick! */ switch (nh1) { /* check start point */ case 0: if (enable) cwire_S (x1, y1, 0, 0, sgww1); else cwire_S (x1, y1, 0, 0, sgww0); break; case 1: cwire_S (x1, y1, 0, 1, sgww0); if (enable) { cwire_C (x1, y1, 1, 1); cwire_E (x1 + 1, y1 + 1, 0, 0); cwire_S (x1 + 1, y1 + 1, 0, 0, sgww1);} else cwire_C (x1, y1, 1, 1); break; case 4: cwire_S (x1, y1, 1, 0, sgww0); if (enable) { cwire_C (x1, y1, 1, 1); cwire_E (x1 + 1, y1 + 1, 0, 0); cwire_S (x1 + 1, y1 + 1, 0, 0, sgww1);} else cwire_C (x1, y1, 1, 1); break; default: err ("plt_d1wire: wire / hole collision", x1, y1, nh1, 0); } switch (nh2) { case 0: cwire_E (x2, y2, 0, 0); break; case 2: if (enable) { cwire_E (x2 - 1, y2 - 1, 0, 0); cwire_S (x2 - 1, y2 - 1, 0, 0, sgww0); } cwire_C (x2, y2, -1, -1); cwire_E (x2, y2, -1, 0); break; case 3: if (enable) { cwire_E (x2 - 1, y2 - 1, 0, 0); cwire_S (x2 - 1, y2 - 1, 0, 0, sgww0); } cwire_C (x2, y2, -1, -1); cwire_E (x2, y2, 0, -1); break; default: err ("plt_d1wire: wire / hole intersection", x2, y2, nh2, 0); } } plt_d2wire (x1, y1, x2, y2) /* plot diag. wire */ int x1, y1, x2, y2; /***********************************************************\ * * * Plot a diagonal wire from <x1,y1> to <x2,y2>. The slope * * is dx = -1, dy = 1. * * * \***********************************************************/ { register int enable, nh1, nh2; nh1 = near_hl (x1, y1); nh2 = near_hl (x2, y2); enable = 3 <= (!nh1 + !nh2 + y2 - y1); /* attn: trick! */ switch (nh1) { /* check start point */ case 0: if (enable) cwire_S (x1, y1, 0, 0, sgww1); else cwire_S (x1, y1, 0, 0, sgww0); break; case 1: cwire_S (x1, y1, 0, 1, sgww0); if (enable) { cwire_C (x1, y1, -1, 1); cwire_E (x1 - 1, y1 + 1, 0, 0); cwire_S (x1 - 1, y1 + 1, 0, 0, sgww1);} else cwire_C (x1, y1, -1, 1); break; case 2: cwire_S (x1, y1, -1, 0, sgww0); if (enable) { cwire_C (x1, y1, -1, 1); cwire_E (x1 - 1, y1 + 1, 0, 0); cwire_S (x1 - 1, y1 + 1, 0, 0, sgww1);} else cwire_C (x1, y1, -1, 1); break; default: err ("plt_d2wire: wire / hole collision", x1, y1, nh1, 0); } switch (nh2) { /* check end point */ case 0: cwire_E (x2, y2, 0, 0); break; case 3: if (enable) { cwire_E (x2 + 1, y2 - 1, 0, 0); cwire_S (x2 + 1, y2 - 1, 0, 0, sgww0); } cwire_C (x2, y2, 1, -1); cwire_E (x2, y2, 0, -1); break; case 4: if (enable) { cwire_E (x2 + 1, y2 - 1, 0, 0); cwire_S (x2 + 1, y2 - 1, 0, 0, sgww0); } cwire_C (x2, y2, 1, -1); cwire_E (x2, y2, 1, 0); break; default: err ("plt_d2wire: wire / hole intersection", x2, y2, nh2, 0); } } plt_hwire (x1, y1, x2, y2) /* plot a horizontal wire */ int x1, y1, x2, y2; /*************************************************************\ * * * Draw a horizontal wire from <x1,y1> to <x2,y2>. The slope * * is: dx = 1, dy = 0; * * * \*************************************************************/ { register int dy, nh1, nh2, wide; dy = 0; /* default displacement */ nh1 = near_hl (x1, y1); nh2 = near_hl (x1 + 1, y1); /* look ahead */ switch (nh1) { /* check start point */ case 0: if (!nh2) { cwire_S (x1, y1, 0, 0, sgww1); wide = 1;} else { cwire_S (x1, y1, 0, 0, sgww0); wide = 0; } break; case 1: cwire_S (x1, y1, 0, 1, sgww0); dy = 1; wide = 0; break; case 3: cwire_S (x1, y1, 0, -1, sgww0); dy = -1; wide = 0; break; case 4: cwire_S (x1, y1, 1, 0, sgww0); wide = 0; break; default: err ("plt_hwire: wire / hole collision", x1, y1, nh1, 0); } while (++x1 < x2) { /* scan wire */ nh1 = nh2; nh2 = near_hl (x1 + 1, y1); switch (nh1) { case 0: if (!wide && !nh2) { if (dy) { /* end any bend */ cwire_C (x1 - 1, y1, 0, dy); dy = 0; } cwire_E (x1, y1, 0, 0); cwire_S (x1, y1, 0, 0, sgww1); wide = 1;} else if (dy) { cwire_C (x1 - 1, y1, 0, dy); cwire_C (x1, y1, 0, 0); dy = 0; } break; case 1: if (dy != 1) { /* start a bend up */ if (wide) { cwire_E (x1 - 1, y1, 0, dy); cwire_S (x1 - 1, y1, 0, dy, sgww0); wide = 0;} else cwire_C (x1 - 1, y1, 0, dy); cwire_C (x1, y1, 0, 1); dy = 1; } break; case 3: if (dy != -1) { /* start a bend down */ if (wide) { cwire_E (x1 - 1, y1, 0, dy); cwire_S (x1 - 1, y1, 0, dy, sgww0); wide = 0;} else cwire_C (x1 - 1, y1, 0, dy); cwire_C (x1, y1, 0, -1); dy = -1; } break; default: err ("plt_hwire: illegal wire/hole realtion", x1,y1, nh1, dy); } } switch (nh2) { /* check end point */ case 0: if (dy != 0) /* finish any bend */ cwire_C (x2 - 1, y2, 0, dy); cwire_E (x2, y2, 0, 0); break; case 1: if (dy != 1) { /* start an incomplete bend up */ if (wide) { cwire_E (x1 - 1, y1, 0, dy); cwire_S (x1 - 1, y1, 0, dy, sgww0);} else cwire_C (x1 - 1, y1, 0, dy); } cwire_E (x2, y2, 0, 1); break; case 2: if (dy != 0) /* finish any bend */ cwire_C (x2 - 1, y2, 0, dy); else if (wide) { cwire_E (x2 - 1, y2, 0, 0); cwire_S (x2 - 1, y2, 0, 0, sgww0); } cwire_E (x2, y2, -1, 0); break; case 3: if (dy != -1) { /* start an incomplete bend down */ if (wide) { cwire_E (x1 - 1, y1, 0, dy); cwire_S (x1 - 1, y1, 0, dy, sgww0);} else cwire_C (x1 - 1, y1, 0, dy); } cwire_E (x2, y2, 0, -1); break; default: err ("plt_hwire: trouble at end point", x2, y2, nh2, dy); } } plt_vwire (x1, y1, x2, y2) /* plot a vertcal wire */ int x1, y1, x2, y2; /**********************************************************\ * * * Draw a vertcal wire from <x1,y1> to <x2,y2>. The slope * * is: dx = 0, dy = 1; * * * \**********************************************************/ { register int dx, nh1, nh2, wide; dx = 0; /* default displacement */ nh1 = near_hl (x1, y1); nh2 = near_hl (x1, y1 + 1); /* look ahead */ switch (nh1) { /* check start */ case 0: if (!nh2) { cwire_S (x1, y1, 0, 0, sgww1); wide = 1;} else { cwire_S (x1, y1, 0, 0, sgww0); wide = 0; } break; case 1: cwire_S (x1, y1, 0, 1, sgww0); wide = 0; break; case 2: cwire_S (x1, y1, -1, 0, sgww0); dx = -1; wide = 0; break; case 4: cwire_S (x1, y1, 1, 0, sgww0); dx = 1; wide = 0; break; default: err ("plt_vwire: wire / hole collision", x1, y1, nh1, dx); } while (++y1 < y2) { /* scan wire */ nh1 = nh2; nh2 = near_hl (x1, y1 + 1); switch (nh1) { case 0: if (!wide && !nh2) { if (dx) { /* end any bend */ cwire_C (x1, y1 - 1, dx, 0); dx = 0; } cwire_E (x1, y1, 0, 0); cwire_S (x1, y1, 0, 0, sgww1); wide = 1;} else if (dx) { /* end any bend */ cwire_C (x1, y1 - 1, dx, 0); cwire_C (x1, y1, 0, 0); dx = 0; } break; case 2: if (dx != -1) { /* start a bend left */ if (wide) { cwire_E (x1, y1 - 1, dx, 0); cwire_S (x1, y1 - 1, dx, 0, sgww0); wide = 0;} else cwire_C (x1, y1 - 1, dx, 0); cwire_C (x1, y1, -1, 0); dx = -1; } break; case 4: if (dx != 1) { /* start a bend right */ if (wide) { cwire_E (x1, y1 - 1, dx, 0); cwire_S (x1, y1 - 1, dx, 0, sgww0); wide = 0;} else cwire_C (x1, y1 - 1, dx, 0); cwire_C (x1, y1, 1, 0); dx = 1; } break; default: err ("plt_vwire: illegal wire/hole realtion", x1,y1, nh1, dx); } } switch (nh2) { /* check end point */ case 0: if (dx != 0) /* finish any bend */ cwire_C (x2, y2 - 1, dx, 0); cwire_E (x2, y2, 0, 0); break; case 2: if (dx != -1) { /* start an incomplte bend left */ if (wide) { cwire_E (x2, y2 - 1, dx, 0); cwire_S (x2, y2 - 1, dx, 0, sgww0);} else cwire_C (x2, y2 - 1, dx, 0); } cwire_E (x2, y2, -1, 0); break; case 3: if (dx != 0) /* finish any bend */ cwire_C (x2, y2 - 1, dx, 0); else if (wide) { cwire_E (x2 - 1, y2, 0, 0); cwire_S (x2 - 1, y2, 0, 0, sgww0); } cwire_E (x2, y2, 0, -1); break; case 4: if (dx != 1) { /* start an incomplete bend up */ if (wide) { cwire_E (x2, y2 - 1, dx, 0); cwire_S (x2, y2 - 1, dx, 0, sgww0);} else cwire_C (x2, y2 - 1, dx, 0); } cwire_E (x2, y2, 1, 0); break; default: err ("plt_vwire: trouble at end point", x2, y2, nh2, dx); } } on_hole (x, y) /* on hole check */ int x, y; /**************************************************************\ * * * Returns '1' if <x,y> is part of a hole that is not part * * of the current net (unselected). It returns '0' otherwise. * * This routine is not fooled by guard bits for via-holes. * * * \**************************************************************/ { if (!(pcb[y][x] & ahb)) /* no hole at all */ return (0); if (pcb[y][x - 1] & ahb) { if (!(pcb[y][x + 1] & ahb)) { x--; if (!(pcb[y][x - 1] & ahb)) return (0); }} else { x++; if (!(pcb[y][x] & pcb[y][x + 1] & ahb)) return (0); } if (pcb[y - 1][x] & ahb) { if (!(pcb[y + 1][x] & ahb)) { y--; if (!(pcb[y - 1][x] & ahb)) return (0); }} else { y++; if (!(pcb[y][x] & pcb[y + 1][x] & ahb)) return (0); } return (!(pcb[y][x] & selb)); /* test for selection */ } near_hl (x, y) /* near hole test */ int x, y; /*******************************************************************\ * * * The relation of <x,y> to the nearest hole (if any) is reported. * * if no hole is present, a 0 is returned. values returned (Hex): * * * * . . 1 1 1 . . * * . . . . . . . * * 2 . * * * . 4 * * 2 . * * * . 4 * * 2 . * * * . 4 * * . . . . . . . * * . . 3 3 3 . . * * * \*******************************************************************/ { int i; static int Rx[4] = { 0, 2, 0,-2}; static int Ry[4] = {-2, 0, 2, 0}; for (i = 0; i < 4; ++i) /* look for nearby hole */ if (on_hole (x + Rx[i], y + Ry[i])) return (i + 1); return (0); /* not near a hole */ } mrk_hole (x, y) /* mark a hole */ int x, y; { pcb[y][x] |= selb; return (0); } umrk_hole (x, y) /* mark a hole */ int x, y; { pcb[y][x] &= ~selb; return (0); } #endif chplt (x, y) /* output via holes */ int x, y; { if (pcb[y][x] & ishb) scall (x, y, viasym); return (0); } static int real_x, real_y, cnt; /* common to cwire_* */ cwire_S (x, y, dx, dy, w) /* start a CIF - wire */ int x, y, dx, dy, w; /********************************************************************\ * * * A CIF wire of width w is started at location <x,y>, which is * * given in raster units. A displacement <dx,dy> is applied to this * * location. * * * \********************************************************************/ { fprintf (ocf, " W %d: %d,%d", w, real_x = x * ucf + dx * pgd, real_y = y * ucf + dy * pgd); cnt = 1; } cwire_C (x, y, dx, dy) /* continue a CIF - wire */ int x, y, dx, dy; { int rx, ry; rx = x * ucf + dx * pgd; ry = y * ucf + dy * pgd; if (rx != real_x || ry != real_y) { real_x = rx; real_y = ry; if (++cnt < max_wcp) fprintf (ocf, " %d,%d", rx, ry); else { cnt = 0; fprintf (ocf, "\n %d,%d", rx, ry); } } } cwire_E (x, y, dx, dy) /* and a CIF - wire */ int x, y, dx, dy; { int rx, ry; rx = x * ucf + dx * pgd; ry = y * ucf + dy * pgd; if (rx != real_x || ry != real_y) fprintf (ocf, " %d,%d;\n", rx, ry); else fprintf (ocf, ";\n"); } opgc () /*******************************************************************\ * * * Output power/ground connections: * * * * Connections to the internal layers (VCC,GND ...) can be made by * * 2 different methods: * * a) by defining a pin to be VCC/GND/VEE/VTT in the type file. * * this is taken care off by the component symbol generation * * in 'ocps'. * * b) by connecting a pin to the special nets VCC/GND/VEE/VTT in * * a given instantiation of the type: this is done here! * * * \*******************************************************************/ { register int j, r, xp, yp; int i, x, y; register struct pin *pin; struct hole *hp; register struct nlhd *net; struct hole *fndh (); for (i = 0; i < V.ncp; i++) { /* scan all components */ if (!strcmp (CP[i].name, DELETED)) continue; /* skip deleted entries */ if (CP[i].ty -> cif) continue; /* skip external cifs */ x = CP[i].x; /* get borad position */ y = CP[i].y; r = CP[i].r; for (j = CP[i].ty -> np, pin = CP[i].ty -> p; j; j--, pin++) { /* scan component pins */ if (pin -> p) continue; /* pwr/gnd is done in symbol def */ xp = x + (pin -> x) * rot_m[r][0] + (pin -> y) * rot_m[r][1]; yp = y + (pin -> x) * rot_m[r][2] + (pin -> y) * rot_m[r][3]; hp = fndh (xp, yp); /* find hole */ if (!hp) err ("opgc: missing hole", xp, yp, 0, 0); net = hp -> n -> nlp; /* insert proper symbols */ if (net == &V.GND) scall (xp, yp, gndsym); else if (net == &V.VCC || net == &V.VEE || net == &V.VTT) scall (xp, yp, pwrsym); else scall (xp, yp, sigsym); } } } ohfs () /****************************************************************\ * * * Hole 'fillet'-s: * * In order to prevent demage to the board if components are * * replaced, extra cooper is added to the area where a wire * * enters a component hole. * * * \****************************************************************/ { register int i, x, y; fprintf (ocf, "L PC1;\n"); /* side 1 first */ for (i = 0; i < V.nch; i++) if (pcb[CH[i].y][CH[i].x] & s1b) { x = CH[i].x; y = CH[i].y; fillet (x, y, s1b); } fprintf (ocf, "L PC4;\n"); /* now side 2 */ for (i = 0; i < V.nch; i++) if (pcb[CH[i].y][CH[i].x] & s2b) { x = CH[i].x; y = CH[i].y; fillet (x, y, s2b); } } /* geometric constraints for fillet round-flash */ #define r0 72 /* = (ucf*sqrt(2^2 + 4^2) - min_dst - via_hole_radius) * 2 */ #define r1 42 /* = (ucf*2 - (sgww1/2 + min_dst)) * 2 */ #define r2 54 /* = (sqrt((ucf*2)^2 + ucf^2) - (sgww1/2 + min_dst)) * 2 */ #define r3 83 /* = (sqrt(2)*ucf*2 - (sgww1/2 + min_dst)) * 2 */ fillet (x, y, s) /* draw a 'fillet' */ int x, y, s; { static int pdx[16] = {2,2,2,1,0,-1,-2,-2,-2,-2,-2,-1,0,1,2,2}; static int pdy[16] = {0,1,2,2,2,2,2,1,0,-1,-2,-2,-2,-2,-2,-1}; static int msk[8] = { 0x8003, 0x001f, 0x0038, 0x01f0, 0x0380, 0x1f00, 0x3800, 0xf001 }; static int d[16] = {r1,r2,r3,r2,r1,r2,r3,r2,r1,r2,r3,r2,r1,r2,r3,r2}; register int xx, yy, j, k, l, r; int i; for (i = 0; i < 16; i++) { /* scan potential candidates */ xx = x + pdx[i]; yy = y + pdy[i]; if (pcb[yy][xx] & s) { /* found a wire */ r = r0; /* default radius */ j = 0; /* reset search mask */ for (k = 0; k < 8; k++) { l = pcb[yy + dr[k][1]][xx + dr[k][0]]; if (l & ishb) r = r1; if (l & (chb | s) && !(l & ishb)) j |= msk[k]; } for (k = 0; k < 16; k++) { /* find max legal radius */ if (j & (1 << k)) continue; /* skip this point */ if (pcb[yy + pdy[k]][xx + pdx[k]] & (ahb | s)) { if (r > d[k]) r = d[k]; } } fprintf (ocf, "R %d %d %d;\n", r, xx * ucf, yy * ucf); } } } oclm () /* output component location marks */ { register int i, j, k, l, dis; char buf[10]; dis = 5 * rsun; /* distance to next mark */ dis /= 2; buf[1] = 0; for (i = dis, j = 1, k = 0; i < V.BSX - 2 * rsun; i += dis) { if (j) { /* character time */ j = 0; buf[0] = 'A' + k++; l = i * ucf - txt_len (buf, 2) / 2; ctxt (l, clm_off, 0, buf, 2); ctxt (l, V.BSY * ucf - chhgh - clm_off, 0, buf, 2);} else { fputs ("L PSSC;\n", ocf); cwire_S (i, 2, 0, 0, coww); cwire_E (i, 5, 0, 0); cwire_S (i, V.BSY - 2, 0, 0, coww); cwire_E (i, V.BSY - 5, 0, 0); fputs ("L PF;\n", ocf); cwire_S (i, 2, 0, 0, coww); cwire_E (i, 5, 0, 0); cwire_S (i, V.BSY - 2, 0, 0, coww); cwire_E (i, V.BSY - 5, 0, 0); j = 1; } } for (i = dis, j = 1, k = 0; i < V.BSY - 2 * rsun; i += dis) { if (j) { /* character time */ j = 0; sprintf (buf, "%d", ++k); l = i * ucf - txt_len (buf, 2) / 2; ctxt (clm_off + chhgh, l, 1, buf, 10); ctxt (V.BSX * ucf - clm_off, l, 1, buf, 10);} else { fputs ("L PSSC;\n", ocf); cwire_S (2, i, 0, 0, coww); cwire_E (5, i, 0, 0); cwire_S (V.BSX - 2, i, 0, 0, coww); cwire_E (V.BSX - 5, i, 0, 0); fputs ("L PF;\n", ocf); cwire_S (2, i, 0, 0, coww); cwire_E (5, i, 0, 0); cwire_S (V.BSX - 2, i, 0, 0, coww); cwire_E (V.BSX - 5, i, 0, 0); j = 1; } } } clean_up () /* remove the marks for wide wire traces */ { register int i, j, ss; register char *p; ss = ~(selb | resb); /* bits to be cleared */ for (i = 0; i < V.BSY; i++) { p = &pcb[i][0]; for (j = V.BSY; j; j--) *p++ &= ss; } } wwb_trc (x, y, s) /* wide wire boarder trace */ int x, y, s; /**********************************************************************\ * * * Wide wires tend to have a rough boarder because 'wtrace' may scan * * the wide wire un-parallel to its main direction. So 'wwb_trc' * * scans the boarder and produce a wire that smoothes this roughness. * * * \**********************************************************************/ { register int ss = ~(s | ahb), i, j, k; register char *p, *ps; p = &pcb[y][x]; while (*(p + 1) & ~ss) p++; /* find boarder */ if (!(*p & ~ss) || *p & resb) return; /* trouble || already done: exit */ for (i = 1; i < 8; i++) /* find initial direction */ if (*(p + pdr[i]) & ~ss) break; ps = p; /* remember start point */ do { *p |= resb; /* mark point */ p += pdr[i]; /* move to next point */ for (j = (i + 6) & 7, k = 7; k; k--, j = (j + 1) & 7) if (!(*(p + pdr[(j + 7) & 7]) & ~ss) && *(p + pdr[j]) & ~ss) break; /* find new direction */ if (i != j) { /* change in direction */ cvplt (((int) ps - (int) pcb) % xmax, ((int) ps - (int) pcb) / xmax, ((int) p - (int) pcb) % xmax, ((int) p - (int) pcb) / xmax ); ps = p; i = j; } } while (!(*p & resb)); } !E!O!F! # # type sh /usru0/agn/pcb/distr/../usenet/part5 to unpack this archive. # echo extracting pcmdl.c... cat >pcmdl.c <<'!E!O!F!' /***************************************************************\ * * * PCB program * * * * Command loop section * * * * (c) 1985 A. Nowatzyk * * * \***************************************************************/ #include "pparm.h" #include "pcdst.h" #define iniCNTX 0 /* initial context */ #define nretry 2 /* retry limit for N_route */ int mv_wind(), zoom_in(), zoom_out(), s_menu(), c_menu(); int st_learn(), learn_sl(), learn_ov(), learn_ex(), lrn_wmv(); int w_zoomi(), w_zoomo(), wnd_urc(), wnd_llc(), exc_adel (), sel_adel(); int w_wmv(), ini_adel(), ini_art(), sel_art(), exc_art(); extern int net_sel(), /* manual edit functions */ net_desel(), m_delete(), mr_delete(), start_nt(), cont_s1(), cont_s2(); extern int exc_cmv(), cmv_plc(), cmv_rr(), cmv_rl(), cmv_sel(); extern int CPp_ini(), CPp_exc(), CPp_plc(), CPp_del(); extern int exc_plow(), plow_ini(), plow_src(), plow_dst(); static struct cntxdsc { /* context descriptrors */ char *name; /* context name */ int (*entcntx)(); /* enter context function */ int (*excntx)(); /* exit context function */ int (*mkfunc[8])(); /* mouse key functions */ } CNTX[] = { {"Start", net_sel, net_desel, start_nt, mv_wind, start_nt, m_delete, zoom_in, s_menu, zoom_out, c_menu }, {"Route", 0, net_desel, cont_s1, mv_wind, cont_s2, mr_delete, zoom_in, s_menu, zoom_out, c_menu }, {"Edit", 0, 0, 0, mv_wind, 0, m_delete, zoom_in, s_menu, zoom_out, c_menu }, {"Learn", st_learn, 0, learn_sl, lrn_wmv, learn_ex, learn_ov, 0, 0, 0, 0 }, {"AR-Del", ini_adel, 0, wnd_urc, w_wmv, wnd_llc, exc_adel, w_zoomi, sel_adel, w_zoomo, sel_adel }, {"A-route", ini_art, 0, wnd_urc, w_wmv, wnd_llc, exc_art, w_zoomi, sel_art, w_zoomo, sel_art }, {"CP_move", 0, 0, cmv_sel, mv_wind, cmv_plc, exc_cmv, zoom_in, cmv_rl, zoom_out, cmv_rr }, {"Trace_mv", plow_ini, 0, plow_src, mv_wind, plow_dst, exc_plow, zoom_in, 0, zoom_out, c_menu }, {"CP_place",CPp_ini, 0, CPp_exc, mv_wind, CPp_plc, CPp_del, zoom_in, s_menu, zoom_out, cmv_rr } }; cmd_loop() /* command loop */ { int nxtc, x, y, i; static int context = iniCNTX; do { /* context loop */ if (CNTX[context].entcntx) {/* call enter function if present */ nxtc = (*CNTX[context].entcntx) (context); if (nxtc != context) {/* context was rejected */ context = nxtc; continue; } } cntx_msg (CNTX[context].name); do { /* loop within context */ i = getcur (&x, &y); unprev (); /* reset pending previews */ err_msg (""); /* clear pending error messages */ if (i < 0) err ("couldn't read graphic tablet", i, 0, 0, 0); nxtc = context; /* default */ if (CNTX[context].mkfunc[i]) nxtc = (*CNTX[context].mkfunc[i]) (x, y, context); else err_msg ("undefined key"); } while (nxtc == context); if (CNTX[context].excntx)/* call exit function if present */ (*CNTX[context].excntx) (nxtc); context = nxtc; } while (context >= 0); } mv_wind (x, y, ctx) /* move window */ int x, y, ctx; { window (x - 256 / cz, y - 256 / cz); return (ctx); /* don't change context */ } /*ARGSUSED*/ zoom_in (x, y, ctx) /* increase zoom */ int x, y, ctx; { if (cz < 16) zoom (cz + 1); return (ctx); /* don't change context */ } /*ARGSUSED*/ zoom_out (x, y, ctx) /* decrease zoom */ int x, y, ctx; { if (cz > 1) zoom (cz - 1); return (ctx); /* don't change context */ } quit () /* quit session */ { static char *mtext[] = { "Continue quit: no save", "Abort quit" }; if (!menu (mtext, 2)) finish (); } /*ARGSUSED*/ s_menu (x, y, ctx) /* start menu */ int x, y, ctx; { static char *mtext[] = { "Plot preview", "CIF - Output", "Exit", "Quit (no save)", "Diagnostics", "Learn sequence", "Area Delete", "Area Route", "Route sequence", "Save Work", "Change color", "Move Component", "Expand wire" }; switch (menu (mtext, 13)) { case 0: Ferr_msg ("Busy: Plotting Bitmap"); pntbm (); err_msg ("Done"); beep (); break; case 1: Ferr_msg ("Busy: Writing CIF file"); cifout (); err_msg ("Done"); beep (); break; case 2: Ferr_msg ("Saving Bitmap & exit"); save (0); finish (); break; case 3: quit (); break; case 4: p_diagn (); break; case 5: return (LEARN); case 6: return (ADELE); case 7: return (AROUTE); case 8: seq_rt (); return (net_sel (START)); case 9: Ferr_msg ("Busy: saving Bitmap"); save (0); beep (); err_msg ("Done"); break; case 10: chg_color (); break; case 11: return (CMOVE); case 12: return wide_wire (ctx); } return (ctx); } /*ARGSUSED*/ c_menu (x, y, ctx) /* configuration menu */ int x, y, ctx; { static char *mtext[] = { 0, /* beep toggle */ 0, /* window toggle */ 0, /* H-route toggle */ 0, /* straight toggle */ "learn off", "Route Parameters", "Print statistics", "Wire desity", "Congestion area", "List", "Update" }; /* update toggles */ mtext[0] = (no_beep) ? "Beep on" : "Beep off"; mtext[1] = (no_adjw) ? "Adjust window" : "Stable window"; mtext[2] = (no_hrout) ? "Enable H-route" : "Disable H-route"; mtext[3] = (st_reroute) ? "Move straight" : "Reroute straight"; switch (menu (mtext, 11)) { case 0: no_beep = (no_beep) ? 0 : 1; break; case 1: no_adjw = (no_adjw) ? 0 : 1; break; case 2: no_hrout = (no_hrout) ? 0 : 1; break; case 3: st_reroute = (st_reroute) ? 0 : 1; break; case 4: flush_lb (); break; case 5: Ferr_msg("See your Terminal"); get_rtprm (); break; case 6: pgen_stat (); break; case 7: dis_pro (); break; case 8: dis_cc (); break; case 9: P_list (); break; case 10: return P_update (ctx); } return (ctx); } static int ov_on = 0; /* over-view display is on */ view_on () /* display a wire over-view */ { int i, xl, yl, xh, yh, x0, y0, x1, y1; struct nlst *p1, *p2; if (ov_on) view_off (); xl = wx; /* get visible area */ xh = wx + 511 / cz; yl = wy; yh = wy + 482 / cz; msg_off (); color (resb, resb); for (i = 0; i < V.nnh; ++i) /* scan through nets */ if (!NH[i].f) { /* only unfinished nets */ p1 = NH[i].lp; while (p1) { x0 = p1 -> c -> x; y0 = p1 -> c -> y; if (x0 < xh && x0 > xl && y0 < yh && y0 > yl) { p2 = p1 -> n; while (p2) {/* display full lines */ x1 = p2 -> c -> x; y1 = p2 -> c -> y; if (x0 < xh && x0 > xl && y0 < yh && y0 > yl) aed_plt (x0, y0, x1, y1); p2 = p2 -> n; } p2 = NH[i].lp; while (p2) {/* display of-screen lines */ x1 = p2 -> c -> x; y1 = p2 -> c -> y; if (x0 >= xh || x0 <= xl || y0 >= yh || y0 <= yl) aed_plt (x0, y0, x1, y1); p2 = p2 -> n; } } p1 = p1 -> n; } } ov_on = 1; } view_off () /* turn off over view */ { if (ov_on) { color (0, resb); rect (wx, wy, wx + 511 / cz, wy + 482 / cz); msg_on (); } ov_on = 0; } static int lrn_cnt = 0; /* learn counter */ static int lrnfull = 0; /* max. number of valid entries */ static struct nlhd *lrn_buf[lrn_max]; /* learn buffer */ /*ARGSUSED*/ st_learn (x, y, ctx) /* start learn mode */ int x, y, ctx; { lrn_cnt = 0; lrnfull = 0; return (LEARN); } learn_sl (x, y, ctx) /* select a wire */ int x, y, ctx; { struct nlhd *p, *loc(), *fly(); int i; if (lrn_cnt >= lrn_max) { view_off (); err_msg ("Learn buffer full"); beep (); return (START); } p = loc (&x, &y); if (!p) p = fly (&x, &y); if (!p) { msg_on (); err_msg ("No net at cursor location"); beep (); return (ctx); } if (p -> f) { msg_on (); err_msg ("Net is already done"); return (ctx); } for (i = 0; i < lrn_cnt; ++i) if (p == lrn_buf[i]) { msg_on (); err_msg ("Net already selected"); beep (); return (ctx); } lrn_buf[lrn_cnt++] = p; lrnfull = lrn_cnt; return (ctx); } lrn_wmv (x, y, ctx) /* learn: move window */ int x, y, ctx; { if (ov_on) view_off (); return (mv_wind (x, y, ctx)); } /*ARGSUSED*/ learn_ex (x, y, ctx) /* learn: exit */ int x, y, ctx; { if (ov_on) view_off (); return (START); } /*ARGSUSED*/ learn_ov (x, y, ctx) /* over-view on */ int x, y, ctx; { if (!ov_on) view_on (); return (ctx); } flush_lb () /* flush learn buffer */ { lrn_cnt = 0; lrnfull = 0; } struct nlhd *ck_lrnb () /* check learn buffer */ { while (lrn_cnt > 0 && lrn_buf[lrn_cnt - 1] -> f) lrn_cnt--; /* skip finished nets */ if (lrn_cnt <= 0) return (nil); /* is empty */ return (lrn_buf[--lrn_cnt]); } seq_rt () /* sequence route */ { struct nlhd *t, *ck_lrnb (); lrn_cnt = lrnfull; /* rewind learn buffer */ if (lrn_cnt <= 0) err_msg ("Learn a sequence first"); else { Ferr_msg ("Busy routing"); while ((t = ck_lrnb ())) { N_route (t, nretry, 0, 0, V.BSX, V.BSY); nettgo -= t -> f; } nets_msg (nettgo); err_msg ("Done"); beep (); } } !E!O!F! # # type sh /usru0/agn/pcb/distr/../usenet/part5 to unpack this archive. # echo extracting pdiag.c... cat >pdiag.c <<'!E!O!F!' /***************************************************************\ * * * PCB program * * * * Diagnostic routines * * * * (c) 1985 A. Nowatzyk * * * \***************************************************************/ #include "pparm.h" #include "pcdst.h" test(x,y) int x, y; { int i, j; printf ("Test at x=%d y=%d\n", x, y); for (i = y + 3; i >= y - 3; --i) { printf ("\t%d: ", i); for (j = -4; j <= 4; j++) { if (i == y) switch (j) { case 0: printf(">"); break; case 1: printf("<"); break; default: printf(" "); break; } else printf(" "); printf("%2x",pcb[i][x + j] & 255); } printf ("\n"); } abm_tst (x, y); } s_test(x,y,x1,y1,s) int x, y, x1, y1; char *s; { int i, j; char c; printf ("Test at x=%d y=%d (..)=%s\n", x, y,s); for (i = y + 3; i >= y - 3; --i) { printf (" %d: ", i); for (j = -4; j <= 4; j++) { c = ' '; if (i == y1 && x + j == x1) c = '('; if (i == y1 && x + j == x1 + 1) c = ')'; if (i == y && !j) c = (c != ' ') ? '*' : '>'; if (i == y && j == 1) c = (c != ' ') ? '*' : '<'; printf("%c%2x",c, pcb[i][x + j] & 255); } if(i == y1 && (x + j) == (x1+1)) printf(")"); printf ("\n"); } abm_tst (x, y); } tst1 () { int x, y, sccm, sccc; sccm = ccm; sccc = ccc; getcur (&x, &y); test (x, y); ccc = sccc; ccm = sccm; } tst2 (x1, y1, x2, y2, c) int x1, y1, x2, y2, c; { int x, y; for (x = x1; x <= x2; ++x) for (y = y1; y <= y2; ++y) pcb[y][x] = c; } verify () /* verify connectivity */ { int i, j; for (nettgo = i = 0; i < V.nnh; ++i) { if (NH[i].l > 0) { j = cchk (&NH[i]); if (j != NH[i].f) { printf ("Net %d: f=%d cchk=%d\n", i, NH[i].f, j); NH[i].f = j; } nettgo += !NH[i].f;} else printf ("Net %d is emty\n", i); } printf ("Done\n"); } p_diagn () /* diagnostic menu */ { static char *mtext[] = { "View", "Verify", "Clean", "Flip"}; switch (menu (mtext, 4)) { case 0: tst1 (); break; case 1: verify (); break; case 2: clean (); break; case 3: flip_s(); break; } } clean () /* scan bitmap for wrong bits */ { register int i, j; struct nlhd *t; t = V.cnet; if (t) deseln (t); color (resb, resb); for (i = 0; i < V.BSX; i++) for (j = 0; j < V.BSY; j++) if (pcb[j][i] & 0xa0) { point (i, j); pcb[j][i] &= 0x5f; }; window (0, 0); update (0, 0, 511, 511); fx = fy = 0; if (t) selnet (t); } flip_s () /* flip sides */ { register int i, j, k; for (i = 0; i < V.BSX; i++) for (j = 0; j < V.BSY; j++) { k = pcb[j][i]; pcb[j][i] = (k & ~vec) | ((k & s2b) >> 1) | ((k & s1b) << 1);} update (0, 0, 511, 511); fx = fy = 0; window (0, 0); } qpat() { TY[81].p = &PN[V.npn]; PN[V.npn + 0].x = 0; PN[V.npn + 0].y = 0; PN[V.npn + 0].p = 0; PN[V.npn + 1].x = 0; PN[V.npn + 1].y = 12; PN[V.npn + 1].p = 0; PN[V.npn + 2].x = 0; PN[V.npn + 2].y = 24; PN[V.npn + 2].p = 0; PN[V.npn + 3].x = 12; PN[V.npn + 3].y = 24; PN[V.npn + 3].p = 0; PN[V.npn + 4].x = 12; PN[V.npn + 4].y = 12; PN[V.npn + 4].p = 0; PN[V.npn + 5].x = 12; PN[V.npn + 5].y = 0; PN[V.npn + 5].p = 0; V.npn += 6; } !E!O!F! # # type sh /usru0/agn/pcb/distr/../usenet/part5 to unpack this archive. # echo extracting pfio.c... cat >pfio.c <<'!E!O!F!' /***************************************************************\ * * * PCB program * * * * File I/O section * * * * (c) 1985 A. Nowatzyk * * * \***************************************************************/ #include <stdio.h> #include "pparm.h" #include "pcdst.h" FILE *inp; /* read/write channels */ extern FILE *fwantread(); extern int rot_m[4][4]; /* rotation matrix */ extern wantread(), wantwrite(); char *getstr(); float scalef; /* sacle factor */ static inp_errs = 0; /* input errors */ rdnl () /* read a netlist */ { register int i, j; if (getbool ("Do you want to read a checkpoint file?",1)) rsto (); else { specs (); /* promt for board specifications*/ rdty (); /* read types */ rdcp (); /* read components */ rdnh (); /* read net list */ if (inp_errs) err ("-Please correct earlier errors and try again", 0, 0, 0, 0); } for (j = 0, i = 0; i < V.nnh; i++) j += !NH[i].f; nettgo = j; nets_msg (nettgo); } rdty () /* read the type definition file */ { char buf[inp_lnl], nm[nmmax + 2], ga[nmmax + 2]; char fname[40]; int i, j, k, ix, iy; float x, y, x1, y1; static char pln[4][4] = {"GND", "VCC", "VEE", "VBB"}; inp = fwantread (".", "test.ty", fname, "Type definition file:"); if (!inp) err("-Failed to read type definition file", 0, 0, 0, 0); fgets (buf, inp_lnl, inp); if (strncmp (buf, "*types:", 7)) err ("-Type-def file doesn't start with '*types:'", 0, 0, 0, 0); i = 1; while (fgets (buf, inp_lnl, inp)) { rms (buf); i++; /* count lines for error msg */ if (V.nty >= tymax) err ("type table too small - increase 'tymax'", V.nty, i, 0, 0); for (j = 0; (j < nmmax) && (buf[j] != ':'); j++) TY[V.nty].name[j] = buf[j]; if (buf[j] == ':') { if (buf[j + 1] != '\0') printf ("Line %d: warning: garbage ignored\n", i); TY[V.nty].name[j] = '\0'; } else if (buf[j + 1] != ':') printf ("Line %d: warning: missing ':'\n", i); for (j = 0; j < V.nty; j++) /* kind of slow, but ... */ if (!strncmp (TY[V.nty].name, TY[j].name, nmmax)) break; if (j < V.nty) { printf ("Line %d: error: '%s' is already defined\n", i, TY[V.nty].name); inp_errs = 1; } TY[V.nty].x = 0; TY[V.nty].y = 0; TY[V.nty].np = 0; TY[V.nty].cif = 0; TY[V.nty].p = nil; while (fgets (buf, inp_lnl, inp)) { /* read type body */ rms (buf); i++; /* count lines */ if (!strncmp (buf, "EXTCIF: ", 8)) { /*** EXTCIF ***/ j = sscanf (&buf[8], "%d", &k); if (j != 1 || k < ex_cifL || k > ex_cifH || TY[V.nty].cif) { printf ("Line %d: illegal 'EXTcif'\n", i); inp_errs = 1;} else { if (V.ncif >= cifmax) err ("EXTcif table too small: increase 'cifmax'", V.ncif, i, 0, 0); CIF[V.ncif].symn = k; CIF[V.ncif].flg = 0; CIF[V.ncif].blk = 0; TY[V.nty].cif = V.ncif + 1; }} else if (!strncmp (buf, "BOX: ", 5)) { /*** BOX ***/ j = sscanf (&buf[5], "%f %f", &x, &y); if (j != 2 || x < 0 || y < 0) { printf ("Line %d: invalid 'Box' statement\n", i); inp_errs = 1;} else { ix = x * rsun * scalef + 0.5; iy = y * rsun * scalef + 0.5; if (TY[V.nty].x < ix) TY[V.nty].x = ix; if (TY[V.nty].y < iy) TY[V.nty].y = iy; }} else if (!strncmp (buf, "BLOCK: ", 7)) { /*** BLOCK ***/ j = sscanf (&buf[7], "%f %f %f %f", &x, &y, &x1, &y1); ix = x1 * rsun * scalef + 0.5; iy = y1 * rsun * scalef + 0.5; if (j != 4 || x < 0 || x1 < 0 || y < 0 || y1 < 0 || x > x1 || y > y1 || !TY[V.nty].cif || ix > TY[V.nty].x || iy > TY[V.nty].y) { printf ("Line %d: invalid 'Block' statement\n", i); inp_errs = 1;} else { if (CIF[V.ncif].blk) { /* need additional record */ CIF[V.ncif].flg = 1; if (V.ncif >= cifmax) err ("EXTcif table too small: increase 'cifmax'", V.ncif, i, 0, 0); CIF[++V.ncif].flg = 0; CIF[V.ncif].symn = CIF[V.ncif - 1].symn; } CIF[V.ncif].blk = 1; CIF[V.ncif].xh = ix; CIF[V.ncif].yh = iy; CIF[V.ncif].xl = x * rsun * scalef + 0.5; CIF[V.ncif].yl = y * rsun * scalef + 0.5; }} else { /*** normal pin statement ***/ j = sscanf (buf, "%f %f %s %s", &x, &y, nm, ga); if (buf[0] == '\0') break; /* exit */ k = 0; /* default type */ switch (j) { case 1: printf ("Line %d: warning: missing y - line ignored\n",i); break; case 4: printf ("Line %d: warning: grabage '%s...' ignored\n", i, ga); case 3: for (k = 0; k < 4; ++k) if (!strncmp (pln[k], nm, nmmax)) break; k = (k + 1) % 5; case 2: if (V.npn >= pnmax) err ("pin table too small - increase 'pnmax'", V.npn, 0, 0, 0); if (TY[V.nty].p == nil) TY[V.nty].p = &PN[V.npn]; (TY[V.nty].np)++; ix = x * rsun * scalef + 0.5; iy = y * rsun * scalef + 0.5; if (TY[V.nty].x < ix) TY[V.nty].x = ix; if (TY[V.nty].y < iy) TY[V.nty].y = iy; PN[V.npn].x = ix; PN[V.npn].y = iy; PN[V.npn].p = k; V.npn++; } } } if (TY[V.nty].y > TY[V.nty].x) printf ("Warning for '%s': y>x (text is aligned to the x-axis)\n", TY[V.nty].name); if (TY[V.nty].cif) V.ncif++; V.nty++; } fclose (inp); printf("Type file: %d types with a total of %d pins defined\n", V.nty, V.npn); } rms (b) char *b; /******************************************************************\ * * * remove stuff: * * The character string <b> is reformatted: * * 1. [a-z] -> [A-Z] * * 2. Comment are removed * * 3. Multiple field seperators (' ', '\t' and ',') are removed * * 4. Field seperators will become ' ' * * 5. Field seperators before '\0' are removed * * 6. Fileds are truncated to 'nmmax' characters * * * \******************************************************************/ { register int i, j, k, s; s = 1; for (i = j = k = 0; i < inp_lnl; ++i) { if (('a' <= b[i]) && ('z' >= b[i])) b[i] -= 'a' - 'A'; /* case folding */ switch (b[i]) { case ' ': case '\t': /* single tab or space separator */ if (!s) b[j++] = ' '; s = 1; k = 0; break; case ';': /* ignor comments */ case '\n': case '\0': j -= s && j; /* remove seperators at EOL */ b[j] = '\0'; i = inp_lnl; break; case ',': b[j++] = ' '; s = 1; k = 0; break; default: if (k > nmmax) { b[j++] = ' '; k = 0;} else { s = 0; b[j++] = b[i]; k++;} break; } } } rdcp() /* read component file */ { char buf[inp_lnl], t[nmmax + 2]; float x, y; register int i, j, k, ix, iy; int r; inp = fwantread (".", "test.cp", buf, "Component definition file:"); if (!inp) err("-Failed to read component definition file", 0, 0, 0, 0); fgets (buf, inp_lnl, inp); if (strncmp (buf, "*components:", 12)) err ("component-def file doesn't start with '*components:'", 0, 0, 0, 0); j = 1; while (fgets (buf, inp_lnl, inp)) { rms (buf); j++; /* count lines */ if (V.ncp >= cpmax) err ("Component table too small: increase 'cpmax'", V.ncp, j,0,0); k = sscanf (buf, "%s %s %f %f %d", CP[V.ncp].name, t, &x, &y, &r); if (k != 5 && k != 2) { /*** argument check ***/ printf ("Line %d error: invalid argumnet count\n", j); inp_errs = 1; continue; } for (i = 0; i < V.ncp; i++) /*** multi-def check ***/ if (!strncmp (CP[i].name, CP[V.ncp].name, nmmax)) break; if (i < V.ncp) { printf ("Line %d error: multiple defined '%s'\n", j, CP[V.ncp].name); inp_errs = 1; continue; } for (i = 0; i < V.nty; i++) /*** get type ***/ if (!strncmp (t, TY[i].name, nmmax)) break; if (i >= V.nty) { printf ("Line %d error: undefined Type '%s'\n", j, t); inp_errs = 1; continue; } CP[V.ncp].ty = &TY[i]; CP[V.ncp].unplaced = 1; /* not yet placed */ if (V.nch + TY[i].np > chmax) err ("Hole table too small, increase 'chmax'\n", chmax, j, 0, 0); for (i = TY[i].np; i;) { /* allocate holes */ CH[V.nch].x = 0; CH[V.nch].y = 0; CH[V.nch].pn = --i; CH[V.nch].cpi = V.ncp; CH[V.nch++].n = nil; } if (5 == k) { /* explicily placed component */ if ((r < 0) || (r > 3)) { printf ("Line %d error: invalid rotation - line ignored\n",j); inp_errs = 1; continue; } ix = rsun * x * scalef + 0.5; iy = rsun * y * scalef + 0.5; if (!C_place (&CP[V.ncp], ix, iy, r)) printf ("Line %d warning: invalid location, place it later\n", j); } V.ncp++; } CH_update (); /* sort holes */ fclose (inp); printf ("Component file: %d components with %d pins allocated\n", V.ncp, V.nch); } rdnh() /* read net list */ { char buf[inp_lnl]; register int i, j; int k; register int mode = 0; /* =0 Multiwire, =1 DP */ register struct nlhd *hptr; inp = fwantread (".", "test.nl", buf, "Net list file:"); if (!inp) err ("-Failed to read Net list file", 0, 0, 0, 0); fgets (buf, inp_lnl, inp); if (strncmp (buf, "Cnetlist:", 9) && (mode = 1, strncmp (buf, "DPnetlist:", 10))) err ("-component-def file doesn't start with 'C/DPnetlist:'", 0, 0, 0, 0); i = 1; while (fgets (buf, inp_lnl, inp)) { rms (buf); i++; if (mode) { /*******************************************************************\ * * * DP netlist reader * * * * Warning: I am too tired to completly rewrite the reader now, so * * there is the limitation that a net has to fit into the * * line buffer (buf). * * * \*******************************************************************/ for (j = 0; buf[j] && buf[j] != '\\'; j++); if (j && !buf[j]) { printf ("Line %d error: DP-name without '\\'\n", i); inp_errs = 1; continue; } if (!j) continue; /* skip empty lines */ if (buf[0] == '!') {/* power net (gnd, vcc, vee, vtt) */ if (!strncmp ("GND", &buf[1], 3)) hptr = &V.GND; else if (!strncmp ("VCC", &buf[1], 3)) hptr = &V.VCC; else if (!strncmp ("VTT", &buf[1], 3)) hptr = &V.VTT; else if (!strncmp ("VEE", &buf[1], 3)) hptr = &V.VEE; else { printf ("Line %d error: unknown power net\n"); inp_errs = 1; continue; }} else { /* normal net */ if (V.nnh >= nhmax) err ("Netlist table too small - increase 'nhmax'", V.nnh, 0, 0, 0); buf[j] = 0; strncpy (NH[V.nnh].name, buf, nmmax); NH[V.nnh].l = 0; NH[V.nnh].lp = nil; NH[V.nnh].x1 = xmax; NH[V.nnh].y1 = ymax; NH[V.nnh].x2 = 0; NH[V.nnh].y2 = 0; NH[V.nnh].f = 0; hptr = &NH[V.nnh]; V.nnh++; } for (j++; (j < inp_lnl) && (buf[j] != '\0'); ++j) if (buf[j] == ' ') addn (&buf[j + 1], hptr, i); continue; /* next net */ } if (buf[0] == 'C') { /* Multiwire net list processing */ j = 3; if (!strncmp ("GND", &buf[1], 3)) hptr = &V.GND; else if (!strncmp ("VCC", &buf[1], 3)) hptr = &V.VCC; else if (!strncmp ("VTT", &buf[1], 3)) hptr = &V.VTT; else if (!strncmp ("VEE", &buf[1], 3)) hptr = &V.VEE; else continue; /* normal comment */ } else { if (!sscanf (buf, "%d", &k)) { printf ("Line %d error: invalid net number\n", i); inp_errs = 1; continue;} else if (k == -1) /* Multiwire end ? */ break; else if ((k < V.nnh) || (k <= 0)) { printf ("Line %d error: net number %d out of sequence\n", i, k); inp_errs = 1; continue;} else { if (k > V.nnh + 1) printf("Line %d warning: net %d missing, next is %d\n", i, V.nnh + 1, k); while (k > V.nnh) {/* start a new net list */ if (V.nnh >= nhmax) err ("Netlist table too small - increase 'nhmax'", V.nnh, 0, 0, 0); sprintf (NH[V.nnh].name, "#%d", V.nnh + 1); NH[V.nnh].l = 0; NH[V.nnh].lp = nil; NH[V.nnh].x1 = xmax; NH[V.nnh].y1 = ymax; NH[V.nnh].x2 = 0; NH[V.nnh].y2 = 0; NH[V.nnh].f = 0; hptr = &NH[V.nnh]; V.nnh++; } } j = 0; } for (j++; (j < inp_lnl) && (buf[j] != '\0'); ++j) if (buf[j] == ' ') addn (&buf[j + 1], hptr, i); } fclose (inp); printf ("Netlist: %d nets with %d nodes allocated\n", V.nnh, V.nnl); } addn(s,net,ln) /* add a node to a net list */ char s[]; struct nlhd *net; int ln; { int k, x1, y1; register int i, j, l, r, x, y; struct hole *hp, *fndh (); for (i = 0; s[i] != '-'; ++i) /* isolate component name */ if ((s[i] == '\0') || (i > nmmax)) { printf ("Line %d error: missing pin number\n", ln); inp_errs = 1; return; } s[i] = '\0'; /* terminate string temporarily */ for (j = 0; j < V.ncp; j++) /* find componet definition */ if (!strncmp (s, CP[j].name, nmmax)) break; if (j >= V.ncp) { printf ("Line %d error: reference to undefined component\n", ln); inp_errs = 1; return; } if ((!sscanf (&s[i + 1], "%d", &k)) || (k <= 0) || (k > CP[j].ty -> np)) { printf("Line %d error: '%s-%d': pin-number out of range\n", ln, s, k); inp_errs = 1; return; } /* check pin number */ --k; /* pin number must start at 0 */ if ((CP[j].ty -> p + k) -> p) printf ("Line %d warning: '%s-%d' is a power/gnd pin\n", ln, s, k+1); s[i] = '*'; /* this is a hack */ if (CP[j].unplaced) { /* need direct search */ hp = nil; for (l = 0; l < V.nch; l++) if (CH[j].cpi == j && CH[j].pn == k) { hp = &CH[l]; break; } } else { x = (CP[j].ty -> p + k) -> x; /* locate hole entry in CH */ y = (CP[j].ty -> p + k) -> y; r = CP[j].r; x1 = CP[j].x + rot_m[r][0] * x + rot_m[r][1] * y; y1 = CP[j].y + rot_m[r][2] * x + rot_m[r][3] * y; hp = fndh (x1, y1); } if (hp == nil) err ("addn: failed to find hole", x1, y1, j, i); if (hp -> n != nil) { /* multiple net node ?? */ printf ("Line %d error: '%s-%d' already used in other net\n", ln, s, k + 1); inp_errs = 1; return; } if (V.nnl >= nlmax) err ("net node table too small - increase 'nlmax'", V.nnl, 0, 0, 0); NL[V.nnl].c = hp; /* enter node to tables */ NL[V.nnl].n = net -> lp; NL[V.nnl].nlp = net; hp -> n = net -> lp = &NL[V.nnl]; net -> l++; V.nnl++; } struct hole *fndh (x,y) /* find hole */ int x, y; { register int i, j, k, xx = x, yy = y; i = 0; j = V.nch; while (i <= j) { k = (i + j) >> 1; if (xx > CH[k].x) { i = k + 1; continue; } if (xx < CH[k].x) { j = k - 1; continue; } if (yy > CH[k].y) { i = k + 1; continue; } if (yy < CH[k].y) { j = k - 1; continue; } return &CH[k]; } return nil; } save (ety) /* save vital data structure */ int ety; { int i, och; char fn[30]; static char fname[2][8] = { "pcb.SAV", "pcb.ERR"}; struct {int r, g, b;} crc; /* color record */ och = wantwrite (".", &fname[ety][0], fn, "Checkpoint file name:", 0); write (och, &V, sizeof (V)); /* write head information */ for (i = 0; i < ymax; ++i) write (och, &pcb[i][0], xmax); for (i = 0; i < V.ncp; ++i) write (och, &CP[i], sizeof (CP[0])); for (i = 0; i < V.nty; ++i) write (och, &TY[i], sizeof (TY[0])); for (i = 0; i < V.npn; ++i) write (och, &PN[i], sizeof (PN[0])); for (i = 0; i < V.nch; ++i) write (och, &CH[i], sizeof (CH[0])); for (i = 0; i < V.nnh; ++i) write (och, &NH[i], sizeof (NH[0])); for (i = 0; i < V.nnl; ++i) write (och, &NL[i], sizeof (NL[0])); for (i = 0; i < ncolors; ++i) { crc.r = Color_tab[i].r; crc.g = Color_tab[i].g; crc.b = Color_tab[i].b; write (och, &crc, sizeof (crc)); } for (i = 0; i < V.ncif; ++i) write (och, &CIF[i], sizeof (struct cif)); i = mgnm; /* mark the end of the grabage */ write (och, &i, sizeof (int)); close (och); } rsto() /* Restore Checkpointed state */ { int i, ich, old; char fn[30]; struct {int r, g, b;} crc; /* color record */ ich = wantread (".", "pcb.SAV", fn, "Checkpoint file name:"); read (ich, &V, sizeof (V)); /* read head information */ old = 0; if (V.pver != pversion) { if (V.pver == 123) /* conversion V 1.23 -> current */ old = 1; else err ("-program version mismatch", V.pver, pversion, 0, 0); } if (V.errtxt[0] != '\0') { printf ("Warning: previous pcb run died with error message:\n"); printf ("\t\"%s\"\n", V.errtxt); printf (" error-info: %d %d %d %d\n", V.err_info[0], V.err_info[1], V.err_info[2], V.err_info[3]); V.errtxt[0] = '\0'; } if ((V.x != xmax) || (V.y != ymax)) err ("-different bit map size", V.x, V.y, xmax, ymax); if (V.ncp > cpmax) err ("-CP table too small - increase 'cpmax'", V.ncp, cpmax, 0, 0); if (V.nty > tymax) err ("-TY table too small - increase 'tymax'", V.nty, tymax, 0, 0); if (V.npn > pnmax) err ("-PN table too small - increase 'pnmax'", V.npn, pnmax, 0, 0); if (V.nch > chmax) err ("-CH table too small - increase 'chmax'", V.nch, chmax, 0, 0); if (V.nnh > nhmax) err ("-NH table too small - increase 'nhmax'", V.nnh, nhmax, 0, 0); if (V.nnl > nlmax) err ("-NL table too small - increase 'nlmax'", V.nnl, nlmax, 0, 0); if (V.ncif > cifmax) err ("-CIF table too small - increase 'cifmax'", V.ncif, cifmax,0, 0); for (i = 0; i < ymax; ++i) read (ich, &pcb[i][0], xmax); for (i = 0; i < V.ncp; ++i) read (ich, &CP[i], sizeof (CP[0])); for (i = 0; i < V.nty; ++i) read (ich, &TY[i], sizeof (TY[0])); for (i = 0; i < V.npn; ++i) read (ich, &PN[i], sizeof (PN[0])); for (i = 0; i < V.nch; ++i) read (ich, &CH[i], sizeof (CH[0])); for (i = 0; i < V.nnh; ++i) read (ich, &NH[i], sizeof (NH[0])); for (i = 0; i < V.nnl; ++i) read (ich, &NL[i], sizeof (NL[0])); for (i = 0; i < ncolors; i++) { read (ich, &crc, sizeof (crc)); Color_tab[i].r = crc.r; Color_tab[i].g = crc.g; Color_tab[i].b = crc.b; } for (i = 0; i < V.ncif; ++i) read (ich, &CIF[i], sizeof (struct cif)); read (ich, &i, sizeof (int)); /* consistency check */ if (i != mgnm) err ("-failed to find magic number in saved file", i, mgnm, 0, 0); close (ich); if ( (V.cp != CP) || (V.ty != TY) || (V.pn != PN) || (V.ch != CH) || (V.nh != NH) || (V.nl != NL) || (V.own != &V)) radjptr (); if (old) convf123 (); /* convert from version 123 */ if (!batch) { ldcmp (); update (0, 0, 511, 511); fx = fy = 0; window (0, 0); } if (V.cnet) /* deselect pending nets */ deseln (V.cnet); } radjptr () /* readjust pointer */ /************************************************************************\ * * * If the saved file was created with an older (but similar) version of * * this program, the saved pointer may have changed due to the new * * complilation. This routine readjusts the old pointer so that they * * correspont to the new locations. * * * \************************************************************************/ { union ptr_int { /* allow arithmetic on pointer */ unsigned i; struct type *ty; struct pin *pn; struct hole *ch; struct nlhd *nh; struct nlst *nl; struct vtin *vi; } p1, p2; unsigned tyof, pnof, chof, nhof, nlof, viof, nh_l, nh_h; register int i; printf("Warning: pcb has been recomplied since the file was saved\n"); p1.ty = V.ty; p2.ty = &TY[0]; tyof = p2.i - p1.i; /* get TY offset */ p1.pn = V.pn; p2.pn = &PN[0]; pnof = p2.i - p1.i; /* get PN offset */ p1.ch = V.ch; p2.ch = &CH[0]; chof = p2.i - p1.i; /* get CH offset */ p1.nl = V.nl; p2.nl = &NL[0]; nlof = p2.i - p1.i; /* get NL offset */ p1.nh = V.nh; p2.nh = &NH[0]; nhof = p2.i - p1.i; /* get NH offset */ p1.vi = V.own; p2.vi = &V; viof = p2.i - p1.i; /* get NH offset */ if (tyof) { for (i = 0; i < V.ncp; ++i) { p1.ty = CP[i].ty; p1.i = p1.i ? p1.i + tyof : nil; CP[i].ty = p1.ty; } } if (pnof) { for (i = 0; i < V.nty; ++i) { p1.pn = TY[i].p; p1.i = p1.i ? p1.i + pnof : nil; TY[i].p = p1.pn; } } if (viof || chof || nlof || nhof) {/* adjust netlist ptr''s */ p1.nh = V.nh; nh_l = p1.i; p1.nh = V.nh + V.nnh; nh_h = p1.i; for (i = 0; i < V.nnl; ++i) { p1.ch = NL[i].c; p1.i = p1.i ? p1.i + chof : nil; NL[i].c = p1.ch; p1.nl = NL[i].n; p1.i = p1.i ? p1.i + nlof : nil; NL[i].n = p1.nl; p1.nh = NL[i].nlp; if (p1.i >= nh_l && p1.i <= nh_h) p1.i += nhof; else p1.i = p1.i ? p1.i + viof : nil; NL[i].nlp = p1.nh; } } if (nlof) { for (i = 0; i < V.nch; ++i) { p1.nl = CH[i].n; p1.i = p1.i ? p1.i + nlof : nil; CH[i].n = p1.nl; } for (i = 0; i < V.nnh; ++i) { p1.nl = NH[i].lp; p1.i = p1.i ? p1.i + nlof : nil; NH[i].lp = p1.nl; } if (V.GND.lp) { p1.nl = V.GND.lp; p1.i += nlof; V.GND.lp = p1.nl; } if (V.VCC.lp) { p1.nl = V.VCC.lp; p1.i += nlof; V.VCC.lp = p1.nl; } if (V.VEE.lp) { p1.nl = V.VEE.lp; p1.i += nlof; V.VEE.lp = p1.nl; } if (V.VTT.lp) { p1.nl = V.VTT.lp; p1.i += nlof; V.VTT.lp = p1.nl; } } if (nhof || nlof) { p1.nh = V.cnet; p1.i = p1.i ? p1.i + nhof : nil; V.cnet = p1.nh; p1.nh = V.enhl; p1.i = p1.i ? p1.i + nhof : nil; V.enhl = p1.nh; p1.nl = V.enll; p1.i = p1.i ? p1.i + nlof : nil; V.enll = p1.nl; } V.own = &V; V.cp = &CP[0]; V.ty = &TY[0]; V.pn = &PN[0]; V.ch = &CH[0]; V.nh = &NH[0]; V.nl = &NL[0]; /* done ! (hopefully) */ /* the next is a temporary fix to correct an old ptr- problem */ /* for (i = 0; i < V.nnh; i++) if (NH[i].l) {int j; struct nlst *p; for (p = NH[i].lp, j = 0; p; p = p -> n, j++) if (p -> nlp != &NH[i]) { printf("#"); p -> nlp = &NH[i]; } if (j != NH[i].l) err ("radjptr: inconsistent length", i, j, NH[i].l, 0); } */ } convf123 () /**************************************************************\ * * * Convert from version 1.23: * * * * Changes: a) Tool holes are no longer needed -> remove them * * b) The hole-structure received a reference to the * * originating hole. * * * \**************************************************************/ { register int j, r, xp, yp; int i, k, x, y; register struct pin *pin; register struct hole *hp; struct nlst *net; struct hole *fndh (); struct oldhole { int x, y; /* coordinates */ struct nlst *n; /* net pointer */ } *oh; printf ("Updating to PCB version 1.24\n"); V.pver = pversion; /* update pgm version */ color (0, fb); for (i = 0; i < 4; i++) /* remove tool holes */ if (V.reserved[i]) { x = V.reserved[i]; y = V.reserved[i + 4]; for (j = x - 3; j <= x + 3; j++) for (k = y - 3; k <= y + 3; k++) pxl (j, k); } for (i = 0; i < 8; i++) V.reserved[i] = 0; for (i = 0; i < V.nch; i++) { /* change hole structure */ oh = (struct oldhole *) &CH[i]; x = oh -> x; y = oh -> y; net = oh -> n; CH[i].x = x; CH[i].y = y; CH[i].n = net; CH[i].pn = 0; CH[i].cpi = 0; } for (i = 0; i < V.ncp; i++) { /* scan all components */ if (CP[i].unplaced) err ("Hey: V1.23 had no unplaced components!", i, 0, 0, 0); x = CP[i].x; /* get borad position */ y = CP[i].y; r = CP[i].r; k = CP[i].ty -> np; for (j = 0, pin = CP[i].ty -> p; j < k; j++, pin++) { /* scan component pins */ xp = x + (pin -> x) * rot_m[r][0] + (pin -> y) * rot_m[r][1]; yp = y + (pin -> x) * rot_m[r][2] + (pin -> y) * rot_m[r][3]; hp = fndh (xp, yp); /* find hole */ if (!hp) err ("convt124: missing hole", xp, yp, 0, 0); hp -> pn = j; hp -> cpi = i; } } } specs() /* promt for bord specs */ { float x, y, getfloat(); x = getfloat ("Width of board in cm:",0.0,100.0,0.0); y = getfloat ("Higth of board in cm:",0.0,100.0,0.0); scalef = getfloat ("Scale factor for pin coordinates:",0.01,100.0,1.0); if ((x < 1.0) || (y < 1.0)) err ("-Use a pencil and paper for such a board", x, y, 0, 0); x *= 3.937007874; /* step by step (rounding problem) */ y *= 3.937007874; x *= rsun; y *= rsun; V.BSX = 0.5 + x; V.BSY = 0.5 + y; if ((V.BSX > xmax - 4) || (V.BSY > ymax - 4)) { printf ("Recompile me with 'xmax'>%d and 'ymax'>%d\n", V.BSX + 3, V.BSY + 3); err ("-bitmap too small", V.BSX, V.BSY, xmax - 4, ymax - 4); } color (fb, fb); /* plot frame */ plt (2, 1, V.BSX + 1, 1); plt (1, 2, 1, V.BSY + 1); plt (V.BSX + 2, 2, V.BSX + 2, V.BSY + 1); plt (2, V.BSY + 2, V.BSX + 1, V.BSY + 2); } !E!O!F!