home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Hacker Chronicles 2
/
HACKER2.BIN
/
640.BOARD.C
< prev
next >
Wrap
C/C++ Source or Header
|
1989-03-05
|
7KB
|
249 lines
#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;
}