home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <malloc.h>
- #include <ctype.h>
- #include "cell.h"
-
- extern int Nrows, Ncols; /* board dimensions */
-
- extern int InitBoardDone; /* sanity check */
- extern int SortConnects; /* 0 = don't sort, 1 = sort */
-
- /* memory usage */
- extern unsigned long Ltotal; /* for board */
- extern unsigned long Itotal; /* for dist */
- extern unsigned long Ctotal; /* for dir */
-
- /*
- ** the following types of input lines are legal (spaces and tabs can separate
- ** tokens, and case is not significant):
- **
- ** 1) a blank line (ignored)
- ** 2) ';' followed by anything (ignored)
- ** use semicolon to insert comments.
- ** 3) DIMENSION (row,column)
- ** this defines the number of rows and columns on the board, and must be
- ** given before any of the lines below. note that the user sees the board
- ** coordinate space as being 1-based, but internally it is 0-based.
- ** 4) HOLE (row,column)
- ** this defines a hole location.
- ** 5) CONNECT thing AND thing
- ** this declares that two holes are to be electrically connected. a thing
- ** can be (row,column), or name1.name2, where name1 is the name of a
- ** CHIPAT-defined chip, and name2 is the name of one of its pins, or a
- ** number, giving the pin number of the named chip. you can use "TO" or
- ** "=" instead of "AND" if you want.
- ** 6) PRIORITY CONNECT thing AND thing
- ** same as above, except the order of connections will be preserved. the
- ** autorouter is free to reorder the non-PRIORITY CONNECTs, and in fact
- ** reorders them shortest first. if there are PRIORITY CONNECTs, they will
- ** all be routed before non-PRIORITY CONNECTs.
- ** 7) INCLUDE filename
- ** this causes the input to be temporarily taken from the given filename.
- ** when the given filename is completely processed (EOF encountered),
- ** control returns to the current file. INCLUDE statements may be nested
- ** (they may occur inside the given filename). complete and partial
- ** pathnames can be used (C:\TTL.INC, ..\TTL.INC, \TTL.INC, FOO\TTL.INC).
- ** 8) CHIP TYPE=type PINS=number HORIZONTAL=number VERTICAL=number
- ** this declares a chip type, which can be used to place chips on the
- ** board (see CHIPAT, below), but does not itself place anything on the
- ** board. TYPE gives the name that will be used in later CHIPAT
- ** statements. PINS declares the number of pins. HORIZONTAL gives the
- ** number of 50-mil units separating adjacent pins (along the long side of
- ** the chip). and VERTICAL gives the number of 50-mil units separating
- ** pins across from each other (across the skinny width of the chip).
- ** standard values for HORIZONTAL and VERTICAL are 2 and 6, respectively.
- ** all CHIP type names must be unique.
- ** 9) number=name
- ** this declares a pin name for the chip that is currently being defined.
- ** this statement must follow a CHIP statement. pins not defined will have
- ** no name, but you can still refer to them by number. each pin on a chip
- ** can be named at most once.
- ** 10) name=number
- ** same as above.
- ** 11) CHIPAT (row,column) NAME=name TYPE=type ORIENTATION=orientation
- ** this defines an instance of a chip, and places the appropriate holes on
- ** the board. (row,column) is the location of pin 1. NAME defines the name
- ** to be used in following CONNECT statements. TYPE declares the
- ** CHIPAT-defined type of the chip. ORIENTATION can have the values
- ** NORMAL, UP, DOWN, and UPSIDEDOWN. all CHIPAT names must be unique.
- **
- ** NORMAL UP DOWN UPSIDEDOWN
- **
- ** 6 5 4 +---+ +---+ 3 2 1
- ** +-*-*-*-+ 4 * * 3 1 * | * 6 +-*-*-*-+
- ** | -> | 5 * ^ * 2 2 * v * 5 | <- |
- ** +-*-*-*-+ 6 * | * 1 3 * * 4 +-*-*-*-+
- ** 1 2 3 +---+ +---+ 4 5 6
- **
- ** usually the highest-numbered pin (pin N) is Vcc (power) and the pin
- ** farthest from it (pin N/2) is GND (ground).
- */
-
- /* chip orientations (rotations) */
- #define ORIENT_NORMAL 1
- #define ORIENT_UP 2
- #define ORIENT_DOWN 3
- #define ORIENT_UPSIDEDOWN 4
-
- /* input token types */
- #define TOK_EOF 1 /* end of file, no more tokens */
- #define TOK_NEWLINE 2 /* end of line */
- #define TOK_NUMBER 3 /* number (digits) */
- #define TOK_HOLE 4 /* "HOLE" */
- #define TOK_ROWCOLUMN 5 /* "(row,column)" */
- #define TOK_CONNECT 6 /* "CONNECT" */
- #define TOK_EQUAL 7 /* "=" */
- #define TOK_AND 8 /* "AND" */
- #define TOK_ALPHANUM 9 /* name (letters, digits, ':','.','\') */
- #define TOK_CHIP 10 /* "CHIP" */
- #define TOK_NAME 11 /* "NAME" */
- #define TOK_PINS 12 /* "PINS" */
- #define TOK_HORIZONTAL 13 /* "HORIZONTAL" */
- #define TOK_VERTICAL 14 /* "VERTICAL" */
- #define TOK_INCLUDE 15 /* "INCLUDE" */
- #define TOK_CHIPAT 16 /* "CHIPAT" */
- #define TOK_TYPE 17 /* "TYPE" */
- #define TOK_ORIENTATION 18 /* "ORIENTATION" */
- #define TOK_NORMAL 19 /* "NORMAL" */
- #define TOK_UP 20 /* "UP" */
- #define TOK_DOWN 21 /* "DOWN" */
- #define TOK_UPSIDEDOWN 22 /* "UPSIDEDOWN" */
- #define TOK_DIMENSION 23 /* "DIMENSION" */
- #define TOK_PRIORITY 24 /* "PRIORITY" */
- #define TOK_TO 25 /* "TO" */
-
- struct reserved { /* reserved word input tokens */
- char *tokenname;
- int tokenvalue;
- };
-
- static struct reserved tokenmatch[] = { /* reserved word table */
- { "HOLE", TOK_HOLE }, { "CONNECT", TOK_CONNECT },
- { "AND", TOK_AND }, { "CHIP", TOK_CHIP },
- { "NAME", TOK_NAME }, { "PINS", TOK_PINS },
- { "HORIZONTAL", TOK_HORIZONTAL }, { "VERTICAL", TOK_VERTICAL },
- { "INCLUDE", TOK_INCLUDE }, { "CHIPAT", TOK_CHIPAT },
- { "TYPE", TOK_TYPE }, { "ORIENTATION", TOK_ORIENTATION },
- { "NORMAL", TOK_NORMAL }, { "UP", TOK_UP },
- { "DOWN", TOK_DOWN }, { "UPSIDEDOWN", TOK_UPSIDEDOWN },
- { "DIMENSION", TOK_DIMENSION }, { "PRIORITY", TOK_PRIORITY },
- { "TO", TOK_TO }
- };
-
- #define MAXTOK 80 /* maximum token length (including null) */
-
- static int numres = sizeof(tokenmatch) / sizeof(tokenmatch[0]);
- static char token[MAXTOK]; /* the current token is formed here */
-
- struct pinassign { /* for assigning names to pins */
- int index;
- char far *name;
- struct pinassign far *next;
- };
-
- struct template { /* for "CHIP" declarations */
- char far *type;
- int pins;
- int horizontal;
- int vertical;
- struct pinassign far *pinlist;
- struct template far *next;
- };
-
- struct instance { /* for "CHIPAT" definitions */
- int row;
- int column;
- char far *name;
- struct template far *type;
- int orientation;
- struct instance far *next;
- };
-
- static struct template far *chip = NULL; /* list of CHIPs */
- static struct instance far *chipat = NULL; /* list of CHIPATs */
-
- extern void InitBoard( void );
- extern long GetCell( int, int, int );
- extern void SetCell( int, int, int, long );
- extern void InitWork( void );
- extern void SetWork( int, int, char far *, int, int, char far *, int );
- extern void SortWork( void );
- extern void Nomem( void );
-
- int Initialize( char *, int );
- static int initfile( FILE *, char * );
- static void initchip( struct instance far *, char *, int );
- static void locate( char *, int *, int *, char *, int );
- static int gettoken( FILE *, char *, int );
- static char far *fcopy( char * );
- static int same( char far *, char far * );
- void Report( FILE * );
-
- int Initialize ( file, echo ) /* get hole coordinates and connections */
- char *file;
- int echo;
- {
- FILE *fp;
- int tot;
-
- if (echo)
- printf( "Enter Initialize()\n" );
- if (!(fp = fopen( file, "r" ))) {
- fprintf( stderr, "can't open %s\n", file );
- exit( -1 );
- }
- InitWork(); /* clear work list */
- tot = initfile( fp, file ); /* read input file(s) */
- if (SortConnects)
- SortWork(); /* arrange to do shortest ones first */
- if (echo) {
- printf( " %lu bytes used for Board\n", Ltotal );
- printf( " %lu bytes used for Dist\n", Itotal );
- printf( " %lu bytes used for Dir\n", Ctotal );
- printf( "Exit Initialize()\n" );
- }
- if (fclose( fp ))
- fprintf( stderr, "error closing %s\n", file );
- return( tot );
- }
-
- /* some useful macros (common code sequences) */
-
- #define FileLine { fprintf( stderr, "%s(%d): ", file, line ); }
-
- #define GetTok(tok) ((tok) = gettoken( fp, file, line ))
-
- #define SkipRest { while (GetTok(tok) != TOK_EOF \
- && tok != TOK_NEWLINE) ; \
- if (tok == TOK_NEWLINE) line++; }
-
- #define SkipTokRest { while (tok != TOK_EOF && tok != TOK_NEWLINE) \
- GetTok(tok); } \
- if (tok == TOK_NEWLINE) line++; \
- continue;
-
- #define CheckInit { if (!InitBoardDone) { \
- FileLine; \
- fprintf( stderr, "need dimensions first\n" ); \
- SkipRest; \
- continue; } }
-
- static int initfile ( fp, file ) /* read and process input file(s) */
- FILE *fp;
- char *file;
- {
- int tok, r1, c1, r2, c2, i, line;
- char far *p;
- char far *n1;
- char far *n2;
- long cell;
- struct template far *p1;
- struct pinassign far *p2;
- struct pinassign far *p22;
- struct instance far *p3;
- FILE *fnew;
- char *fname;
- int tot = 0;
-
- line = 1;
- while (GetTok(tok) != TOK_EOF) {
- if (tok == TOK_DIMENSION) {
- if (InitBoardDone) { /* can only do it once */
- FileLine;
- fprintf( stderr,
- "redundant dimensions\n" );
- SkipRest;
- continue;
- }
- if (GetTok(tok) != TOK_ROWCOLUMN) {
- FileLine;
- fprintf( stderr, "expect (row,column)\n" );
- SkipTokRest;
- }
- sscanf( token, "(%d,%d)", &Nrows, &Ncols );
- if (Nrows <= 0 || Ncols <= 0) {
- FileLine;
- fprintf( stderr, "dimension error\n" );
- }
- else /* allocate memory for data structures */
- InitBoard();
- }
- else if (tok == TOK_HOLE) {
- CheckInit; /* must get dimensions first */
- if (GetTok(tok) != TOK_ROWCOLUMN) {
- FileLine;
- fprintf( stderr, "expect (row,column)\n" );
- SkipTokRest;
- }
- sscanf( token, "(%d,%d)", &r1, &c1 );
- if (r1 <= 0 || r1 > Nrows || c1 <= 0 || c1 > Ncols) {
- FileLine;
- fprintf( stderr, "out of range\n" );
- }
- else { /* position the hole on the board */
- /* should check for neighbor holes (error) */
- SetCell( r1-1, c1-1, TOP, HOLE );
- SetCell( r1-1, c1-1, BOTTOM, HOLE );
- }
- }
- else if (tok == TOK_CONNECT) {
- CheckInit; /* must get dimensions first */
- if (GetTok(tok) == TOK_ROWCOLUMN)
- sscanf( token, "(%d,%d)", &r1, &c1 );
- else if (tok == TOK_ALPHANUM)
- locate( token, &r1, &c1, file, line );
- else {
- FileLine;
- fprintf( stderr,
- "expect (row,column) or name\n" );
- SkipTokRest;
- }
- n1 = fcopy( token );
- if (GetTok(tok) != TOK_EQUAL
- && tok != TOK_AND && tok != TOK_TO) {
- FileLine;
- fprintf( stderr, "expect = or AND or TO\n" );
- SkipTokRest;
- }
- if (GetTok(tok) == TOK_ROWCOLUMN)
- sscanf( token, "(%d,%d)", &r2, &c2 );
- else if (tok == TOK_ALPHANUM)
- locate( token, &r2, &c2, file, line );
- else {
- FileLine;
- fprintf( stderr,
- "expect (row,column) or name\n" );
- SkipTokRest;
- }
- n2 = fcopy( token );
- if (r1 <= 0 || r1 > Nrows || r2 <= 0 || r2 > Nrows
- || c1 <= 0 || c1 > Ncols
- || c2 <= 0 || c2 > Ncols) {
- FileLine;
- fprintf( stderr, "out of range\n" );
- _ffree( n1 );
- _ffree( n2 );
- }
- else {
- cell = GetCell( r1-1, c1-1, TOP );
- if (!(cell & HOLE)) {
- FileLine;
- fprintf( stderr, "no source hole\n" );
- _ffree( n1 );
- _ffree( n2 );
- SkipRest;
- continue;
- }
- cell = GetCell( r2-1, c2-1, TOP );
- if (!(cell & HOLE)) {
- FileLine;
- fprintf( stderr, "no target hole\n" );
- _ffree( n1 );
- _ffree( n2 );
- SkipRest;
- continue;
- }
- SetWork( r1-1, c1-1, n1, r2-1, c2-1, n2, 0 );
- tot++;
- }
- }
- else if (tok == TOK_PRIORITY) {
- CheckInit; /* must get dimensions first */
- if (GetTok(tok) != TOK_CONNECT) {
- FileLine;
- fprintf( stderr, "expect CONNECT\n" );
- SkipTokRest;
- }
- if (GetTok(tok) == TOK_ROWCOLUMN)
- sscanf( token, "(%d,%d)", &r1, &c1 );
- else if (tok == TOK_ALPHANUM)
- locate( token, &r1, &c1, file, line );
- else {
- FileLine;
- fprintf( stderr,
- "expect (row,column) or name\n" );
- SkipTokRest;
- }
- n1 = fcopy( token );
- if (GetTok(tok) != TOK_EQUAL
- && tok != TOK_AND && tok != TOK_TO) {
- FileLine;
- fprintf( stderr, "expect = or AND or TO\n" );
- SkipTokRest;
- }
- if (GetTok(tok) == TOK_ROWCOLUMN)
- sscanf( token, "(%d,%d)", &r2, &c2 );
- else if (tok == TOK_ALPHANUM)
- locate( token, &r2, &c2, file, line );
- else {
- FileLine;
- fprintf( stderr,
- "expect (row,column) or name\n" );
- SkipTokRest;
- }
- n2 = fcopy( token );
- if (r1 <= 0 || r1 > Nrows || r2 <= 0 || r2 > Nrows
- || c1 <= 0 || c1 > Ncols
- || c2 <= 0 || c2 > Ncols) {
- FileLine;
- fprintf( stderr, "out of range\n" );
- _ffree( n1 );
- _ffree( n2 );
- }
- else {
- cell = GetCell( r1-1, c1-1, TOP );
- if (!(cell & HOLE)) {
- FileLine;
- fprintf( stderr, "no source hole\n" );
- _ffree( n1 );
- _ffree( n2 );
- SkipRest;
- continue;
- }
- cell = GetCell( r2-1, c2-1, TOP );
- if (!(cell & HOLE)) {
- FileLine;
- fprintf( stderr, "no target hole\n" );
- _ffree( n1 );
- _ffree( n2 );
- SkipRest;
- continue;
- }
- SetWork( r1-1, c1-1, n1, r2-1, c2-1, n2, 1 );
- tot++;
- }
- }
- else if (tok == TOK_INCLUDE) {
- CheckInit; /* must get dimensions first */
- if (GetTok(tok) != TOK_ALPHANUM) {
- FileLine;
- fprintf( stderr,
- "expect file name for INCLUDE\n" );
- SkipTokRest;
- }
- if (!(fnew = fopen( token, "r" ))) {
- FileLine;
- fprintf( stderr,
- "can't open INCLUDE file %s\n",
- token );
- SkipRest;
- continue;
- }
- if (!(fname = strdup( token )))
- Nomem();
- if (GetTok(tok) != TOK_EOF
- && tok != TOK_NEWLINE) {
- FileLine;
- fprintf( stderr,
- "extra chars on INCLUDE line\n" );
- SkipRest;
- }
- if (tok == TOK_NEWLINE)
- line++;
- tot += initfile( fnew, fname ); /* recurse */
- if (fclose( fnew )) {
- FileLine;
- fprintf( stderr,
- "error closing INCLUDE file\n" );
- }
- free( fname );
- continue; /* already ate the NEWLINE, if any */
- }
- else if (tok == TOK_CHIP) {
- CheckInit; /* must get dimensions first */
- if (GetTok(tok) != TOK_TYPE
- || GetTok(tok) != TOK_EQUAL
- || GetTok(tok) != TOK_ALPHANUM) {
- FileLine;
- fprintf( stderr, "expect TYPE=type\n" );
- SkipTokRest;
- }
- if (!(p1 = (struct template far *)
- _fmalloc( sizeof(struct template) )))
- Nomem();
- p1->type = fcopy( token );
- if (GetTok(tok) != TOK_PINS
- || GetTok(tok) != TOK_EQUAL
- || GetTok(tok) != TOK_NUMBER) {
- FileLine;
- fprintf( stderr, "expect PINS=number\n" );
- _ffree( p1->type );
- _ffree( p1 );
- SkipTokRest;
- }
- sscanf( token, "%d", &i );
- p1->pins = i;
- if ((p1->pins = i) < 0 || (i & 1)) {
- FileLine;
- fprintf( stderr, "PINS negative or odd\n" );
- }
- if (GetTok(tok) != TOK_HORIZONTAL
- || GetTok(tok) != TOK_EQUAL
- || GetTok(tok) != TOK_NUMBER) {
- FileLine;
- fprintf( stderr,
- "expect HORIZONTAL=number\n" );
- _ffree( p1->type );
- _ffree( p1 );
- SkipTokRest;
- }
- sscanf( token, "%d", &i );
- if ((p1->horizontal = i) <= 0) {
- FileLine;
- fprintf( stderr, "HORIZONTAL nonpositive\n" );
- }
- if (GetTok(tok) != TOK_VERTICAL
- || GetTok(tok) != TOK_EQUAL
- || GetTok(tok) != TOK_NUMBER) {
- FileLine;
- fprintf( stderr, "expect VERTICAL=number\n" );
- _ffree( p1->type );
- _ffree( p1 );
- SkipTokRest;
- }
- sscanf( token, "%d", &i );
- if ((p1->vertical = i) < 0) {
- FileLine;
- fprintf( stderr, "VERTICAL nonpositive\n" );
- }
- p1->pinlist = NULL;
- p1->next = chip;
- chip = p1;
- }
- else if (tok == TOK_NUMBER) {
- CheckInit; /* must get dimensions first */
- if (!chip) {
- FileLine;
- fprintf( stderr, "no template\n" );
- SkipRest;
- continue;
- }
- sscanf( token, "%d", &i );
- if (GetTok(tok) != TOK_EQUAL
- || GetTok(tok) != TOK_ALPHANUM) {
- FileLine;
- fprintf( stderr, "expect number=name\n" );
- SkipTokRest;
- }
- if (!(p2 = (struct pinassign far *)
- _fmalloc( sizeof(struct pinassign) )))
- Nomem();
- p2->name = fcopy( token );
- p2->index = i;
- /* check uniqueness of name and index */
- for (p22 = chip->pinlist; p22; p22 = p22->next)
- if (p22->index == i
- || same( p22->name, p )) {
- FileLine;
- fprintf( stderr,
- "warning: repeated pin\n" );
- break;
- }
- p2->next = chip->pinlist;
- chip->pinlist = p2;
- }
- else if (tok == TOK_ALPHANUM) {
- CheckInit; /* must get dimensions first */
- if (!chip) {
- FileLine;
- fprintf( stderr, "no template\n" );
- SkipRest;
- continue;
- }
- p = fcopy( token );
- if (GetTok(tok) != TOK_EQUAL
- || GetTok(tok) != TOK_NUMBER) {
- FileLine;
- fprintf( stderr, "expect name=number\n" );
- _ffree( p );
- SkipTokRest;
- }
- sscanf( token, "%d", &i );
- if (!(p2 = (struct pinassign far *)
- _fmalloc( sizeof(struct pinassign) )))
- Nomem();
- p2->name = p;
- p2->index = i;
- /* check uniqueness of name and index */
- for (p22 = chip->pinlist; p22; p22 = p22->next)
- if (p22->index == i
- || same( p22->name, p )) {
- FileLine;
- fprintf( stderr,
- "warning: repeated pin\n" );
- break;
- }
- p2->next = chip->pinlist;
- chip->pinlist = p2;
- }
- else if (tok == TOK_CHIPAT) {
- CheckInit; /* must get dimensions first */
- if (GetTok(tok) != TOK_ROWCOLUMN) {
- FileLine;
- fprintf( stderr, "expect (row,column)\n" );
- SkipTokRest;
- }
- sscanf( token, "(%d,%d)", &r1, &c1 );
- if (GetTok(tok) != TOK_NAME
- || GetTok(tok) != TOK_EQUAL
- || GetTok(tok) != TOK_ALPHANUM) {
- FileLine;
- fprintf( stderr, "expect NAME=name\n" );
- SkipTokRest;
- }
- if (!(p3 = (struct instance far *)
- _fmalloc( sizeof(struct instance) )))
- Nomem();
- p3->name = fcopy( token );
- p3->row = r1;
- p3->column = c1;
- if (GetTok(tok) != TOK_TYPE
- || GetTok(tok) != TOK_EQUAL
- || GetTok(tok) != TOK_ALPHANUM) {
- FileLine;
- fprintf( stderr, "expect TYPE=type\n" );
- _ffree( p3->name );
- _ffree( p3 );
- SkipTokRest;
- }
- for (p3->type = chip; p3->type;
- p3->type = p3->type->next)
- if (same( token, p3->type->type ))
- break;
- if (!(p3->type)) {
- FileLine;
- fprintf( stderr,
- "couldn't find chip type\n" );
- _ffree( p3->name );
- _ffree( p3 );
- SkipTokRest;
- }
- if (GetTok(tok) != TOK_ORIENTATION
- || GetTok(tok) != TOK_EQUAL
- || (GetTok(tok) != TOK_NORMAL
- && tok != TOK_UP && tok != TOK_DOWN
- && tok != TOK_UPSIDEDOWN)) {
- FileLine;
- fprintf( stderr,
- "expect ORIENTATION=orientation\n" );
- _ffree( p3->name );
- _ffree( p3 );
- SkipTokRest;
- }
- switch (tok) {
- case TOK_NORMAL:
- p3->orientation = ORIENT_NORMAL; break;
- case TOK_UP:
- p3->orientation = ORIENT_UP; break;
- case TOK_DOWN:
- p3->orientation = ORIENT_DOWN; break;
- case TOK_UPSIDEDOWN:
- p3->orientation = ORIENT_UPSIDEDOWN; break;
- default:
- FileLine;
- fprintf( stderr, "internal error\n" );
- exit( -1 );
- break;
- }
- p3->next = chipat;
- chipat = p3;
- initchip( p3, file, line );
- }
- else if (tok == TOK_NEWLINE) {
- line++;
- continue;
- }
- else { /* something unexpected */
- FileLine;
- fprintf( stderr, "syntax error: unexpected input\n" );
- }
- if (GetTok(tok) != TOK_EOF
- && tok != TOK_NEWLINE) {
- FileLine;
- fprintf( stderr,
- "syntax error: expected end of line\n" );
- SkipRest;
- }
- else if (tok == TOK_NEWLINE)
- line++;
- }
- return( tot );
- }
-
- static void initchip ( p, file, line ) /* init chip definition (make holes) */
- struct instance far *p;
- char *file;
- int line;
- {
- int r, c, pin;
- struct template far *t;
-
- pin = 1;
- r = p->row;
- c = p->column;
- t = p->type;
- /* should check for neighboring holes (warning if so) */
- switch (p->orientation) {
- case ORIENT_NORMAL:
- while (pin <= t->pins / 2) {
- SetCell( r-1, c-1, TOP, HOLE );
- SetCell( r-1, c-1, BOTTOM, HOLE );
- pin++;
- c += t->horizontal;
- }
- c -= t->horizontal;
- r += t->vertical;
- while (pin <= t->pins) {
- SetCell( r-1, c-1, TOP, HOLE );
- SetCell( r-1, c-1, BOTTOM, HOLE );
- pin++;
- c -= t->horizontal;
- }
- break;
- case ORIENT_UP:
- while (pin <= t->pins / 2) {
- SetCell( r-1, c-1, TOP, HOLE );
- SetCell( r-1, c-1, BOTTOM, HOLE );
- pin++;
- r += t->horizontal;
- }
- r -= t->horizontal;
- c -= t->vertical;
- while (pin <= t->pins) {
- SetCell( r-1, c-1, TOP, HOLE );
- SetCell( r-1, c-1, BOTTOM, HOLE );
- pin++;
- r -= t->horizontal;
- }
- break;
- case ORIENT_DOWN:
- while (pin <= t->pins / 2) {
- SetCell( r-1, c-1, TOP, HOLE );
- SetCell( r-1, c-1, BOTTOM, HOLE );
- pin++;
- r -= t->horizontal;
- }
- r += t->horizontal;
- c += t->vertical;
- while (pin <= t->pins) {
- SetCell( r-1, c-1, TOP, HOLE );
- SetCell( r-1, c-1, BOTTOM, HOLE );
- pin++;
- r += t->horizontal;
- }
- break;
- case ORIENT_UPSIDEDOWN:
- while (pin <= t->pins / 2) {
- SetCell( r-1, c-1, TOP, HOLE );
- SetCell( r-1, c-1, BOTTOM, HOLE );
- pin++;
- c -= t->horizontal;
- }
- c += t->horizontal;
- r -= t->vertical;
- while (pin <= t->pins) {
- SetCell( r-1, c-1, TOP, HOLE );
- SetCell( r-1, c-1, BOTTOM, HOLE );
- pin++;
- c += t->horizontal;
- }
- break;
- default:
- FileLine;
- fprintf( stderr, "internal error: unexpected orientation\n" );
- exit( -1 );
- break;
- }
- }
-
- static void locate ( p, r, c, file, line )
- /* find location of name1.{name2,number} */
- char *p;
- int *r, *c;
- char *file;
- int line;
- {
- char *q;
- int i;
- struct instance far *s;
- struct pinassign far *t;
-
- if (!(q = strchr( p, '.' ))) {
- FileLine;
- fprintf( stderr, "expect name1.{name2,number}\n" );
- return;
- }
- *q++ = 0; /* separate into two parts & point at second part */
- for (s = chipat; s; s = s->next) /* find proper chip */
- if (same( p, s->name ))
- break;
- if (!s || !(s->type)) {
- FileLine;
- fprintf( stderr, "can't find chip or chip type\n" );
- return;
- }
- if (isdigit( *q )) { /* get pin number */
- i = atoi( q );
- if (i <= 0 || i > s->type->pins) {
- FileLine;
- fprintf( stderr, "pin out of range\n" );
- return;
- }
- }
- else { /* get index of named pin via the template */
- for (t = s->type->pinlist; t; t = t->next)
- if (same( q, t->name ))
- break;
- if (!t) {
- FileLine;
- fprintf( stderr, "can't find pin\n" );
- return;
- }
- i = t->index;
- }
- *r = s->row;
- *c = s->column;
- switch (s->orientation) {
- case ORIENT_NORMAL:
- if (i <= s->type->pins / 2)
- *c += (i-1) * s->type->horizontal;
- else {
- *r += s->type->vertical;
- *c += (s->type->pins - i) * s->type->horizontal;
- }
- break;
- case ORIENT_UP:
- if (i <= s->type->pins / 2)
- *r += (i-1) * s->type->horizontal;
- else {
- *c -= s->type->vertical;
- *r += (s->type->pins - i) * s->type->horizontal;
- }
- break;
- case ORIENT_DOWN:
- if (i <= s->type->pins / 2)
- *r -= (i-1) * s->type->horizontal;
- else {
- *c += s->type->vertical;
- *r -= (s->type->pins - i) * s->type->horizontal;
- }
- break;
- case ORIENT_UPSIDEDOWN:
- if (i <= s->type->pins / 2)
- *c -= (i-1) * s->type->horizontal;
- else {
- *r -= s->type->vertical;
- *c -= (s->type->pins - i) * s->type->horizontal;
- }
- break;
- default:
- FileLine;
- fprintf( stderr, "internal error: unexpected orientation\n" );
- exit( -1 );
- break;
- }
- *--q = '.'; /* put back the separator */
- }
-
- static int gettoken ( fp, file, line )
- /* get next token into token[], return value */
- FILE *fp;
- char *file;
- int line;
- {
- int ch, i;
-
- /* burn whitespace */
- while ((ch = getc( fp )) == ' ' || ch == '\t')
- ;
- if (ch == EOF)
- return( TOK_EOF );
- else if (ch == '\n')
- return( TOK_NEWLINE );
- else if (ch == ';') { /* comment; burn to end of line */
- while ((ch = getc( fp )) != EOF && ch != '\n')
- ;
- return( (ch == '\n') ? TOK_NEWLINE : TOK_EOF );
- }
- else if (ch == '=')
- return( TOK_EQUAL );
- else if (isdigit( ch )) { /* a number; move it to the buffer */
- i = 0;
- do {
- if (i < MAXTOK-1)
- token[i++] = (char)ch;
- ch = getc( fp );
- } while (isdigit( ch ));
- token[i] = 0;
- if (ch != EOF)
- ungetc( ch, fp );
- return( TOK_NUMBER );
- }
- else if (isalpha( ch ) || ch == '.' || ch == '\\') {
- /* a name; move it to the buffer */
- i = 0;
- do {
- if (i < MAXTOK-1)
- token[i++] = (char)ch;
- ch = getc( fp );
- } while (isalnum( ch ) || ch == ':' || ch == '.'
- || ch == '\\');
- token[i] = 0;
- if (ch != EOF)
- ungetc( ch, fp );
- /* try to identify it as a reserved word */
- for (i = 0; i < numres; i++) /* search table */
- if (!stricmp( tokenmatch[i].tokenname, token ))
- return( tokenmatch[i].tokenvalue );
- /* it's not a reserved word; just return it */
- strupr( token );
- return( TOK_ALPHANUM );
- }
- else if (ch == '(') { /* "(row,column)", move it to the buffer */
- token[0] = (char)ch;
- i = 1;
- while ((ch = getc( fp )) == ' ' || ch == '\t')
- ;
- if (!isdigit( ch )) {
- FileLine;
- fprintf( stderr, "syntax error: expected digit\n" );
- exit( -1 );
- }
- do {
- if (i < MAXTOK-1)
- token[i++] = (char)ch;
- ch = getc( fp );
- } while (isdigit( ch ));
- while (ch == ' ' || ch == '\t')
- ch = getc( fp );
- if (ch != ',') {
- FileLine;
- fprintf( stderr, "syntax error: expected comma\n" );
- exit( -1 );
- }
- if (i < MAXTOK-1)
- token[i++] = (char)ch;
- while ((ch = getc( fp )) == ' ' || ch == '\t')
- ;
- if (!isdigit( ch )) {
- FileLine;
- fprintf( stderr, "syntax error: expected digit\n" );
- exit( -1 );
- }
- do {
- if (i < MAXTOK-1)
- token[i++] = (char)ch;
- ch = getc( fp );
- } while (isdigit( ch ));
- while (ch == ' ' || ch == '\t')
- ch = getc( fp );
- if (ch != ')') {
- FileLine;
- fprintf( stderr,
- "syntax error: expected right paren\n" );
- exit( -1 );
- }
- if (i < MAXTOK-1)
- token[i++] = (char)ch;
- token[i] = 0;
- return( TOK_ROWCOLUMN );
- }
- else {
- FileLine;
- fprintf( stderr, "syntax error: unrecognized token\n" );
- exit( -1 );
- }
- }
-
- static char far *fcopy ( p ) /* return ptr to far string copy */
- char *p;
- {
- char far *q;
- char far *r;
-
- if (!(q = r = _fmalloc( strlen( p ) + 1 )))
- Nomem();
- while (*r++ = *p++) /* copy string */
- ;
- return( q );
- }
-
- static int same ( p, q ) /* return 1 if far strings are identical, else 0 */
- char far *p;
- char far *q;
- {
- while (*p && *p == *q) { /* compare bytes until mismatch or end */
- p++;
- q++;
- }
- return( (*p || *q) ? 0 : 1 );
- }
-
- void Report ( fp ) /* output routed board */
- FILE *fp;
- {
- int r, c;
- char b;
- long x;
-
- printf( "Enter Report()\n" );
- /* output dimensions first */
- b = (char)Nrows; putc( b, fp );
- b = (char)(Nrows>>8); putc( b, fp );
- b = (char)Ncols; putc( b, fp );
- b = (char)(Ncols>>8); putc( b, fp );
- /* now do rows and columns */
- for (r = 0; r < Nrows; r++)
- for (c = 0; c < Ncols; c++) {
- x = GetCell( r, c, TOP ); /* first do frontside */
- b = (char)x; putc( b, fp );
- b = (char)(x>>8); putc( b, fp );
- b = (char)(x>>16); putc( b, fp );
- b = (char)(x>>24); putc( b, fp );
- x = GetCell( r, c, BOTTOM ); /* then do backside */
- b = (char)x; putc( b, fp );
- b = (char)(x>>8); putc( b, fp );
- b = (char)(x>>16); putc( b, fp );
- b = (char)(x>>24); putc( b, fp );
- }
- if (ferror( fp ))
- fprintf( stderr, "output error; disk might be full\n" );
- printf( "Exit Report()\n" );
- }
-