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
19 #include "tkgate.h"
20 #include "switch.h"
21 #include "print.h"
22
23 #define CENTER_JUST (BetweenTopAndBottom|BetweenLeftAndRight)
24
25 #define DIP_OUT 0
26
27 extern int SimulatorActive;
28
29 GCElement *Dip_Make(EditState **es,GModuleDef *env,int GType,
30 int x,int y,int r,const char *Name,int noWires,const char**,int);
31
32 void Dip_Draw(GCElement *g,int md);
33 int Dip_EditProps(GCElement *g,int isLoadDialog);
34 void Dip_PSWrite(GPrint *P,GModLayout*,GCElement *g);
35 int Dip_SimHitFunc(EditState *ss,GCElement *g);
36 void Dip_SimInitFunc(EditState *es,GCElement *g,const char *path);
37
38 static iconDimensions dip_iconDims[] = {
39 {0, 0, 75, 20, 37, 10},
40 };
41 static int dip_iconBoldOffset = 21;
42
43
44 GPadLoc dip_out_loc[] = {
45 {0,10,0,10,D_DOWN},
46 {38,0,38,0,D_RIGHT},
47 {0,-11,0,-11,D_UP},
48 {-38,0,-38,0,D_LEFT},
49 };
50
51 static char *psDip[] = {
52 "%",
53 "% (v) x y r dip",
54 "%",
55 "/psdip {",
56 " dup 4 1 roll",
57 " startnorotgate",
58 " 3.5 0.5 translate",
59 " -42 -10 moveto",
60 " 34 -10 lineto",
61 " 34 10 lineto",
62 " -42 10 lineto",
63 " closepath stroke",
64 " 8 rfont",
65 " 1 -1 scale",
66 " -180 eq { 38 5 LJ } { -4 -12 CT } ifelse",
67 " 1 -1 scale",
68 " 5 rfont",
69 " -38 3 moveto (ON) show",
70 " -38 -6 moveto (OFF) show",
71 " -24 7 25 {-5 ds} for",
72 " grestore",
73 "} def",
74 0
75 };
76
77 GGateInfo gate_dip_info = {
78 GC_DIP,
79 "DIP",
80 "dip",0x0u,
81 "psdip",psDip,
82 -1,-1,
83
84 {{"d", {"gm.io",0}, {"gm.io.dip",0,0,200}, "gat_make DIP"},
85 {0}},
86
87 dip_iconDims,
88
89 1,{{"Z",OUT,8,1,dip_out_loc}},
90 {{-42,0,RJ},{-35,23,LJ},{-35,23,LJ},{-35,23,LJ}},
91 {1,0,1,0,0,1},
92
93 {0},
94
95 Dip_Make,
96 Nop_WriteCellDef,
97 Generic_Init,
98 Generic_Delete,
99 Generic_GetExtents,
100 Generic_HitDistance,
101 Dip_Draw,
102 Generic_Move,
103 SwitchDip_Copy,
104 Err_AddInput,
105 Err_AddOutput,
106 Err_AddInOut,
107 Generic_Rotate,
108 Err_RemovePort,
109 Err_ChangePin,
110 Dip_SimInitFunc,
111 Dip_SimHitFunc,
112 Dip_PSWrite,
113 Dip_EditProps,
114 SwitchDip_VerSave,
115 SwitchDip_SetProp
116 };
117
Dip_Make(EditState ** es,GModuleDef * env,int GType,int x,int y,int r,const char * Name,int noWires,const char ** options,int nOptions)118 GCElement *Dip_Make(EditState **es,GModuleDef *env,int GType,
119 int x,int y,int r,const char *Name,int noWires,const char **options,int nOptions)
120 {
121 GCElement *g;
122 const char *DefV;
123
124 if (!(g = Generic_Make(es,env,GType,x,y,r,Name,noWires,options,nOptions)))
125 return NULL;
126
127 DefV = seekOption("-value",options,nOptions);
128 if (!DefV || sscanf(DefV,"%d",&g->u.sw.dipval) != 1)
129 g->u.sw.dipval = 0;
130
131 g->u.sw.perm_dipval = g->u.sw.dipval;
132
133 g->u.sw.showNet = TkGate.circuit->showSwitchNets;
134
135 return g;
136 }
137
Dip_Draw(GCElement * g,int md)138 void Dip_Draw(GCElement *g,int md)
139 {
140 char s[STRMAX];
141 char compositeName[STRMAX];
142 int vox,voy;
143
144 mk_gate(g->xpos,g->ypos,g->typeinfo,g->orient,g->selected);
145 gate_drawWires(g,md);
146
147 SwitchDip_getCompositeName(g, compositeName);
148 if (*compositeName)
149 gate_drawgatename(g,compositeName);
150
151 if (g->wires[DIP_OUT]) {
152 unsigned mask = nmask(g->wires[DIP_OUT]->net->n_nbits);
153 unsigned dipValue;
154
155 if (tkgate_currentMode() == MM_SIMULATE)
156 dipValue = g->u.sw.dipval;
157 else
158 dipValue = g->u.sw.perm_dipval;
159
160 sprintf(s,"%x",dipValue & mask);
161
162 vox = (g->orient == 2) ? 43 : 0;
163 voy = (g->orient == 2) ? 5 : -15;
164
165 if (g->selected)
166 XSetFont(TkGate.D,TkGate.instGC,TkGate.stextbXF[TkGate.circuit->zoom_factor]->fid);
167 else
168 XSetFont(TkGate.D,TkGate.instGC,TkGate.stextXF[TkGate.circuit->zoom_factor]->fid);
169 dce_DrawString(TkGate.instGC,g->xpos+vox,g->ypos+voy,
170 CENTER_JUST,s);
171 }
172 }
173
Dip_PSWrite(GPrint * P,GModLayout * L,GCElement * g)174 void Dip_PSWrite(GPrint *P,GModLayout *L,GCElement *g)
175 {
176 Generic_PSLabels(P,g);
177
178 fprintf(P->p_f,"(%x) %d %d %d %s\n",
179 g->u.sw.perm_dipval & nmask(g->wires[DIP_OUT]->net->n_nbits),
180 g->xpos,g->ypos,-g->orient*90,g->typeinfo->psprint);
181 }
182
Dip_EditProps(GCElement * g,int isLoadDialog)183 int Dip_EditProps(GCElement *g,int isLoadDialog)
184 {
185 Tcl_Interp *tcl = TkGate.tcl;
186
187 Generic_EditProps(g,isLoadDialog);
188 if (isLoadDialog) {
189 DoTcl("set ::edgat_dip %x",g->u.sw.perm_dipval);
190 DoTcl("set ::edgat_shownet %d",g->u.sw.showNet);
191 } else {
192 const char *p;
193
194 ob_touch(g);
195
196 if ((p = Tcl_GetVar(tcl,"edgat_dip",TCL_GLOBAL_ONLY)))
197 if (sscanf(p,"%x",&g->u.sw.perm_dipval) != 1)
198 message(1,msgLookup("err.badhex"),p); /* "Illegal hex value '%s' ignored." */
199 g->u.sw.dipval = g->u.sw.perm_dipval;
200
201 if ((p = Tcl_GetVar(tcl,"edgat_shownet",TCL_GLOBAL_ONLY)))
202 sscanf(p,"%d",&g->u.sw.showNet);
203 }
204
205 return 0;
206 }
207
Dip_SimInitFunc(EditState * es,GCElement * g,const char * path)208 void Dip_SimInitFunc(EditState *es,GCElement *g,const char *path)
209 {
210 g->u.sw.dipval = g->u.sw.perm_dipval;
211 }
212
Dip_SimHitFunc(EditState * es,GCElement * g)213 int Dip_SimHitFunc(EditState *es,GCElement *g)
214 {
215 GSimSwitch *ss = SHash_find(es->smod->switches,g->ename);
216
217 DoTcl("Simulator::dipEntry %s %x %d %d",
218 ss->gname,g->u.sw.dipval,
219 ctow_x(g->xpos),ctow_y(g->ypos));
220
221 return 1;
222 }
223
init_dip()224 void init_dip()
225 {
226 Pixmap P;
227
228 P = Pixmap_registerFromFile("dip","dip.b");
229 gateinfo_1iconInit(&gate_dip_info,P,dip_iconDims,dip_iconBoldOffset);
230 RegisterGate(&gate_dip_info);
231 }
232