Subversion Repositories OpenARM Single-board Computer

Rev

Rev 134 | Rev 141 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
118 jelle 1
#!/usr/bin/perl
2
# -*- perl -*-
3
 
4
# Copyright (C) 2006 DJ Delorie dj@delorie.com
5
# Released under the terms of the GNU General Public License, version 2
6
 
7
# Usage: djboxsym sample.symdef > sample.sym
8
 
133 agaran 9
$y{left} = 300;
10
$y{right} = 300;
131 agaran 11
$y{labels} = -200;
118 jelle 12
$labelpin = 0;
13
 
14
# Read in the file, storing information about each pin.
15
 
16
while (<>) {
17
    next if /^#/;
18
    s/^\s+//;
19
    s/\s+$//;
20
    s/[\s\t]+/ /g;
21
    s/[\r\n]+$//;
22
 
23
    # Note change of section.
24
    if (/^\[(.*)\]/) {
25
        $side = $1;
26
        $space = 0;
27
        next;
28
    }
29
 
30
    # Start a bus
31
    if (/^\.bus/) {
32
        $busmode = 1;
33
        next;
34
    }
35
 
36
    # blank lines - cancel bus, add gap.
37
    if (! /\S/) {
38
        if ($busmode) {
39
            $y{$side} += 200;
40
        }
41
        $busmode = 0;
42
        if ($space) {
43
            if ($side =~ /left|right/) {
131 agaran 44
                $y{$side} += 300;
118 jelle 45
            }
46
            if ($side =~ /top|bottom/) {
47
                $x{$side} += 400;
48
            }
49
            $space = 0;
50
        }
51
        next;
52
    }
53
 
54
    # Hidden labels are stored separately, because we don't care how
55
    # big they are.
56
    if (/! (\S.*)/ && $side eq "labels") {
57
        push(@attrs, $1);
58
        next;
59
    }
60
 
61
    # Visible labels are stored as pins because their size affects the
62
    # size of the symbols' box.
63
    if (/\S/ && $side eq "labels") {
64
        $labelpin --;
65
        $pinside{$labelpin} = $side;
66
        $piny{$labelpin} = $y{labels};
67
        $pinlabel{$labelpin} = $_;
131 agaran 68
        $y{labels} -= 200;
118 jelle 69
        $rlen{$labelpin} = &textlen($_);
70
        next;
71
    }
72
 
73
    # Regular pins are handled here.
74
    if (/^([0-9A-Za-z]+)\s*(.*)/) {
75
        $space = 1;
76
        ($pin, $rest) = ($1,$2);
77
 
78
        if ($saw_pin{$pin}) {
79
            print STDERR "DUPLICATE PIN $pin (was $pinlabel{$pin}, now $rest)\n";
80
            $errors ++;
81
        }
82
        $saw_pin{$pin} = 1;
83
        $maxpin = $pin if $maxpin < $pin;
84
 
85
        $pinside{$pin} = $side;
86
        next if $side eq "nc";
87
        if ($rest =~ /^([!>]+) (.*)/) {
88
            $flags = $1;
89
            $pinlabel{$pin} = $2;
90
            $bubble{$pin} = 1 if $flags =~ /!/;
91
            $edge{$pin} = 1 if $flags =~ />/;
92
        } else {
93
            $pinlabel{$pin} = $rest;
94
        }
95
        $rlen{$pin} = &textlen($pinlabel{$pin});
96
 
97
        if ($side =~ /left|right/) {
98
            $y = $piny{$pin} = $y{$side};
132 agaran 99
            $y{$side} += ($busmode ? 200 : 300);
118 jelle 100
        }
101
        if ($side =~ /top|bottom/) {
102
            $tw = &alignpin((200 + $rlen{$pin}) / 2);
103
            $pinx{$pin} = $w{$side} + $tw;
104
            $w{$side} += $tw + $tw;
105
        }
106
 
107
    }
108
 
109
}
110
 
111
$minpin = $labelpin;
112
$boxwidth = 0;
113
%bw = ();
114
 
115
# for each horizontal slice of the symbol, keep track of how much
116
# width is used up by the left, middle, and right labels.
117
for $lp (keys %pinside) {
118
    next unless $pinside{$lp} =~ /left|right|label/;
119
    $yb = &alignpin($piny{$lp});
120
    for ($y=$yb-100; $y<=$yb+100; $y+=100) {
121
        if ($bw{$y}{$pinside{$lp}} < $rlen{$lp}) {
122
            $bw{$y}{$pinside{$lp}} = $rlen{$lp};
123
        }
124
    }
125
}
126
 
127
# Compute the height of the box. 
128
for $p (keys %pinside) {
129
    next unless $pinside{$p} =~ /left|right/;
130
    if ($maxy < $piny{$p}) {
131
        $maxy = $piny{$p};
132
    }
133
}
133 agaran 134
$maxy += 300;
118 jelle 135
 
136
# Now, use the slice widths to compute the minimum width of the box.
137
for ($i=0; $i<$maxy; $i+=100) {
138
    $w = $bw{$i}{left} + $bw{$i}{labels} + $bw{$i}{right};
139
    if ($bw{$i}{labels}) {
140
        $wl = ($bw{$i}{left} + $bw{$i}{labels}/2) * 2;
141
        $w = $wl if $w < $wl;
142
        $wl = ($bw{$i}{right} + $bw{$i}{labels}/2) * 2;
143
        $w = $wl if $w < $wl;
144
    }
145
    if ($bw{$i}{left} && $bw{$i}{labels}) {
146
        $w += 100;
147
    } elsif ($bw{$i}{left} && $bw{$i}{right}) {
148
        $w += 200;
149
    }
150
    if ($bw{$i}{right} && $bw{$i}{labels}) {
151
        $w += 100;
152
    }
153
    if ($boxwidth < $w) {
154
        $boxwidth = $w;
155
    }
156
}
157
 
121 jelle 158
 
159
for ($i = $y{labels}; $i <= 0; $i+=100) {
160
        my $w = $bw{$i}{labels};
161
        $w += 100 - ($w%100);
162
        #$w = (int($w/100) * 100) + (($w/100) > int($w/100))?100:0;
163
        if ($boxwidth < $w) {
164
                $boxwidth = $w;
165
        }
166
}
167
 
168
#printf STDERR "test: %d\n", $y{labels};
169
 
118 jelle 170
$boxwidth = $w{top} if $boxwidth < $w{top};
171
$boxwidth = $w{bottom} if $boxwidth < $w{bottom};
172
 
173
# Flip Y coordinates (we count from the top, but symbols coordinates
174
# are from the bottom).
175
for $p (keys %pinside) {
133 agaran 176
    next unless $pinside{$p} =~ /left|right/;
118 jelle 177
    $piny{$p} = $maxy - $piny{$p} + 300;
178
}
179
 
133 agaran 180
for $p (keys %pinside) {
181
    next unless $pinside{$p} =~ /label/;
182
    $piny{$p} = $maxy + $piny{$p} - $minpin * 200 + 400;
183
}
184
 
118 jelle 185
$boxwidth = &alignpin($boxwidth);
186
$boxwidth += 200;
187
 
188
# Adjust the position of the top/bottom pins so that, as a group,
189
# they're centered.
190
for $p (keys %pinside) {
191
    next unless $pinside{$p} =~ /top|bottom/;
192
    $pinx{$p} += &alignpin(($boxwidth - $w{$pinside{$p}})/2) + 300;
193
}
194
 
195
# Labels are centered in the box.
121 jelle 196
# labels have to be top, lef
118 jelle 197
for $lp ($minpin..-1) {
121 jelle 198
    #$pinx{$lp} = &alignpin($boxwidth/2) + 300;
131 agaran 199
    $pinx{$lp} = 300; # + &textlen($pinlabel{$lp})/2;
118 jelle 200
}
201
 
202
# Version.
203
print "v 20060123 1\n";
204
 
205
# Symbol box.
206
printf("B %d %d %d %d 3 0 0 0 -1 -1 0 -1 -1 -1 -1 -1\n",
207
       300, 300, $boxwidth, $maxy);
208
 
209
# These are the hidden labels.
210
$ax = 300 + $boxwidth;
211
$ay = 400 + $maxy;
212
for $a (reverse @attrs) {
213
    printf("T %d %d 9 10 0 0 0 0 1\n%s\n",
214
           $ax, $ay, $a);
215
    $ay += 200;
216
}
217
 
218
# Now print all the pins.
219
for $p (sort {$a<=>$b} keys %pinside) {
220
    next unless $pinside{$p};
221
    if ($pinside{$p} eq "left") {
222
        $pinx{$p} = 300;
223
    }
224
    if ($pinside{$p} eq "right") {
225
        $pinx{$p} = 300 + $boxwidth;
226
    }
227
    if ($p > 0 && !$saw_pin{$p}) {
228
        print STDERR "MISSING PIN $p\n";
229
        $errors++;
230
    } else {
231
        printf STDERR ("%3d  %-6s  %4d %4d  %s\n",
232
                       $p, $pinside{$p}, $pinx{$p}, $piny{$p}, $pinlabel{$p});
233
    }
234
 
235
    eval "&drawpin_$pinside{\"$p\"} (\"$p\")";
236
}
237
 
238
# what remains are helper functions; for drawing each type of pin,
239
# each type of label, etc.
240
 
241
sub drawpin_nc {
242
}
243
 
244
sub drawpin_top {
245
    my($pin) = @_;
246
    $y = $maxy + 300;
247
    printf("P %d %d %d %d 1 0 0\n",
248
           $pinx{$pin}, $y+300, $pinx{$pin}, $y);
249
    print "{\n";
250
    &pltext($pinx{$pin}, $y-50, 5, $pinlabel{$pin});
251
    &ntext($pinx{$pin}+50, $y+50, 0, $pin);
252
    print "}\n";
253
}
254
 
255
sub drawpin_bottom {
256
    my($pin) = @_;
257
    printf("P %d %d %d %d 1 0 0\n",
258
           $pinx{$pin}, 0, $pinx{$pin}, 300);
259
    print "{\n";
260
    &pltext($pinx{$pin}, 350, 3, $pinlabel{$pin});
261
    &ntext($pinx{$pin}+50, 250, 2, $pin);
262
    print "}\n";
263
}
264
 
265
sub drawpin_labels {
266
    my($pin) = @_;
131 agaran 267
    &ltext($pinx{$pin}, $piny{$pin}, 0, $pinlabel{$pin});
118 jelle 268
}
269
 
270
sub circle {
271
    my ($x, $y) = @_;
272
    print "V $x $y 50 3 0 0 0 -1 -1 0 -1 -1 -1 -1 -1\n";
273
}
274
 
275
sub drawpin_left {
276
    my($pin) = @_;
277
    $x = $pinx{$pin};
278
    $px = 50;
279
    if ($bubble{$pin}) {
280
        $x -= 100;
281
        &circle($x+50, $piny{$pin});
282
    }
283
    if ($edge{$pin}) {
284
        $px += 100;
285
        printf("L %d %d %d %d 3 0 0 0 0 0\n",
286
               $pinx{$pin}, $piny{$pin}-50,
287
               $pinx{$pin}+100, $piny{$pin});
288
        printf("L %d %d %d %d 3 0 0 0 0 0\n",
289
               $pinx{$pin}+100, $piny{$pin},
290
               $pinx{$pin}, $piny{$pin}+50);
291
 
292
    }
293
    printf("P %d %d %d %d 1 0 0\n",
294
           $pinx{$pin} - 300, $piny{$pin}, $x, $piny{$pin});
295
    print "{\n";
296
    &pltext($pinx{$pin} + $px, $piny{$pin}, 1, $pinlabel{$pin});
297
    &ntext($pinx{$pin} -100, $piny{$pin} + 50, 6, $pin);
298
    print "}\n";
299
}
300
 
301
sub drawpin_right {
302
    my($pin) = @_;
303
    $x = $pinx{$pin};
304
    $px = 50;
305
    if ($bubble{$pin}) {
306
        $x += 100;
307
        &circle($x-50, $piny{$pin});
308
    }
309
    if ($edge{$pin}) {
310
        $px += 100;
311
        printf("L %d %d %d %d 3 0 0 0 0 0\n",
312
               $pinx{$pin}, $piny{$pin}-50,
313
               $pinx{$pin}-100, $piny{$pin});
314
        printf("L %d %d %d %d 3 0 0 0 0 0\n",
315
               $pinx{$pin}-100, $piny{$pin},
316
               $pinx{$pin}, $piny{$pin}+50);
317
 
318
    }
319
    printf("P %d %d %d %d 1 0 0\n",
320
           $pinx{$pin} + 300, $piny{$pin}, $x, $piny{$pin});
321
    print "{\n";
322
    &pltext($pinx{$pin} - $px, $piny{$pin}, 7, $pinlabel{$pin});
323
    &ntext($pinx{$pin} +100, $piny{$pin} + 50, 0, $pin);
324
    print "}\n";
325
}
326
 
327
sub ntext {
328
    my ($x, $y, $a, $s) = @_;
329
    printf("T %d %d 5 8 1 1 0 %s 1\npinnumber=%s\n", $x, $y, $a, $s);
330
    printf("T %d %d 5 8 0 1 0 %s 1\npinseq=%s\n", $x, $y, $a, $s);
331
}
332
 
333
sub pltext {
334
    my ($x, $y, $a, $s) = @_;
335
    $s = "pinlabel=$s" unless $s =~ /=/;
336
    printf("T %d %d 9 10 1 1 0 %s 1\n%s\n", $x, $y, $a, $s);
337
}
338
 
339
sub ltext {
340
    my ($x, $y, $a, $s) = @_;
134 agaran 341
    printf("T %d %d 5 10 1 1 0 %s 1\n%s\n", $x, $y, $a, $s);
118 jelle 342
}
343
 
344
sub textlen {
345
    my($t) = @_;
346
    $t =~ s/^[^=]*=//;
347
    $t =~ s@\\_@@g;
348
    return length($t) * 120;
349
}
350
 
351
sub alignpin {
352
    my($v) = @_;
353
    return int(($v + 99) / 100) * 100;
354
}
355
 
356
exit $errors;