PCB part 8 of 10
Andreas Nowatzyk
agn at cmu-cs-unh.ARPA
Tue Aug 13 10:08:37 AEST 1985
#
# type sh /usru0/agn/pcb/usenet/part8 to unpack this archive.
#
echo extracting pplow.c...
cat >pplow.c <<'!E!O!F!'
/***************************************************************\
* *
* PCB program *
* *
* Wire plowing stuff *
* *
* (c) 1985 A. Nowatzyk *
* *
\***************************************************************/
#include <stdio.h>
#include "pparm.h"
#include "pcdst.h"
extern char uc_tab[]; /* see pwork: ck_rdnb */
static char plow_s; /* plow side (either s1b or s2b) */
int pdr[8] = /* offset direction table */
{1, xmax + 1, xmax, xmax - 1, -1, -1 - xmax, -xmax, 1 - xmax};
extern int sp[9][2]; /* search pattern */
static char **seg_lst = 0; /* segment list */
static char **dead_lst = 0; /* dead segment list */
static char *first, *last; /* ptr to the ends of a segment */
static int seg_max = xmax; /* max number of points in seg */
static int seg_cnt; /* segment count */
static char *dvt; /* direction vectors for straight*/
char *straight ();
/********************************************************************\
* *
* Table 1 is to be indexed with an element of pcb: *
* bit0 (LSB): 1 -> adjacent squares are illegal for side1 (s1b) *
* bit1 : 1 -> adjacent squares are illegal for side2 (s2b) *
* bit2 : 1 -> square is illegal for side1 (s1b) *
* bit3 : 1 -> square is illegal for side2 (s2b) *
* bit4 : 1 -> square is used by side1 (s1b) *
* bit5 : 1 -> square is used by side2 (s2b) *
* *
\********************************************************************/
char drc_tab1[256] = {
0, 17, 34, 51, 3, 19, 35, 51,
3, 19, 35, 51, 3, 19, 35, 51,
3, 19, 35, 51, 3, 19, 35, 51,
3, 19, 35, 51, 3, 19, 35, 51,
0, 17, 34, 51, 3, 19, 35, 51,
3, 19, 35, 51, 3, 19, 35, 51,
3, 19, 35, 51, 3, 19, 35, 51,
3, 19, 35, 51, 3, 19, 35, 51,
0, 17, 34, 51, 3, 19, 35, 51,
3, 19, 35, 51, 3, 19, 35, 51,
3, 19, 35, 51, 3, 19, 35, 51,
3, 19, 35, 51, 3, 19, 35, 51,
0, 17, 34, 51, 3, 19, 35, 51,
3, 19, 35, 51, 3, 19, 35, 51,
3, 19, 35, 51, 3, 19, 35, 51,
3, 19, 35, 51, 3, 19, 35, 51,
0, 24, 36, 50, 0, 16, 32, 48,
0, 16, 32, 48, 0, 16, 32, 48,
3, 27, 39, 51, 3, 19, 35, 51,
3, 19, 35, 51, 3, 19, 35, 51,
0, 24, 36, 49, 0, 16, 32, 48,
0, 16, 32, 48, 0, 16, 32, 48,
3, 27, 39, 51, 3, 19, 35, 51,
3, 19, 35, 51, 3, 19, 35, 51,
0, 24, 36, 50, 0, 16, 32, 48,
0, 16, 32, 48, 0, 16, 32, 48,
3, 27, 39, 51, 3, 19, 35, 51,
3, 19, 35, 51, 3, 19, 35, 51,
0, 24, 36, 49, 0, 16, 32, 48,
0, 16, 32, 48, 0, 16, 32, 48,
3, 27, 39, 51, 3, 19, 35, 51,
3, 19, 35, 51, 3, 19, 35, 51 };
eval_s5 (p)
char *p;
/**************************************************************************\
* *
* Evaluate 5 by 5 square: *
* *
* p p p p p *
* p 3 2 1 p *
* p 4 x 0 p *
* p 5 6 7 p *
* p p p p p *
* *
* <p> points to the bitmap location x. For each adjacent squares 0-7, *
* two things are checked: a: is the square currently occupied *
* b: is it a leagal square for this trace *
* for each square the following value is computed: *
* 0: the square is empty and can be used *
* 1: the square is in use by this trace *
* 2: the square is blocked due to design rules *
* The values are combined to a table index (8 digits in a base 3 system) *
* *
\**************************************************************************/
{
register char *pp;
register int i, s;
/*******************************************************************\
* *
* Table 2 is used to convert a 8 bit vector into a base-3 number. *
* For each 1 in the bit-vector, the corresponding digit is 2. *
* *
\*******************************************************************/
static int tab2[256] = {
0, 2, 6, 8, 18, 20, 24, 26,
54, 56, 60, 62, 72, 74, 78, 80,
162, 164, 168, 170, 180, 182, 186, 188,
216, 218, 222, 224, 234, 236, 240, 242,
486, 488, 492, 494, 504, 506, 510, 512,
540, 542, 546, 548, 558, 560, 564, 566,
648, 650, 654, 656, 666, 668, 672, 674,
702, 704, 708, 710, 720, 722, 726, 728,
1458,1460,1464,1466,1476,1478,1482,1484,
1512,1514,1518,1520,1530,1532,1536,1538,
1620,1622,1626,1628,1638,1640,1644,1646,
1674,1676,1680,1682,1692,1694,1698,1700,
1944,1946,1950,1952,1962,1964,1968,1970,
1998,2000,2004,2006,2016,2018,2022,2024,
2106,2108,2112,2114,2124,2126,2130,2132,
2160,2162,2166,2168,2178,2180,2184,2186,
4374,4376,4380,4382,4392,4394,4398,4400,
4428,4430,4434,4436,4446,4448,4452,4454,
4536,4538,4542,4544,4554,4556,4560,4562,
4590,4592,4596,4598,4608,4610,4614,4616,
4860,4862,4866,4868,4878,4880,4884,4886,
4914,4916,4920,4922,4932,4934,4938,4940,
5022,5024,5028,5030,5040,5042,5046,5048,
5076,5078,5082,5084,5094,5096,5100,5102,
5832,5834,5838,5840,5850,5852,5856,5858,
5886,5888,5892,5894,5904,5906,5910,5912,
5994,5996,6000,6002,6012,6014,6018,6020,
6048,6050,6054,6056,6066,6068,6072,6074,
6318,6320,6324,6326,6336,6338,6342,6344,
6372,6374,6378,6380,6390,6392,6396,6398,
6480,6482,6486,6488,6498,6500,6504,6506,
6534,6536,6540,6542,6552,6554,6558,6560 };
/*static int ttt=0;*/
/* if (ttt){ i=(int) p - (int) pcb; test(i % xmax, i / xmax);} */
pp = p; /* for speed reasons */
s = ~plow_s;
i = 0; /* compute DR constraints */
if (drc_tab1[*(pp + 2) & 0xff] & ~s) i |= 0x83;
if (drc_tab1[*(pp + 1 * xmax + 2) & 0xff] & ~s) i |= 0x03;
if (drc_tab1[*(pp + 2 * xmax + 2) & 0xff] & ~s) i |= 0x02;
if (drc_tab1[*(pp + 2 * xmax + 1) & 0xff] & ~s) i |= 0x06;
if (drc_tab1[*(pp + 2 * xmax ) & 0xff] & ~s) i |= 0x0e;
if (drc_tab1[*(pp + 2 * xmax - 1) & 0xff] & ~s) i |= 0x0c;
if (drc_tab1[*(pp + 2 * xmax - 2) & 0xff] & ~s) i |= 0x08;
if (drc_tab1[*(pp + 1 * xmax - 2) & 0xff] & ~s) i |= 0x18;
if (drc_tab1[*(pp - 2) & 0xff] & ~s) i |= 0x38;
if (drc_tab1[*(pp - 1 * xmax - 2) & 0xff] & ~s) i |= 0x30;
if (drc_tab1[*(pp - 2 * xmax - 2) & 0xff] & ~s) i |= 0x20;
if (drc_tab1[*(pp - 2 * xmax - 1) & 0xff] & ~s) i |= 0x60;
if (drc_tab1[*(pp - 2 * xmax ) & 0xff] & ~s) i |= 0xe0;
if (drc_tab1[*(pp - 2 * xmax + 1) & 0xff] & ~s) i |= 0xc0;
if (drc_tab1[*(pp - 2 * xmax + 2) & 0xff] & ~s) i |= 0x80;
if (drc_tab1[*(pp - 1 * xmax + 2) & 0xff] & ~s) i |= 0x81;
s = ~(plow_s << 2); /* s1b <-> s2b interaction */
if (drc_tab1[*(pp + 1) & 0xff] & ~s) i |= 0x01;
if (drc_tab1[*(pp + xmax + 1) & 0xff] & ~s) i |= 0x02;
if (drc_tab1[*(pp + xmax ) & 0xff] & ~s) i |= 0x04;
if (drc_tab1[*(pp + xmax - 1) & 0xff] & ~s) i |= 0x08;
if (drc_tab1[*(pp - 1) & 0xff] & ~s) i |= 0x10;
if (drc_tab1[*(pp - xmax - 1) & 0xff] & ~s) i |= 0x20;
if (drc_tab1[*(pp - xmax ) & 0xff] & ~s) i |= 0x40;
if (drc_tab1[*(pp - xmax + 1) & 0xff] & ~s) i |= 0x80;
s = ~(plow_s << 4); /* check connection */
i = tab2[i]; /* compute connectivity */
if (drc_tab1[*(pp + 1) & 0xff] & ~s) i += 1;
if (drc_tab1[*(pp + xmax + 1) & 0xff] & ~s) i += 3;
if (drc_tab1[*(pp + xmax ) & 0xff] & ~s) i += 9;
if (drc_tab1[*(pp + xmax - 1) & 0xff] & ~s) i += 27;
if (drc_tab1[*(pp - 1) & 0xff] & ~s) i += 81;
if (drc_tab1[*(pp - xmax - 1) & 0xff] & ~s) i += 243;
if (drc_tab1[*(pp - xmax ) & 0xff] & ~s) i += 729;
if (drc_tab1[*(pp - xmax + 1) & 0xff] & ~s) i += 2187;
if (i >= 6561) { /* illegal square in use */
s = (int) pp - (int) pcb;
err ("eval_s5: DR fault encountered", s % xmax, s / xmax, i, 0);
}
return i;
}
char *fnd_seg (x, y, s)
int x, y, s;
/**************************************************************************\
* *
* find segment: *
* <x,y> must point to a part of a trace on side <s>. fnd_seg dumps *
* the pointer to all bits of that segment on the segment list. The *
* segment is terminated by either the center of a hole, the center *
* of a 'Y' or the last point of a floating end. The terminating *
* point is not added to the segment list. *
* *
* fnd_seg returns a pointer to a point on the segment if it succeeds. *
* a '0' is returned otherwise. *
* *
\**************************************************************************/
{
register int i;
if (!seg_lst) { /* alloacte segment list */
seg_lst = (char **) malloc (sizeof (char *) * seg_max);
dead_lst = (char **) malloc (sizeof (char *) * seg_max);
}
seg_cnt = 0; /* reset segment list counter */
plow_s = s;
if (!(pcb[y][x] & s))
return 0; /* no start point !! */
ckgp (x, y, s); /* prevent false starts */
if (!(pcb[y][x] & s)) { /* lost start */
for (i = 0; i < 8; i++)
if (pcb[y + dr[i][1]][x + dr[i][0]] & s) {
x += dr[i][0];
y += dr[i][1];
break;
}
if (i >= 8)
return 0; /* start on unconnected garbage */
}
for (i = 0; i <= 8; i++) /* find direction */
if (pcb[y + dr[i][1]][x + dr[i][0]] & s)
break;
if (i > 7)
return 0; /* start on single point ?? */
/* scan one way */
seg_scan (&pcb[y][x], i, s, &first);
/* scan the other way */
seg_scan (&pcb[y + dr[i][1]][x + dr[i][0]], (i + 4) & 7, s, &last);
return seg_lst[0];
}
seg_scan (p, d, s, ep)
char *p, **ep;
int d, s;
/******************************************************************\
* *
* Segment scan: *
* <p> points to the start point. <d> is the direction of the *
* next point. The next point will be added to the list if it *
* is a non-terminal point. If the next point was non-terminal, *
* it becomes the new start point. The scan is terminated *
* otherwise. Hope that this does not loop! *
* *
\******************************************************************/
{
register char *pp, *t;
register int i, j = d, k, ss = ~s;
int l;
pp = p + pdr[j];
do {
i = 0;
if (*(pp + 1) & ~ss) i++;
if (*(pp + xmax + 1) & ~ss) i++;
if (*(pp + xmax ) & ~ss) i++;
if (*(pp + xmax - 1) & ~ss) i++;
if (*(pp - 1) & ~ss) i++;
if (*(pp - xmax - 1) & ~ss) i++;
if (*(pp - xmax ) & ~ss) i++;
if (*(pp - xmax + 1) & ~ss) i++;
if (i < 2) break; /* floating terminal point */
if (i > 2) { /* might be a Y - terminal */
for (i = 5, k = 1; i <= 11; i++)
if (*(t = pp + pdr[(i + j) & 7]) & ~ss) {
if (*t & ahb && /* hole center ? */
*(t + 1) & ahb &&
*(t + xmax + 1) & ahb &&
*(t + xmax ) & ahb &&
*(t + xmax - 1) & ahb &&
*(t - 1) & ahb &&
*(t - xmax - 1) & ahb &&
*(t - xmax ) & ahb &&
*(t - xmax + 1) & ahb ) k++;
else { /* no ! */
if (*t & ahb)
color (0, plow_s);
else
color (0, selb | plow_s);
l = (int) t - (int) pcb;
ck_rdnb (l % xmax, l / xmax, plow_s);
if (*t & ~ss)
k++; /* still here! */
}
}
if (k > 2)
break; /* found a real Y - terminal */
}
if (*pp & ahb && /* hole terminal point check */
*(pp + 1) & ahb &&
*(pp + xmax + 1) & ahb &&
*(pp + xmax ) & ahb &&
*(pp + xmax - 1) & ahb &&
*(pp - 1) & ahb &&
*(pp - xmax - 1) & ahb &&
*(pp - xmax ) & ahb &&
*(pp - xmax + 1) & ahb ) break;
if (seg_cnt >= seg_max) { /* need more space */
seg_max += 10 + seg_max / 2;
free (dead_lst);
seg_lst = (char **) realloc (seg_lst, sizeof (char *) * seg_max);
dead_lst = (char **) malloc (sizeof (char *) * seg_max);
}
seg_lst[seg_cnt++] = pp; /* add point */
for (i = 6; i < 11; i++) /* find new direction */
if (*(pp + pdr[(j + i) & 7]) & ~ss)
break;
pp += pdr[j = (j + i) & 7];
} while (i < 11);
*ep = pp;
}
plow (x, y, s, d, n)
int x, y, d, n;
/***************************************************************************\
* *
* Move a wire-trace on side <s> in direction <d> by <n> units. The wire is *
* selected by a point <x,y> on it. The corresponding net will be selected. *
* *
\***************************************************************************/
{
struct nlhd *get_net (), *net;
register char *p;
register int i, j, k, l, ss = ~s;
int m, dc, d1, d2, dec_b, add, lst_key ();
static char tab3[6561] = {
/**************************************************************************\
* *
* This table is indexed by the configuration number returned by eval_s5. *
* For each of the 8 desired move directions, it has the corresonding bit *
* set to 1 if the move is legal (that is: no DR violation and no loss *
* of connectivity) *
* *
\**************************************************************************/
255,239,124,143,239, 12,255,239,124,191,255, 60,191,255, 60,191,
255, 60,241,225,112,129,225, 0,241,225,112, 62, 46, 60, 14, 46,
12, 62, 46, 60,191,255, 60,191,255, 60,191,255, 60, 48, 32, 48,
0, 32, 0, 48, 32, 48,255,239,124,143,239, 12,255,239,124,191,
255, 60,191,255, 60,191,255, 60,241,225,112,129,225, 0,241,225,
112,254,238,124,142,238, 12,254,238,124,255,255,124,255,255,124,
255,255,124,240,224,112,128,224, 0,240,224,112,254,238,124,142,
238, 12,254,238,124,255,255,124,255,255,124,255,255,124,240,224,
112,128,224, 0,240,224,112,254,238,124,142,238, 12,254,238,124,
255,255,124,255,255,124,255,255,124,240,224,112,128,224, 0,240,
224,112,199,199, 68,135,199, 4,199,199, 68,135,199, 4,135,199,
4,135,199, 4,193,193, 64,129,193, 0,193,193, 64, 6, 6, 4,
6, 6, 4, 6, 6, 4,135,199, 4,135,199, 4,135,199, 4, 0,
0, 0, 0, 0, 0, 0, 0, 0,199,199, 68,135,199, 4,199,199,
68,135,199, 4,135,199, 4,135,199, 4,193,193, 64,129,193, 0,
193,193, 64,248,232,120,136,232, 8,248,232,120,184,248, 56,184,
248, 56,184,248, 56,240,224,112,128,224, 0,240,224,112, 56, 40,
56, 8, 40, 8, 56, 40, 56,184,248, 56,184,248, 56,184,248, 56,
48, 32, 48, 0, 32, 0, 48, 32, 48,248,232,120,136,232, 8,248,
232,120,184,248, 56,184,248, 56,184,248, 56,240,224,112,128,224,
0,240,224,112,254,238,124,142,238, 12,254,238,124,255,255,124,
255,255,124,255,255,124,240,224,112,128,224, 0,240,224,112,254,
238,124,142,238, 12,254,238,124,255,255,124,255,255,124,255,255,
124,240,224,112,128,224, 0,240,224,112,254,238,124,142,238, 12,
254,238,124,255,255,124,255,255,124,255,255,124,240,224,112,128,
224, 0,240,224,112,192,192, 64,128,192, 0,192,192, 64,128,192,
0,128,192, 0,128,192, 0,192,192, 64,128,192, 0,192,192, 64,
0, 0, 0, 0, 0, 0, 0, 0, 0,128,192, 0,128,192, 0,128,
192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,192,192, 64,128,192,
0,192,192, 64,128,192, 0,128,192, 0,128,192, 0,192,192, 64,
128,192, 0,192,192, 64,255,239,124,143,239, 12,255,239,124,191,
255, 60,191,255, 60,191,255, 60,241,225,112,129,225, 0,241,225,
112, 62, 46, 60, 14, 46, 12, 62, 46, 60,191,255, 60,191,255, 60,
191,255, 60, 48, 32, 48, 0, 32, 0, 48, 32, 48,255,239,124,143,
239, 12,255,239,124,191,255, 60,191,255, 60,191,255, 60,241,225,
112,129,225, 0,241,225,112,254,238,124,142,238, 12,254,238,124,
255,255,124,255,255,124,255,255,124,240,224,112,128,224, 0,240,
224,112,254,238,124,142,238, 12,254,238,124,255,255,124,255,255,
124,255,255,124,240,224,112,128,224, 0,240,224,112,254,238,124,
142,238, 12,254,238,124,255,255,124,255,255,124,255,255,124,240,
224,112,128,224, 0,240,224,112,199,199, 68,135,199, 4,199,199,
68,135,199, 4,135,199, 4,135,199, 4,193,193, 64,129,193, 0,
193,193, 64, 6, 6, 4, 6, 6, 4, 6, 6, 4,135,199, 4,135,
199, 4,135,199, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0,199,199,
68,135,199, 4,199,199, 68,135,199, 4,135,199, 4,135,199, 4,
193,193, 64,129,193, 0,193,193, 64,251,255,120,139,255, 8,251,
255,120,187,255, 56,187,255, 56,187,255, 56,241,241,112,129,241,
0,241,241,112, 58, 62, 56, 10, 62, 8, 58, 62, 56,187,255, 56,
187,255, 56,187,255, 56, 48, 48, 48, 0, 48, 0, 48, 48, 48,251,
255,120,139,255, 8,251,255,120,187,255, 56,187,255, 56,187,255,
56,241,241,112,129,241, 0,241,241,112,255,255,124,143,255, 12,
255,255,124,255,255,124,255,255,124,255,255,124,241,241,112,129,
241, 0,241,241,112,255,255,124,143,255, 12,255,255,124,255,255,
124,255,255,124,255,255,124,241,241,112,129,241, 0,241,241,112,
255,255,124,143,255, 12,255,255,124,255,255,124,255,255,124,255,
255,124,241,241,112,129,241, 0,241,241,112,195,199, 64,131,199,
0,195,199, 64,131,199, 0,131,199, 0,131,199, 0,193,193, 64,
129,193, 0,193,193, 64, 2, 6, 0, 2, 6, 0, 2, 6, 0,131,
199, 0,131,199, 0,131,199, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0,195,199, 64,131,199, 0,195,199, 64,131,199, 0,131,199, 0,
131,199, 0,193,193, 64,129,193, 0,193,193, 64,251,255,120,139,
255, 8,251,255,120,187,255, 56,187,255, 56,187,255, 56,241,241,
112,129,241, 0,241,241,112, 58, 62, 56, 10, 62, 8, 58, 62, 56,
187,255, 56,187,255, 56,187,255, 56, 48, 48, 48, 0, 48, 0, 48,
48, 48,251,255,120,139,255, 8,251,255,120,187,255, 56,187,255,
56,187,255, 56,241,241,112,129,241, 0,241,241,112,255,255,124,
143,255, 12,255,255,124,255,255,124,255,255,124,255,255,124,241,
241,112,129,241, 0,241,241,112,255,255,124,143,255, 12,255,255,
124,255,255,124,255,255,124,255,255,124,241,241,112,129,241, 0,
241,241,112,255,255,124,143,255, 12,255,255,124,255,255,124,255,
255,124,255,255,124,241,241,112,129,241, 0,241,241,112,195,199,
64,131,199, 0,195,199, 64,131,199, 0,131,199, 0,131,199, 0,
193,193, 64,129,193, 0,193,193, 64, 2, 6, 0, 2, 6, 0, 2,
6, 0,131,199, 0,131,199, 0,131,199, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0,195,199, 64,131,199, 0,195,199, 64,131,199, 0,
131,199, 0,131,199, 0,193,193, 64,129,193, 0,193,193, 64,251,
255,120,139,255, 8,251,255,120,187,255, 56,187,255, 56,187,255,
56,241,241,112,129,241, 0,241,241,112, 58, 62, 56, 10, 62, 8,
58, 62, 56,187,255, 56,187,255, 56,187,255, 56, 48, 48, 48, 0,
48, 0, 48, 48, 48,251,255,120,139,255, 8,251,255,120,187,255,
56,187,255, 56,187,255, 56,241,241,112,129,241, 0,241,241,112,
255,255,124,143,255, 12,255,255,124,255,255,124,255,255,124,255,
255,124,241,241,112,129,241, 0,241,241,112,255,255,124,143,255,
12,255,255,124,255,255,124,255,255,124,255,255,124,241,241,112,
129,241, 0,241,241,112,255,255,124,143,255, 12,255,255,124,255,
255,124,255,255,124,255,255,124,241,241,112,129,241, 0,241,241,
112,195,199, 64,131,199, 0,195,199, 64,131,199, 0,131,199, 0,
131,199, 0,193,193, 64,129,193, 0,193,193, 64, 2, 6, 0, 2,
6, 0, 2, 6, 0,131,199, 0,131,199, 0,131,199, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0,195,199, 64,131,199, 0,195,199, 64,
131,199, 0,131,199, 0,131,199, 0,193,193, 64,129,193, 0,193,
193, 64, 31, 15, 28, 15, 15, 12, 31, 15, 28, 31, 31, 28, 31, 31,
28, 31, 31, 28, 17, 1, 16, 1, 1, 0, 17, 1, 16, 30, 14, 28,
14, 14, 12, 30, 14, 28, 31, 31, 28, 31, 31, 28, 31, 31, 28, 16,
0, 16, 0, 0, 0, 16, 0, 16, 31, 15, 28, 15, 15, 12, 31, 15,
28, 31, 31, 28, 31, 31, 28, 31, 31, 28, 17, 1, 16, 1, 1, 0,
17, 1, 16, 30, 14, 28, 14, 14, 12, 30, 14, 28, 31, 31, 28, 31,
31, 28, 31, 31, 28, 16, 0, 16, 0, 0, 0, 16, 0, 16, 30, 14,
28, 14, 14, 12, 30, 14, 28, 31, 31, 28, 31, 31, 28, 31, 31, 28,
16, 0, 16, 0, 0, 0, 16, 0, 16, 30, 14, 28, 14, 14, 12, 30,
14, 28, 31, 31, 28, 31, 31, 28, 31, 31, 28, 16, 0, 16, 0, 0,
0, 16, 0, 16, 7, 7, 4, 7, 7, 4, 7, 7, 4, 7, 7, 4,
7, 7, 4, 7, 7, 4, 1, 1, 0, 1, 1, 0, 1, 1, 0, 6,
6, 4, 6, 6, 4, 6, 6, 4, 7, 7, 4, 7, 7, 4, 7, 7,
4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 4, 7, 7, 4,
7, 7, 4, 7, 7, 4, 7, 7, 4, 7, 7, 4, 1, 1, 0, 1,
1, 0, 1, 1, 0, 24, 8, 24, 8, 8, 8, 24, 8, 24, 24, 24,
24, 24, 24, 24, 24, 24, 24, 16, 0, 16, 0, 0, 0, 16, 0, 16,
24, 8, 24, 8, 8, 8, 24, 8, 24, 24, 24, 24, 24, 24, 24, 24,
24, 24, 16, 0, 16, 0, 0, 0, 16, 0, 16, 24, 8, 24, 8, 8,
8, 24, 8, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 16, 0, 16,
0, 0, 0, 16, 0, 16, 30, 14, 28, 14, 14, 12, 30, 14, 28, 31,
31, 28, 31, 31, 28, 31, 31, 28, 16, 0, 16, 0, 0, 0, 16, 0,
16, 30, 14, 28, 14, 14, 12, 30, 14, 28, 31, 31, 28, 31, 31, 28,
31, 31, 28, 16, 0, 16, 0, 0, 0, 16, 0, 16, 30, 14, 28, 14,
14, 12, 30, 14, 28, 31, 31, 28, 31, 31, 28, 31, 31, 28, 16, 0,
16, 0, 0, 0, 16, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 31, 15, 28, 15, 15, 12, 31, 15,
28, 31, 31, 28, 31, 31, 28, 31, 31, 28, 17, 1, 16, 1, 1, 0,
17, 1, 16, 30, 14, 28, 14, 14, 12, 30, 14, 28, 31, 31, 28, 31,
31, 28, 31, 31, 28, 16, 0, 16, 0, 0, 0, 16, 0, 16, 31, 15,
28, 15, 15, 12, 31, 15, 28, 31, 31, 28, 31, 31, 28, 31, 31, 28,
17, 1, 16, 1, 1, 0, 17, 1, 16, 30, 14, 28, 14, 14, 12, 30,
14, 28, 31, 31, 28, 31, 31, 28, 31, 31, 28, 16, 0, 16, 0, 0,
0, 16, 0, 16, 30, 14, 28, 14, 14, 12, 30, 14, 28, 31, 31, 28,
31, 31, 28, 31, 31, 28, 16, 0, 16, 0, 0, 0, 16, 0, 16, 30,
14, 28, 14, 14, 12, 30, 14, 28, 31, 31, 28, 31, 31, 28, 31, 31,
28, 16, 0, 16, 0, 0, 0, 16, 0, 16, 7, 7, 4, 7, 7, 4,
7, 7, 4, 7, 7, 4, 7, 7, 4, 7, 7, 4, 1, 1, 0, 1,
1, 0, 1, 1, 0, 6, 6, 4, 6, 6, 4, 6, 6, 4, 7, 7,
4, 7, 7, 4, 7, 7, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0,
7, 7, 4, 7, 7, 4, 7, 7, 4, 7, 7, 4, 7, 7, 4, 7,
7, 4, 1, 1, 0, 1, 1, 0, 1, 1, 0,227,239, 96,131,239,
0,227,239, 96,163,255, 32,163,255, 32,163,255, 32,225,225, 96,
129,225, 0,225,225, 96, 34, 46, 32, 2, 46, 0, 34, 46, 32,163,
255, 32,163,255, 32,163,255, 32, 32, 32, 32, 0, 32, 0, 32, 32,
32,227,239, 96,131,239, 0,227,239, 96,163,255, 32,163,255, 32,
163,255, 32,225,225, 96,129,225, 0,225,225, 96,226,238, 96,130,
238, 0,226,238, 96,227,255, 96,227,255, 96,227,255, 96,224,224,
96,128,224, 0,224,224, 96,226,238, 96,130,238, 0,226,238, 96,
227,255, 96,227,255, 96,227,255, 96,224,224, 96,128,224, 0,224,
224, 96,226,238, 96,130,238, 0,226,238, 96,227,255, 96,227,255,
96,227,255, 96,224,224, 96,128,224, 0,224,224, 96,195,199, 64,
131,199, 0,195,199, 64,131,199, 0,131,199, 0,131,199, 0,193,
193, 64,129,193, 0,193,193, 64, 2, 6, 0, 2, 6, 0, 2, 6,
0,131,199, 0,131,199, 0,131,199, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0,195,199, 64,131,199, 0,195,199, 64,131,199, 0,131,
199, 0,131,199, 0,193,193, 64,129,193, 0,193,193, 64,224,232,
96,128,232, 0,224,232, 96,160,248, 32,160,248, 32,160,248, 32,
224,224, 96,128,224, 0,224,224, 96, 32, 40, 32, 0, 40, 0, 32,
40, 32,160,248, 32,160,248, 32,160,248, 32, 32, 32, 32, 0, 32,
0, 32, 32, 32,224,232, 96,128,232, 0,224,232, 96,160,248, 32,
160,248, 32,160,248, 32,224,224, 96,128,224, 0,224,224, 96,226,
238, 96,130,238, 0,226,238, 96,227,255, 96,227,255, 96,227,255,
96,224,224, 96,128,224, 0,224,224, 96,226,238, 96,130,238, 0,
226,238, 96,227,255, 96,227,255, 96,227,255, 96,224,224, 96,128,
224, 0,224,224, 96,226,238, 96,130,238, 0,226,238, 96,227,255,
96,227,255, 96,227,255, 96,224,224, 96,128,224, 0,224,224, 96,
192,192, 64,128,192, 0,192,192, 64,128,192, 0,128,192, 0,128,
192, 0,192,192, 64,128,192, 0,192,192, 64, 0, 0, 0, 0, 0,
0, 0, 0, 0,128,192, 0,128,192, 0,128,192, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,192,192, 64,128,192, 0,192,192, 64,128,
192, 0,128,192, 0,128,192, 0,192,192, 64,128,192, 0,192,192,
64,227,239, 96,131,239, 0,227,239, 96,163,255, 32,163,255, 32,
163,255, 32,225,225, 96,129,225, 0,225,225, 96, 34, 46, 32, 2,
46, 0, 34, 46, 32,163,255, 32,163,255, 32,163,255, 32, 32, 32,
32, 0, 32, 0, 32, 32, 32,227,239, 96,131,239, 0,227,239, 96,
163,255, 32,163,255, 32,163,255, 32,225,225, 96,129,225, 0,225,
225, 96,226,238, 96,130,238, 0,226,238, 96,227,255, 96,227,255,
96,227,255, 96,224,224, 96,128,224, 0,224,224, 96,226,238, 96,
130,238, 0,226,238, 96,227,255, 96,227,255, 96,227,255, 96,224,
224, 96,128,224, 0,224,224, 96,226,238, 96,130,238, 0,226,238,
96,227,255, 96,227,255, 96,227,255, 96,224,224, 96,128,224, 0,
224,224, 96,195,199, 64,131,199, 0,195,199, 64,131,199, 0,131,
199, 0,131,199, 0,193,193, 64,129,193, 0,193,193, 64, 2, 6,
0, 2, 6, 0, 2, 6, 0,131,199, 0,131,199, 0,131,199, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0,195,199, 64,131,199, 0,195,
199, 64,131,199, 0,131,199, 0,131,199, 0,193,193, 64,129,193,
0,193,193, 64,251,255,120,139,255, 8,251,255,120,187,255, 56,
187,255, 56,187,255, 56,241,241,112,129,241, 0,241,241,112, 58,
62, 56, 10, 62, 8, 58, 62, 56,187,255, 56,187,255, 56,187,255,
56, 48, 48, 48, 0, 48, 0, 48, 48, 48,251,255,120,139,255, 8,
251,255,120,187,255, 56,187,255, 56,187,255, 56,241,241,112,129,
241, 0,241,241,112,255,255,124,143,255, 12,255,255,124,255,255,
124,255,255,124,255,255,124,241,241,112,129,241, 0,241,241,112,
255,255,124,143,255, 12,255,255,124,255,255,124,255,255,124,255,
255,124,241,241,112,129,241, 0,241,241,112,255,255,124,143,255,
12,255,255,124,255,255,124,255,255,124,255,255,124,241,241,112,
129,241, 0,241,241,112,195,199, 64,131,199, 0,195,199, 64,131,
199, 0,131,199, 0,131,199, 0,193,193, 64,129,193, 0,193,193,
64, 2, 6, 0, 2, 6, 0, 2, 6, 0,131,199, 0,131,199, 0,
131,199, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,195,199, 64,131,
199, 0,195,199, 64,131,199, 0,131,199, 0,131,199, 0,193,193,
64,129,193, 0,193,193, 64,251,255,120,139,255, 8,251,255,120,
187,255, 56,187,255, 56,187,255, 56,241,241,112,129,241, 0,241,
241,112, 58, 62, 56, 10, 62, 8, 58, 62, 56,187,255, 56,187,255,
56,187,255, 56, 48, 48, 48, 0, 48, 0, 48, 48, 48,251,255,120,
139,255, 8,251,255,120,187,255, 56,187,255, 56,187,255, 56,241,
241,112,129,241, 0,241,241,112,255,255,124,143,255, 12,255,255,
124,255,255,124,255,255,124,255,255,124,241,241,112,129,241, 0,
241,241,112,255,255,124,143,255, 12,255,255,124,255,255,124,255,
255,124,255,255,124,241,241,112,129,241, 0,241,241,112,255,255,
124,143,255, 12,255,255,124,255,255,124,255,255,124,255,255,124,
241,241,112,129,241, 0,241,241,112,195,199, 64,131,199, 0,195,
199, 64,131,199, 0,131,199, 0,131,199, 0,193,193, 64,129,193,
0,193,193, 64, 2, 6, 0, 2, 6, 0, 2, 6, 0,131,199, 0,
131,199, 0,131,199, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,195,
199, 64,131,199, 0,195,199, 64,131,199, 0,131,199, 0,131,199,
0,193,193, 64,129,193, 0,193,193, 64,251,255,120,139,255, 8,
251,255,120,187,255, 56,187,255, 56,187,255, 56,241,241,112,129,
241, 0,241,241,112, 58, 62, 56, 10, 62, 8, 58, 62, 56,187,255,
56,187,255, 56,187,255, 56, 48, 48, 48, 0, 48, 0, 48, 48, 48,
251,255,120,139,255, 8,251,255,120,187,255, 56,187,255, 56,187,
255, 56,241,241,112,129,241, 0,241,241,112,255,255,124,143,255,
12,255,255,124,255,255,124,255,255,124,255,255,124,241,241,112,
129,241, 0,241,241,112,255,255,124,143,255, 12,255,255,124,255,
255,124,255,255,124,255,255,124,241,241,112,129,241, 0,241,241,
112,255,255,124,143,255, 12,255,255,124,255,255,124,255,255,124,
255,255,124,241,241,112,129,241, 0,241,241,112,195,199, 64,131,
199, 0,195,199, 64,131,199, 0,131,199, 0,131,199, 0,193,193,
64,129,193, 0,193,193, 64, 2, 6, 0, 2, 6, 0, 2, 6, 0,
131,199, 0,131,199, 0,131,199, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0,195,199, 64,131,199, 0,195,199, 64,131,199, 0,131,199,
0,131,199, 0,193,193, 64,129,193, 0,193,193, 64, 3, 15, 0,
3, 15, 0, 3, 15, 0, 3, 31, 0, 3, 31, 0, 3, 31, 0, 1,
1, 0, 1, 1, 0, 1, 1, 0, 2, 14, 0, 2, 14, 0, 2, 14,
0, 3, 31, 0, 3, 31, 0, 3, 31, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 3, 15, 0, 3, 15, 0, 3, 15, 0, 3, 31, 0, 3,
31, 0, 3, 31, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 2, 14,
0, 2, 14, 0, 2, 14, 0, 3, 31, 0, 3, 31, 0, 3, 31, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 14, 0, 2, 14, 0, 2,
14, 0, 3, 31, 0, 3, 31, 0, 3, 31, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 2, 14, 0, 2, 14, 0, 2, 14, 0, 3, 31, 0,
3, 31, 0, 3, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
7, 0, 3, 7, 0, 3, 7, 0, 3, 7, 0, 3, 7, 0, 3, 7,
0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 2, 6, 0, 2, 6, 0,
2, 6, 0, 3, 7, 0, 3, 7, 0, 3, 7, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 3, 7, 0, 3, 7, 0, 3, 7, 0, 3, 7,
0, 3, 7, 0, 3, 7, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0,
0, 8, 0, 0, 8, 0, 0, 8, 0, 0, 24, 0, 0, 24, 0, 0,
24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 8,
0, 0, 8, 0, 0, 24, 0, 0, 24, 0, 0, 24, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 8, 0, 0, 8, 0, 0,
24, 0, 0, 24, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 2, 14, 0, 2, 14, 0, 2, 14, 0, 3, 31, 0, 3, 31, 0,
3, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 14, 0, 2,
14, 0, 2, 14, 0, 3, 31, 0, 3, 31, 0, 3, 31, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 2, 14, 0, 2, 14, 0, 2, 14, 0,
3, 31, 0, 3, 31, 0, 3, 31, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 3, 15, 0, 3, 15, 0, 3, 15, 0, 3, 31, 0, 3,
31, 0, 3, 31, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 2, 14,
0, 2, 14, 0, 2, 14, 0, 3, 31, 0, 3, 31, 0, 3, 31, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 15, 0, 3, 15, 0, 3,
15, 0, 3, 31, 0, 3, 31, 0, 3, 31, 0, 1, 1, 0, 1, 1,
0, 1, 1, 0, 2, 14, 0, 2, 14, 0, 2, 14, 0, 3, 31, 0,
3, 31, 0, 3, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2,
14, 0, 2, 14, 0, 2, 14, 0, 3, 31, 0, 3, 31, 0, 3, 31,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 14, 0, 2, 14, 0,
2, 14, 0, 3, 31, 0, 3, 31, 0, 3, 31, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 3, 7, 0, 3, 7, 0, 3, 7, 0, 3, 7,
0, 3, 7, 0, 3, 7, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0,
2, 6, 0, 2, 6, 0, 2, 6, 0, 3, 7, 0, 3, 7, 0, 3,
7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 7, 0, 3, 7,
0, 3, 7, 0, 3, 7, 0, 3, 7, 0, 3, 7, 0, 1, 1, 0,
1, 1, 0, 1, 1, 0,255,239,124,143,239, 12,255,239,124,191,
255, 60,191,255, 60,191,255, 60,241,225,112,129,225, 0,241,225,
112, 62, 46, 60, 14, 46, 12, 62, 46, 60,191,255, 60,191,255, 60,
191,255, 60, 48, 32, 48, 0, 32, 0, 48, 32, 48,255,239,124,143,
239, 12,255,239,124,191,255, 60,191,255, 60,191,255, 60,241,225,
112,129,225, 0,241,225,112,254,238,124,142,238, 12,254,238,124,
255,255,124,255,255,124,255,255,124,240,224,112,128,224, 0,240,
224,112,254,238,124,142,238, 12,254,238,124,255,255,124,255,255,
124,255,255,124,240,224,112,128,224, 0,240,224,112,254,238,124,
142,238, 12,254,238,124,255,255,124,255,255,124,255,255,124,240,
224,112,128,224, 0,240,224,112,199,199, 68,135,199, 4,199,199,
68,135,199, 4,135,199, 4,135,199, 4,193,193, 64,129,193, 0,
193,193, 64, 6, 6, 4, 6, 6, 4, 6, 6, 4,135,199, 4,135,
199, 4,135,199, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0,199,199,
68,135,199, 4,199,199, 68,135,199, 4,135,199, 4,135,199, 4,
193,193, 64,129,193, 0,193,193, 64,248,232,120,136,232, 8,248,
232,120,184,248, 56,184,248, 56,184,248, 56,240,224,112,128,224,
0,240,224,112, 56, 40, 56, 8, 40, 8, 56, 40, 56,184,248, 56,
184,248, 56,184,248, 56, 48, 32, 48, 0, 32, 0, 48, 32, 48,248,
232,120,136,232, 8,248,232,120,184,248, 56,184,248, 56,184,248,
56,240,224,112,128,224, 0,240,224,112,254,238,124,142,238, 12,
254,238,124,255,255,124,255,255,124,255,255,124,240,224,112,128,
224, 0,240,224,112,254,238,124,142,238, 12,254,238,124,255,255,
124,255,255,124,255,255,124,240,224,112,128,224, 0,240,224,112,
254,238,124,142,238, 12,254,238,124,255,255,124,255,255,124,255,
255,124,240,224,112,128,224, 0,240,224,112,192,192, 64,128,192,
0,192,192, 64,128,192, 0,128,192, 0,128,192, 0,192,192, 64,
128,192, 0,192,192, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,
192, 0,128,192, 0,128,192, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0,192,192, 64,128,192, 0,192,192, 64,128,192, 0,128,192, 0,
128,192, 0,192,192, 64,128,192, 0,192,192, 64,255,239,124,143,
239, 12,255,239,124,191,255, 60,191,255, 60,191,255, 60,241,225,
112,129,225, 0,241,225,112, 62, 46, 60, 14, 46, 12, 62, 46, 60,
191,255, 60,191,255, 60,191,255, 60, 48, 32, 48, 0, 32, 0, 48,
32, 48,255,239,124,143,239, 12,255,239,124,191,255, 60,191,255,
60,191,255, 60,241,225,112,129,225, 0,241,225,112,254,238,124,
142,238, 12,254,238,124,255,255,124,255,255,124,255,255,124,240,
224,112,128,224, 0,240,224,112,254,238,124,142,238, 12,254,238,
124,255,255,124,255,255,124,255,255,124,240,224,112,128,224, 0,
240,224,112,254,238,124,142,238, 12,254,238,124,255,255,124,255,
255,124,255,255,124,240,224,112,128,224, 0,240,224,112,199,199,
68,135,199, 4,199,199, 68,135,199, 4,135,199, 4,135,199, 4,
193,193, 64,129,193, 0,193,193, 64, 6, 6, 4, 6, 6, 4, 6,
6, 4,135,199, 4,135,199, 4,135,199, 4, 0, 0, 0, 0, 0,
0, 0, 0, 0,199,199, 68,135,199, 4,199,199, 68,135,199, 4,
135,199, 4,135,199, 4,193,193, 64,129,193, 0,193,193, 64,251,
255,120,139,255, 8,251,255,120,187,255, 56,187,255, 56,187,255,
56,241,241,112,129,241, 0,241,241,112, 58, 62, 56, 10, 62, 8,
58, 62, 56,187,255, 56,187,255, 56,187,255, 56, 48, 48, 48, 0,
48, 0, 48, 48, 48,251,255,120,139,255, 8,251,255,120,187,255,
56,187,255, 56,187,255, 56,241,241,112,129,241, 0,241,241,112,
255,255,124,143,255, 12,255,255,124,255,255,124,255,255,124,255,
255,124,241,241,112,129,241, 0,241,241,112,255,255,124,143,255,
12,255,255,124,255,255,124,255,255,124,255,255,124,241,241,112,
129,241, 0,241,241,112,255,255,124,143,255, 12,255,255,124,255,
255,124,255,255,124,255,255,124,241,241,112,129,241, 0,241,241,
112,195,199, 64,131,199, 0,195,199, 64,131,199, 0,131,199, 0,
131,199, 0,193,193, 64,129,193, 0,193,193, 64, 2, 6, 0, 2,
6, 0, 2, 6, 0,131,199, 0,131,199, 0,131,199, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0,195,199, 64,131,199, 0,195,199, 64,
131,199, 0,131,199, 0,131,199, 0,193,193, 64,129,193, 0,193,
193, 64,251,255,120,139,255, 8,251,255,120,187,255, 56,187,255,
56,187,255, 56,241,241,112,129,241, 0,241,241,112, 58, 62, 56,
10, 62, 8, 58, 62, 56,187,255, 56,187,255, 56,187,255, 56, 48,
48, 48, 0, 48, 0, 48, 48, 48,251,255,120,139,255, 8,251,255,
120,187,255, 56,187,255, 56,187,255, 56,241,241,112,129,241, 0,
241,241,112,255,255,124,143,255, 12,255,255,124,255,255,124,255,
255,124,255,255,124,241,241,112,129,241, 0,241,241,112,255,255,
124,143,255, 12,255,255,124,255,255,124,255,255,124,255,255,124,
241,241,112,129,241, 0,241,241,112,255,255,124,143,255, 12,255,
255,124,255,255,124,255,255,124,255,255,124,241,241,112,129,241,
0,241,241,112,195,199, 64,131,199, 0,195,199, 64,131,199, 0,
131,199, 0,131,199, 0,193,193, 64,129,193, 0,193,193, 64, 2,
6, 0, 2, 6, 0, 2, 6, 0,131,199, 0,131,199, 0,131,199,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,195,199, 64,131,199, 0,
195,199, 64,131,199, 0,131,199, 0,131,199, 0,193,193, 64,129,
193, 0,193,193, 64,251,255,120,139,255, 8,251,255,120,187,255,
56,187,255, 56,187,255, 56,241,241,112,129,241, 0,241,241,112,
58, 62, 56, 10, 62, 8, 58, 62, 56,187,255, 56,187,255, 56,187,
255, 56, 48, 48, 48, 0, 48, 0, 48, 48, 48,251,255,120,139,255,
8,251,255,120,187,255, 56,187,255, 56,187,255, 56,241,241,112,
129,241, 0,241,241,112,255,255,124,143,255, 12,255,255,124,255,
255,124,255,255,124,255,255,124,241,241,112,129,241, 0,241,241,
112,255,255,124,143,255, 12,255,255,124,255,255,124,255,255,124,
255,255,124,241,241,112,129,241, 0,241,241,112,255,255,124,143,
255, 12,255,255,124,255,255,124,255,255,124,255,255,124,241,241,
112,129,241, 0,241,241,112,195,199, 64,131,199, 0,195,199, 64,
131,199, 0,131,199, 0,131,199, 0,193,193, 64,129,193, 0,193,
193, 64, 2, 6, 0, 2, 6, 0, 2, 6, 0,131,199, 0,131,199,
0,131,199, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,195,199, 64,
131,199, 0,195,199, 64,131,199, 0,131,199, 0,131,199, 0,193,
193, 64,129,193, 0,193,193, 64, 31, 15, 28, 15, 15, 12, 31, 15,
28, 31, 31, 28, 31, 31, 28, 31, 31, 28, 17, 1, 16, 1, 1, 0,
17, 1, 16, 30, 14, 28, 14, 14, 12, 30, 14, 28, 31, 31, 28, 31,
31, 28, 31, 31, 28, 16, 0, 16, 0, 0, 0, 16, 0, 16, 31, 15,
28, 15, 15, 12, 31, 15, 28, 31, 31, 28, 31, 31, 28, 31, 31, 28,
17, 1, 16, 1, 1, 0, 17, 1, 16, 30, 14, 28, 14, 14, 12, 30,
14, 28, 31, 31, 28, 31, 31, 28, 31, 31, 28, 16, 0, 16, 0, 0,
0, 16, 0, 16, 30, 14, 28, 14, 14, 12, 30, 14, 28, 31, 31, 28,
31, 31, 28, 31, 31, 28, 16, 0, 16, 0, 0, 0, 16, 0, 16, 30,
14, 28, 14, 14, 12, 30, 14, 28, 31, 31, 28, 31, 31, 28, 31, 31,
28, 16, 0, 16, 0, 0, 0, 16, 0, 16, 7, 7, 4, 7, 7, 4,
7, 7, 4, 7, 7, 4, 7, 7, 4, 7, 7, 4, 1, 1, 0, 1,
1, 0, 1, 1, 0, 6, 6, 4, 6, 6, 4, 6, 6, 4, 7, 7,
4, 7, 7, 4, 7, 7, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0,
7, 7, 4, 7, 7, 4, 7, 7, 4, 7, 7, 4, 7, 7, 4, 7,
7, 4, 1, 1, 0, 1, 1, 0, 1, 1, 0, 24, 8, 24, 8, 8,
8, 24, 8, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 16, 0, 16,
0, 0, 0, 16, 0, 16, 24, 8, 24, 8, 8, 8, 24, 8, 24, 24,
24, 24, 24, 24, 24, 24, 24, 24, 16, 0, 16, 0, 0, 0, 16, 0,
16, 24, 8, 24, 8, 8, 8, 24, 8, 24, 24, 24, 24, 24, 24, 24,
24, 24, 24, 16, 0, 16, 0, 0, 0, 16, 0, 16, 30, 14, 28, 14,
14, 12, 30, 14, 28, 31, 31, 28, 31, 31, 28, 31, 31, 28, 16, 0,
16, 0, 0, 0, 16, 0, 16, 30, 14, 28, 14, 14, 12, 30, 14, 28,
31, 31, 28, 31, 31, 28, 31, 31, 28, 16, 0, 16, 0, 0, 0, 16,
0, 16, 30, 14, 28, 14, 14, 12, 30, 14, 28, 31, 31, 28, 31, 31,
28, 31, 31, 28, 16, 0, 16, 0, 0, 0, 16, 0, 16, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 15,
28, 15, 15, 12, 31, 15, 28, 31, 31, 28, 31, 31, 28, 31, 31, 28,
17, 1, 16, 1, 1, 0, 17, 1, 16, 30, 14, 28, 14, 14, 12, 30,
14, 28, 31, 31, 28, 31, 31, 28, 31, 31, 28, 16, 0, 16, 0, 0,
0, 16, 0, 16, 31, 15, 28, 15, 15, 12, 31, 15, 28, 31, 31, 28,
31, 31, 28, 31, 31, 28, 17, 1, 16, 1, 1, 0, 17, 1, 16, 30,
14, 28, 14, 14, 12, 30, 14, 28, 31, 31, 28, 31, 31, 28, 31, 31,
28, 16, 0, 16, 0, 0, 0, 16, 0, 16, 30, 14, 28, 14, 14, 12,
30, 14, 28, 31, 31, 28, 31, 31, 28, 31, 31, 28, 16, 0, 16, 0,
0, 0, 16, 0, 16, 30, 14, 28, 14, 14, 12, 30, 14, 28, 31, 31,
28, 31, 31, 28, 31, 31, 28, 16, 0, 16, 0, 0, 0, 16, 0, 16,
7, 7, 4, 7, 7, 4, 7, 7, 4, 7, 7, 4, 7, 7, 4, 7,
7, 4, 1, 1, 0, 1, 1, 0, 1, 1, 0, 6, 6, 4, 6, 6,
4, 6, 6, 4, 7, 7, 4, 7, 7, 4, 7, 7, 4, 0, 0, 0,
0, 0, 0, 0, 0, 0, 7, 7, 4, 7, 7, 4, 7, 7, 4, 7,
7, 4, 7, 7, 4, 7, 7, 4, 1, 1, 0, 1, 1, 0, 1, 1,
0 };
net = get_net (x, y, s); /* find net */
if (V.cnet != net) { /* select the net */
if (V.cnet)
deseln (V.cnet);
selnet (net);
}
/* find segment to work on */
if (!fnd_seg (x, y, s) || seg_cnt <= 2) /* not worth the efford */
return;
un_display (x, y); /* un-display wire */
dec_b = 1 << d; /* decision bit */
add = (s & s1b) ? selb | s1b : selb | s2b | resb;/* add bits */
if (d & 1) { /* diagonal move */
d1 = pdr[(d + 1) & 7];
d2 = pdr[(d + 7) & 7];
for (n += n; 0 < n; n--) { /* move loop */
/*********************************************************************\
* *
* The diagonal move is kind of complicated: it needs several phases *
* 1. find points to be moved (enter them in dead-list) *
* 2. add all new points (2 for each removed points) *
* 3. remove all dead points (this may overlap with those *
* added in step 2) *
* 4. remove new points that are redundant *
* 5. update the seg_list: a) add new points *
* b) remove dead ones *
* c) remove multiples *
* *
\*********************************************************************/
dc = 0; /* dead point counter */
for (i = 0; i < seg_cnt; i++) /** STEP 1 **/
if (dec_b & tab3[eval_s5 (seg_lst[i])]) /* move it */
dead_lst[dc++] = seg_lst[i];
if (seg_cnt + 2 * dc > seg_max) { /* add space */
seg_max = 10 + 2 * dc;
seg_lst = (char **) realloc (seg_lst,
sizeof (char *) * seg_max);
dead_lst = (char **) realloc (dead_lst,
sizeof (char *) * seg_max);
}
for (i = 0, j = seg_cnt; i < dc; i++) { /** STEP 2 **/
p = dead_lst[i];
*(seg_lst[j++] = p + d1) |= add; /* add wire (5a) */
*(seg_lst[j++] = p + d2) |= add;
}
for (i = 0; i < dc; i++) { /** STEP 3 **/
p = dead_lst[i];
if (!(*p & ahb && *(p + 1) & ahb && *(p - 1) & ahb &&
*(p + xmax) & ahb && *(p - xmax) & ahb)) {
*p &= ~add; /* remove wire */
if (*p & ahb)
*p |= selb;
}
}
do {
m = 0;
for (k = i = seg_cnt; i < j; i++) { /** STEP 4 **/
p = seg_lst[i];
if (*p & ~ss) {
/*l = (int) p - (int) pcb;
test(l%xmax,l/xmax);*/
l = 0;
if (*(p + 1) & ~ss) l |= 0x01;
if (*(p + xmax + 1) & ~ss) l |= 0x02;
if (*(p + xmax ) & ~ss) l |= 0x04;
if (*(p + xmax - 1) & ~ss) l |= 0x08;
if (*(p - 1) & ~ss) l |= 0x10;
if (*(p - xmax - 1) & ~ss) l |= 0x20;
if (*(p - xmax ) & ~ss) l |= 0x40;
if (*(p - xmax + 1) & ~ss) l |= 0x80;
if (uc_tab[l] && !(*p & ahb &&
*(p + 1) & ahb && *(p - 1) & ahb &&
*(p + xmax) & ahb && *(p - xmax) & ahb)){
/* useless: remove */
*p &= ~add;
m = 1;
if (*p & ahb)
*p |= selb;}
else
seg_lst[k++] = p;
}
}
j = k;
} while (m); /* I know, this is horrible */
seg_cnt = j;
if (!dc) /* nothing moved: exit */
break;
else { /** STEP 5 **/
qsort (seg_lst, seg_cnt, sizeof (char *), lst_key);
qsort (dead_lst, dc, sizeof (char *), lst_key);
for (i = 0, k = 0, l = 0; i < j; i++) { /* rm dead (5b) */
while (k < dc && seg_lst[i] > dead_lst[k])
k++;
if (k >= dc) { /* dead list exhausted */
while (i < j) /* copy rest */
seg_lst[l++] = seg_lst[i++];
break;
}
if (seg_lst[i] < dead_lst[k]) /* alive */
seg_lst[l++] = seg_lst[i];
}
/* l has now the number of live entries */
for (i = 0, j = 1; j < l; j++) /* rm multiples (5c) */
if (seg_lst[i] != seg_lst[j])
seg_lst[++i] = seg_lst[j];
seg_cnt = i + 1;
}
}}
else {
/************************************************\
* *
* horizontal move (much simpler): *
* 1. Identify new point (add to dead_lst) *
* 2. add them *
* 3. remove old ones *
* 4. update seg_lst (just remove multiples) *
* *
\************************************************/
d1 = pdr[d];
for (; 0 < n; n--) { /* move loop */
for (j = 0, i = 0; i < seg_cnt; i++) /** STEP 1 **/
if (dec_b & tab3[eval_s5 (seg_lst[i])]) { /* move it */
p = seg_lst[i];
dead_lst[j++] = p;
seg_lst[i] = p + d1;
}
for (i = 0; i < j; i++) /** STEP 2 **/
*(dead_lst[i] + d1) |= add; /* add trace */
for (i = 0; i < j; i++) { /** STEP 3 **/
p = dead_lst[i];
if (!(*p & ahb && *(p + 1) & ahb && *(p - 1) & ahb &&
*(p + xmax) & ahb && *(p - xmax) & ahb)) {
*p &= ~add; /* remove wire */
if (*p & ahb)
*p |= selb;
}
}
if (!j) /* nothing moved: exit */
break;
else { /** STEP 4 **/
j = seg_cnt;
qsort (seg_lst, j, sizeof (char *), lst_key);
for (i = 0, k = 1; k < j; k++) /* remove multiples */
if (seg_lst[i] != seg_lst[k])
seg_lst[++i] = seg_lst[k];
seg_cnt = i + 1;
}
}
}
re_display (); /* redisplay trace */
}
lst_key (a, b) /* seg_lst sort key */
int *a, *b;
{
return *a - *b;
}
static int hole_x = 0, hole_y = 0; /* coordinate to restatrt wtrace */
un_display (x, y) /* un-display wire */
int x, y;
{
int sv_hole (), rm_line ();
wthf = sv_hole; /* save hole */
wtvf = rm_line;
color (0, selb | plow_s);
wtrace (x, y, plow_s);
}
sv_hole (x, y) /* save hole */
int x, y;
{
if (pcb[y][x] & chb) {
hole_x = x;
hole_y = y;
}
return 0;
}
rm_line (x1, y1, x2, y2) /* remove line */
int x1, y1, x2, y2;
{
if (wtsb == plow_s)
plts (x1, y1, x2, y2);
}
re_display () /* redisplay wire */
{
int rm_line (), sel_hole ();
wthf = sel_hole;
wtvf = rm_line;
color (selb | plow_s, selb | plow_s);
wtrace (hole_x, hole_y, vec);
}
sel_hole (x, y) /* (re-) select holes */
int x, y;
{
color (selb, selb);
dpin (x, y);
color (selb | plow_s, selb | plow_s);
return 0;
}
static int x_start, y_start, started; /* contex - info */
static int x_end, y_end, plen, pdir;
plow_ini (ctx) /* initialize plowing */
int ctx;
{
if (ctx != PLOW)
started = 0;
return ctx;
}
plow_src (x, y, ctx) /* source */
int x, y, ctx;
{
register int i;
if (started){ /* remove pointer */
color (0, resb);
plts (x_start, y_start, x_end, y_end);
}
for (i = 0; i < 9; i++)
if (pcb[y + sp[i][1]][x + sp[i][0]] & vec)
break;
if (i >= 9) {
started = 0;
err_msg ("No trace found");}
else {
started = 1;
x_end = x_start = x + sp[i][0];
y_end = y_start = y + sp[i][1];
plen = 0;
color (resb, resb);
point (x_start, y_start);
plow_s = pcb[y + sp[i][1]][x + sp[i][0]] & vec;
if (plow_s == vec)
plow_s = top_side;
}
return ctx;
}
plow_dst (x, y, ctx) /* plow destination */
int x, y, ctx;
{
register int i, j;
double atan2 ();
if (!started)
err_msg ("designate source first");
else {
color (0, resb);
plts (x_start, y_start, x_end, y_end);
pdir = (atan2 ((y - y_start) * 0.5, (x - x_start) * 0.5)
+ 6.676885) * 1.27324;
pdir = pdir % 8; /* chose a direction */
j = abs (y - y_start);
i = abs (x - x_start);
if (pdir & 1)
plen = (j < i) ? j : i; /* run min. length (diag) */
else
plen = dr[pdir][0] ? i : j; /* run axis projection */
x_end = x_start + plen * dr[pdir][0];
y_end = y_start + plen * dr[pdir][1];
color (resb, resb);
plts (x_start, y_start, x_end, y_end);
}
return ctx;
}
/*ARGSUSED*/
exc_plow (x, y, ctx) /* execute plow */
int x, y, ctx;
{
if (!started)
err_msg ("Nothing to move");
else {
color (0, resb);
plts (x_start, y_start, x_end, y_end);
if (plen)
plow (x_start, y_start, plow_s, pdir, plen);
else
straight (x_start, y_start, plow_s);
started = 0;
}
return START;
}
adj_sort (src, dst, n)
int n;
char *src, *dst;
/********************************************************************\
* *
* Adjacenty sort: *
* *
* "seg_lst" is the pointer to a array of <n> pcb-pointer that are *
* supposed to point to the pixel of a trace that starts at <src>. *
* "dvt" points to an char array (of at least <n> elements, that *
* will receive the direction vectors to get from <src> to <dst>. *
* <src> and <dst> must not be adjacent. Error conditions exists if *
* there is no path from <src> to <dst> (loss of connectivity). *
* *
* "seg_lst" will receive the points of the shortest path. *
* *
* Side-effect: dead_lst is used for scratch and must be > <n> *
* *
* Note: the dvt-vector has n+1 elsements: the last is pointing *
* to the destination. *
* *
\********************************************************************/
{
int lst_key ();
register char *p;
register int h, i, j, k, l;
int m, add, suc;
char *s;
static int *nxt = 0, nxt_max;
/*
static char ttt = 0;
*/
if (!nxt) { /* need to next pointers */
nxt_max = seg_max;
nxt = (int *) malloc (sizeof (int) * nxt_max);}
else if (nxt_max < n) { /* need to add space */
nxt_max = 10 + n;
free (nxt);
nxt = (int *) malloc (sizeof (int) * nxt_max);
}
qsort (seg_lst, n, sizeof (char *), lst_key); /* sort pointer */
for (i = 0, j = 0; j < n; j++) { /* remove multiples */
p = seg_lst[j];
if ((!i || seg_lst[i - 1] != p) && p != src && p != dst) {
dvt[i] = 1;
seg_lst[i++] = p;
}
}
n = i; /* update length */
add = (plow_s & s1b) ? selb | s1b : selb | s2b | resb;
dead_lst[0] = src; /* enter start point */
nxt[0] = 0; /* terminate back pointer chain */
for (m = 0, i = 1; m < i;m++) { /* main loop */
s = dead_lst[m]; /* get point to work on */
/*
if(ttt){s_test(((int)s-(int)pcb)%xmax,((int)s-(int)pcb)/xmax,
((int)dst-(int)pcb)%xmax,((int)dst-(int)pcb)/xmax,"DST");
getchar();}
*/
suc = 1; /* successor test */
for (j = 0; j < 8; j++) { /* find new direction */
p = s + pdr[j]; /* pointer to candidate */
if (!(*p & plow_s)) /* skip hyperspace */
continue;
if (p == dst)
break; /* done !!!!!! */
l = 0; /* do a binary search for p */
h = n - 1;
while (l <= h) {
k = (l + h) >> 1;
if (p > seg_lst[k]) {
l = k + 1;
continue; }
if (p < seg_lst[k]) {
h = k - 1;
continue; }
break; /* found it! */
}
if (l <= h && dvt[k]) { /* found it: k */
/*
if(ttt)
printf("found: i=%d x=%3d y=%3d\n",i,
((int)p-(int)pcb)%xmax,((int)p-(int)pcb)/xmax);
*/
suc = 0;
dvt[k] = 0;
nxt[i] = ((4 + j) & 7) + (m << 3);
dead_lst[i++] = p;
}
}
if (j < 8) /* Found the shortest path */
break;
if (suc) { /* need to eat unrelated trace */
/************************************************************************\
* *
* This is a rare case: during shortening, the connectivity of the new *
* path becomes dependent on a piece of unrelated trace of the same *
* net. The O(n*n) approach to cycle avoidence is ok because it happens *
* rarely! *
* *
\************************************************************************/
for (j = 0; j < 8; j++)
if (*(p = s + pdr[j]) & plow_s && p != src) {
for (k = 0; k < i; k++)
if (dead_lst[k] == p)
break;
if (k >= i) { /* found a new point */
if (i >= nxt_max) { /* shit: need more space */
nxt_max = seg_max + 10 + seg_max / 2;
seg_max = nxt_max;
dead_lst = (char **) realloc (dead_lst,
sizeof (char *) * seg_max);
seg_lst = (char **) realloc (seg_lst,
sizeof (char *) * seg_max);
nxt = (int *) realloc (nxt,
sizeof (int) * seg_max);
dvt = (char *) realloc (dvt,
sizeof (char) * seg_max);
}
/*
if(ttt)
printf("eat (%d,%d): i=%d m=%d\n",((int)p-(int)pcb)%xmax,((int)p-(int)pcb)/xmax,i,m);
*/
nxt[i] = ((4 + j) & 7) + (m << 3);
dead_lst[i++] = p;
}
}
}
}
if (i <= m)
err ("adj_sort: loss of connectivity", i, m,
((int) s - (int) pcb) % xmax, ((int) s - (int) pcb) / xmax);
dvt[0] = (j + 4) & 7; /* get direction vectors */
for (i = 1; m; m = nxt[m] >> 3) {
*dead_lst[m] |= mrkb; /* mark trace to avoid delete */
dvt[i++] = nxt[m] & 7;
}
n = --i; /* number of points in new trace */
for (j = 0, k = 0, l = ~plow_s, i = ~mrkb; j < n; j++) {
p = seg_lst[j]; /* remove unreached points */
if (*p & ~i) /* point in use */
continue;
h = 0; /* check connectivity */
if (*(p + 1) & ~l) h |= 0x01;
if (*(p + xmax + 1) & ~l) h |= 0x02;
if (*(p + xmax ) & ~l) h |= 0x04;
if (*(p + xmax - 1) & ~l) h |= 0x08;
if (*(p - 1) & ~l) h |= 0x10;
if (*(p - xmax - 1) & ~l) h |= 0x20;
if (*(p - xmax ) & ~l) h |= 0x40;
if (*(p - xmax + 1) & ~l) h |= 0x80;
if (*p & ahb) {
if (*(p - 1) & ahb && *(p + 1) & ahb &&
*(p + xmax) & ahb && *(p - xmax) & ahb)
continue; /* skip holes */
if (uc_tab[h]) {
*p &= ~add; /* delete point */
*p |= selb;}
else
seg_lst[k++] = p;}
else {
if (uc_tab[h])
*p &= ~add; /* delete point */
else
seg_lst[k++] = p;
}
}
for (i = k + 1; k && k < i;) /* make sure that all are gone */
for (j = 0, i = k, k = 0; j < i; j++) {
p = seg_lst[j];
h = 0; /* check connectivity */
if (*(p + 1) & ~l) h |= 0x01;
if (*(p + xmax + 1) & ~l) h |= 0x02;
if (*(p + xmax ) & ~l) h |= 0x04;
if (*(p + xmax - 1) & ~l) h |= 0x08;
if (*(p - 1) & ~l) h |= 0x10;
if (*(p - xmax - 1) & ~l) h |= 0x20;
if (*(p - xmax ) & ~l) h |= 0x40;
if (*(p - xmax + 1) & ~l) h |= 0x80;
if (uc_tab[h]) { /* delete point */
if (*p & ahb) {
*p &= ~add;
*p |= selb;}
else
*p &= ~add;}
else
seg_lst[k++] = p;
}
for (p = dst, j = n, i = 0, k = mrkb; i < j; i++)
*(p += pdr[dvt[i]]) &= ~k; /* remove mark bits */
return n;
}
char *straight (x, y, s)
int x, y, s;
/******************************************************************\
* *
* Try to remove unnecessary turn from a wire segment on side <s> *
* that is identified by <x,y> *
* *
\******************************************************************/
{
struct nlhd *net, *get_net ();
register int i, j, k, c1, c2;
char *t, *R_straight ();
if (!(pcb[y][x] & s)) /* no trace found */
return 0;
net = get_net (x, y, s); /* find and selevt the net */
if (!net)
err ("straight: unconnected object via wtrace from pin?", x, y, s, 0);
if (V.cnet != net) {
if (V.cnet)
deseln (V.cnet);
selnet (net);
}
/* find the segment */
if (!fnd_seg (x, y, s) || seg_cnt <= 4)
return 0; /* not worth the efford */
i = abs (x - ((int) first - (int) pcb) % xmax) +
abs (y - ((int) first - (int) pcb) / xmax);
j = abs (x - ((int) last - (int) pcb) % xmax) +
abs (y - ((int) last - (int) pcb) / xmax);
if (j > i) { /* make sure that fisrt is first */
t = first;
first = last;
last = t;
}
if (!batch)
un_display (x, y);
if (st_reroute)
return R_straight ();
dvt = (char *) malloc (sizeof (char) * seg_max);
seg_cnt = adj_sort (first, last, seg_cnt);
for (i = 0, c1 = 0, k = seg_cnt; i < k; i++)
c1 += (dvt[i] & 1) + 2; /* hv: 2 diag: 3 units */
do { /* s-loop */
c2 = c1;
s_move (last);
if (j++ & 1) { /* randomly sequence */
seg_cnt = adj_sort (last, first, seg_cnt);
s_move (first);}
else {
seg_cnt = adj_sort (first, last, seg_cnt);
s_move (last);
}
seg_cnt = adj_sort (last, first, seg_cnt);
s_move (first);
seg_cnt = adj_sort (first, last, seg_cnt);
for (i = 0, c1 = 0, k = seg_cnt; i < k; i++)
c1 += (dvt[i] & 1) + 2; /* hv: 2 diag: 3 units */
} while (c2 > c1);
t = 0;
if (seg_cnt > 3)
t = last + (pdr[dvt[0]] + pdr[dvt[1]]);
free (dvt);
if (!batch)
re_display ();
return t;
}
char *R_straight ()
/*******************************************************************\
* *
* R_straight is a sub-function of 'straight': it removes the old *
* wire and uses the router to re-insert it. *
* *
\*******************************************************************/
{
register int i, j, x, y;
int xl, yl, xh, yh;
register char *p;
xl = ((int) first - (int) pcb) % xmax; /* consider start */
yl = ((int) first - (int) pcb) / xmax;
xh = ((int) last - (int) pcb) % xmax; /* ... and end */
yh = ((int) last - (int) pcb) / xmax;
if (xl > xh) {i = xl; xl = xh; xh = i;}
if (yl > yh) {i = yl; yl = yh; yh = i;}
for (i = 0, j = (plow_s & s1b) ? selb | s1b : selb | s2b | resb;
i < seg_cnt; i++) {
p = seg_lst[i];
x = (int) p - (int) pcb; /* get maze-size */
y = x / xmax;
x = x % xmax;
if (x < xl) xl = x;
if (y < yl) yl = y;
if (x > xh) xh = x;
if (y > yh) yh = y;
if (*p & ahb) { /* erase point */
*p &= ~j;
*p |= selb;}
else
*p &= ~j;
}
i = batch;
batch = 1;
RE_route (first, last, xl - 2, yl - 2, xh + 2, yh + 2, plow_s);
batch = i;
re_display ();
return 0; /*** need to find a ptr!! ***/
}
s_move (st)
char *st;
/*******************************************************\
* *
* Scan a trace and move points if there appears to be *
* a better place for them. *
* *
\*******************************************************/
{
static char tab4[6561] ={
/********************************************************************\
* *
* Tab4 is indexed by the 5x5 configration as suplied by eval_s5: *
* MSB ----==== LSB *
* ....0ddd -> move center point in direction <ddd> (0-7) *
* ....1000 -> no move (do not change configuration) *
* ....1001 -> remove center point *
* ....else -> not used *
* *
* All other values are currently unused (the 4 MSBs are reserved *
* for an other table) *
* *
\********************************************************************/
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 2, 9, 2, 8,
2, 9, 2, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 9,
8, 8, 8, 9, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 8, 9, 2, 8, 2, 9, 8, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 8, 9, 8, 8, 8, 9, 8, 9, 9, 8, 9, 8,
8, 8, 9, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8,
9, 8, 8, 8, 9, 8, 9, 9, 8, 9, 2, 8, 2, 9, 8, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 9, 8, 8, 8, 9,
8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 2, 9,
2, 8, 2, 9, 2, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
8, 9, 8, 8, 8, 9, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 6, 9, 8, 8, 8, 9, 6, 9, 4, 8, 4, 8,
8, 8, 4, 8, 4, 9, 6, 9, 8, 8, 8, 9, 6, 9, 4, 8,
4, 8, 8, 8, 4, 8, 4, 8, 8, 8, 8, 8, 8, 8, 8, 8,
4, 8, 4, 8, 8, 8, 4, 8, 4, 9, 6, 9, 8, 8, 8, 9,
6, 9, 4, 8, 4, 8, 8, 8, 4, 8, 4, 9, 6, 9, 8, 8,
8, 9, 6, 9, 9, 8, 9, 8, 8, 8, 9, 8, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 8, 9, 8, 8, 8, 9, 8, 9, 9,
8, 9, 8, 8, 8, 9, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 8, 9, 8, 8, 8, 9, 8, 9, 9, 8, 9, 8, 8, 8,
9, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 9, 8,
8, 8, 9, 8, 9, 9, 6, 9, 8, 8, 8, 9, 6, 9, 8, 8,
8, 8, 8, 8, 8, 8, 8, 9, 6, 9, 8, 8, 8, 9, 6, 9,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 6, 9, 8, 8,
8, 9, 6, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 6, 9,
8, 8, 8, 9, 6, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 2, 9, 2, 8, 2, 9, 2, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 8, 9, 8, 8, 8, 9, 8, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 8, 9, 2, 8, 2, 9, 8, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 9, 8, 8, 8, 9,
8, 9, 9, 8, 9, 8, 8, 8, 9, 8, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 8, 9, 8, 8, 8, 9, 8, 9, 9, 8, 9,
2, 8, 2, 9, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
8, 9, 8, 8, 8, 9, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 2, 9, 2, 8, 2, 9, 2, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 8, 9, 8, 8, 8, 9, 8, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 8, 9,
9, 9, 8, 9, 8, 8, 9, 8, 8, 9, 8, 9, 9, 9, 0, 9,
8, 9, 9, 9, 4, 8, 4, 8, 8, 8, 4, 8, 4, 8, 9, 8,
8, 9, 8, 8, 9, 8, 4, 8, 4, 8, 8, 8, 4, 8, 4, 9,
9, 9, 0, 9, 8, 9, 9, 9, 8, 9, 8, 8, 9, 8, 8, 9,
8, 9, 9, 9, 0, 9, 8, 9, 9, 9, 9, 9, 9, 8, 9, 8,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8,
9, 8, 9, 9, 9, 9, 9, 9, 8, 9, 8, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 9, 8, 9, 9, 9,
9, 9, 9, 8, 9, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 8, 9, 8, 9, 9, 9, 9, 9, 9, 0, 9,
8, 9, 9, 9, 8, 9, 8, 8, 9, 8, 8, 9, 8, 9, 9, 9,
0, 9, 8, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
9, 8, 8, 9, 8, 8, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 9, 9, 9, 0, 9, 8, 9, 9, 9, 8, 9, 8, 8, 9, 8,
8, 9, 8, 9, 9, 9, 0, 9, 8, 9, 9, 9, 9, 9, 9, 8,
9, 8, 9, 9, 9, 8, 9, 8, 8, 9, 8, 8, 9, 8, 9, 9,
9, 8, 9, 8, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 9, 8, 8, 9, 8, 8, 9, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 9, 9, 9, 8, 9, 8, 9, 9, 9, 8, 9, 8, 8, 9,
8, 8, 9, 8, 9, 9, 9, 8, 9, 8, 9, 9, 9, 9, 9, 9,
8, 9, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 8, 9, 8, 9, 9, 9, 9, 9, 9, 8, 9, 8, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 9, 8,
9, 9, 9, 9, 9, 9, 8, 9, 8, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 8, 9, 8, 9, 9, 9, 9, 9,
9, 8, 9, 8, 9, 9, 9, 8, 9, 8, 8, 9, 8, 8, 9, 8,
9, 9, 9, 8, 9, 8, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 9, 8, 8, 9, 8, 8, 9, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 9, 9, 9, 8, 9, 8, 9, 9, 9, 8, 9, 8,
8, 9, 8, 8, 9, 8, 9, 9, 9, 8, 9, 8, 9, 9, 9, 9,
9, 9, 0, 9, 8, 9, 9, 9, 8, 9, 8, 8, 9, 8, 8, 9,
8, 9, 9, 9, 0, 9, 8, 9, 9, 9, 4, 8, 4, 8, 8, 8,
4, 8, 4, 8, 9, 8, 8, 9, 8, 8, 9, 8, 4, 8, 4, 8,
8, 8, 4, 8, 4, 9, 9, 9, 0, 9, 8, 9, 9, 9, 8, 9,
8, 8, 9, 8, 8, 9, 8, 9, 9, 9, 0, 9, 8, 9, 9, 9,
9, 9, 9, 8, 9, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 8, 9, 8, 9, 9, 9, 9, 9, 9, 8, 9,
8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
8, 9, 8, 9, 9, 9, 9, 9, 9, 8, 9, 8, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 9, 8, 9, 9,
9, 9, 9, 9, 0, 9, 8, 9, 9, 9, 8, 9, 8, 8, 9, 8,
8, 9, 8, 9, 9, 9, 0, 9, 8, 9, 9, 9, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 9, 8, 8, 9, 8, 8, 9, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 0, 9, 8, 9, 9, 9,
8, 9, 8, 8, 9, 8, 8, 9, 8, 9, 9, 9, 0, 9, 8, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 2, 9,
2, 8, 2, 9, 2, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
8, 9, 8, 8, 8, 9, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 8, 9, 2, 8, 2, 9, 8, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 8, 9, 8, 8, 8, 9, 8, 9, 9, 8,
9, 8, 8, 8, 9, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 8, 9, 8, 8, 8, 9, 8, 9, 9, 8, 9, 2, 8, 2, 9,
8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 9, 8, 8,
8, 9, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
2, 9, 2, 8, 2, 9, 2, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 8, 9, 8, 8, 8, 9, 8, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 8, 9, 8, 8, 8, 9, 8, 9, 4, 8,
4, 8, 8, 8, 4, 8, 4, 9, 8, 9, 8, 8, 8, 9, 8, 9,
4, 8, 4, 8, 8, 8, 4, 8, 4, 8, 8, 8, 8, 8, 8, 8,
8, 8, 4, 8, 4, 8, 8, 8, 4, 8, 4, 9, 8, 9, 8, 8,
8, 9, 8, 9, 4, 8, 4, 8, 8, 8, 4, 8, 4, 9, 8, 9,
8, 8, 8, 9, 8, 9, 9, 8, 9, 8, 8, 8, 9, 8, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 9, 8, 8, 8, 9, 8,
9, 9, 8, 9, 8, 8, 8, 9, 8, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 8, 9, 8, 8, 8, 9, 8, 9, 9, 8, 9, 8,
8, 8, 9, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8,
9, 8, 8, 8, 9, 8, 9, 9, 8, 9, 8, 8, 8, 9, 8, 9,
8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 8, 9, 8, 8, 8, 9,
8, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 8, 9,
8, 8, 8, 9, 8, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9,
8, 9, 8, 8, 8, 9, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 2, 9, 2, 8, 2, 9, 2, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 8, 9, 8, 8, 8, 9, 8, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 9, 2, 8, 2, 9,
8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 9, 8, 8,
8, 9, 8, 9, 9, 8, 9, 8, 8, 8, 9, 8, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 8, 9, 8, 8, 8, 9, 8, 9, 9,
8, 9, 2, 8, 2, 9, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 8, 9, 8, 8, 8, 9, 8, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 2, 9, 2, 8, 2, 9, 2, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 8, 9, 8, 8, 8, 9, 8, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9,
8, 9, 9, 9, 0, 9, 8, 8, 9, 8, 0, 9, 8, 9, 9, 9,
0, 9, 8, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
9, 8, 8, 9, 8, 8, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 9, 9, 9, 0, 9, 8, 9, 9, 9, 0, 9, 8, 8, 9, 8,
0, 9, 8, 9, 9, 9, 0, 9, 8, 9, 9, 9, 6, 8, 6, 8,
8, 8, 6, 8, 6, 8, 9, 8, 8, 9, 8, 8, 9, 8, 6, 8,
6, 8, 8, 8, 6, 8, 6, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 9, 8, 8, 9, 8, 8, 9, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 6, 8, 6, 8, 8, 8, 6, 8, 6, 8, 9, 8, 8, 9,
8, 8, 9, 8, 6, 8, 6, 8, 8, 8, 6, 8, 6, 9, 9, 9,
0, 9, 8, 9, 9, 9, 0, 9, 8, 8, 9, 8, 0, 9, 8, 9,
9, 9, 0, 9, 8, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 9, 8, 8, 9, 8, 8, 9, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 9, 9, 9, 0, 9, 8, 9, 9, 9, 0, 9, 8, 8,
9, 8, 0, 9, 8, 9, 9, 9, 0, 9, 8, 9, 9, 9, 6, 8,
6, 8, 8, 8, 6, 8, 6, 8, 8, 8, 8, 8, 8, 8, 8, 8,
6, 8, 6, 8, 8, 8, 6, 8, 6, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 6, 8, 6, 8, 8, 8, 6, 8, 6, 8, 8, 8,
8, 8, 8, 8, 8, 8, 6, 8, 6, 8, 8, 8, 6, 8, 6, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 8, 8, 9, 8, 8, 9,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 9, 8, 8, 9, 8, 8, 9, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9,
8, 8, 9, 8, 8, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
6, 8, 6, 8, 8, 8, 6, 8, 6, 8, 8, 8, 8, 8, 8, 8,
8, 8, 6, 8, 6, 8, 8, 8, 6, 8, 6, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 6, 8, 6, 8, 8, 8, 6, 8, 6, 8,
8, 8, 8, 8, 8, 8, 8, 8, 6, 8, 6, 8, 8, 8, 6, 8,
6, 9, 9, 9, 0, 9, 8, 9, 9, 9, 0, 9, 8, 8, 9, 8,
0, 9, 8, 9, 9, 9, 0, 9, 8, 9, 9, 9, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 9, 8, 8, 9, 8, 8, 9, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 0, 9, 8, 9, 9, 9,
0, 9, 8, 8, 9, 8, 0, 9, 8, 9, 9, 9, 0, 9, 8, 9,
9, 9, 6, 8, 6, 8, 8, 8, 6, 8, 6, 8, 9, 8, 8, 9,
8, 8, 9, 8, 6, 8, 6, 8, 8, 8, 6, 8, 6, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 9, 8, 8, 9, 8, 8, 9, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 6, 8, 6, 8, 8, 8, 6, 8,
6, 8, 9, 8, 8, 9, 8, 8, 9, 8, 6, 8, 6, 8, 8, 8,
6, 8, 6, 9, 9, 9, 0, 9, 8, 9, 9, 9, 0, 9, 8, 8,
9, 8, 0, 9, 8, 9, 9, 9, 0, 9, 8, 9, 9, 9, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 9, 8, 8, 9, 8, 8, 9, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 0, 9, 8, 9,
9, 9, 0, 9, 8, 8, 9, 8, 0, 9, 8, 9, 9, 9, 0, 9,
8, 9, 9, 9, 9, 9, 9, 8, 9, 8, 9, 9, 9, 8, 9, 8,
8, 9, 8, 8, 9, 8, 9, 9, 9, 8, 9, 8, 9, 9, 9, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 8, 8, 9, 8, 8, 9,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 8, 9, 8,
9, 9, 9, 8, 9, 8, 8, 9, 8, 8, 9, 8, 9, 9, 9, 8,
9, 8, 9, 9, 9, 9, 9, 9, 8, 9, 8, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 9, 8, 9, 9, 9,
9, 9, 9, 8, 9, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 8, 9, 8, 9, 9, 9, 9, 9, 9, 8, 9,
8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
8, 9, 8, 9, 9, 9, 9, 9, 9, 8, 9, 8, 9, 9, 9, 8,
9, 8, 8, 9, 8, 8, 9, 8, 9, 9, 9, 8, 9, 8, 9, 9,
9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 8, 8, 9, 8,
8, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 8,
9, 8, 9, 9, 9, 8, 9, 8, 8, 9, 8, 8, 9, 8, 9, 9,
9, 8, 9, 8, 9, 9, 9, 9, 9, 9, 8, 9, 8, 9, 9, 9,
8, 9, 8, 8, 9, 8, 8, 9, 8, 9, 9, 9, 8, 9, 8, 9,
9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 8, 8, 9,
8, 8, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9,
8, 9, 8, 9, 9, 9, 8, 9, 8, 8, 9, 8, 8, 9, 8, 9,
9, 9, 8, 9, 8, 9, 9, 9, 9, 9, 9, 8, 9, 8, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 9, 8,
9, 9, 9, 9, 9, 9, 8, 9, 8, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 8, 9, 8, 9, 9, 9, 9, 9,
9, 8, 9, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 8, 9, 8, 9, 9, 9, 9, 9, 9, 8, 9, 8, 9,
9, 9, 8, 9, 8, 8, 9, 8, 8, 9, 8, 9, 9, 9, 8, 9,
8, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 8,
8, 9, 8, 8, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9,
9, 9, 8, 9, 8, 9, 9, 9, 8, 9, 8, 8, 9, 8, 8, 9,
8, 9, 9, 9, 8, 9, 8, 9, 9, 9, 9, 9, 9, 8, 9, 8,
9, 9, 9, 8, 9, 8, 8, 9, 8, 8, 9, 8, 9, 9, 9, 8,
9, 8, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9,
8, 8, 9, 8, 8, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
9, 9, 9, 8, 9, 8, 9, 9, 9, 8, 9, 8, 8, 9, 8, 8,
9, 8, 9, 9, 9, 8, 9, 8, 9, 9, 9, 9, 9, 9, 8, 9,
8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
8, 9, 8, 9, 9, 9, 9, 9, 9, 8, 9, 8, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 9, 8, 9, 9,
9, 9, 9, 9, 8, 9, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 8, 9, 8, 9, 9, 9, 9, 9, 9, 8,
9, 8, 9, 9, 9, 8, 9, 8, 8, 9, 8, 8, 9, 8, 9, 9,
9, 8, 9, 8, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 9, 8, 8, 9, 8, 8, 9, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 9, 9, 9, 8, 9, 8, 9, 9, 9, 8, 9, 8, 8, 9,
8, 8, 9, 8, 9, 9, 9, 8, 9, 8, 9, 9, 9, 9, 9, 9,
0, 9, 8, 9, 9, 9, 0, 9, 8, 8, 9, 8, 0, 9, 8, 9,
9, 9, 0, 9, 8, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 9, 8, 8, 9, 8, 8, 9, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 9, 9, 9, 0, 9, 8, 9, 9, 9, 0, 9, 8, 8,
9, 8, 0, 9, 8, 9, 9, 9, 0, 9, 8, 9, 9, 9, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 9, 8, 8, 9, 8, 8, 9, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 9, 8, 8, 9, 8, 8, 9, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 8,
8, 9, 8, 8, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9,
9, 9, 0, 9, 8, 9, 9, 9, 0, 9, 8, 8, 9, 8, 0, 9,
8, 9, 9, 9, 0, 9, 8, 9, 9, 9, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 9, 8, 8, 9, 8, 8, 9, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 9, 9, 9, 0, 9, 8, 9, 9, 9, 0, 9,
8, 8, 9, 8, 0, 9, 8, 9, 9, 9, 0, 9, 8, 9, 9, 9,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 8, 8, 9, 8,
8, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 9, 8, 8, 9, 8, 8, 9, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 9, 8, 8, 9, 8, 8, 9, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 9, 9, 9, 0, 9, 8, 9, 9, 9, 0, 9, 8, 8,
9, 8, 0, 9, 8, 9, 9, 9, 0, 9, 8, 9, 9, 9, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 9, 8, 8, 9, 8, 8, 9, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 0, 9, 8, 9,
9, 9, 0, 9, 8, 8, 9, 8, 0, 9, 8, 9, 9, 9, 0, 9,
8, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 8,
8, 9, 8, 8, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 8, 8, 9, 8, 8, 9,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 9, 8, 8, 9, 8, 8, 9, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 9, 9, 9, 0, 9, 8, 9, 9, 9, 0, 9,
8, 8, 9, 8, 0, 9, 8, 9, 9, 9, 0, 9, 8, 9, 9, 9,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 8, 8, 9, 8, 8,
9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 0, 9,
8, 9, 9, 9, 0, 9, 8, 8, 9, 8, 0, 9, 8, 9, 9, 9,
0, 9, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 2, 9, 2, 8, 2, 9, 2, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 8, 9, 8, 8, 8, 9, 8, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 8, 9, 2, 8, 2, 9, 8, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 9, 8, 8, 8, 9,
8, 9, 9, 8, 9, 8, 8, 8, 9, 8, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 8, 9, 8, 8, 8, 9, 8, 9, 9, 8, 9,
2, 8, 2, 9, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
8, 9, 8, 8, 8, 9, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 2, 9, 2, 8, 2, 9, 2, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 8, 9, 8, 8, 8, 9, 8, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 6, 9, 8, 8, 8, 9,
6, 9, 4, 8, 4, 8, 8, 8, 4, 8, 4, 9, 6, 9, 8, 8,
8, 9, 6, 9, 4, 8, 4, 8, 8, 8, 4, 8, 4, 8, 8, 8,
8, 8, 8, 8, 8, 8, 4, 8, 4, 8, 8, 8, 4, 8, 4, 9,
6, 9, 8, 8, 8, 9, 6, 9, 4, 8, 4, 8, 8, 8, 4, 8,
4, 9, 6, 9, 8, 8, 8, 9, 6, 9, 9, 8, 9, 8, 8, 8,
9, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 9, 8,
8, 8, 9, 8, 9, 9, 8, 9, 8, 8, 8, 9, 8, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 8, 9, 8, 8, 8, 9, 8, 9,
9, 8, 9, 8, 8, 8, 9, 8, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 8, 9, 8, 8, 8, 9, 8, 9, 9, 6, 9, 8, 8,
8, 9, 6, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 6, 9,
8, 8, 8, 9, 6, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 9, 6, 9, 8, 8, 8, 9, 6, 9, 8, 8, 8, 8, 8, 8,
8, 8, 8, 9, 6, 9, 8, 8, 8, 9, 6, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 2, 9, 2, 8, 2, 9, 2, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 9, 8, 8, 8, 9,
8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 9,
2, 8, 2, 9, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
8, 9, 8, 8, 8, 9, 8, 9, 9, 8, 9, 8, 8, 8, 9, 8,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 9, 8, 8, 8,
9, 8, 9, 9, 8, 9, 2, 8, 2, 9, 8, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 8, 9, 8, 8, 8, 9, 8, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 2, 9, 2, 8, 2, 9,
2, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 9, 8, 8,
8, 9, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 0, 9, 8, 9, 9, 9, 8, 9, 8, 8, 9, 8, 8, 9,
8, 9, 9, 9, 0, 9, 8, 9, 9, 9, 4, 8, 4, 8, 8, 8,
4, 8, 4, 8, 9, 8, 8, 9, 8, 8, 9, 8, 4, 8, 4, 8,
8, 8, 4, 8, 4, 9, 9, 9, 0, 9, 8, 9, 9, 9, 8, 9,
8, 8, 9, 8, 8, 9, 8, 9, 9, 9, 0, 9, 8, 9, 9, 9,
9, 9, 9, 8, 9, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 8, 9, 8, 9, 9, 9, 9, 9, 9, 8, 9,
8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
8, 9, 8, 9, 9, 9, 9, 9, 9, 8, 9, 8, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 9, 8, 9, 9,
9, 9, 9, 9, 0, 9, 8, 9, 9, 9, 8, 9, 8, 8, 9, 8,
8, 9, 8, 9, 9, 9, 0, 9, 8, 9, 9, 9, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 9, 8, 8, 9, 8, 8, 9, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 0, 9, 8, 9, 9, 9,
8, 9, 8, 8, 9, 8, 8, 9, 8, 9, 9, 9, 0, 9, 8, 9,
9, 9, 9, 9, 9, 8, 9, 8, 9, 9, 9, 8, 9, 8, 8, 9,
8, 8, 9, 8, 9, 9, 9, 8, 9, 8, 9, 9, 9, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 9, 8, 8, 9, 8, 8, 9, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 8, 9, 8, 9, 9,
9, 8, 9, 8, 8, 9, 8, 8, 9, 8, 9, 9, 9, 8, 9, 8,
9, 9, 9, 9, 9, 9, 8, 9, 8, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 8, 9, 8, 9, 9, 9, 9, 9,
9, 8, 9, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 8, 9, 8, 9, 9, 9, 9, 9, 9, 8, 9, 8, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 9,
8, 9, 9, 9, 9, 9, 9, 8, 9, 8, 9, 9, 9, 8, 9, 8,
8, 9, 8, 8, 9, 8, 9, 9, 9, 8, 9, 8, 9, 9, 9, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 8, 8, 9, 8, 8, 9,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 8, 9, 8,
9, 9, 9, 8, 9, 8, 8, 9, 8, 8, 9, 8, 9, 9, 9, 8,
9, 8, 9, 9, 9, 9, 9, 9, 0, 9, 8, 9, 9, 9, 8, 9,
8, 8, 9, 8, 8, 9, 8, 9, 9, 9, 0, 9, 8, 9, 9, 9,
4, 8, 4, 8, 8, 8, 4, 8, 4, 8, 9, 8, 8, 9, 8, 8,
9, 8, 4, 8, 4, 8, 8, 8, 4, 8, 4, 9, 9, 9, 0, 9,
8, 9, 9, 9, 8, 9, 8, 8, 9, 8, 8, 9, 8, 9, 9, 9,
0, 9, 8, 9, 9, 9, 9, 9, 9, 8, 9, 8, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 9, 8, 9, 9,
9, 9, 9, 9, 8, 9, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 8, 9, 8, 9, 9, 9, 9, 9, 9, 8,
9, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 8, 9, 8, 9, 9, 9, 9, 9, 9, 0, 9, 8, 9, 9, 9,
8, 9, 8, 8, 9, 8, 8, 9, 8, 9, 9, 9, 0, 9, 8, 9,
9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 8, 8, 9,
8, 8, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9,
0, 9, 8, 9, 9, 9, 8, 9, 8, 8, 9, 8, 8, 9, 8, 9,
9, 9, 0, 9, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 2, 9, 2, 8, 2, 9, 2, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 8, 9, 8, 8, 8, 9, 8, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 9, 2, 8, 2, 9,
8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 9, 8, 8,
8, 9, 8, 9, 9, 8, 9, 8, 8, 8, 9, 8, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 8, 9, 8, 8, 8, 9, 8, 9, 9,
8, 9, 2, 8, 2, 9, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 8, 9, 8, 8, 8, 9, 8, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 2, 9, 2, 8, 2, 9, 2, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 8, 9, 8, 8, 8, 9, 8, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 9, 8, 8,
8, 9, 8, 9, 4, 8, 4, 8, 8, 8, 4, 8, 4, 9, 8, 9,
8, 8, 8, 9, 8, 9, 4, 8, 4, 8, 8, 8, 4, 8, 4, 8,
8, 8, 8, 8, 8, 8, 8, 8, 4, 8, 4, 8, 8, 8, 4, 8,
4, 9, 8, 9, 8, 8, 8, 9, 8, 9, 4, 8, 4, 8, 8, 8,
4, 8, 4, 9, 8, 9, 8, 8, 8, 9, 8, 9, 9, 8, 9, 8,
8, 8, 9, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8,
9, 8, 8, 8, 9, 8, 9, 9, 8, 9, 8, 8, 8, 9, 8, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 9, 8, 8, 8, 9,
8, 9, 9, 8, 9, 8, 8, 8, 9, 8, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 8, 9, 8, 8, 8, 9, 8, 9, 9, 8, 9,
8, 8, 8, 9, 8, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9,
8, 9, 8, 8, 8, 9, 8, 9, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 9, 8, 9, 8, 8, 8, 9, 8, 9, 8, 8, 8, 8,
8, 8, 8, 8, 8, 9, 8, 9, 8, 8, 8, 9, 8, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 2, 9, 2, 8, 2, 9,
2, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 9, 8, 8,
8, 9, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
8, 9, 2, 8, 2, 9, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 8, 9, 8, 8, 8, 9, 8, 9, 9, 8, 9, 8, 8, 8,
9, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 9, 8,
8, 8, 9, 8, 9, 9, 8, 9, 2, 8, 2, 9, 8, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 8, 9, 8, 8, 8, 9, 8, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 2, 9, 2, 8,
2, 9, 2, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 9,
8, 8, 8, 9, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9 };
static char tab5[64] = { /* origin move translation */
-1, 6, 7,-1,-1,-1, 1, 2,
2,-1, 0,-1,-1,-1,-1,-1,
3, 4,-1, 0, 1,-1,-1,-1,
-1,-1, 4,-1, 2,-1,-1,-1,
-1,-1, 5, 6,-1, 2, 3,-1,
-1,-1,-1,-1, 6,-1, 4,-1,
5,-1,-1,-1, 7, 0,-1, 4,
6,-1,-1,-1,-1,-1, 0,-1 };
register int i, j, k, lstm, add;
register char *p;
/*
static int ttt=0;
*/
lstm = 8; /* last move */
add = (plow_s & s1b) ? selb | s1b : selb | s2b | resb;
for (p = st, i = 0, k = 0; i < seg_cnt; i++) {
p += pdr[dvt[i]];
j = tab4[eval_s5(p)];
/*
if(ttt){
test(((int)p -(int)pcb)%xmax,((int)p -(int)pcb)/xmax);
printf("=====> j=%d\n",j);
getchar();}
*/
if (!(j & 8)) { /* filter */
if (lstm & 8) {
if (dvt[i] == dvt[i + 1]) j = 8;}
else {
if (tab5[lstm + (dvt[i] << 3)] == dvt[i + 1]) j = 8;
}
}
lstm = j;
if (j & 0x08) { /* either delete or unchnged */
if (j & 1 && /* remove center point */
!(*p & ahb && *(p - 1) & ahb && *(p + 1) & ahb &&
*(p - xmax) & ahb && *(p + xmax) & ahb)) {
*p &= ~add;
if (*p & ahb)
*p |= selb;}
else
seg_lst[k++] = p; /* just keep it */
} else {
*(seg_lst[k++] = p + pdr[j & 7]) |= add;
if (*p & ahb) {
if (!(*p & ahb && *(p - 1) & ahb && *(p + 1) & ahb &&
*(p - xmax) & ahb && *(p + xmax) & ahb)) {
*p &= ~add;
*p |= selb;
}}
else
*p &= ~add;
}
}
}
static char **sa_s1, **sa_s2; /* pointer to segments */
static int sa_s1c, sa_s2c; /* counters */
static int sa_1max = 1000, /* max size */
sa_2max = 1000;
static char **sal_s1, **sal_s2; /* local pointer (in a net) */
static int sal_s1c, sal_s2c; /* counter */
static int sal_1max = 100, /* max size */
sal_2max = 100;
get_seg ()
/***********************************************************************\
* *
* Get segment pointer: *
* For each net, the associated wires are scanned and a entry is made *
* for each segment (here: a piece of trace that runs on one side and *
* is terminated by holes, 'Y'-s or floating end). The 'straight' will *
* operate on these segments. *
* *
\***********************************************************************/
{
register int i;
int gs_vf(), gs_hf();
if (V.cnet) /* no selection */
deseln (V.cnet);
/* allocate space */
sa_s1 = (char **) malloc (sizeof (char *) * sa_1max);
sa_s1c = 0;
sa_s2 = (char **) malloc (sizeof (char *) * sa_2max);
sa_s2c = 0;
sal_s1 = (char **) malloc (sizeof (char *) * sal_1max);
sal_s2 = (char **) malloc (sizeof (char *) * sal_2max);
wthf = gs_hf; /* prepare wtrace */
wtvf = gs_vf;
for (i = 0; i < V.nnh; i++) /* scan all nets */
gs_scan (&NH[i]);
}
gs_hf (x, y) /* hole function */
int x, y;
{
register struct hole *hp;
struct hole *fndh();
if (pcb[y][x] & chb) {
hp = fndh (x, y);
hp -> n -> mk = 0;
}
return 0;
}
gs_vf (x1, y1, x2, y2)
int x1, y1, x2, y2;
{
register int dx, dy;
dx = x2 - x1;
dy = y2 - y1;
if (dx && dy) {
dx = (dx + 1) >> 1;
dy = (dy > 0) ? abs (dx) : -abs (dx);}
else {
dx = (dx + 1) >> 1;
dy = (dy + 1) >> 1;
}
if (wtsb == s1b) {
if (sal_s1c >= sal_1max) { /* need more space */
sal_1max += 10 + sal_1max / 2; /* add 50% */
sal_s1 = (char **) realloc (sal_s1, sizeof (char *) * sal_1max);
}
sal_s1[sal_s1c++] = &pcb[y1 + dy][x1 + dx];}
else {
if (sal_s2c >= sal_2max) { /* need more space */
sal_2max += 10 + sal_2max / 2; /* add 50% */
sal_s2 = (char **) realloc (sal_s2, sizeof (char *) * sal_2max);
}
sal_s2[sal_s2c++] = &pcb[y1 + dy][x1 + dx];
}
}
gs_scan (net)
struct nlhd *net;
/***********************************************************************\
* *
* Get segments scan: *
* the centers of all vectors that form a paricular net are collected. *
* A segment scan is done for each potential candidate, and the *
* generic segment pointer are added to sa_s1/2. *
* *
\***********************************************************************/
{
register struct nlst *p;
register int i, j, k, c1, c2;
char *t;
int lst_key();
sal_s1c = 0;
sal_s2c = 0;
for (p = net -> lp; p; p = p -> n) /* reset marks */
p -> mk = -1;
for (p = net -> lp; p; p = p -> n) /* get vector centers */
if (p -> mk) {
i = p -> c -> x;
j = p -> c -> y;
wtrace (i, j, vec);
}
if (sal_s1c) { /* process stuff on side 1 */
qsort (sal_s1, sal_s1c, sizeof (char *), lst_key);
while (sal_s1c) { /* copy generic ptr-s */
if (sa_s1c >= sa_1max) { /* need more space */
sa_1max += 10 + sa_1max / 2; /* add 50% */
sa_s1 = (char **) realloc (sa_s1, sizeof (char *) * sa_1max);
}
t = sal_s1[--sal_s1c];
if (!(*t & s1b))
continue; /* point was deleted by earlier fnd_seg */
t = fnd_seg (((int) t - (int) pcb) % xmax,
((int) t - (int) pcb) / xmax, s1b);
if (!t || seg_cnt < 4) /* not worth the efford */
continue;
sa_s1[sa_s1c++] = t;
qsort (seg_lst, seg_cnt, sizeof (char *), lst_key);
c1 = sal_s1c; /* save a few nsec */
c2 = seg_cnt;
for (i = 0, j = 0, k = 0; i < c1; i++) {
while (j < c2 && sal_s1[i] > seg_lst[j])
j++;
if (j >= c2) { /* segment list exhausted */
while (i < c1)
sal_s1[k++] = sal_s1[i++];
break;
}
if (sal_s1[i] < seg_lst[j])
sal_s1[k++] = sal_s1[i];
}
sal_s1c = k;
}
}
if (sal_s2c) { /* process stuff on side 2 */
qsort (sal_s2, sal_s2c, sizeof (char *), lst_key);
while (sal_s2c) { /* copy generic ptr-s */
if (sa_s2c >= sa_2max) { /* need more space */
sa_2max += 10 + sa_2max / 2; /* add 50% */
sa_s2 = (char **) realloc (sa_s2, sizeof (char *) * sa_2max);
}
t = sal_s2[--sal_s2c];
if (!(*t & s2b))
continue; /* point was deleted by earlier fnd_seg */
t = fnd_seg (((int) t - (int) pcb) % xmax,
((int) t - (int) pcb) / xmax, s2b);
if (!t || seg_cnt < 4)
continue; /* not worth the efford */
sa_s2[sa_s2c++] = t;
qsort (seg_lst, seg_cnt, sizeof (char *), lst_key);
c1 = sal_s2c; /* save a few nsec */
c2 = seg_cnt;
for (i = 0, j = 0, k = 0; i < c1; i++) {
while (j < c2 && sal_s2[i] > seg_lst[j])
j++;
if (j >= c2) { /* segment list exhausted */
while (i < c1)
sal_s2[k++] = sal_s2[i++];
break;
}
if (sal_s2[i] < seg_lst[j])
sal_s2[k++] = sal_s2[i];
}
sal_s2c = k;
}
}
}
straight_all () /* total pcb improver */
{
register int i;
int lst_key (), alt_key ();
Ferr_msg ("Prepare wire straightening");
st_reroute = 0; /* use move strategy for first 2 pases */
get_seg ();
printf ("Wire segments: %d on side1 %d on side2\n", sa_s1c, sa_s2c);
Ferr_msg ("Straight wires: pass 1");
for (i = 0; i < sa_s1c; i++)
sa_s1[i] = straight (((int) sa_s1[i] - (int) pcb) % xmax,
((int) sa_s1[i] - (int) pcb) / xmax, s1b);
for (i = 0; i < sa_s2c; i++)
sa_s2[i] = straight (((int) sa_s2[i] - (int) pcb) % xmax,
((int) sa_s2[i] - (int) pcb) / xmax, s2b);
Ferr_msg ("Straight wires: pass 2");
qsort (sa_s1, sa_s1c, sizeof (char *), lst_key);
qsort (sa_s2, sa_s2c, sizeof (char *), lst_key);
for (i = 0; i < sa_s1c; i++)
sa_s1[i] = straight (((int) sa_s1[i] - (int) pcb) % xmax,
((int) sa_s1[i] - (int) pcb) / xmax, s1b);
for (i = 0; i < sa_s2c; i++)
sa_s2[i] = straight (((int) sa_s2[i] - (int) pcb) % xmax,
((int) sa_s2[i] - (int) pcb) / xmax, s2b);
Ferr_msg ("Straight wires: pass 3");
st_reroute = 1; /* use re-route for last pass */
qsort (sa_s1, sa_s1c, sizeof (char *), alt_key);
qsort (sa_s2, sa_s2c, sizeof (char *), alt_key);
for (i = 0; i < sa_s1c; i++)
sa_s1[i] = straight (((int) sa_s1[i] - (int) pcb) % xmax,
((int) sa_s1[i] - (int) pcb) / xmax, s1b);
for (i = 0; i < sa_s2c; i++)
sa_s2[i] = straight (((int) sa_s2[i] - (int) pcb) % xmax,
((int) sa_s2[i] - (int) pcb) / xmax, s2b);
Ferr_msg ("Done");
save (0);
pgen_stat ();
}
alt_key (a, b) /* alternate sort key */
int *a, *b;
{
return *b - *a;
}
!E!O!F!
More information about the Comp.sources.unix
mailing list