1 /****************************************************************************
2     Copyright (C) 1987-2015 by Jeffery P. Hansen
3 
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8 
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13 
14     You should have received a copy of the GNU General Public License along
15     with this program; if not, write to the Free Software Foundation, Inc.,
16     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 ****************************************************************************/
18 #ifndef __wires_h
19 #define __wires_h
20 
21 #define NUMPOS 39
22 
23 /* Split node directions */
24 #define IN_DIR 42
25 #define OUT_DIR 7
26 
27 /* wire_makestraight conditions */
28 #define OK 42
29 #define IMMOBILE 0
30 
31 /* Wire selction modes (These are bit masks) */
32 typedef enum {
33   UNSELECTED  = 0x0,
34 #define UNSELECTED   UNSELECTED
35   HORIZONTAL  = 0x1,
36 #define HORIZONTAL   HORIZONTAL
37   VERTICAL    = 0x2,
38 #define VERTICAL     VERTICAL
39   FULL        = 0x3,
40 #define FULL         FULL
41   NOSTRAIGHTEN = 0x4,
42 #define NOSTRAIGHTEN NOSTRAIGHTEN
43 } WireSelectMode_t;
44 
45 #define DRIVER 42
46 #define DRIVEE 0
47 #define UNKNOWN 8
48 
49 /* Hit Operations */
50 #define F_GATE 0x01
51 #define F_WIRE 0x02
52 #define F_WIREEND 0x12
53 #define F_WIRENOEND 0x22
54 
55 enum {
56   D_RIGHT = 0,
57   D_UP    = 1,
58   D_LEFT  = 2,
59   D_DOWN  = 3
60 };
61 
62 /*
63    A "GWire" is really an end point of a wire segment.  It might have been
64    more appropriate to call it a port.
65 */
66 struct wire {
67   GNet	*net;			/* Net this wire is a part of */
68   char *name;			/* Port name (if connected to a block) */
69   int nidx;			/* Index within net */
70   unsigned invert : 1;		/* Inverter at this end? */
71   unsigned xanchor : 1;		/* X coordinate is anchored */
72   unsigned yanchor : 1;		/* Y coordinate is anchored */
73   unsigned cpath : 1;		/* Is this seg. on displayed path? */
74   short orient;			/* Orientation: UP, RIGHT, DOWN, LEFT */
75   struct {
76     short num,den;		/* Offset of wire position (as a fraction) */
77   } offset;
78   char wtype;			/* DRIVER/DRIVEE tag */
79   short PadNum;			/* Pad number (computed before simulation) */
80   short WireDir;		/* Direction  (computed before simulation) */
81   GCElement *gate;		/* Gate connected to this wire end */
82   GWireNode *nodes;		/* Nodes on this wire */
83   GWire *driver;		/* Driving end of wire */
84   GWire *next;			/* Next wire in global list */
85 };
86 
87 struct wirenode {
88   int x,y;			/* Node position */
89   WireSelectMode_t stype;			/* What kind of node selection */
90   unsigned showSize : 1;	/* Show wire size on this link? */
91   unsigned mark : 1;		/* Has this node been touched */
92   unsigned isLabeled : 1;	/* Non-zero if this node is labeled */
93   unsigned labelSide : 1;	/* Side label is on (0=left/top, 1=right/bottom) */
94   unsigned offset : 8;		/* Offset of label */
95 
96   GWireNode *out;		/* Output nodes */
97   GWireNode *in;		/* Input nodes */
98   GWire *end;			/* End of wire */
99 };
100 
101 GWireNode *new_GWireNode();
102 void delete_GWireNode(GWireNode*);
103 GWire *wirenode_driver(GWireNode*);
104 GWire *wirenode_drivee(GWireNode*);
105 void GWireNode_displaySize(GWireNode *n,GNet *net);
106 GWireNode *wirenode_cutsegment(int,int,GWireNode *,GModuleDef *);
107 GWireNode *wirenode_cutcorner(GWireNode *,GModuleDef *);
108 void GWireNode_freenodelist(GWireNode *n);
109 
110 void wire_free(GWire*);
111 GWire *wire_unattach(GWire *w,GWire *wl);
112 GWire *wire_driver(GWire*);
113 GWire *wire_drivee(GWire*);
114 GWire *wire_other(GWire *w);
115 GWire *wire_append(GWire *wl,GWire *w);
116 int wire_addToGate(GCElement *g,int p,GModuleDef *mdef,int invertp);
117 int wire_new(GModuleDef *mdef,GWire **e,GWire **e2);
118 int wire_newNetSegment(GModuleDef *mdef,GNet*,GWire **e,GWire **e2);
119 GWireList *wire_unlink(GWireList *wl,GWire *w);
120 GWireList *wire_link(GWireList *wl,GWire *w);
121 char *wire_removeName(GWire*);
122 void wire_setName(GWire*,char*);
123 GWire *wire_sigroot(GWire*);
124 GWire *wire_newend(GModuleDef *M,GNet*,int doNode);
125 void wire_setNet(GWire *w,GNet *net);
126 void wire_move(GWireNode *n,int dx,int dy,WireSelectMode_t type);
127 void wire_moveto(GWireNode *n,int x,int y);
128 GWireNode *wire_iohit(int,int,GWireList*);
129 GWireNode *wire_hitanynode(int,int,GWireList*);
130 GWireNode *wire_hitall(int,int,GWireList*);
131 GWireNode *wire_hit(int,int,GWireList*);
132 GWire *wire_endhit(GWire*,GWireList*);
133 GWireNode *wire_hit_other(GWire*,GWireList*);
134 void wire_snapgate(GCElement *g,int doRedraw);
135 void GWire_snap(GWire *w);
136 GWire *wire_connect(GModuleDef *env,GWire *w1,GWire *w2);
137 GWireNode *wire_makecorner(GWireNode *n,int tx,int ty);
138 int wire_shorten(GWire*,GModuleDef*,int drawp);
139 int wire_nuke(GWire*,int,GModuleDef*);
140 void wire_drawnet(GWire *w);
141 void GWire_draw(GWire *);
142 void wire_deletezeronodes(GWireNode *n);
143 void wire_finalizeNet(GWire *w);
144 void wire_cut(int x,int y,GWireNode *n,GModuleDef *env);
145 void wire_makestraightaux(GWireNode *n,int wt,int ox,int oy,int nx,int ny);
146 void wire_setPadSpacing(GCElement *g,int p);
147 void wire_deletenode(GWireNode *n);
148 int wire_force(GWire *w,int d,int retry);
149 void wire_drawlist(GWire *w,GCElement *g);
150 GWire *wire_findClosest(GWire*,int,int);
151 void wire_addstub(EditState *es,int x,int y);
152 int GWire_pickProbePosition(GWire *w,int *x,int *y);
153 int GWire_getNetWires(GWire *w,GWire **wlist,unsigned which);
154 void GWire_updateLabels(GWire *w);
155 void GWire_insertNode(GWire*w);
156 
157 void GWireNode_getLabelPos(GWireNode *n,GNet *net,int *x,int *y,int *p);
158 
159 void joint_connect(GCElement *g,GWireNode *n);
160 void joint_make(int x,int y,GWire *w1,GWire *w2,GWire *w3,GWire *w4,EditState *es);
161 void joint_fixwires(GCElement *j,GWire *w,int retry);
162 int joint_dejoint(GWireNode *n,GModuleDef *env,int drawp);
163 void joint_addstub(GCElement *g,EditState *es);
164 
165 GCElement *join_wires(GWire *w,GWireNode *n,EditState *es);
166 void join_wirereverse(GWire *w);
167 void join_treereverse(GWire *w);
168 void join_treereverse_aux(GWire *w);
169 
170 void tap_transmute(GWire *branch,EditState *es);
171 
172 void setwiresize(EditState *es);
173 void SignalNamePos(GWireNode *n1,GWireNode *n2,int *x,int *y,int *p,int *q);
174 
175 int wireorient(GWireNode *n,int d);
176 void createwire(GModuleDef *e,GCElement *g,int p,int invertp);
177 
178 void wire_dump(EditState *es);
179 int wire_numOnPad(GWire *w);
180 
181 GWireNode *wire_nodehit(int x,int y,GWireNode *n,int includeend,int range,int corneronly);
182 GWireNode *wire_splitnode(GWireNode *n,int dir);
183 GWire *wire_endhit(GWire *w,GWireList *wl);
184 GCElement *wire_drivinggate(GWire *w);
185 void wire_rePort(GWire *w,int wx,int wy,int dir);
186 
187 #endif
188