home *** CD-ROM | disk | FTP | other *** search
- /* ---------------------------------------------------------------------- */
- /* 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();
- }
-
-
-