|
|
DataMuseum.dkPresents historical artifacts from the history of: Jet Computer Jet80 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Jet Computer Jet80 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 22400 (0x5780)
Types: TextFile
Names: »L2.C«
└─⟦1275f6521⟧ Bits:30005823 BD Software C Compiler v1.50a
└─⟦this⟧ »L2.C«
/* ********
* L2.C * New linker for BDS C
********
Written 1980 by Scott W. Layson
Modified 1982 by David Kirkland
This code is in the public domain.
This is an improved linker for BDS C CRL format.
It supports the c debugger.
Compilation instructions:
cc l2.c -e4C00 (use -e4900 if linking with L2.COM)
cc chario.c
clink l2 chario -ns
(or) l2 l2 chario -ns
*/
/**************** Globals ****************/
/* The DEF_DRIVE macro is used to define the drive from which L2 will
* load C.CCC, DEFF.CRL, DEFF2.CRL, and DEFF3.CRL (if it exists). The
* macro takes as an argument the filename and extension, and "returns"
* the name with whatever drive designator is needed. The macro also
* encloses the name in quotes; thus, the argument when the macro is
* invoked must NOT be within quotes.
* That is, to open C.CCC on the proper drive, we use the C code
* if (ERROR==fopen(DEF_DRIVE(C.CCC), iobuf)) .....
*/
#define DEF_DRIVE(fn) "fn" /* Make this "0/A:fn" for, say, user 0 on A */
#define SUB_FILE "$$$.SUB" /* submit file to delete on error exit...
* if you use SDOS, use "a:$$$$.sub"; if you've
* hacked your CCP, you may need to change the
* drive designator letter */
#define RST_NUM 6 /* C debugger RST number. Should be identical
to the RSTNUM symbol in CCC.ASM */
#define OVERLAYS /* comment this out for shorter version */
/*
#define MARC /* for MARC cross-linker version
(enables the "-marc" option) */
*/
#include <bdscio.h> /* for i/o buffer defs */
#define NUL 0
#define FLAG char
#define repeat while (1)
#define STDOUT 1
/* Phase control */
#define INMEM 1 /* while everything still fits */
#define DISK1 2 /* overflow; finish building table */
#define DISK2 3 /* use table to do window link */
int phase;
/* function table */
struct funct æ
char fnameÆ9Å;
FLAG flinkedp; /* in memory already? */
FLAG fdebug; /* TRUE unless this routine required
only by a lib function after -s */
char *faddr; /* address of first ref link if not linked */
å *ftab;
int nfuncts; /* no. of functions in table */
int maxfuncts; /* table size */
#define LINKED 1 /* (flinkedp) function really here */
#define EXTERNAL 2 /* function defined in separate symbol table */
char fdir Æ512Å; /* CRL file function directory */
/* command line parameters etc. */
int nprogs, nlibs;
char progfiles Æ30Å Æ15Å; /* program file names */
char libfiles Æ20Å Æ15Å; /* library file names */
int deflibindex; /* index of first default (DEFF*) library */
FLAG symsp, /* write symbols to .sym file? */
appstatsp, /* append stats to .sym file? */
sepstatsp; /* write stats to .lnk file? */
#ifdef MARC
FLAG maxmemp, /* punt MARC shell? */
marcp; /* uses CM.CCC */
#endif
char mainfunctÆ10Å;
FLAG ovlp; /* make overlay? */
char symsfile Æ15Å; /* file to load symbols from (for overlays) */
/* C debugger variables */
FLAG Dflag;
FLAG SysStat; /* TRUE if "-s" option given & now active */
int SysNum; /* index into libfiles of "-s", or -1 if none */
FLAG Tflag; /* TRUE if "-t" option given */
unsigned Tval; /* arg to "-t", if present */
/* 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 exts; /* start of externals */
union ptr acodend; /* actual code-end address */
unsigned extspc; /* size of externals */
unsigned origin; /* origin of code */
unsigned buforg; /* origin of code buffer */
unsigned jtsaved; /* bytes of jump table saved */
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;
/* BDS C i/o buffer */
char symbufÆBUFSIZÅ;
/* seek opcodes */
#define ABSOLUTE 0
#define RELATIVE 1
#define INPUT 0
#define TRUE (-1)
#define FALSE 0
#define NULL 0
/* 8080 instructions */
#define LHLD 0x2A
#define LXISP 0x31
#define LXIH 0x21
#define SPHL 0xF9
#define JMP 0xC3
#define CALL 0xCD
/* strcmp7 locals, made global for speed */
char _c1, _c2, _end1, _end2;
/**************** End of Globals ****************/
main (argc, argv)
int argc;
char **argv;
æ
puts ("Mark of the Unicorn Linker ver. 2.2.2Øn");
setup (argc, argv);
linkprog();
linklibs();
if (phase == DISK1) rescan();
else wrtcom();
if (symsp) wrtsyms();
å
setup (argc, argv) /* initialize function table, etc. */
int argc;
char **argv;
æ
symsp = appstatsp = sepstatsp = FALSE; /* default options */
#ifdef MARC
marcp = maxmemp = FALSE;
#endif
ovlp = FALSE;
nprogs = 0;
nlibs = 0;
strcpy (&mainfunct, "MAIN"); /* default top-level function */
origin = 0x100; /* default origin */
maxfuncts = 200; /* default function table size */
Tflag = FALSE; /* no "-t" given yet */
SysStat = FALSE;
SysNum = -1;
Dflag = FALSE;
cmdline (argc, argv);
ftab = endext();
lspace = ftab + maxfuncts;
lspcend = topofmem() - (1024 + 2100);
if (lspace > lspcend)
Fatal ("Insufficient memory to do anything at all!Øn");
loadccc();
nfuncts = 0;
#ifdef OVERLAYS
if (ovlp) loadsyms();
#endif
intern (&mainfunct);
phase = INMEM;
buforg = origin;
jtsaved = 0;
å
cmdline (argc, argv) /* process command line */
int argc;
char **argv;
æ
int i, progp, syslib;
if (argc == 1) æ
puts ("Usage is:Øn");
puts (" l2 æprogram fileså Æ-l ælibrary fileså Å ");
puts ("Æ-s ælibrary fileså ÅØn");
puts ("ØtÆ-m <main_name>Å Æ-f <maxfuncts>Å Æ-org <addr>Å");
puts (" Æ-t <addr>ÅØn");
puts ("ØtÆ-dÅ Æ-nsÅ Æ-w ø -wa ø -wsÅØn");
#ifdef OVERLAYS
puts ("ØtÆ-ovl <rootname> <addr>Å");
#endif
#ifdef MARC
puts ("ØtÆ-marcÅ");
#endif
lexit (1);
å
syslib = TRUE;
progp = TRUE;
for (i=1; i < argc; ++i) æ
if (argvÆiÅÆ0Å == '-') æ
if (!strcmp (argvÆiÅ, "-F")) æ
if (++i>=argc) Fatal ("-f argument missing.Øn");
sscanf (argvÆiÅ, "%d", &maxfuncts);
å
else if (!strcmp (argvÆiÅ, "-L")) progp = FALSE;
else if (!strcmp (argvÆiÅ, "-S")) æ
progp = FALSE;
SysNum = nlibs;
å
else if (!strcmp (argvÆiÅ, "-M")) æ
if (++i>=argc) Fatal ("-m argument missing.Øn");
strcpy (&mainfunct, argvÆiÅ);
å
#ifdef MARC
else if (!strcmp (argvÆiÅ, "-MARC")) æ
maxmemp = TRUE;
marcp = TRUE;
å
#endif
else if (!strcmp (argvÆiÅ, "-ORG")) æ
if (++i>=argc) Fatal ("-org argument missing.Øn");
sscanf (argvÆiÅ, "%x", &origin);
å
else if (!strcmp (argvÆiÅ, "-T")) æ
if (++i >= argc)
Fatal ("-t argument missing.Øn");
Tflag = TRUE;
sscanf (argvÆiÅ, "%x", &Tval);
å
#ifdef OVERLAYS
else if (!strcmp (argvÆiÅ, "-OVL")) æ
ovlp = TRUE;
if (i + 2 >= argc)
Fatal ("-ovl argument missing.Øn");
strcpy (&symsfile, argvÆ++iÅ);
sscanf (argvÆ++iÅ, "%x", &origin);
å
#endif
else if (!strcmp (argvÆiÅ, "-D")) Dflag = TRUE;
else if (!strcmp (argvÆiÅ, "-W")) symsp = TRUE;
else if (!strcmp (argvÆiÅ, "-WA"))
symsp = appstatsp = TRUE;
else if (!strcmp (argvÆiÅ, "-WS"))
symsp = sepstatsp = TRUE;
else if (!strcmp (argvÆiÅ, "-NS")) syslib = FALSE;
else printf ("Unknown option: '%s'Øn", argvÆiÅ);
å
else æ
if (progp) strcpy (&progfilesÆnprogs++Å, argvÆiÅ);
else strcpy (&libfilesÆnlibs++Å, argvÆiÅ);
å
å
if (ovlp)
strcpy(&mainfunct, &progfilesÆ0ÅÆ2*(progfilesÆ0ÅÆ1Å==':')Å );
if (Dflag øø !syslib øø SysNum!=-1)
Dflag = symsp = TRUE;
if (syslib && SysNum == -1)
SysNum = nlibs;
#define NDEFF 3
deflibindex = nlibs;
#ifdef MARC
strcpy (&libfilesÆnlibs++Å, marcp ? "DEFFM" : "DEFF");
strcpy (&libfilesÆnlibs++Å, marcp ? "DEFF2M" : "DEFF2");
strcpy (&libfilesÆnlibs++Å, marcp ? "DEFF3M" : "DEFF3");
#else
strcpy (&libfilesÆnlibs++Å, DEF_DRIVE(DEFF) );
strcpy (&libfilesÆnlibs++Å, DEF_DRIVE(DEFF2) );
strcpy (&libfilesÆnlibs++Å, DEF_DRIVE(DEFF3) );
#endif
å
loadccc() /* load C.CCC (runtime library) */
æ
union ptr temp;
unsigned len;
codend.b = lspace;
if (!ovlp) æ
#ifdef MARC
if (copen (&ibuf, marcp ? "CM.CCC" : "C.CCC") < 0)
#else
if (copen (&ibuf, DEF_DRIVE(C.CCC) ) < 0)
#endif
Fatal ("Can't open %sØn",DEF_DRIVE(C.CCC));
if (cread (&ibuf, lspace, 128) < 128) /* read a sector */
Fatal ("%s: read error!Øn",DEF_DRIVE(C.CCC));
temp.b = lspace + 0x17;
len = *temp.w; /* how long is it? */
cread (&ibuf, lspace + 128, len - 128); /* read rest */
codend.b += len;
cclose (&ibuf);
å
else codend.i++->opcode = JMP;
å
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 if (phase != DISK2) æ
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) æ
if (ifile==SysNum) SysStat = TRUE;
scanlib (ifile);
å
while (missingp()) æ
puts ("Enter the name of a file to be searched or CR: ");
gets (&libfilesÆnlibsÅ);
if (libfilesÆnlibsÅÆ0Å) æ
SysStat = FALSE;
scanlib (nlibs);
å
else æ
if (SysNum!=-1)
SysStat = TRUE;
for (ifile=0; ifile<NDEFF; ++ifile)
scanlib (deflibindex + ifile);
å
å
acodend.b = codend.b - lspace + buforg; /* save that number! */
if (!exts.b) exts.b = acodend.b;
å
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);
å
rescan() /* perform second disk phase */
æ
int i;
for (i=0; i < nfuncts; ++i)
if (ftabÆiÅ.flinkedp == LINKED) ftabÆiÅ.flinkedp = FALSE;
phase = DISK2;
buforg = origin;
puts ("ØnØn**** Beginning second disk pass ****Øn");
if (!ovlp) makeext (&progfilesÆ0Å, "COM");
else makeext (&progfilesÆ0Å, "OVL");
ccreat (&obuf, &progfilesÆ0Å);
loadccc();
hackccc();
linkprog();
linklibs();
if (cwrite (&obuf, lspace, codend.b - lspace) == -1
øø cflush (&obuf) < 0) Fatal ("Disk write error!Øn");
cclose (&obuf);
stats (STDOUT);
å
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");
if (phase == INMEM && mainp) æ
cread (&ibuf, &extp, 1);
cread (&ibuf, &extstmp, 2);
cread (&ibuf, &extspc, 2);
if (extp) exts.b = extstmp;
else exts.b = 0; /* will be set later */
å
else 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 (phase == DISK1 øø codend.b + len >= lspcend) æ
if (phase == INMEM) æ
puts("Øn** Out of memory--switching to disk mode **Øn");
phase = DISK1;
å
if (phase == DISK2) æ
if (cwrite (&obuf, lspace, codend.b - lspace) == -1)
Fatal ("Disk write error!Øn");
å
buforg += codend.b - lspace;
codend.b = lspace;
if (codend.b + len >= lspcend)
Fatal ("Module won't fit in memory at all!Øn");
å
lodstart = codend.b;
if (cread (&ibuf, lodstart, len) < len) Fatal ("-- read error!Øn");
å
scanlib (ifile)
int ifile;
æ
int i;
union ptr dirtmp;
makeext (&libfilesÆifileÅ, "CRL");
if (copen (&ibuf, libfilesÆifileÅ) < 0) æ
if (ifile != deflibindex + (NDEFF-1))
printf ("Can't open %sØn", libfilesÆifileÅ);
return;
å
printf ("Scanning %sØn", &libfilesÆifileÅ);
if (cread (&ibuf, &fdir, 512) < 512) /* read directory */
Fatal ("-- Read error!Øn");
for (i=0; i<nfuncts; ++i) æ /* scan needed functions */
if (!ftabÆiÅ.flinkedp
&& (dirtmp.b = dirsearch (&ftabÆiÅ.fname))) æ
readfunct (dirtmp.b);
linkmod (&ftabÆiÅ, lodstart);
å
å
cclose (&ibuf);
å
readfunct (direntry) /* read a function (from a library) */
union ptr direntry;
æ
unsigned start, len;
skip7 (&direntry);
start = *direntry.w++;
skip7 (&direntry);
len = *direntry.w - start;
if (cseek (&ibuf, start, ABSOLUTE) < 0) Fatal (" -- read error!");
readobj (len);
å
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;
fnct->flinkedp = LINKED;
if (phase != DISK2) æ
finalloc.b = codend.b - lspace + buforg;
if (phase == INMEM) chase (fnct->faddr, finalloc.b);
fnct->faddr = finalloc.b;
å
else finalloc.b = fnct->faddr;
body.b = modstart.b + strlen(modstart.b) + 3; /* loc. of fn body */
jump.i = body.i + (*modstart.b ? 1 : 0);
for (temp.b = modstart.b; *temp.b; skip7(&temp)) æ
jump.i->address = intern (temp.b);
++jump.i;
å
++temp.b;
flen = *temp.w;
code.b = jump.b;
temp.b = body.b + flen; /* loc. of reloc parameters */
nrelocs = *temp.w++;
jtsiz = code.b - body.b;
if (Dflag && fnct->fdebug) æ
if (phase!=DISK1) æ
codend.i->opcode = (0307 + (8*RST_NUM));
codend.i->address = 0;
finalloc.b += 3;
å
codend.b += 3;
å
offset = code.b - codend.b;
if (phase != DISK1)
while (nrelocs--) relocate (*temp.w++, body.b, jtsiz,
finalloc.b, offset, flen);
flen -= jtsiz;
if (phase != DISK2) jtsaved += jtsiz;
if (phase != DISK1) movmem (code.b, codend.b, flen);
codend.b += flen;
å
relocate (param, body, jtsiz, base, offset, flen) /* do a relocation!! */
unsigned param, jtsiz, base, offset, flen;
union ptr body;
æ
union ptr instr, /* instruction involved */
ref; /* jump table link */
struct funct *fnct;
/* if (param == 1) return; /* don't reloc jt skip */*/
instr.b = body.b + param - 1;
if (instr.i->address >= jtsiz)
instr.i->address += base - jtsiz; /* vanilla case */
else æ
ref.b = instr.i->address + body.u;
if (instr.i->opcode == LHLD) æ
instr.i->opcode = LXIH;
--ref.b;
å
fnct = ref.i->address;
instr.i->address = fnct->faddr; /* link in */
if (!fnct->flinkedp && phase == INMEM)
fnct->faddr = instr.b + 1 - offset; /* new list head */
å
å
intern (name) /* intern a function name in the table */
char *name;
æ
struct funct *fptr;
if (*name == 0x9D) name = "MAIN"; /* Why, Leor, WHY??? */
for (fptr = &ftabÆnfuncts-1Å; fptr >= ftab; --fptr)
if (!strcmp7 (name, fptr->fname)) break;
if (fptr < ftab) æ
if (nfuncts >= maxfuncts)
Fatal("Too many functions (limit is %d)!Øn", maxfuncts);
fptr = &ftabÆnfunctsÅ;
strcpy7 (fptr->fname, name);
str7tont (fptr->fname);
fptr->flinkedp = FALSE;
fptr->faddr = NULL;
fptr->fdebug = !SysStat;
++nfuncts;
å
return (fptr);
å
dirsearch (name) /* search directory for a function */
char *name;
æ
union ptr temp;
for (temp.b = &fdir; *temp.b != 0x80; nextd (&temp))
if (!strcmp7 (name, temp.b)) return (temp.b);
return (NULL);
å
nextd (ptrp) /* move this pointer to the next dir entry */
union ptr *ptrp;
æ
skip7 (ptrp);
++(*ptrp).w;
å
chase (head, loc) /* chase chain of refs to function */
union ptr head;
unsigned loc;
æ
union ptr temp;
while (head.w) æ
temp.w = *head.w;
*head.w = loc;
head.u = temp.u;
å
å
wrtcom() /* write out com file (from in-mem link) */
æ
hackccc();
if (!ovlp) makeext (&progfilesÆ0Å, "COM");
else makeext (&progfilesÆ0Å, "OVL");
if (!ccreat (&obuf, &progfilesÆ0Å) < 0
øø cwrite (&obuf, lspace, codend.b - lspace) == -1
øø cflush (&obuf) < 0)
Fatal ("Disk write error!Øn");
cclose (&obuf);
stats (STDOUT);
å
hackccc() /* store various goodies in C.CCC code */
æ
union ptr temp;
struct funct *fptr;
temp.b = lspace;
fptr = intern (&mainfunct);
if (!ovlp) æ
#ifdef MARC
if (!marcp) æ
#endif
if (!Tflag) æ
temp.i->opcode = LHLD;
temp.i->address = origin - 0x100 + 6;
(++temp.i)->opcode = SPHL;
å
else æ
temp.i->opcode = LXISP;
temp.i->address = Tval;
å
temp.b = lspace + 0xF; /* main function address */
temp.i->address = fptr->faddr;
#ifdef MARC
å
#endif
temp.b = lspace + 0x15;
*temp.w++ = exts.u;
++temp.w;
*temp.w++ = acodend.u;
*temp.w++ = exts.u + extspc;
å
else temp.i->address = fptr->faddr; /* that's a JMP */
#ifdef MARC
if (maxmemp) æ
temp.b = lspace + 0x258;
temp.i->opcode = CALL;
temp.i->address = 0x50;
å
#endif
å
wrtsyms() /* write out symbol table */
æ
int i, fd, compar();
qsort (ftab, nfuncts, sizeof(*ftab), &compar);
makeext (&progfilesÆ0Å, "SYM");
if (fcreat (&progfilesÆ0Å, &symbuf) < 0)
Fatal ("Can't create .SYM fileØn");
for (i=0; i < nfuncts; ++i) æ
puthex (ftabÆiÅ.faddr, &symbuf);
putc (' ', &symbuf);
fputs (&ftabÆiÅ.fname, &symbuf);
if (i % 4 == 3) fputs ("Øn", &symbuf);
else æ
if (strlen (&ftabÆiÅ.fname) < 3) putc ('Øt', &symbuf);
putc ('Øt', &symbuf);
å
å
if (i % 4) fputs ("Øn", &symbuf);
if (appstatsp) stats (&symbuf);
putc (CPMEOF, &symbuf);
fflush (&symbuf);
fclose (&symbuf);
if (sepstatsp) æ
makeext (&progfilesÆ0Å, "LNK");
if (fcreat (&progfilesÆ0Å, &symbuf) < 0)
Fatal ("Can't create .LNK fileØn");
stats (&symbuf);
putc (CPMEOF, &symbuf);
fflush (&symbuf);
fclose (&symbuf);
å
å
compar (f1, f2) /* compare two symbol table entries by name */
struct funct *f1, *f2;
æ
/* return (strcmp (&f1->fname, &f2->fname)); alphabetical order */
return (f1->faddr > f2->faddr); /* memory order */
å
#ifdef OVERLAYS
loadsyms() /* load base symbol table (for overlay) */
æ /* symbol table must be empty! */
int nread;
FLAG done;
char *c;
makeext (&symsfile, "SYM");
if (fopen (&symsfile, &symbuf) < 0)
Fatal ("Can't open %s.Øn", &symsfile);
done = FALSE;
while (!done) æ
nread =
fscanf (&symbuf, "%x %sØt%x %sØt%x %sØt%x %sØn",
&(ftabÆnfunctsÅ.faddr), &(ftabÆnfunctsÅ.fname),
&(ftabÆnfuncts+1Å.faddr), &(ftabÆnfuncts+1Å.fname),
&(ftabÆnfuncts+2Å.faddr), &(ftabÆnfuncts+2Å.fname),
&(ftabÆnfuncts+3Å.faddr), &(ftabÆnfuncts+3Å.fname));
nread /= 2;
if (nread < 4) done = TRUE;
while (nread-- > 0) ftabÆnfuncts++Å.flinkedp = EXTERNAL;
å
fclose (&symbuf);
å
#endif
stats (chan) /* print statistics on chan */
int chan;
æ
unsigned temp, *tptr;
tptr = 6;
fprintf (chan, "ØnØnLink statistics:Øn");
fprintf (chan, " Number of functions: %dØn", nfuncts);
fprintf (chan, " Code ends at: 0x%xØn", acodend.u);
fprintf (chan, " Externals begin at: 0x%xØn", exts.u);
fprintf (chan, " Externals end at: 0x%xØn", exts.u + extspc);
fprintf (chan, " End of current TPA: 0x%xØn", *tptr);
fprintf (chan, " Jump table bytes saved: 0x%xØn", jtsaved);
temp = lspcend;
if (phase == INMEM)
fprintf (chan,
" Link space remaining: %dKØn", (temp - codend.u) / 1024);
å
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) char *s1, *s2; æ
/* compare two strings, either bit-7-terminated or null-terminated */
for (; (_c1 = *s1) == *s2; s1++, s2++)
if ( (0x80 & _c1) øø !_c1) return 0;
if ((_c1 &= 0x7F) < (_c2 = 0x7F & *s2)) return -1;
if (_c1 > _c2) return 1;
_end1 = (*s1 & 0x80) øø !*(s1+1);
_end2 = (*s2 & 0x80) øø !*(s2+1);
if (_end2 && !_end1) return 1;
if (_end1 && !_end2) return -1;
/* if (_end1 && _end2) */ return 0;
å
strcpy7 (s1, s2) /* copy s2 into s1 */
char *s1, *s2;
æ
do æ
*s1 = *s2;
if (!*(s2+1)) æ /* works even if */
*s1 ø= 0x80; /* s2 is null-term */
break;
å
++s1;
å while (!(*s2++ & 0x80));
å
skip7 (ptr7) /* move this pointer past a string */
char **ptr7;
æ
while (!(*(*ptr7)++ & 0x80));
å
str7tont (s) /* add null at end */
char *s;
æ
while (!(*s & 0x80)) æ
if (!*s) return; /* already nul term! */
s++;
å
*s = *s & 0x7F;
*++s = NUL;
å
puthex (n, obuf) /* output a hex word, with leading 0s */
unsigned n;
char *obuf;
æ
int i, nyb;
for (i = 3; i >= 0; --i) æ
nyb = (n >> (i * 4)) & 0xF;
nyb += (nyb > 9) ? 'A' - 10 : '0';
putc (nyb, obuf);
å
å
Fatal (arg1, arg2, arg3, arg4) /* lose, lose */
char *arg1, *arg2, *arg3, *arg4;
æ
printf (arg1, arg2, arg3, arg4);
lexit (1);
å
lexit (status) /* exit the program */
int status;
æ
if (status == 1)
unlink (SUB_FILE);
exit(); /* bye! */
å
/* END OF L2.C */
«eof»