home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <stdlib.h>
- #include "cell.h"
-
- #define LIMIT 0x10000 /* 64k */
-
- /* board dimensions */
- int Nrows = ILLEGAL;
- int Ncols = ILLEGAL;
-
- int InitBoardDone = 0; /* sanity check */
-
- /* memory usage */
- long Ltotal = 0; /* for board */
- long Itotal = 0; /* for dist */
- long Ctotal = 0; /* for dir */
-
- /*
- ** memory is allocated in blocks of rows. as many rows as will fit in 64k are
- ** allocated in each block. blocks are linked together by pointers. the last
- ** block has a null 'next' pointer. if you want to route some *really* big
- ** boards (so big that 640k is not sufficient), you should change the
- ** algorithms below to test for Lotus-Intel-Microsoft expanded memory (LIM 3.2
- ** or 4.0) and use it if present. this would be a major enhancement, so if you
- ** do it i hope you will send it back to me so that it can be incorporated in
- ** future versions.
- */
-
- struct lmem { /* a block of longs */
- struct lmem far *next; /* ptr to next block */
- long mem[1]; /* more than 1 is actually allocated */
- };
-
- struct imem { /* a block of ints */
- struct imem far *next; /* ptr to next block */
- int mem[1]; /* more than 1 is actually allocated */
- };
-
- struct cmem { /* a block of chars */
- struct cmem far *next; /* ptr to next block */
- char mem[1]; /* more than 1 is actually allocated */
- };
-
- struct lhead { /* header of blocks of longs */
- int numrows; /* number of rows per block */
- struct lmem far *side[2]; /* ptr to first block of each chain */
- };
-
- struct ihead { /* header of blocks of ints */
- int numrows; /* number of rows per block */
- struct imem far *side[2]; /* ptr to first block of each chain */
- };
-
- struct chead { /* header of blocks of chars */
- int numrows; /* number of rows per block */
- struct cmem far *side[2]; /* ptr to first block of each chain */
- };
-
- static struct lhead Board = { 0, {NULL,NULL} }; /* 2-sided board */
- static struct ihead Dist = { 0, {NULL,NULL} }; /* path distance to cells */
- static struct chead Dir = { 0, {NULL,NULL} }; /* pointers back to source */
-
- extern int justboard;
-
- extern char far *Alloc( long );
-
- void InitBoard( void );
- long GetCell( int, int, int );
- void SetCell( int, int, int, long );
- void OrCell( int, int, int, long );
- int GetDist( int, int, int );
- void SetDist( int, int, int, int );
- int GetDir( int, int, int );
- void SetDir( int, int, int, int );
-
- void InitBoard () { /* initialize the data structures */
- long lx, ly; /* for calculating block sizes */
- struct lmem far * far *ltop; /* for building board chain */
- struct lmem far * far *lbottom; /* for building board chain */
- struct imem far * far *itop; /* for building dist chain */
- struct imem far * far *ibottom; /* for building dist chain */
- struct cmem far * far *ctop; /* for building dir chain */
- struct cmem far * far *cbottom; /* for building dir chain */
- int r, c, i, j, k; /* for calculating number of rows per block */
-
- InitBoardDone = 1; /* we have been called */
- /* allocate Board (longs) */
- for (lx = (long)Ncols*sizeof(long), ly = 0, i = 0;
- i < Nrows && ly <= LIMIT - sizeof(long far *); ly += lx, i++)
- ; /* calculate maximum number of rows per block */
- Board.numrows = --i;
- ltop = &(Board.side[TOP]);
- lbottom = &(Board.side[BOTTOM]);
- for (j = Nrows; j > 0; j -= i) {
- k = (j > i) ? i : j;
- ly = ((long)k * lx) + sizeof(long far *);
- *ltop = (struct lmem far *)Alloc( ly );
- *lbottom = (struct lmem far *)Alloc( ly );
- Ltotal += 2*ly;
- ltop = (struct lmem far * far *)(*ltop);
- lbottom = (struct lmem far * far *)(*lbottom);
- }
- *ltop = *lbottom = NULL;
- if (!justboard) {
- /* allocate Dist (ints) */
- for (lx = (long)Ncols*sizeof(int), ly = 0, i = 0;
- i < Nrows && ly <= LIMIT - sizeof(int far *);
- ly += lx, i++)
- ; /* calculate maximum number of rows per block */
- Dist.numrows = --i;
- itop = &(Dist.side[TOP]);
- ibottom = &(Dist.side[BOTTOM]);
- for (j = Nrows; j > 0; j -= i) {
- k = (j > i) ? i : j;
- ly = ((long)k * lx) + sizeof(int far *);
- *itop = (struct imem far *)Alloc( ly );
- *ibottom = (struct imem far *)Alloc( ly );
- Itotal += 2*ly;
- itop = (struct imem far * far *)(*itop);
- ibottom = (struct imem far * far *)(*ibottom);
- }
- *itop = *ibottom = NULL;
- /* allocate Dir (chars) */
- for (lx = (long)Ncols*sizeof(char), ly = 0, i = 0;
- i < Nrows && ly <= LIMIT - sizeof(char far *);
- ly += lx, i++)
- ; /* calculate maximum number of rows per block */
- Dir.numrows = --i;
- ctop = &(Dir.side[TOP]);
- cbottom = &(Dir.side[BOTTOM]);
- for (j = Nrows; j > 0; j -= i) {
- k = (j > i) ? i : j;
- ly = ((long)k * lx) + sizeof(char far *);
- *ctop = (struct cmem far *)Alloc( ly );
- *cbottom = (struct cmem far *)Alloc( ly );
- Ctotal += 2*ly;
- ctop = (struct cmem far * far *)(*ctop);
- cbottom = (struct cmem far * far *)(*cbottom);
- }
- *ctop = *cbottom = NULL;
- }
- /* initialize everything to empty */
- for (r = 0; r < Nrows; r++) {
- for (c = 0; c < Ncols; c++) {
- SetCell( r, c, TOP, (long)EMPTY );
- SetCell( r, c, BOTTOM, (long)EMPTY );
- if (!justboard) {
- SetDist( r, c, TOP, EMPTY );
- SetDist( r, c, BOTTOM, EMPTY );
- SetDir( r, c, TOP, EMPTY );
- SetDir( r, c, BOTTOM, EMPTY );
- }
- }
- }
- }
-
- long GetCell( r, c, s ) /* fetch board cell */
- int r, c, s;
- {
- struct lmem far *p;
-
- p = Board.side[s];
- while (r >= Board.numrows) {
- p = p->next;
- r -= Board.numrows;
- }
- return( p->mem[r*Ncols+c] );
- }
-
- void SetCell( r, c, s, x ) /* store board cell */
- int r, c, s;
- long x;
- {
- struct lmem far *p;
-
- p = Board.side[s];
- while (r >= Board.numrows) {
- p = p->next;
- r -= Board.numrows;
- }
- p->mem[r*Ncols+c] = x;
- }
-
- void OrCell( r, c, s, x ) /* augment board cell */
- int r, c, s;
- long x;
- {
- struct lmem far *p;
-
- p = Board.side[s];
- while (r >= Board.numrows) {
- p = p->next;
- r -= Board.numrows;
- }
- p->mem[r*Ncols+c] |= x;
- }
-
- int GetDist( r, c, s ) /* fetch distance cell */
- int r, c, s;
- {
- struct imem far *p;
-
- p = Dist.side[s];
- while (r >= Dist.numrows) {
- p = p->next;
- r -= Dist.numrows;
- }
- return( p->mem[r*Ncols+c] );
- }
-
- void SetDist( r, c, s, x ) /* store distance cell */
- int r, c, s, x;
- {
- struct imem far *p;
-
- p = Dist.side[s];
- while (r >= Dist.numrows) {
- p = p->next;
- r -= Dist.numrows;
- }
- p->mem[r*Ncols+c] = x;
- }
-
- int GetDir( r, c, s ) /* fetch direction cell */
- int r, c, s;
- {
- struct cmem far *p;
-
- p = Dir.side[s];
- while (r >= Dir.numrows) {
- p = p->next;
- r -= Dir.numrows;
- }
- return( (int)(p->mem[r*Ncols+c]) );
- }
-
- void SetDir( r, c, s, x ) /* store direction cell */
- int r, c, s, x;
- {
- struct cmem far *p;
-
- p = Dir.side[s];
- while (r >= Dir.numrows) {
- p = p->next;
- r -= Dir.numrows;
- }
- p->mem[r*Ncols+c] = (char)x;
- }
-