<overlay slot size> <relocation info size>
<CRL file> ... (default search list)
... (more default search list)
<blank line>
<overlay name> <slot number>
<function name> <comments or whatnot>
<function name> <comments or whatnot>
... (an entry for each top-level function in the overlay)
<blank line>
<overlay name> <slot number>
<function name> <comments or whatnot>
<function name> <comments or whatnot>
...
... (an entry for each overlay in the file)
Overlay segments are of length <overlay slot size> bytes, of which the
last <relocation info size> bytes holds a list of relocation offsets.
This is a null-terminated string of byte values giving the difference
between successive addresses to be relocated; a value of 255 means to
add 255 to the next byte value to get the offset. The first offset is
relative to -1 (so that we can relocate the first word of the
overlay). At the beginning of the overlay is a table of addresses of
top-level functions, one address for each function listed for that
overlay in the descriptor file.
The -l option works as for L2: CRL files listed before the -l are
loaded in entirety; those after are just scanned for needed functions.
Any functions specified in the default search list in the overlay
descriptor file are also scanned, unless the -nd (no default) option
is given.
The overlay, once created, is written into <root name>.OVL, at address
<slot number> * <overlay slot size>.
*/
/**************** Globals ****************/
#define SDOS /* comment this out for CP/M */
#include "bdscio.h" /* for i/o buffer defs */
#define NUL 0
#define FLAG char
#define repeat while (1)
#define STDOUT 1
/* function table */
struct funct {
char fname[9];
FLAG flinkedp; /* in memory already? */
char *faddr; /* address of first ref link if not linked */
} ftab [300];
int nfuncts; /* no. of functions in table */
#define LINKED 255 /* (flinkedp) function really here */
#define EXTERNAL 254 /* function defined in separate symbol table */
char fdir [512]; /* CRL file function directory */
/* command line parameters etc. */
char rootname[15]; /* name of root program */
char ovlname[40]; /* name of overlay to be built */
int nprogs, nlibs;
char progfiles [20] [15]; /* program file names */
char libfiles [30] [15]; /* library file names */
FLAG srchdefs; /* search default libraries? */
/* overlay description */
int ovlsize, relsize; /* size of overlay slot & of relocation info */
int ovlslot; /* slot # to put overlay in */
char topfuncts[10][32]; /* names of top level functions */
int ntops; /* number of top level functions */
char *relstart; /* beginning of relocation info */
char *relnext; /* next relocation value */
char *reladdr; /* last address relocated */
/* useful things to have defined */
struct inst {
char opcode;
char *address;
};
union ptr {
unsigned u; /* an int */
unsigned *w; /* a word ptr */
char *b; /* a byte ptr */
struct inst *i; /* an instruction ptr */
};
/* Link control variables */
union ptr codend; /* last used byte of code buffer + 1 */
union ptr acodend; /* actual code-end address */
unsigned origin; /* origin of code */
unsigned buforg; /* origin of code buffer */
char *lspace; /* space to link in */
char *lspcend; /* end of link area */
char *lodstart; /* beginning of current file */
/* i/o buffer */
struct iobuf {
int fd;
int isect; /* currently buffered sector */
int nextc; /* index of next char in buffer */
char buff [128];
} ibuf, obuf;
linkprog() /* link in all program files */
{
int i;
union ptr dirtmp;
struct funct *fnct;
for (i=0; i<nprogs; ++i) {
makeext (&progfiles[i], "CRL");
if (copen (&ibuf, progfiles[i]) < 0) {
printf ("Can't open %s\n", progfiles[i]);
continue;
}
printf ("Loading %s\n", &progfiles[i]);
readprog (i==0);
for (dirtmp.b=&fdir; *dirtmp.b != 0x80;) {
fnct = intern (dirtmp.b); /* for each module */
skip7 (&dirtmp); /* in directory */
if (!fnct->flinkedp)
linkmod (fnct, lodstart + *dirtmp.w - 0x205);
else {
puts (" Duplicate program function '");
puts (&fnct->fname);
puts ("', not linked.\n");
}
dirtmp.w++;
} /* intern & link it */
cclose (&ibuf);
}
}
linklibs() /* link in library files */
{
int ifile;
for (ifile = 0; ifile < nlibs; ++ifile) scanlib (ifile);
while (missingp()) {
puts ("Enter the name of a file to be searched: ");
gets (&libfiles[nlibs]);
upcase (&libfiles[nlibs]);
scanlib (nlibs++);
}
acodend.b = codend.b - lspace + buforg; /* save that number! */
}
missingp() /* are any functions missing? print them out */
{
int i, foundp;
foundp = FALSE;
for (i=0; i<nfuncts; ++i)
if (!ftab[i].flinkedp) {
if (!foundp) puts ("*** Missing functions:\n");
puts (&ftab[i].fname);
puts ("\n");
foundp = TRUE;
}
return (foundp);
}
readprog (mainp) /* read in a program file */
FLAG mainp;
{
char extp; /* was -e used? */
char *extstmp;
union ptr dir;
unsigned len;
if (cread (&ibuf, &fdir, 512) < 512) /* read directory */
Fatal ("-- read error!\n");
cseek (&ibuf, 5, RELATIVE);
for (dir.b=&fdir; *dir.b != 0x80; nextd (&dir)); /* find end of dir */
++dir.b;
len = *dir.w - 0x205;
readobj (len);
}
readobj (len) /* read in an object (program or lib funct) */
unsigned len;
{
if (codend.b + len >= lspcend) Fatal ("-- out of memory!\n");
lodstart = codend.b;
if (cread (&ibuf, lodstart, len) < len)
Fatal ("-- read error (read 0x%x)!\n", len);
}
scanlib (ifile)
int ifile;
{
int i;
union ptr dirtmp;
linkmod (fnct, modstart) /* link in a module */
struct funct *fnct;
union ptr modstart; /* loc. of module in memory */
{
union ptr temp,
jump, /* jump table temp */
body, /* loc. of function in memory */
code, /* loc. of code proper in mem. */
finalloc; /* runtime loc. of function */
unsigned flen, nrelocs, jtsiz, offset;
makeext (fname, ext) /* force a file extension to ext */
char *fname, *ext;
{
while (*fname && (*fname != '.')) {
*fname = toupper (*fname); /* upcase as well */
++fname;
}
*fname++ = '.';
strcpy (fname, ext);
}
strcmp7 (s1, s2) /* compare two bit-7-terminated strings */
char *s1, *s2; /* also works for non-null NUL-term strings */
{
/* char c1, c2, end1, end2; (These are now global for speed) */