home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Crawly Crypt Collection 1
/
crawlyvol1.bin
/
program
/
compiler
/
nasm20b
/
nasm_src
/
link65.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-01-19
|
11KB
|
405 lines
/* ---------------------------------------------------------------------- */
/* Copyright (C) 1992 by Natürlich! */
/* This file is copyrighted! */
/* Refer to the documentation for details. */
/* ---------------------------------------------------------------------- */
#define LINKER 1
#include "defines.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include OSBIND
#include "nasm.h"
#include "debug.h"
#include NMALLOC_H
#include "code.h"
#if STATISTICS
# include <time.h>
#endif
#define STDORIGIN 0x2000
#define MAXFILES 256 /* max files to link together */
#define MAXLIBS 16
char *currfile;
static char *infile[MAXFILES],
*libraries[ MAXLIBS],
linkfile[ 256],
outfile[ 256],
#if OS == TOS
_usage[] =
"Usage:\nnlink65 [-{tiwv}][-m [xxxx]][-s *][-b batch][-d ldir][-l lib]\
[-o com] <files>\n",
#else
_usage[] =
"Usage:\nnlink65 [-{wiv}][-m [xxxx]][-s *][-b batch][-d ldir][-l lib]\
[-o com] <files>\n",
#if PORTED
portnoy[] =
{
# if INCOMPATIBLE
'W','a','r','n','i','n','g',':',' ','O','b','j','e','c','t',' ',
'f','i','l','e',' ',
'i','n','c','o','m','p','a','t','i','b','i','l','t','y','.',' ',
# endif
'P','o','r','t','e','d',' ','b','y',' ',PORTER,'\n',
0
},
# endif
#endif
notice[] =
{
'N','l','i','n','k','6','5',' ','v',VERSION+'0','.',
LINKREVISION/10+'0',LINKREVISION%10+'0',' ',
'b','y',' ',AUTHOR,' ',' ','C','o','p','y','r','i','g','h','t',' ',
'(','c',')',' ','1','9','9','2',' ',ORGANIZATION,'\r','\n',0
};
extern seg *sp;
seg *l_seg;
char header[128];
int relocatable,
moveable,
dumpvalues,
verbose,
runad,
pageflag = 1,
#if OS == TOS
tossable,
#endif
what_the_fuck, /* cited from "Everybody wants some" */
bootable,
fdout,
files,
#if STATISTICS
tok_remain,
#endif
libs,
maxerrors = 20;
word relative = 743,
mv_offset,
origin = STDORIGIN;
extern int freshflag,
errors;
void main( argc, argv)
int argc;
char **argv;
{
#if STATISTICS
clock_t t_start, t_finish, t_result, t_tmp;
#endif
char *x;
int i = 0,
foo;
ENTER("main");
#if STATISTICS
t_start = clock();
#endif
if( x = getenv( "LIB65"))
{
strcpy( header, x);
fixheader();
}
#if OS == TOS
else
tossable = 1;
#endif
#if DEBUG
if( argc > 1)
printf("Argc=%d argv[1]=\"%s\"\n", argc, argv[1]);
#endif
while( ++i < argc)
if( *argv[i] == '-')
switch( Xtolower( argv[i][1]))
{
case 'b' :
{
register char c;
FILE *fp, *fopen();
static char x[256];
if( ++i >= argc)
goto usage;
strcpy( linkfile, argv[i]);
complete( linkfile, ".lnk", 0);
if( ! (fp = fopen( linkfile, "r")))
nferror("Opening the linkfile failed");
do
switch( c = getc( fp))
{
case '#' :
while( (c = getc( fp)) != '\n' && c != EOF);
break;
default :
{
register int i = 0;
do
x[i++] = c;
while( (c = getc( fp)) != ' ' && c != '\t' &&
c != '\r' && c != '\n' && c != EOF && i < 255);
x[i++] = 0;
infile[ files++] = strcpy( (char *) nmalloc( (long) i), x);
}
case ' ' :
case '\t' :
case '\r' :
case '\n' :
case EOF : ;
}
while( c != EOF);
fclose( fp);
}
break;
case 'd' :
if( ++i == argc)
goto usage;
strcpy( header, argv[i]);
fixheader();
break;
case 'i' :
runad = ! runad;
break;
case 'l' :
if( ++i >= argc)
goto usage;
libraries[ libs++] = argv[i];
break;
case 'm' :
switch( argv[i][2])
{
case 'm' :
relocatable = -9;
moveable = 1;
case '3' :
relocatable += 2;
case '2' :
if( ++i == argc || ! sscanf( argv[i],"%X", &foo))
default :
goto usage;
relative = foo;
relocatable += 2;
case '1' :
relocatable++;
case '0' :
case 0 :
if( pageflag)
pageflag = ++relocatable & 2; /* **-Port #7-** */
}
break;
case 'o' :
if( ++i == argc)
default :
goto usage;
strcpy( outfile, argv[i]);
break;
case 's' :
if( ++i >= argc || ! sscanf( argv[i], "%X", &foo))
goto usage;
if( (origin = foo) < 0x100)
nwarning("Zeropage destination");
else
if( origin < 0x200)
nwarning("Stack destination");
if( pageflag)
pageflag = ! (origin & 0xFF);
break;
#if OS == TOS
case 't' :
tossable = ! tossable;
break;
#endif
#ifdef __DATE__
case ':' :
fputs( __DATE__, stderr);
# ifdef __TIME__
fprintf( stderr, " %s", __TIME__);
# endif
putc( '\n', stderr);
break;
#endif
case 'v' :
if( Xtolower( argv[ i][2]) == 'f')
{
dumpvalues = ! dumpvalues;
if( Xtolower( argv[ i][3]) != 'l')
break;
}
verbose = ! verbose;
break;
case 'w' :
what_the_fuck = ! what_the_fuck;
break;
case 'x' :
{
char *p = &argv[i][2];
bootable = ! bootable;
if( *p)
{
if( *p == ':')
bootable++;
if( ! sscanf( p, "%X", &foo))
goto usage;
define( "_BOOT_INIT", (word) foo);
}
}
}
else
infile[files++] = argv[i];
if( ! infile[0])
goto usage;
#if OS == MSDOS
_fmode = O_BINARY;
#endif
Cconws( notice);
#if ! VERSION
Cconws("unfinished - unstable - unsupported -- untested. Don't use it!\r\n");
version0();
#endif
#if PORTED
Cconws( portnoy);
#endif
if( relocatable && pageflag)
origin = (origin & 0xFF00) - 3;
if( moveable)
mv_offset = relative - origin;
pro_init();
#if VERSION
sexp_alloc();
#endif
for( i = 0; i != files; i++)
if( (x = strrchr( currfile = infile[ i], '.')) && x[ 1] == 'l')
lload( currfile);
else
aload( currfile, 0);
if( lerr_undefs( 1))
for( i = 0; i != libs; i++)
lload( currfile = libraries[ i]);
if( lerr_undefs( 1))
lload( currfile = "std.l65");
currfile = 0;
/* YOU CAN'T DO ANYTHING BELOW THIS POINT IN TERMS OF LIST */
/* MANAGEMENT LOADING OF FILES ET.C. */
lerr_undefs( 0);
#if ! VERSION
if( ! errors)
lerr_imms();
#endif
if( relocatable)
{
extern word __pc, r_end, head_off;
r_end = __pc;
dpoke( __program + head_off - 2, r_end); /* Fix JSR to RELOC.O65 */
def_label( "|MEMLO", relative);
def_label( "|R_END", __pc);
l_seg = sp;
if( ! moveable)
{
aload( currfile = (pageflag ? "preloc.o65" : "breloc.o65"), 1);
dump_reloc();
dump_imm( pageflag);
}
else
aload( currfile = "mover.o65", 1);
#if ! VERSION
if( ! errors)
lerr_undefs( 0);
#endif
}
if( dumpvalues)
show_values();
pro_exit();
if( ! outfile[0])
{
strcpy( outfile, infile[0]);
complete( outfile, bootable ? ".boo" : ".com", 1);
}
#if ! DEBUG
if( ! errors || what_the_fuck)
{
#endif
if( (fdout = (int) Fkreate( outfile, 0x775)) < 0)
nferror("Can't create output file");
write_results( fdout);
#if ! DEBUG
}
#endif
MESS("OK JUST ABOUT DONE");
#if STATISTICS
t_finish = clock();
if( t_start > t_finish)
t_tmp = t_start - t_finish;
else
t_tmp = t_finish - t_start;
t_result = (t_finish - t_start) / (word) CLK_TCK;
finalstats(1);
printf("Link took %ld.%lds\n", t_result,
(t_tmp - (t_result * (word) CLK_TCK)) >> 1 );
stats();
#endif
LEAVE();
nexit( errors ? 1 : 0);
usage:
fputs( _usage, ESTREAM);
fputs( "\
\t-v : verbose\n\
\t-i : append RUNAD for DOS 2.X\n\
\t-x[binit] : create boot sectors (restrictions may apply)\n\
\t-w : write output file anyway (W.T.F.)\n\
\t-m[0] : mover to (LOMEM) [Default]\n\
\t-m1 : mover to (LOMEM) page aligned\n\
\t-m2 <xxxx> : mover to (xxxx)\n\
\t-m3 <xxxx> : mover to (xxxx) page aligned\n\
\t-mm <xxxx> : mover to xxxx\n\
\t-s <xxxx> : origin to load/run binary at\n\
\t-d <path> : default directory\n\
\t-o <file> : output file\n\
\t-b <batch>: take input files from batchfile\n\
\t-l <libs> : libraries to use\n", ESTREAM);
#if OS == TOS
fputs( "\
\t-t : wait for keypress before exit\n", ESTREAM);
#endif
LEAVE();
nexit( 1);
}
void fixheader()
{
static char foo[] = { DIRSLASH, 0 };
ENTER("fixheader");
if( header[ strlen( header)] != DIRSLASH)
strcat( header, foo);
#if DEBUG
printf("Current include-path : \"%s\" \n", header);
#endif
LEAVE();
}