3 ## Library version 0.94
4 ## This program is released under the terms of the GNU GPL
5 ## See www.fsf.org for a copy of the license
7 ## Copyright 1999 Matthew Ettus
8 ## For more info, email matt@ettus.com
10 ## This program will convert ORCAD text libraries to gEDA components
12 ## Changes 0.94 by <egil@kvaleberg.no>, october 5th 2002
13 ## Implement CLK modifier
14 ## Implement negation for text ('\'-character)
15 ## Doubled size to better fit with gEDA symbols
16 ## Default to U? refdes, fixed refdes and made visible
17 ## Define sarlacc_dim attribute for sarlacc_scheme
18 ## Command line options
20 ## Changes 0.93 by <egil@kvaleberg.no>, october 4th 2002
21 ## Pin attribs modified for 20020825 convention
22 ## File format to 20020825 convention
23 ## Give duplicate components correct names
25 ## Implemented CONVERT
26 ## Implemented multiple slot component
27 ## Better syntax check for pin defs
28 ## Removed negative coordinates by adding an offset
29 ## Got rid of need to calculate text sizes
31 ## Graphics components has invisible pin labels
32 ## Implemented pintype PWR
33 ## Implement pintypes (IN, I/O, hiZ, OUT, PAS, OC, OE)
36 ## Implement symbols like THREE_STATE
41 $gedaversion="20020825";
46 $pin_color = 1; # white
47 $graphic_color = 3; # green
48 $attribute_color = 5; # yellow
49 $text_color = 9; # green
62 $xoffset = $pinlen * $scale;
63 $yoffset = $pinlen * $scale;
66 # character width table (approximate)
69 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
70 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
71 11,14,14,22,28,28,24,10,12,12,16,20,14,20,12,18,
72 26,16,26,20,26,20,24,20,22,26,12,12,20,20,20,20,
73 36,29,29,28,26,29,21,30,29,9,21,27,22,32,28,32,
74 25,32,26,25,23,27,27,37,27,25,27,12,14,12,20,25,
75 10,24,22,22,20,20,12,24,20,8,10,19,9,32,20,20,
76 20,24,14,18,12,19,20,28,19,20,21,12,10,12,22,0,
77 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
78 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
79 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
80 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
81 0,0,0,0,29,29,0,0,0,0,0,0,0,0,0,0,
82 0,0,0,0,0,0,32,0,0,0,0,0,0,0,0,0,
83 0,0,0,0,24,24,0,0,0,0,0,0,0,0,0,0,
84 0,0,0,0,0,0,20,0,0,0,0,0,0,0,0,0
91 @expanded = unpack "C*",$_[0];
92 foreach $char (@expanded)
94 $width += $char_width[$char];
96 $width = ($_[1]*$width)/$char_points;
112 $sx = 1 if ($dx > 0);
113 $sx = -1 if ($dx < 0);
115 $sy = 1 if ($dy > 0);
116 $sy = -1 if ($dy < 0);
118 $x2 = $x1 + $sx * $len;
119 $y2 = $y1 + $sy * $len;
123 local $xa,$ya,$xb,$xb;
125 $xa = $x1 - $sy * $spacing;
126 $xb = $x1 - $sx * $spacing;
127 $ya = $y1 - $sx * $spacing;
128 $yb = $y1 - $sy * $spacing;
129 print COMPONENT
"L $xa $ya $xb $yb $graphic_color".
131 $xa = $x1 + $sy * $spacing;
132 $ya = $y1 + $sx * $spacing;
133 print COMPONENT
"L $xa $ya $xb $yb $graphic_color".
137 if ( not ($pinlabel =~ /\$/) && not $is_graphic)
140 if ( $pinlabel =~ /\\/ )
143 $pinlabel =~ tr/\\//d;
144 $w = string_len
($pinlabel,$pinnumsize);
147 local $xa,$ya,$xb,$xb;
149 $xa = $x1 + abs($sy) * $spacing
151 $xb = $x1 + abs($sy) * $spacing
152 - $sx * ($spacing + $w);
153 $ya = $y1 + abs($sx) * $spacing
155 $yb = $y1 + abs($sx) * $spacing
156 - $sy * ($spacing + $w);
157 print COMPONENT
"L $xa $ya $xb $yb $text_color".
170 print COMPONENT
"V $x1 $y1 $rad $pin_color ",
171 " 0 0 0 -1 -1 0 -1 -1 -1 -1 -1\n";
176 print COMPONENT
"P $x1 $y1 $x2 $y2 $pin_color\n";
191 if ($pinnumbers =~ /^(.*)[ \t]+([A-Za-z]+)[ \t]*$/ )
202 $len = $pinlen * $scale;
206 if ($modifier eq "DOT")
208 $dotsize = $scale / 2;
210 elsif ($modifier eq "SHORT")
214 elsif ($modifier eq "CLK")
218 elsif ($modifier ne "")
220 print "Modifier not supported: $modifier\n";
224 if ($pintype eq "PWR")
229 elsif (($a = $pintype_assoc{$pintype}) ne "")
233 elsif ($pintype ne "")
235 ## BAD others are: tp clk pwr
236 print "Pintype not supported: $pintype\n";
240 $pinlabel = "Vcc" if ($pinlabel eq "VCC");
243 # extract the pin numbers
247 $length = @array = split(" ",$pinnumbers);
248 if ($length != $slots)
250 print "Error: incorrect number of pins $length, should be $slots\n";
255 $def_slot[$pinseq] = [ @array ];
257 $pinnumber = $array[0];
261 $pinnumber = $pinnumbers;
263 $pinnumber =~ tr/ //d;
264 $pinnumber =~ tr/\'//d;
273 $letter = $num = $place;
274 $letter =~ tr/0-9//d;
276 $spacing = $scale / 2;
281 $y1 = $yoffset + $ysize - $num*$scale;
284 $textx = $xoffset - $spacing;
285 $texty = $y1 + $scale/10;
286 $namex = $xoffset + $spacing;
291 elsif ($letter eq "R")
293 $x1 = $xoffset + $xsize;
294 $y1 = $yoffset + $ysize - $num*$scale;
297 $textx = $xoffset + $xsize + $spacing;
298 $texty = $y1 + $scale/10;
299 $namex = $xoffset + $xsize - $spacing;
303 elsif ($letter eq "T")
305 $x1 = $xoffset + $num*$scale;
306 $y1 = $yoffset + $ysize;
309 $textx = $x1 - $scale/10;
310 $texty = $yoffset + $ysize + $spacing;
312 $namey = $yoffset + $ysize - $spacing;
313 $pinnumangle = $pinlabelangle = 90;
316 elsif ($letter eq "B")
319 $x1 = $xoffset + $num*$scale;
322 $textx = $x1 - $scale/10;
323 $texty = $yoffset - $spacing;
325 $namey = $yoffset + $spacing;
326 $pinnumangle = $pinlabelangle = 90;
332 print "Cannot happen: $letter\n";
338 if ($pinnumber ne "")
340 print COMPONENT
"T $textx $texty $attribute_color $pinnumsize 0 0 0 0\n";
341 print COMPONENT
"net=$pinlabel:$pinnumber\n";
350 print COMPONENT
"{\n";
352 # *EK* use pinnumber= and pinseq= for 20020825
353 if ($pinnumber ne "")
355 print COMPONENT
"T $textx $texty $attribute_color $pinnumsize $visibility 1 $pinnumangle $pinnumalign\n";
356 print COMPONENT
"pinnumber=$pinnumber\n";
358 print COMPONENT
"T $textx $texty $attribute_color $pinnumsize 0 0 0 0\n";
359 print COMPONENT
"pinseq=$pinseq\n";
360 print COMPONENT
"T $textx $texty $attribute_color $pinnumsize 0 0 0 0\n";
361 print COMPONENT
"pintype=$pintype\n";
363 if ( not ($pinlabel =~ /\$/) )
365 # do not show label if graphic package
366 $visibility = 0 if ($is_graphic);
368 print COMPONENT
"T $namex $namey $text_color ",
369 "$pinnumsize $visibility 1 $pinlabelangle $pinlabelalign\n";
370 print COMPONENT
"pinlabel=$pinlabel\n";
372 print COMPONENT
"}\n";
387 for ($pin = 0; $pin < $pins; ++$pin)
389 $place = $def_place[$pin];
390 $pinnumbers = $def_pinnumbers[$pin];
391 $pintype = $def_pintype[$pin];
392 $pinlabel = $def_pinlabel[$pin];
406 open(COMPONENT
,">$component-$convert.sym");
407 print COMPONENT
"v $gedaversion\n";
409 print COMPONENT
"T $scale 0 $attribute_color $partnamesize 1 1 0 0\n";
410 print COMPONENT
"refdes=$refdes?\n";
412 # make displayed name also an attribute
413 print COMPONENT
"T $scale $scale $attribute_color $partnamesize 1 1 0 0\n";
414 print COMPONENT
"partno=$component\n";
415 print COMPONENT
"T $scale $scale $attribute_color $partnamesize 0 1 0 0\n";
416 print COMPONENT
"device=$component\n";
421 print COMPONENT
"T $scale $scale $attribute_color $partnamesize 0 0 0 0\n";
422 print COMPONENT
"slot=1\n";
423 print COMPONENT
"T $scale $scale $attribute_color $partnamesize 0 0 0 0\n";
424 print COMPONENT
"numslots=$slots\n";
428 print COMPONENT
"T $scale $scale $attribute_color $partnamesize 0 0 0 0\n";
429 print COMPONENT
"numslots=0\n";
437 while (($line = <LIBRARY
>) =~
438 /(^[LRTB][0-9]+)(.*)[ \t]+([A-Za-z\/]+)[ \t]+'(.*)'/ )
439 # L1 3 DOT I/O 'OUTPUT'
441 $def_place[$pins] = $1;
442 $def_pinnumbers[$pins] = $2;
443 $def_pintype[$pins] = $3;
444 $def_pinlabel[$pins] = $4;
453 while ($line =~ /\{/)
458 if ( $line =~ /BITMAP[ \t]+'(.*)'/ )
463 # re-use previous vector image
464 $def_body = $body{$1};
468 elsif (( $line = <LIBRARY
>) =~ /VECTOR/ )
474 while (not (( $line = <LIBRARY
>) =~ /END/))
478 ($dummy,$x1,$y1,$x2,$y2)=
480 $x1 = $xoffset + $x1*$scale;
481 $y1 = $yoffset + $ysize - $y1*$scale;
482 $x2 = $xoffset + $x2*$scale;
483 $y2 = $yoffset + $ysize - $y2*$scale;
484 $def_body .= "L $x1 $y1 $x2 $y2 $graphic_color".
487 elsif($line =~ /TEXT/)
489 # BAD set textsize properly , check multi-line text
490 ($dummy,$x1,$y1,$textsize,$text)=split(" ",$line);
491 $x1 = $xoffset + $x1*$scale;
492 $y1 = $yoffset + $ysize - $y1*$scale;
494 # print "Text=$text\n";
495 if ($text eq "OPEN_L")
499 elsif ($text eq "OPEN_H")
503 elsif ($text eq "THREE_STATE")
509 print "Symbol not supported: $text\n";
514 $textsize *= $pinnumsize;
515 $def_body .= "T $x1 $y1 $graphic_color $textsize 1 0 0 0\n".
519 elsif ($line =~ /CIRCLE/)
521 ($dummy,$x1,$y1,$radius) = split(" ",$line);
522 $x1 = $xoffset + $x1*$scale;
523 $y1 = $yoffset + $ysize - $y1*$scale;
525 $def_body .= "V $x1 $y1 $radius $graphic_color".
526 " 0 0 0 -1 -1 0 -1 -1 -1 -1 -1\n";
528 elsif ($line =~ /ARC/)
530 ($dummy,$x1,$y1,$dx1,$dy1,$dx2,$dy2,$rad) =
532 $x1 = $xoffset + $x1*$scale;
533 $y1 = $yoffset + $ysize - $y1*$scale;
534 $factor = 180 / atan2(1,1) / 4;
535 $startangle = int ( $factor * atan2 (-$dy1, $dx1));
536 $endangle = int ( $factor * atan2 (-$dy2, $dx2));
537 $sweepangle = $endangle - $startangle;
538 # Orcad brain damage: ARC is always < 180 deg
539 if ($sweepangle > 180) {
542 if ($sweepangle < -180) {
546 $def_body .= "A $x1 $y1 $rad".
547 " $startangle $sweepangle $graphic_color".
550 elsif ($line =~ /FILL/)
556 print "Unrecognized tag:\n $line \n";
571 $def_body = "B $x1 $y1 $xsize $ysize $graphic_color".
572 " 0 0 0 -1 -1 0 -1 -1 -1 -1 -1\n";
577 # define slots, if any
581 for ($s = 0; $s < $slots; ++$s)
583 print COMPONENT
"T $scale $scale $attribute_color $partnamesize 0 0 0 0\n";
584 print COMPONENT
"slotdef=",$s+1;
587 for ($n = 0; $n < $pinseq; ++$n)
589 $pin = $def_slot[$n][$s];
590 print COMPONENT
"$c$pin";
593 print COMPONENT
"\n";
600 print COMPONENT
"$def_body";
601 $body{$component} = "$def_body";
606 print COMPONENT
"T $scale $scale $attribute_color $partnamesize 0 0 0 0\n";
607 print COMPONENT
"sarlacc_dim=$xoffset,$yoffset,$xsize,$ysize\n";
612 # make copies for multiple component names.
613 # device= changed to suit
615 foreach $duplicate (@namelist)
617 # make duplicate component, remembering to change device name
618 `cat $component-1.sym |
619 sed "s/partno=$component/partno=$duplicate/" |
620 sed "s/device=$component/device=$duplicate/" |
621 cat >$duplicate-1.sym`;
631 local $library = $_[0];
633 open(LIBRARY
,$library ) or die "Can't open $library: $!\n";
636 if ( not ($line =~ /Compiled/ ))
639 print "Not a library file: $library\n";
643 while (not (<LIBRARY
> =~ /PREFIX/)){};
644 while (not (<LIBRARY
> =~ /END/)){};
648 while (not (eof LIBRARY
))
653 $component =~ s/\'//g;
655 $component =~ s/\r//g;
656 $component =~ s/\ /_/g;
660 # Handle components with multiple names....
662 while (($line = <LIBRARY
>) =~ /^\'/)
668 push @namelist ,( $line);
671 if ($line =~ /REFERENCE/)
673 ($dummy,$refdes) = split("\'",$line);
677 ($dummy,$x,$y,$slots) = split("=}",$line);
678 ($xsize) = split(" ",$x);
679 ($ysize) = split(" ",$y);
686 # print "Define: $component\n";
690 elsif ( $line =~ /CONVERT/ )
707 # pin types for Orcad to gEDA
708 $pintype_assoc{'PWR'} = "pwr";
709 $pintype_assoc{'IN'} = "in";
710 $pintype_assoc{'I/O'} = "io";
711 $pintype_assoc{'OUT'} = "out";
712 $pintype_assoc{'hiZ'} = "tri";
713 $pintype_assoc{'PAS'} = "pas";
714 $pintype_assoc{'OC'} = "oc";
715 $pintype_assoc{'OE'} = "oe";
719 for ($argn = 0; $argn < @ARGV; ++$argn)
722 if ($arg =~ /^-([A-Za-z?])(.*)$/ ) {
725 } elsif ($1 eq "v") {
726 print "sarlacc_sym ver $version\n";
728 print "Convert Oracd symbol library (text format) to gEDA\n";
729 print "\nUsage: sarlacc_sym [options] library",
731 # "\n -d<dir> directory for symbols",
733 "\n -s<n> scale <n>%, default is $scale",