1 /*   Orcad.c  v 0.92
2  *   Copyright (C) 1999-2010 Matthew Ettus
3  *   Copyright (C) 1999-2016 gEDA Contributors
4  *   Copyright (C) 2017-2019 Lepton EDA Contributors
5  *
6  *   For more info email matt@ettus.com
7  *   Ths code is released under the terms of the GNU GPL
8  *   See www.fsf.org for a copy of the license
9  *
10  *  Changes 0.94 by <egil@kvaleberg.no>, october 5th 2002
11  *    Scaling defaults to 200%
12  *    Bus implemented - but still no bus entries!
13  *    Check for stack overwrite and other horrors
14  *    Changed orcad_xsize/orcad_ysize to sarlacc_dim
15  *    Port improved
16  *    Command line options
17  *
18  *  Todo:
19  *    Hierarchy
20  *    Bus entries
21  *    Many details - see BAD
22  */
23 
24 /*   This program will convert an ORCAD SDT IV file to geda format */
25 
26 #ifdef HAVE_CONFIG_H
27 #include "config.h"
28 #endif
29 
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <ctype.h>
33 #include <sys/types.h>
34 #include <sys/stat.h>
35 #include <fcntl.h>
36 #include <unistd.h>
37 #include <string.h>
38 #ifdef HAVE_GETOPT_H
39 #include <getopt.h>
40 #endif
41 
42 #include <liblepton/liblepton.h>
43 
44 /*
45  *  command line options
46  */
47 #define SARVERSION "0.94"
48 #define GEDAVERSION "20020825"
49 
50 #define DEFAULT_SCALE 200 /* was 100 */
51 
52 char *symbol_dir = 0;
53 int scale = DEFAULT_SCALE;
54 
55 #define TEXTSIZE ((scale <= 100) ? 6 : 10)
56 
57 /*
58  *  orcad
59  */
60 #define GET_TAG(VAL) (VAL & 0x0F)
61 
CONV16(char * base,int offset)62 int CONV16(char *base,int offset)
63 {
64 	int retval;
65 	retval = ((base[offset+1] & 255) <<8) | (base[offset] & 255);
66 	if(base[offset+1]&128)
67 		retval = retval | (65535U << 16);
68 	return retval;
69 }
70 
71 #define CONV32(VAR,POS) (VAR[POS]+VAR[POS+1]*256+VAR[POS+2]*65536+VAR[POS+3]*256*16777216)
72 
73 #define CONV(X)  ( (scale/10)*X )
74 #define CONVX(X) CONV(X)
75 #define CONVY(Y) ( 32700 - ((scale/10)*Y) )
76 
77 #define HDR_LEN 0x20
78 #define BYTECOUNT       0x16
79 #define DATE    0x05
80 #define PATH    0x3B
81 #define REV     0x60
82 #define TITLE   0x64
83 #define ORG     0x91
84 #define ADDR1   0xBE
85 #define ADDR2   0xEB
86 #define ADDR3   0x118
87 #define ADDR4   0x145
88 
remove_spaces(char * src)89 void remove_spaces(char *src)
90 {
91 	char *ptr=src;
92 	while (*ptr != 0)
93 	{
94 		if(*ptr == ' ')
95 			*ptr = '_';
96 		ptr++;
97 	}
98 }
99 
100 /*
101  *  read block from Orcad file
102  *  return size
103  */
read_block(int fd,char * block,int block_min_size,int block_max_size)104 unsigned read_block(int fd, char *block, int block_min_size,int block_max_size)
105 {
106     char sizebuf[2];
107     unsigned size;
108 
109     read(fd,sizebuf,2);
110     size = CONV16(sizebuf,0);
111     if (size < block_min_size) {
112 	fprintf(stderr,"Segment too small; size %d, min is %d\n",
113 						size, block_min_size);
114 	exit(1);
115     }
116     if (size > block_max_size) {
117 	fprintf(stderr,"Segment too large; size %d, max is %d\n",
118 						size, block_max_size);
119 	exit(1);
120     }
121     if (read(fd,block,size) != size) {
122 	fprintf(stderr,"File truncated\n");
123 	exit(1);
124     }
125     return size;
126 }
127 
read_string(char * dest,int dest_size,char * src)128 unsigned read_string(char *dest, int dest_size, char *src)
129 {
130     unsigned size = ((unsigned char *)src)[0];
131 
132     if (size+1 > dest_size) {
133 	fprintf(stderr,"Text too large; size %d, max is %d\n",
134 						size, dest_size-1);
135 	exit(1);
136     }
137     strncpy(dest,src+1,size);
138     dest[size] = '\0';
139     return size;
140 }
141 
read_string_file(int fd,char * dest,int dest_size)142 void read_string_file(int fd,char *dest, int dest_size)
143 {
144     unsigned char len;
145 
146     if (read(fd,&len,1) != 1) {
147 	fprintf(stderr,"File truncated\n");
148 	exit(1);
149     }
150     if (len+1 > dest_size) {
151 	fprintf(stderr,"Text too large; size %d, max is %d\n",
152 						len, dest_size-1);
153 	exit(1);
154     }
155     if (len > 0) {
156 	if (read(fd,dest,len) != len) {
157 	    fprintf(stderr,"File truncated\n");
158 	    exit(1);
159 	}
160     }
161     dest[len] = '\0';
162 }
163 
164 /*
165  *
166  */
parse_header(int fd1,int fd2)167 void parse_header(int fd1,int fd2)
168 {
169     unsigned char localbuf[32];
170     int length;
171 
172     read(fd1,localbuf,32);
173     if( strncmp((char *) localbuf,"Schematic FILE",14) )
174     {
175 	fprintf(stderr,"\nFile is not an ORCAD 16 Bit Schematic\n");
176 	exit(1);
177     }
178 
179     length=CONV32(localbuf,BYTECOUNT);
180     fprintf(stderr,"length: %d\n",length);
181 
182     lseek(fd2,length+HDR_LEN,SEEK_SET);
183 }
184 
185 /* BAD more titleblock stuff */
parse_titleblock(int fd)186 void parse_titleblock(int fd)
187 {
188     int size,sheet,total,ypos;
189     char localbuf[1000];
190     char data[100];
191     char pagesize;
192 
193     size = read_block(fd,localbuf,5,sizeof(localbuf));
194     // fprintf(stderr,"\nTitleblock %d bytes\n",size);
195 
196     sheet=CONV16(localbuf,0x00);
197     total=CONV16(localbuf,0x02);
198     fprintf(stderr,"Sheet #%d of %d\n",sheet,total);
199     read_string(data,sizeof(data),localbuf+DATE);
200     fprintf(stderr,"%s\n",data);
201 
202     switch(localbuf[4] & 0x0F)
203     {
204 	case 0: pagesize = 'A'; ypos = 8*scale+scale/2; break;
205 	case 1: pagesize = 'B'; ypos = 11*scale; break;
206 	case 2: pagesize = 'C'; ypos = 17*scale; break;
207 	case 3: pagesize = 'D'; ypos = 22*scale; break;
208 	case 4: pagesize = 'E'; ypos = 34*scale; break;
209 	default:  fprintf(stderr,"Unknown Page Size\n");exit(-1);
210     }
211     if (scale==100) {
212 	fprintf(stdout,"C %d %d 0 0 0 title-%c.sym\n",CONVX(0),CONVY(ypos),pagesize);
213     }
214 }
215 
216 /*  BAD  Rotation and mirroring origin issues */
217 /* Other component label issues */
parse_component(int fd1,int fd2)218 void parse_component(int fd1,int fd2)
219 {
220     char localbuf[1000];
221     char partname[256];
222     char filename[512];
223     char full_filename[1024];
224     int size;
225     int x,y;
226     int xpos = 0,ypos = 0,xpossav,ypossav;
227     int xgeda,ygeda;
228     int angle,mirror;
229     int i = 0;
230     int sarlacc_xsize = 0, sarlacc_ysize = 0;
231     int sarlacc_xoffset = 0, sarlacc_yoffset = 0;
232     int attribcnt;
233 
234     int refx,refy,ref_vis;
235     char refdes[32];
236     int valx,valy,val_vis;
237     char value[64];
238     char attrib[64];
239     char attribsav[64];
240 
241     char flags;
242     char vis;
243 
244     int pointer;
245     FILE *cfp;
246     char buff[128];
247 
248     size = read_block(fd1,localbuf,29,sizeof(localbuf));
249 
250     x=CONV16(localbuf,0);
251     y=CONV16(localbuf,2);
252 
253     refx = CONVX(x + CONV16(localbuf,4));
254     refy = CONVY(y + CONV16(localbuf,6));
255 
256     valx = CONVX(x + CONV16(localbuf,8));
257     valy = CONVY(y + CONV16(localbuf,10));
258 
259     xgeda = CONVX(x);
260     ygeda = CONVY(y);
261 
262     if(localbuf[12] & 0x80) mirror=1;
263     else mirror=0;
264 
265     angle=0;
266     if (localbuf[12] & 0x20) angle=90;
267     if (localbuf[12] & 0x40) angle+=180;
268 /* BAD decode and use device number, fix rotation offset */
269 
270     ref_vis=val_vis=1;
271 
272     flags = localbuf[13];
273     if (flags & 2) ref_vis=0;
274     if (flags & 4) val_vis=0;
275 /* BAD decode more flags */
276 
277     vis = localbuf[14];
278 
279     /* 14-27 */
280 
281     pointer = 28 + read_string(refdes,sizeof(refdes),localbuf+28) +1;
282     pointer = pointer + 1 +read_string(value,sizeof(value),localbuf+pointer);
283 
284     read_string_file(fd2,partname,sizeof(partname));
285     remove_spaces(partname);
286  // fprintf(stderr,"Component %s: %s\n",refdes,partname);
287     snprintf(filename,sizeof(filename),"%s-1.sym", partname);
288     if (symbol_dir) {
289 	snprintf(full_filename,sizeof(full_filename),"%s/%s",
290 					       symbol_dir, filename);
291     } else {
292 	snprintf(full_filename,sizeof(full_filename),"%s", filename);
293     }
294 
295     cfp = fopen(full_filename, "r");
296     if (cfp != NULL) {
297 	/* "sarlacc_dim=" set by sarlacc_sym */
298 	while (!feof(cfp)) {
299 	  fgets(buff, 128, cfp);
300 	  if (!strncmp(buff, "sarlacc_dim=", 12)) {
301 	    sscanf(buff+12, "%d,%d,%d,%d",
302 	    &sarlacc_xoffset,&sarlacc_yoffset,&sarlacc_xsize,&sarlacc_ysize);
303 	  }
304 	}
305 	fclose(cfp);
306 
307 	fprintf(stderr,"ref: %s dim = %d %d %d %d angle = %d mirror = %d\n",
308 	      refdes,
309 	      sarlacc_xoffset, sarlacc_yoffset,
310 	      sarlacc_xsize, sarlacc_ysize, angle, mirror);
311 
312 	switch (angle) {
313 	default: /* 0 */
314 	    if (mirror) {
315 		xgeda = xgeda + sarlacc_xsize + sarlacc_xoffset;
316 	    } else {
317 		xgeda = xgeda - sarlacc_xoffset;
318 	    }
319 	    ygeda = ygeda - (sarlacc_ysize + sarlacc_yoffset);
320 	    break;
321 	case 90:
322 	    xgeda = xgeda + sarlacc_ysize + sarlacc_yoffset;
323 	    if (mirror) {
324 		/* BAD untested */
325 		ygeda = ygeda + sarlacc_xoffset;
326 	    } else {
327 		ygeda = ygeda - (sarlacc_xsize + sarlacc_xoffset);
328 	    }
329 	    break;
330 	case 180:
331 	    if (mirror) {
332 		xgeda = xgeda - sarlacc_xoffset;
333 	    } else {
334 		xgeda = xgeda + sarlacc_xsize + sarlacc_xoffset;
335 	    }
336 	    ygeda = ygeda + sarlacc_yoffset;
337 	    break;
338 	case 270:
339 	    xgeda = xgeda - sarlacc_yoffset;
340 	    if (mirror) {
341 		/* BAD untested */
342 		ygeda = ygeda - (sarlacc_xsize + sarlacc_xoffset);
343 	    } else {
344 		ygeda = ygeda + sarlacc_xoffset;
345 	    }
346 	    break;
347 	}
348     } else {
349 	fprintf(stderr,"Couldn't find symbol %s in file: %s\n"
350 		       "Position on sheet will be uncertain\n", partname, full_filename);
351     }
352 
353     fprintf(stdout,"C %d %d 1 %d %d %s\n",
354 	xgeda,ygeda,angle,mirror,filename);
355     fprintf(stdout,"{\n");
356 
357 #if 0
358     /* For sarlacc debugging purposes, it's useful to see
359        if a component is mirrored and how much it's rotated */
360        fprintf(stdout,"T %d %d %d %d %d 1 0 0\nmirror=%d\n",
361 				refx,refy,GRAPHIC_COLOR,TEXTSIZE,0,mirror);
362        fprintf(stdout,"T %d %d %d %d %d 1 0 0\nrotation=%d\n",
363 				refx,refy,GRAPHIC_COLOR,TEXTSIZE,0,angle);
364 #endif
365     if (refdes[0] != 0) {
366       if (value[0] && refx==valx && refy==valy) {
367 	/* prevent text overlap */
368 	refy += scale;
369       }
370       fprintf(stdout,"T %d %d %d %d %d 1 0 0\nrefdes=%s\n",
371 	      refx,refy,ATTRIBUTE_COLOR,TEXTSIZE,ref_vis,refdes);
372     }
373 
374     if (value[0] != 0) {
375       fprintf(stdout,"T %d %d %d %d %d 1 0 0\nvalue=%s\n",
376 	      valx,valy,ATTRIBUTE_COLOR,TEXTSIZE,val_vis,value);
377     }
378 
379     attribcnt = 0;
380     if(flags & 0x40) {
381 	for(i=0;i<8;i++) {
382 	  /* This assumes that the last attribute is the footprint */
383 	    xpos = CONVX(x + CONV16(localbuf,pointer));
384 	    ypos = CONVY(y + CONV16(localbuf,pointer+2));
385 	    pointer += 4;
386 	    size = read_string(attrib,sizeof(attrib),localbuf+pointer);
387 	    pointer += size + 1;
388 	    if (size > 0) {
389 	      attribcnt++;
390 	      fprintf(stdout,"T %d %d %d %d %d 1 0 0\npattern=%s\n",
391 				xpos,ypos,ATTRIBUTE_COLOR,TEXTSIZE,
392 		      ( (flags & (1<<i))?1:0 ),attrib);
393 	      xpossav = xpos;
394 	      ypossav = ypos;
395 	      strcpy(attribsav, attrib);
396 	    }
397 	}
398     }
399     if (attribcnt > 0 && attrib[0]) {
400       fprintf(stdout,"T %d %d %d %d %d 1 0 0\n"
401 		     "footprint=%s\n",
402 		     xpos,ypos,ATTRIBUTE_COLOR,TEXTSIZE,
403 	      ( (flags & (1<<i))?1:0 ),attrib);
404     }
405     fprintf(stdout,"}\n");
406 }
407 
408 /*  BAD  Sheets need work  */
parse_sheet(int fd)409 void parse_sheet (int fd)
410 {
411     char localbuf[1000];
412     char filename[1000];
413     char filetext[1000];
414     int size;
415     int index;
416     int n;
417     int x1,y1,x2,y2;
418 
419     size = read_block(fd,localbuf,15,sizeof(localbuf));
420     // fprintf(stderr,"Sheet %d bytes\n",size);
421 
422     x1=CONVX(CONV16(localbuf,0));
423     y1=CONVY(CONV16(localbuf,2));
424 
425     x2=CONV(CONV16(localbuf,4));
426     y2=CONV(CONV16(localbuf,6));
427     index = 8;
428 
429     /* BAD 5 bytes - dunno? */
430     index += 5;
431 
432     n = 1+read_string(filename,sizeof(filename),localbuf+index);
433     index += n;
434     n = 1+read_string(filetext,sizeof(filetext),localbuf+index);
435     index += n;
436 
437     /* BAD Implement Hierarchy properly! */
438     fprintf(stderr,"Hierarchy\n");
439     fprintf(stderr,"xy = %d %d %d %d\n",x1,y1,x2,y2);
440     for (n=8; n<13; ++n) fprintf(stderr,"%02x ",localbuf[n] & 0xff);
441     fprintf(stderr,"\nfile = %s\n",filename);
442     fprintf(stderr,"text = %s\n",filetext);
443 
444     /* BAD not the way to do it... */
445     fprintf(stdout,"C %d %d 0 0 0 include-1.sym\n",x1,y1-y2);
446     fprintf(stdout,"{\n");
447     fprintf(stdout,"B %d %d %d %d %d 0 0 0 -1 -1 0 -1 -1 -1 -1 -1\n",
448 					x1,y1-y2,x2,y2,GRAPHIC_COLOR);
449     fprintf(stdout,"T %d %d %d %d 0 1 0 0\n"
450 		   "source=%s\n",x1,y1-y2,ATTRIBUTE_COLOR,TEXTSIZE,filename);
451     fprintf(stdout,"T %d %d %d %d 1 1 0 0\n"
452 		   "%s\n",x1,(y1-y2)-scale,ATTRIBUTE_COLOR,TEXTSIZE,filetext);
453     fprintf(stdout,"}\n");
454 }
455 
456 static int pending_netlabel=0;
457 static char netlabel[256];
458 static int netlabel_x, netlabel_y, netlabel_angle;
459 
460 /* BAD Set wire color properly  */
wire_or_bus(int fd,char kind,int color)461 static void wire_or_bus(int fd, char kind, int color)
462 {
463     char localbuf[32];
464     int size;
465     int x1,y1,x2,y2;
466 
467     size = read_block(fd,localbuf,8,sizeof(localbuf));
468 
469     x1=CONVX(CONV16(localbuf,0));
470     y1=CONVY(CONV16(localbuf,2));
471 
472     x2=CONVX(CONV16(localbuf,4));
473     y2=CONVY(CONV16(localbuf,6));
474     fprintf(stdout,"%c %d %d %d %d %d 0 0 0 -1 -1\n",kind,x1,y1,x2,y2,color);
475     if (pending_netlabel) {
476       fprintf(stdout,"{\n");
477       fprintf(stdout,"T %d %d %d %d 1 1 %d 0\n", netlabel_x, netlabel_y,
478 			      ATTRIBUTE_COLOR, TEXTSIZE, netlabel_angle);
479       fprintf(stdout,"label=%s\n", netlabel); /* BAD netname= */
480       fprintf(stdout,"}\n");
481       pending_netlabel = 0;
482     }
483 }
484 
parse_wire(int fd)485 void parse_wire (int fd)
486 {
487     wire_or_bus(fd, 'N', NET_COLOR);
488 }
489 
490 /*  BAD Haven't implemented GEDA buses */
491 /*  but guessing that Orcad busses are parsed just like wires... */
parse_bus(int fd)492 void parse_bus (int fd)
493 {
494     wire_or_bus(fd, 'U', BUS_COLOR);
495 }
496 
497 /*  BAD How do we handle junctions in GEDA? */
498 /* 19990726 I think we don't need to worry
499  * ORCAD splits wires at junction points
500  */
501 
parse_junction(int fd)502 void parse_junction (int fd)
503 {
504     char localbuf[32];
505     int size;
506 
507     size = read_block(fd,localbuf,4,sizeof(localbuf));
508 
509 /*
510     x=CONVX(CONV16(localbuf,0));
511     y=CONVY(CONV16(localbuf,2));
512     fprintf(stderr,"Junctions %d %d\n",x,y);
513 */
514 
515 }
516 
517 /* BAD Fix handling of ports */
518 
parse_port(int fd)519 void parse_port (int fd)
520 {
521     char localbuf[1024];
522     char textbuf[1024];
523     int size;
524     int x,y;
525     int w;
526     int m;
527     int mirror = 0;
528 
529     size = read_block(fd,localbuf,7,sizeof(localbuf));
530 
531     x = CONVX(CONV16(localbuf,0));
532     y = CONVY(CONV16(localbuf,2));
533     w = localbuf[4] & 0xff;
534     m = localbuf[5] & 0xff;
535     read_string(textbuf,sizeof(textbuf),localbuf+6);
536 
537     // fprintf(stderr,"PORT %s %d %d %d 0x%x\n",textbuf,x,y,w,m);
538 
539     switch (m & 0x60) {
540     case 0x40: /* 0101 */
541     case 0x20: /* 1010 */
542 	x += scale + w * (scale/10);
543 	break;
544     case 0x00: /* 0000 */
545 	       /* 1001 */
546     case 0x60: /* 1111 */
547 	mirror = 1;
548 	break;
549     }
550     fprintf(stdout,"C %d %d 1 0 %d input-orcad-1.sym\n",x,y,mirror);
551     fprintf(stdout,"{\n"
552 		   "T %d %d %d 8 1 1 0 0\nvalue=%s\n"
553 		   "}\n",x,y,GRAPHIC_COLOR,
554 								      textbuf);
555 }
556 
557 /* BAD Fix Labels attach to wire.  Multiline issues?*/
558 /* Fix text sizing */
parse_label(int fd)559 void parse_label (int fd)
560 {
561     char localbuf[1000];
562     char textbuf[1000];
563     int size;
564     int x,y;
565     int angle;
566     int textsize;
567 
568     size = read_block(fd,localbuf,5,sizeof(localbuf));
569 
570     x=CONVX(CONV16(localbuf,0));
571     y=CONVY(CONV16(localbuf,2));
572 
573     read_string(textbuf,sizeof(textbuf),localbuf+0x06);
574 
575     angle=0;
576     textsize = 5* CONV16(localbuf,4);
577     if (textsize<0)
578     {
579 	textsize *= -1;
580 	angle = 90;
581     }
582     /*    fprintf(stdout,"T %d %d %d %d 1 1 %d 0\n",x,y,GRAPHIC_COLOR, TEXTSIZE, angle);
583 	  fprintf(stdout,"net=%s ATTACHME\n",textbuf);                    */
584     pending_netlabel = 1;
585     strncpy(netlabel, textbuf, 256);
586     netlabel_x = x;
587     netlabel_y = y;
588     netlabel_angle = angle;
589 }
590 
591 /* BAD Fix Entries */
592 
parse_entry(int fd)593 void parse_entry (int fd)
594 {
595     char localbuf[32];
596     int size;
597     int x,y,type;
598 
599     size = read_block(fd,localbuf,5,sizeof(localbuf));
600     // fprintf(stderr,"Entry %d bytes\n",size);
601 
602     x=CONVX(CONV16(localbuf,0));
603     y=CONVY(CONV16(localbuf,2));
604     type=localbuf[4];
605     fprintf(stderr,"Entry %d %d type %d\n",x,y,type);
606 }
607 
608 /* BAD Fix Dashed Lines */
609 
parse_dashed(int fd)610 void parse_dashed (int fd)
611 {
612     char localbuf[32];
613     int size;
614     int x,y,type;
615 
616     size = read_block(fd,localbuf,4,sizeof(localbuf));
617     fprintf(stderr,"Dashed  %d bytes\n",size);
618 
619     x=CONVX(CONV16(localbuf,0));
620     y=CONVY(CONV16(localbuf,2));
621     type=localbuf[4];
622 }
623 
624 /* BAD Fix power */
625 /* How do netlisters handle power connections/nets? */
626 
parse_power(int fd)627 void parse_power (int fd)
628 {
629     char localbuf[256];
630     char textbuf[256];
631     const char *symbol;
632     int size;
633     int x,y,xtext,ytext;
634     int angle;
635     char type;
636 
637     size = read_block(fd,localbuf,5,sizeof(localbuf));
638     // fprintf(stderr,"POWER %d bytes\n",size);
639 
640     read_string(textbuf,sizeof(textbuf),localbuf+0x05);
641 
642     x=CONVX(CONV16(localbuf,0));
643     y=CONVY(CONV16(localbuf,2));
644     type = localbuf[4];
645     switch(type & 0x0C)
646     {
647 	case 0x04: angle = 180; xtext = x; ytext = y - 600; break;
648 	case 0x08: angle = 90; ytext = y; xtext = x-600; break;
649 	case 0x0C: angle = 270;ytext = y; xtext = x+600; break;
650 	default: angle = 0; xtext=x;ytext = y+600;
651     }
652     switch(type & 0x03)
653     {
654 /*  BAD  GEDA only has bar and circle pix.  Also, they
655  *  All say VCC or VDD, which they should not */
656 	case 0x02:
657 		symbol = "vcc-orcad-bar-1.sym";break; /* BAR */
658 	case 0x00: /* circle */
659 	case 0x01: /* arrow */
660 	case 0x03: /* wave */
661 	default:
662 		symbol = "vcc-orcad-circle-1.sym";break;
663     }
664     fprintf(stdout,"C %d %d 1 %d 0 %s\n",x,y,angle,symbol);
665     /*    fprintf(stdout,"{\n"
666 			 "T %d %d %d %d 1 1 %d 0\n"
667 			 "value=%s\n"
668 			 "}\n",
669 	    xtext,ytext,GRAPHIC_COLOR,TEXTSIZE,angle%180,textbuf);*/
670     fprintf(stdout,"{\n"
671 		   "T %d %d %d %d 1 1 %d 0\n"
672 		   "net=%s:1\n"
673 		   "}\n",
674 	    xtext,ytext,GRAPHIC_COLOR,TEXTSIZE,angle%180,textbuf);
675 }
676 
677 /*  BAD Fix Text color and check rotation */
678 /*  BAD Fix multi-line text */
679 
parse_text(int fd)680 void parse_text (int fd)
681 {
682     char localbuf[1024];
683     char textbuf[1024];
684     int size;
685     int x,y,textsize,angle;
686 
687     size = read_block(fd,localbuf,7,sizeof(localbuf));
688 
689     x=CONVX(CONV16(localbuf,0));
690     y=CONVY(CONV16(localbuf,2));
691     read_string(textbuf,sizeof(textbuf),localbuf+6);
692 
693     angle=0;
694     textsize = TEXTSIZE * CONV16(localbuf,4);
695     if (textsize<0)
696     {
697 	textsize *= -1;
698 	angle = 90;
699     }
700     fprintf(stdout,"T %d %d %d %d 1 1 %d 0\n",x,y,GRAPHIC_COLOR,textsize,angle);
701     fprintf(stdout,"%s\n",textbuf);
702 }
703 
704 /* BAD - Markers are unimplemented in gEDA (yet).
705  * They are the no-connects that you can place on pins to
706  * exempt them from the connectivity checks in DRC/ERC
707  */
708 
parse_marker(int fd)709 void parse_marker (int fd)
710 {
711     char localbuf[1024];
712     int size;
713 
714     size = read_block(fd,localbuf,0,sizeof(localbuf));
715 
716     /* fprintf(stderr,"MARKER %d\n",size); */
717 }
718 
719 
parse_block(int fd1,int fd2)720 int parse_block(int fd1,int fd2)
721 {
722     char tag;
723     read(fd1,&tag,1);
724     switch(GET_TAG(tag))
725     {
726 	case 0x00:
727 	    parse_titleblock(fd1);
728 	    break;
729 	case 0x01:
730 	    parse_sheet(fd1);
731 	    break;
732 	case 0x02:
733 	    parse_component(fd1,fd2);
734 	    break;
735 	case 0x03:
736 	    parse_wire(fd1);
737 	    break;
738 	case 0x04:
739 	    parse_bus(fd1);
740 	    break;
741 	case 0x05:
742 	    parse_junction(fd1);
743 	    break;
744 	case 0x06:
745 	    parse_port(fd1);
746 	    break;
747 	case 0x07:
748 	    parse_label(fd1);
749 	    break;
750 	case 0x08:
751 	    parse_entry(fd1);
752 	    break;
753 	case 0x09:
754 	    parse_dashed(fd1);
755 	    break;
756 	case 0x0a:
757 	    parse_power(fd1);
758 	    break;
759 	case 0x0b:
760 	    parse_text(fd1);
761 	    break;
762 	case 0x0c:
763 	    parse_marker(fd1);
764 	    break;
765 	case 0x0f:
766 	    return 0;
767 	    break;
768 	default:
769 	    fprintf(stderr,"\nUnknown Block Tag\n");
770 	    exit(-1);
771 	    break;
772     }
773 
774 
775     return 1;
776 }
777 
778 int
main(int argc,char ** argv)779 main(int argc, char **argv)
780 {
781     int c;
782     int fd1,fd2;
783 
784     while ((c = getopt(argc, argv, "d:hs:v")) > 0) {
785 	switch (c) {
786 	case 'd':
787 	    symbol_dir = optarg;
788 	    break;
789 	case 's':
790 	    scale = atoi(optarg);
791 	    break;
792 	case 'v':
793 	    fprintf(stderr,"sarlacc_scheme ver %s\n", SARVERSION);
794 	    exit(0);
795 	    break;
796 	case 'h':
797 	default:
798 	    fprintf(stderr,"Convert Oracd schematics file (16 bit format) to gEDA\n");
799 	  usage:
800 	    fprintf(stderr,"\nUsage:   %s [options] infile >outfile\n"
801 			   "\nOptions:"
802 			   "\n         -d<dir>  directory for symbols (from sarlacc_sym)"
803 			   "\n         -h       help"
804 			   "\n         -s<n>    scale <n>%%, default is %d"
805 			   "\n         -v       version"
806 			   "\n\n",
807 			   argv[0],DEFAULT_SCALE);
808 	    exit(1);
809 	    break;
810 	}
811     }
812 
813     if( optind+1 != argc )
814     {
815 	goto usage;
816     }
817 
818     /* BAD update to latest file format.. */
819     fprintf(stdout,"v %s\n",GEDAVERSION);
820 
821     fd1 = open(argv[optind],O_RDONLY);
822     if( fd1 < 0 )
823     {
824 	fprintf(stderr,"\nCould not open input file: %s\n",argv[optind]);
825 	exit(1);
826     }
827     fd2 = open(argv[optind],O_RDONLY);
828     if( fd2 < 0 )
829     {
830 	fprintf(stderr,"\n  Could not open input file part deux\n");
831 	exit(-1);
832     }
833 
834     parse_header(fd1,fd2);
835 
836     while(parse_block(fd1,fd2));
837     fprintf(stderr,"\n Normal End\n");
838 
839     return(0);
840 }
841 
842 
843 
844 
845