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 Last edit by hansen on Sat Sep 26 14:30:18 2009
19 ****************************************************************************/
20
21 #include "tkgate.h"
22 #include "print.h"
23
24 #define LED_IN 0
25
26 #define MAXDIGITS 12
27
28 #define LT_BASIC 0
29 #define LT_BAR 1
30 #define LT_HEX 2
31 #define LT_DEC 3
32 #define LT_SEG 4
33
34 static iconDimensions led_iconDims[] = {
35 {0, 0, 13, 14, 6, 7},
36 {14, 0, 14, 13, 7, 6},
37 {15, 14, 13, 14, 6, 6},
38 {0, 15, 14, 13, 6, 6},
39 };
40 static int led_iconBoldOffset = 29;
41
42 GCElement *Led_Make(EditState **,GModuleDef *,int,int,int,int,const char *,int,const char**,int);
43 void Led_GetExtents(GCElement *g,TargetDev_e,int *minx,int *miny,int *maxx,int *maxy,int *bd);
44 void Led_Draw(GCElement *g,int md);
45 void Led_VerSave(FILE*,GCElement*);
46 void Led_SetProp(GCElement*,const char*,const void*);
47 int Led_EditProps(GCElement *g,int isLoadDialog);
48 void Led_PSWrite(GPrint *P,GModLayout*,GCElement *g);
49 GCElement *Led_Copy(GModuleDef *M,GCElement *g,int x,int y,unsigned flags);
50
51 GPadLoc led_in_loc[] = { /* Control line */
52 {0,7,0,7,D_DOWN},
53 {7,0,7,0,D_RIGHT},
54 {0,-7,0,-7,D_UP},
55 {-7,0,-7,0,D_LEFT}};
56
57 static char *psLed[] = {
58 "%",
59 "% An LED (bit)",
60 "%",
61 "/psled_bit {",
62 " startgate",
63 " -5 -7 moveto",
64 " 5 -7 lineto",
65 " 5 0 lineto",
66 " 0 0 5 0 180 arc",
67 " closepath",
68 " gsave .8 setgray fill grestore",
69 " stroke",
70 " grestore",
71 "} bind def",
72 "%",
73 "% Single bar graph segment",
74 "%",
75 "/psled_barseg {",
76 " gsave",
77 " 3 -13 translate",
78 " 3 10 pbox ",
79 " gsave .8 setgray fill grestore",
80 " stroke",
81 " grestore",
82 "} def",
83 "%",
84 "% An LED (bar graph)",
85 "%",
86 "/psled_bar {",
87 " startgate",
88 " neg 0 0 4 2 roll box",
89 " 1 1 3 -1 roll { psled_barseg 5 0 translate } for",
90 " grestore",
91 "} bind def",
92 "%",
93 "% Single 7-segment digit",
94 "%",
95 "/psled_7segdig {",
96 " gsave",
97 " 2 setlinewidth",
98 " 0 -27 translate",
99 " 5 0 17 0 line",
100 " 5 11 17 11 line",
101 " 5 22 17 22 line",
102 "",
103 " 4 1 4 10 line",
104 " 18 1 18 10 line",
105 " 4 12 4 21 line",
106 " 18 12 18 21 line",
107 " grestore",
108 "} def",
109 "%",
110 "% An LED (7 segment)",
111 "%",
112 "/psled_7seg {",
113 " startgate",
114 " neg 0 0 4 2 roll box",
115 " 1 1 3 -1 roll { psled_7segdig 20 0 translate } for",
116 " grestore",
117 "} bind def",
118 0
119 };
120
121 GGateInfo gate_led_info = {
122 GC_LED,
123 "LED",
124 "led",0x0,
125 "psled",psLed,
126 -1,0,
127
128 { {"l", {"gm.io",0}, {"gm.io.led",0,"led",100}, "gat_make LED -type basic"},
129 {"L 1", {0,0}, {0,0,0,0}, "gat_make LED -type bar -bits 1"},
130 {"L 2", {0,0}, {0,0,0,0}, "gat_make LED -type bar -bits 2"},
131 {"L 3", {0,0}, {0,0,0,0}, "gat_make LED -type bar -bits 3"},
132 {"L 4", {0,0}, {0,0,0,0}, "gat_make LED -type bar -bits 4"},
133 {"L 5", {0,0}, {0,0,0,0}, "gat_make LED -type bar -bits 5"},
134 {"L 6", {0,0}, {0,0,0,0}, "gat_make LED -type bar -bits 6"},
135 {"L 7", {0,0}, {0,0,0,0}, "gat_make LED -type bar -bits 7"},
136 {"L 8", {"gm.io",0}, {"gm.io.ledbar",0,"led",200}, "gat_make LED -type bar -bits 8"},
137 {"L 9", {0,0}, {0,0,0,0}, "gat_make LED -type bar -bits 9"},
138 {"L h", {"gm.io",0}, {"gm.io.ledhex",0,"led",300}, "gat_make LED -type hex -bits 8"},
139 {"L d", {"gm.io",0}, {"gm.io.leddec",0,"led",400}, "gat_make LED -type dec -bits 8"},
140 {"L s", {"gm.io",0}, {"gm.io.ledseg",0,"led",500}, "gat_make LED -type seg -bits 7"},
141 {0}},
142
143 led_iconDims,
144
145 1,{{"I",IN,1,1,led_in_loc,0}},
146 {{0,-12,CT},{-12,3,RJ},{0,18,CT},{12,3,LJ}},
147 {1,1,0,0,0},
148
149 {0},
150
151 Led_Make,
152 Nop_WriteCellDef,
153 Generic_Init,
154 Generic_Delete,
155 Led_GetExtents,
156 Generic_HitDistance,
157 Led_Draw,
158 Generic_Move,
159 Led_Copy,
160 Generic_AddInput,
161 Err_AddOutput,
162 Err_AddInOut,
163 Generic_Rotate,
164 Err_RemovePort,
165 Err_ChangePin,
166 Nop_SimInitFunc,
167 Nop_SimHitFunc,
168 Led_PSWrite,
169 Led_EditProps,
170 Led_VerSave,
171 Led_SetProp
172 };
173
174
175 Icon *inled_icon[8]; /* Special icons for 'light' part of led. */
176 Icon *seg_icon[7]; /* Icons for 7-segment display */
177
Led_Make(EditState ** es,GModuleDef * env,int GType,int x,int y,int r,const char * Name,int noWires,const char ** options,int nOptions)178 GCElement *Led_Make(EditState **es,GModuleDef *env,int GType,
179 int x,int y,int r,const char *Name,int noWires,const char **options,int nOptions)
180 {
181 GCElement *g = Generic_Make(es,env,GType,x,y,r,Name,noWires,options,nOptions);
182 const char *LType,*NBits;
183 int n;
184
185 ob_touch(g);
186
187 g->u.led.ltype = LT_BASIC;
188 g->u.led.value = 0;
189 g->u.led.valid = ~0;
190 n = 1;
191
192 LType = seekOption("-type",options,nOptions);
193 NBits = seekOption("-bits",options,nOptions);
194
195 if (LType) {
196 if (strcmp(LType,"basic") == 0)
197 g->u.led.ltype = LT_BASIC;
198 else if (strcmp(LType,"hex") == 0)
199 g->u.led.ltype = LT_HEX;
200 else if (strcmp(LType,"dec") == 0)
201 g->u.led.ltype = LT_DEC;
202 else if (strcmp(LType,"bar") == 0)
203 g->u.led.ltype = LT_BAR;
204 else if (strcmp(LType,"seg") == 0)
205 g->u.led.ltype = LT_SEG;
206 }
207
208 if (NBits) {
209 sscanf(NBits,"%d",&n);
210 if (n < 1) n = 1;
211 if (n > 32) n = 32;
212 }
213
214 if (!noWires)
215 net_setSize(g->wires[LED_IN]->net,n);
216
217 return g;
218 }
219
220 /*
221 * Returns number of decimal digits required to display an n-bit number.
222 */
decDigits(unsigned n)223 static unsigned decDigits(unsigned n)
224 {
225
226 unsigned m;
227
228 if (n < 32)
229 m = (1 << n) - 1;
230 else
231 m = 0xffffffff;
232
233 n = 0;
234 while (m > 0) {
235 m /= 10;
236 n++;
237 }
238 if (!n) n = 1;
239
240 return n;
241 }
242
243 /*
244 * Returns number of 7-seg digits.
245 */
numDigits(GCElement * g)246 static unsigned numDigits(GCElement *g)
247 {
248 unsigned n = g->wires[LED_IN]->net->n_nbits;
249
250 switch (g->u.led.ltype) {
251 case LT_HEX :
252 default :
253 n = (n+3)/4;
254 break;
255 case LT_SEG :
256 n = (n+6)/7;
257 break;
258 case LT_DEC :
259 n = decDigits(n);
260 break;
261 }
262
263 return n;
264 }
265
266 /*
267 * _1
268 * 2| |3
269 * -4
270 * 5| |6
271 * _7
272 */
getLedSegments(GCElement * g,unsigned * seg_value,unsigned * seg_valid,unsigned * n)273 static void getLedSegments(GCElement *g,unsigned *seg_value,unsigned *seg_valid,unsigned *n)
274 {
275 #define S(n) (1 << (n-1))
276 static unsigned seg_data[] = {
277 S(1)|S(2)|S(3)|S(5)|S(6)|S(7), /* 0 */
278 S(3)|S(6), /* 1 */
279 S(1)|S(3)|S(4)|S(5)|S(7), /* 2 */
280 S(1)|S(3)|S(4)|S(6)|S(7), /* 3 */
281 S(2)|S(4)|S(3)|S(6), /* 4 */
282 S(1)|S(2)|S(4)|S(6)|S(7), /* 5 */
283 S(1)|S(2)|S(4)|S(5)|S(6)|S(7), /* 6 */
284 S(1)|S(3)|S(6), /* 7 */
285 S(1)|S(2)|S(3)|S(4)|S(5)|S(6)|S(7), /* 8 */
286 S(1)|S(2)|S(3)|S(4)|S(6), /* 9 */
287 S(1)|S(2)|S(3)|S(4)|S(5)|S(6), /* A */
288 S(2)|S(4)|S(5)|S(6)|S(7), /* b */
289 S(1)|S(2)|S(5)|S(7), /* C */
290 S(3)|S(4)|S(5)|S(6)|S(7), /* d */
291 S(1)|S(2)|S(4)|S(5)|S(7), /* E */
292 S(1)|S(2)|S(4)|S(5), /* F */
293 };
294 #undef S
295 int nb = g->wires[LED_IN]->net->n_nbits;
296 unsigned valid = g->u.led.valid;
297 unsigned value = g->u.led.value;
298 int i;
299
300 /*
301 * 0 extend if necessary
302 */
303 if (nb < 32) {
304 value &= (1<<nb)-1;
305 valid |= ~((1<< nb)-1);
306 }
307
308 *n = numDigits(g);
309
310 i = *n - 1;
311 switch (g->u.led.ltype) {
312 case LT_HEX :
313 default :
314 for (i = *n-1;i >= 0;i--) {
315 unsigned a = value & 0xf;
316 unsigned b = valid & 0xf;
317
318 if (b == 0xf) {
319 seg_value[i] = seg_data[a];
320 seg_valid[i] = 0x7f;
321 } else {
322 seg_value[i] = 0;
323 seg_valid[i] = 0;
324 }
325
326 valid >>= 4;
327 value >>= 4;
328 }
329 break;
330 case LT_SEG :
331 for (i = *n-1;i >= 0;i--) {
332 unsigned a = value & 0x7f;
333 unsigned b = valid & 0x7f;
334
335 seg_value[i] = a;
336 seg_valid[i] = b;
337
338 valid >>= 7;
339 value >>= 7;
340 }
341 break;
342 case LT_DEC :
343 if (valid == 0xffffffff) {
344 for (i = *n-1;i >= 0;i--) {
345 unsigned a = value % 10;
346
347 seg_value[i] = seg_data[a];
348 seg_valid[i] = 0x7f;
349
350 value /= 10;
351 }
352 } else {
353 for (i = *n-1;i >= 0;i--) {
354 seg_value[i] = 0;
355 seg_valid[i] = 0;
356 }
357 }
358 break;
359 }
360 }
361
Led_GetExtents(GCElement * g,TargetDev_e target,int * minx,int * miny,int * maxx,int * maxy,int * bd)362 void Led_GetExtents(GCElement *g,TargetDev_e target,int *minx,int *miny,int *maxx,int *maxy,int *bd)
363 {
364 switch (g->u.led.ltype) {
365 case LT_BASIC :
366 default :
367 Generic_GetExtents(g,target,minx,miny,maxx,maxy,bd);
368 break;
369 case LT_BAR :
370 {
371 int x = 0,y = 0,w,h,n;
372
373 n = g->wires[LED_IN]->net->n_nbits;
374 h = 15;
375 w = 3 + 5*n;
376
377 switch (g->orient) {
378 case D_RIGHT :
379 x = g->xpos - w/2;
380 y = g->ypos - 9;
381 break;
382 case D_UP :
383 x = g->xpos - w + 6;
384 y = g->ypos - 7 ;
385 break;
386 case D_LEFT :
387 x = g->xpos - w/2;
388 y = g->ypos - 6;
389 break;
390 case D_DOWN :
391 x = g->xpos - 6 ;
392 y = g->ypos - 7;
393 break;
394 }
395
396 if (bd) *bd = 10;
397 if (minx) *minx = x;
398 if (miny) *miny = y;
399 if (maxx) *maxx = x + w;
400 if (maxy) *maxy = y + h;
401 break;
402 }
403 case LT_HEX :
404 case LT_SEG :
405 case LT_DEC :
406 {
407 int x = 0,y = 0,w,h;
408 unsigned n;
409
410 n = numDigits(g);
411 h = 31;
412 w = 3 + 20*n;
413
414 switch (g->orient) {
415 case D_RIGHT :
416 x = g->xpos - w/2;
417 y = g->ypos - h + 6;
418 break;
419 case D_UP :
420 x = g->xpos - w + 6;
421 y = g->ypos - h/2 ;
422 break;
423 case D_LEFT :
424 x = g->xpos - w/2;
425 y = g->ypos - 6;
426 break;
427 case D_DOWN :
428 x = g->xpos - 6;
429 y = g->ypos - h/2;
430 break;
431 }
432
433 if (bd) *bd = 10;
434 if (minx) *minx = x;
435 if (miny) *miny = y;
436 if (maxx) *maxx = x + w;
437 if (maxy) *maxy = y + h;
438 break;
439 }
440
441 }
442 }
443
led_drawname(GCElement * g,char * ename,int ax,int ay,int w,int h)444 void led_drawname(GCElement *g,char *ename,int ax,int ay,int w,int h)
445 {
446 int x,y;
447
448 if (g->selected)
449 XSetFont(TkGate.D,TkGate.instGC,TkGate.textbXF[TkGate.circuit->zoom_factor]->fid);
450 else
451 XSetFont(TkGate.D,TkGate.instGC,TkGate.textXF[TkGate.circuit->zoom_factor]->fid);
452
453 x = ax+w/2;
454
455 if (g->orient == 2) {
456 if (g->u.led.ltype != LT_BAR)
457 y = ay+h+22;
458 else
459 y = ay+h+12;
460 } else
461 y = ay-5;
462
463 dce_DrawString(TkGate.instGC,x,y,CT,ename);
464 }
465
led_PSdrawname(GPrint * P,GCElement * g,char * ename,int ax,int ay,int w,int h)466 void led_PSdrawname(GPrint *P,GCElement *g,char *ename,int ax,int ay,int w,int h)
467 {
468 int x,y;
469 HtmlFont font[1];
470 GateFont gateFont = {FF_HELVETICA,FP_ROMAN};
471
472 if (g->selected)
473 XSetFont(TkGate.D,TkGate.instGC,TkGate.textbXF[TkGate.circuit->zoom_factor]->fid);
474 else
475 XSetFont(TkGate.D,TkGate.instGC,TkGate.textXF[TkGate.circuit->zoom_factor]->fid);
476
477 x = ax+w/2;
478
479 if (g->orient == 2) {
480 if (g->u.led.ltype != LT_BAR)
481 y = ay+h+22;
482 else
483 y = ay+h+12;
484 } else
485 y = ay-5;
486
487 PSDrawText(P,HtmlFont_init(font,gateFont,8),
488 x,y,ename,BetweenLeftAndRight|AtBaseline);
489 }
490
Led_Draw_basic(GCElement * g,int md)491 static void Led_Draw_basic(GCElement *g,int md)
492 {
493 int idx;
494
495 Generic_Draw(g,md);
496
497 if (!(g->u.led.valid & 0x1)) {
498 Tkg_changeColor(TkGate.instGC, GXxor, TkGate.ledunknown_pixel);
499 } else if (g->u.led.value) {
500 Tkg_changeColor(TkGate.instGC, GXxor, TkGate.ledon_pixel);
501 } else {
502 Tkg_changeColor(TkGate.instGC, GXxor, TkGate.ledoff_pixel);
503 }
504
505 idx = g->orient;
506 if (g->selected) idx += 4;
507 Icon_draw(TkGate.D,TkGate.W,TkGate.instGC,ctow_x(g->xpos),ctow_y(g->ypos),inled_icon[idx]);
508
509 Tkg_changeColor(TkGate.instGC, GXxor, TkGate.inst_pixel);
510 }
511
Led_Draw_bar(GCElement * g,int md)512 static void Led_Draw_bar(GCElement *g,int md)
513 {
514 int i,n,x,y,x2,y2,w,h,dx;
515
516 n = g->wires[LED_IN]->net->n_nbits;
517
518 Led_GetExtents(g,TD_X11,&x,&y,&x2,&y2,0);
519 w = x2-x;
520 h = y2-y;
521
522 if (g->show_name && g->ename)
523 led_drawname(g,g->ename,x,y,w,h);
524
525 ZDrawRectangle(TkGate.D,TkGate.W,TkGate.instGC,ctow_x(x),ctow_y(y),w,h);
526 if (g->selected)
527 ZDrawRectangle(TkGate.D,TkGate.W,TkGate.instGC,ctow_x(x)+1,ctow_y(y)+1,w-2,h-2);
528
529 x += 3;
530 y += 3;
531
532 /*
533 * Draw all of the unknown bits
534 */
535 Tkg_changeColor(TkGate.instGC, GXxor, TkGate.ledunknown_pixel);
536 dx = 0;
537 for (i = 0;i < n;i++) {
538 if (!(g->u.led.valid & (1 << (n-i-1)))) {
539 ZFillRectangle(TkGate.D,TkGate.W,TkGate.instGC,ctow_x(x+dx),ctow_y(y),3,10);
540 }
541 dx += 5;
542 }
543
544 /*
545 * Draw all of the on bits
546 */
547 Tkg_changeColor(TkGate.instGC, GXxor, TkGate.ledon_pixel);
548 dx = 0;
549 for (i = 0;i < n;i++) {
550 if ((g->u.led.valid & (1 << (n-i-1)) && (g->u.led.value & (1 << (n-i-1))))) {
551 ZFillRectangle(TkGate.D,TkGate.W,TkGate.instGC,ctow_x(x+dx),ctow_y(y),3,10);
552 }
553 dx += 5;
554 }
555
556 /*
557 * Draw all of the off bits
558 */
559 Tkg_changeColor(TkGate.instGC, GXxor, TkGate.ledoff_pixel);
560 dx = 0;
561 for (i = 0;i < n;i++) {
562 if ((g->u.led.valid & (1 << (n-i-1)) && !(g->u.led.value & (1 << (n-i-1))))) {
563 ZFillRectangle(TkGate.D,TkGate.W,TkGate.instGC,ctow_x(x+dx),ctow_y(y),3,10);
564 }
565 dx += 5;
566 }
567
568 Tkg_changeColor(TkGate.instGC, GXxor, TkGate.inst_pixel);
569 gate_drawWires(g,md);
570 }
571
572
Led_Draw_7segs(GCElement * g,int md)573 void Led_Draw_7segs(GCElement *g,int md)
574 {
575 int i,j,x,y,x2,y2,w,h,dx;
576 unsigned seg_value[MAXDIGITS];
577 unsigned seg_valid[MAXDIGITS];
578 unsigned n;
579 char *seg_type = 0;
580
581 Led_GetExtents(g,TD_X11,&x,&y,&x2,&y2,0);
582 w = x2-x;
583 h = y2-y;
584
585 if (g->show_name && g->ename)
586 led_drawname(g,g->ename,x,y,w,h);
587
588 getLedSegments(g,seg_value,seg_valid,&n);
589
590 ZDrawRectangle(TkGate.D,TkGate.W,TkGate.instGC,ctow_x(x),ctow_y(y),w,h);
591 if (g->selected)
592 ZDrawRectangle(TkGate.D,TkGate.W,TkGate.instGC,ctow_x(x+1),ctow_y(y+1),w-2,h-2);
593
594 dx = 0;
595 for (i = 0;i < n;i++, dx += 20)
596 ZDrawRectangle(TkGate.D,TkGate.W,TkGate.instGC,ctow_x(x+dx+3),ctow_y(y+3),17,25);
597
598
599 /*
600 Draw the type indicator for 7-seg LEDs
601 */
602 switch (g->u.led.ltype) {
603 case LT_HEX :
604 seg_type = "16";
605 break;
606 case LT_SEG :
607 seg_type = "D";
608 break;
609 case LT_DEC :
610 seg_type = "10";
611 break;
612 }
613
614 if (seg_type) {
615 if (g->selected)
616 XSetFont(TkGate.D,TkGate.instGC,TkGate.stextbXF[TkGate.circuit->zoom_factor]->fid);
617 else
618 XSetFont(TkGate.D,TkGate.instGC,TkGate.stextXF[TkGate.circuit->zoom_factor]->fid);
619 dce_DrawString(TkGate.instGC,x+w/2+5,y+40,LJ,seg_type);
620 }
621
622 dx = 0;
623 Tkg_changeColor(TkGate.instGC, GXxor, TkGate.ledunknown_pixel);
624 for (i = 0;i < n;i++, dx += 20) {
625 for (j = 0;j < 7;j++) {
626 if (!(seg_valid[i] & (1<<j)))
627 Icon_draw(TkGate.D,TkGate.W,TkGate.instGC,ctow_x(x+dx+5),ctow_y(y+5),seg_icon[j]);
628 }
629 }
630
631 dx = 0;
632 Tkg_changeColor(TkGate.instGC, GXxor, TkGate.ledon_pixel);
633 for (i = 0;i < n;i++, dx += 20) {
634 for (j = 0;j < 7;j++) {
635 if ((seg_valid[i] & (1<<j)) && (seg_value[i] & (1<<j)))
636 Icon_draw(TkGate.D,TkGate.W,TkGate.instGC,ctow_x(x+dx+5),ctow_y(y+5),seg_icon[j]);
637 }
638 }
639
640 dx = 0;
641 Tkg_changeColor(TkGate.instGC, GXxor, TkGate.ledoff_pixel);
642 for (i = 0;i < n;i++, dx += 20) {
643 for (j = 0;j < 7;j++) {
644 if ((seg_valid[i] & (1<<j)) && !(seg_value[i] & (1<<j)))
645 Icon_draw(TkGate.D,TkGate.W,TkGate.instGC,ctow_x(x+dx+5),ctow_y(y+5),seg_icon[j]);
646 }
647 }
648
649 Tkg_changeColor(TkGate.instGC, GXxor, TkGate.inst_pixel);
650 gate_drawWires(g,md);
651 }
652
653
Led_Draw(GCElement * g,int md)654 void Led_Draw(GCElement *g,int md)
655 {
656 if (tkgate_currentMode() != MM_SIMULATE) {
657 g->u.led.valid = 0xffffffff;
658 g->u.led.value = 0;
659 }
660
661 switch (g->u.led.ltype) {
662 case LT_BASIC :
663 Led_Draw_basic(g,md);
664 break;
665 case LT_BAR :
666 Led_Draw_bar(g,md);
667 break;
668 default :
669 Led_Draw_7segs(g,md);
670 break;
671 }
672 }
673
Led_Copy(GModuleDef * M,GCElement * g,int x,int y,unsigned flags)674 GCElement *Led_Copy(GModuleDef *M,GCElement *g,int x,int y,unsigned flags)
675 {
676 GCElement *ng;
677
678 ng = Generic_Copy(M,g,x,y,flags);
679 ob_touch(ng);
680
681 ng->u.led.ltype = g->u.led.ltype;
682 ng->u.led.value = g->u.led.value;
683 ng->u.led.valid = g->u.led.value;
684
685 return ng;
686 }
687
688
Led_VerSave(FILE * f,GCElement * g)689 void Led_VerSave(FILE *f,GCElement *g)
690 {
691 fprintf(f," //: %s %s (%s)"
692 ,g->typeinfo->name
693 ,g->ename
694 ,g->wires[0]->net->n_signame);
695 VerilogBasicGateComment(f,g,0);
696 fprintf(f," /type:%d",g->u.led.ltype);
697 fprintf(f,"\n");
698
699 #if 0
700 VerilogBasicGateCall(f,g);
701 VerilogBasicGateParmList(f,g);
702 VerilogBasicGateComment(f,g,1);
703 fprintf(f," /type:%d",g->u.led.ltype);
704 fprintf(f,"\n");
705 #endif
706 }
707
Led_EditProps(GCElement * g,int isLoadDialog)708 int Led_EditProps(GCElement *g,int isLoadDialog)
709 {
710 Tcl_Interp *tcl = TkGate.tcl;
711
712 Generic_EditProps(g,isLoadDialog);
713 if (isLoadDialog) {
714 DoTcl("set ::edgat_ledType %d",g->u.led.ltype);
715 } else {
716 const char *p;
717
718 if ((p = Tcl_GetVar(tcl,"edgat_ledType",TCL_GLOBAL_ONLY))) {
719 ob_touch(g);
720 sscanf(p,"%d",&g->u.led.ltype);
721 }
722 }
723 return 0;
724 }
725
Led_SetProp(GCElement * g,const char * prop,const void * value)726 void Led_SetProp(GCElement *g,const char *prop,const void *value)
727 {
728 if (strcmp(prop,"/type") == 0) {
729 int n = *((int*)value);
730 ob_touch(g);
731 g->u.led.ltype = n;
732 }
733 }
734
Led_PSWrite(GPrint * P,GModLayout * L,GCElement * g)735 void Led_PSWrite(GPrint *P,GModLayout *L,GCElement *g)
736 {
737 int n;
738 int x,y,x2,y2,w,h;
739 HtmlFont font[1];
740 GateFont gateFont = {FF_HELVETICA,FP_ROMAN};
741
742 Led_GetExtents(g,TD_PRINT,&x,&y,&x2,&y2,0);
743 w = x2-x;
744 h = y2-y;
745
746 switch (g->u.led.ltype) {
747 case LT_BASIC :
748 default :
749 Generic_PSLabels(P,g);
750 fprintf(P->p_f,"%d %d %d psled_bit\n",g->xpos,g->ypos,-g->orient*90);
751 break;
752 case LT_BAR :
753 if (g->show_name && g->ename)
754 led_PSdrawname(P,g,g->ename,x,y,w,h);
755
756 n = g->wires[LED_IN]->net->n_nbits;
757 fprintf(P->p_f,"%d %d %d %d %d 0 psled_bar\n",n,w,h,x,y);
758 break;
759 case LT_HEX :
760 case LT_SEG :
761 case LT_DEC :
762 if (g->show_name && g->ename)
763 led_PSdrawname(P,g,g->ename,x,y,w,h);
764 n = numDigits(g);
765 fprintf(P->p_f,"%d %d %d %d %d 0 psled_7seg\n",n,w,h,x,y);
766 break;
767 }
768
769 switch (g->u.led.ltype) {
770 case LT_HEX :
771 PSDrawText(P,HtmlFont_init(font,gateFont,8),x+w/2+3,y+30,"16",AtLeft|AtTop);
772 break;
773 case LT_SEG :
774 PSDrawText(P,HtmlFont_init(font,gateFont,8),x+w/2+3,y+30,"D",AtLeft|AtTop);
775 break;
776 case LT_DEC :
777 PSDrawText(P,HtmlFont_init(font,gateFont,8),x+w/2+3,y+30,"10",AtLeft|AtTop);
778 break;
779 }
780 }
781
782
init_led()783 void init_led()
784 {
785 Pixmap P;
786 int i;
787 char buf1[STRMAX],buf2[STRMAX];
788 iconDimensions *id = led_iconDims;
789
790 P = Pixmap_registerFromFile("led","led.b");
791 gateinfo_iconInit(&gate_led_info,P,led_iconDims,led_iconBoldOffset);
792 RegisterGate(&gate_led_info);
793
794 for (i = 0;i < 7;i++) {
795 sprintf(buf1,"ledseg%d",i+1);
796 sprintf(buf2,"ledseg%d.b",i+1);
797 P = Pixmap_registerFromFile(buf1,buf2);
798 seg_icon[i] = new_Icon(P,0,0,13,21,0,0);
799 }
800
801 /*
802 * Load special pixmap for leds.
803 */
804 P = Pixmap_registerFromFile("ledinside","ledinside.b");
805 for (i = 0;i < 4;i++) {
806 inled_icon[i] = new_Icon(P,id[i].x,id[i].y,id[i].w,id[i].h,id[i].ox,id[i].oy);
807 inled_icon[i+4] = new_Icon(P,id[i].x,id[i].y+led_iconBoldOffset,id[i].w,id[i].h,id[i].ox,id[i].oy);
808 }
809
810 }
811