home *** CD-ROM | disk | FTP | other *** search
/ Crawly Crypt Collection 1 / crawlyvol1.bin / program / compiler / nasm20b / nasm_src / link65.c < prev    next >
C/C++ Source or Header  |  1993-01-19  |  11KB  |  405 lines

  1. /* ---------------------------------------------------------------------- */
  2. /*                   Copyright (C) 1992 by Natürlich!                     */
  3. /*                      This file is copyrighted!                         */
  4. /*                Refer to the documentation for details.                 */
  5. /* ---------------------------------------------------------------------- */
  6. #define LINKER 1
  7. #include "defines.h"
  8. #include <stdio.h>
  9. #include <string.h>
  10. #include <stdlib.h>
  11. #include OSBIND
  12. #include "nasm.h"
  13. #include "debug.h"
  14. #include NMALLOC_H
  15. #include "code.h"
  16. #if STATISTICS
  17. # include <time.h>
  18. #endif
  19.  
  20.  
  21. #define STDORIGIN    0x2000
  22. #define MAXFILES     256         /* max files to link together */
  23. #define MAXLIBS      16
  24.  
  25. char          *currfile;
  26. static char   *infile[MAXFILES],
  27.               *libraries[ MAXLIBS],
  28.               linkfile[ 256],
  29.               outfile[ 256],
  30. #if OS == TOS
  31. _usage[] =
  32. "Usage:\nnlink65 [-{tiwv}][-m [xxxx]][-s *][-b batch][-d ldir][-l lib]\
  33. [-o com] <files>\n",
  34. #else
  35. _usage[] =
  36. "Usage:\nnlink65 [-{wiv}][-m [xxxx]][-s *][-b batch][-d ldir][-l lib]\
  37. [-o com] <files>\n",
  38. #if PORTED
  39. portnoy[] =
  40. {
  41. #  if INCOMPATIBLE
  42.    'W','a','r','n','i','n','g',':',' ','O','b','j','e','c','t',' ',
  43.    'f','i','l','e',' ',
  44.    'i','n','c','o','m','p','a','t','i','b','i','l','t','y','.',' ',
  45. #  endif
  46.    'P','o','r','t','e','d',' ','b','y',' ',PORTER,'\n',
  47.    0
  48. },
  49. # endif
  50. #endif
  51. notice[] =
  52. {
  53.    'N','l','i','n','k','6','5',' ','v',VERSION+'0','.',
  54.    LINKREVISION/10+'0',LINKREVISION%10+'0',' ',
  55.    'b','y',' ',AUTHOR,' ',' ','C','o','p','y','r','i','g','h','t',' ',
  56.    '(','c',')',' ','1','9','9','2',' ',ORGANIZATION,'\r','\n',0
  57. };
  58.  
  59. extern seg  *sp;
  60. seg         *l_seg;
  61. char        header[128];
  62. int         relocatable, 
  63.             moveable,
  64.             dumpvalues,
  65.             verbose,
  66.             runad,
  67.             pageflag = 1,
  68. #if OS == TOS
  69.             tossable,
  70. #endif
  71.             what_the_fuck,        /* cited from "Everybody wants some" */
  72.             bootable,
  73.             fdout,
  74.             files,
  75. #if STATISTICS
  76.             tok_remain,
  77. #endif            
  78.             libs,
  79.             maxerrors = 20;
  80.  
  81. word        relative = 743,
  82.             mv_offset,
  83.             origin = STDORIGIN;
  84.  
  85. extern int  freshflag,
  86.             errors;
  87.  
  88.  
  89. void  main( argc, argv)
  90. int   argc;
  91. char  **argv;
  92. {
  93. #if STATISTICS
  94.    clock_t        t_start, t_finish, t_result, t_tmp;
  95. #endif
  96.    char           *x;
  97.    int            i = 0,
  98.                   foo;
  99.  
  100.    ENTER("main");
  101. #if STATISTICS
  102.    t_start = clock();
  103. #endif
  104.    if( x = getenv( "LIB65"))
  105.    {
  106.       strcpy( header, x);
  107.       fixheader();
  108.    }
  109. #if OS == TOS
  110.    else
  111.       tossable = 1;
  112. #endif
  113.  
  114. #if DEBUG
  115.    if( argc > 1)
  116.       printf("Argc=%d  argv[1]=\"%s\"\n", argc, argv[1]);
  117. #endif
  118.  
  119.    while( ++i < argc)
  120.       if( *argv[i] == '-')
  121.          switch( Xtolower( argv[i][1]))
  122.          {
  123.             case 'b' :
  124.             {
  125.                register char  c;
  126.                FILE           *fp, *fopen();
  127.                static char    x[256];
  128.  
  129.                if( ++i >= argc)
  130.                   goto usage;
  131.                strcpy( linkfile, argv[i]);
  132.                complete( linkfile, ".lnk", 0);
  133.                if( ! (fp = fopen( linkfile, "r")))
  134.                   nferror("Opening the linkfile failed");
  135.                do
  136.                   switch( c = getc( fp))
  137.                   {
  138.                      case '#'  :
  139.                         while( (c = getc( fp)) != '\n' && c != EOF);
  140.                         break;
  141.  
  142.                      default   :
  143.                      {
  144.                         register int   i = 0;
  145.  
  146.                         do
  147.                            x[i++] = c;
  148.                         while( (c = getc( fp)) != ' '  && c != '\t' &&
  149.                                c != '\r' && c != '\n' && c != EOF && i < 255);
  150.                         x[i++] = 0;
  151.                         infile[ files++] = strcpy( (char *) nmalloc( (long) i), x);
  152.                      }
  153.                      case ' '  :
  154.                      case '\t' :
  155.                      case '\r' :
  156.                      case '\n' :
  157.                      case EOF  : ;
  158.                   }
  159.                while( c != EOF);
  160.                fclose( fp);
  161.             }
  162.             break;
  163.  
  164.             case 'd' :
  165.                if( ++i == argc)
  166.                   goto usage;
  167.                strcpy( header, argv[i]);
  168.                fixheader();
  169.                break;
  170.  
  171.             case 'i' :
  172.                runad = ! runad;
  173.                break;
  174.  
  175.             case 'l' :
  176.                if( ++i >= argc)
  177.                   goto usage;
  178.                libraries[ libs++] = argv[i];
  179.                break;
  180.  
  181.             case 'm' :
  182.                switch( argv[i][2])
  183.                {
  184.                   case 'm' :
  185.                      relocatable = -9;
  186.                      moveable    = 1;
  187.                   case '3' :
  188.                      relocatable += 2;
  189.                   case '2' :
  190.                      if( ++i == argc || ! sscanf( argv[i],"%X", &foo))
  191.                   default  :
  192.                         goto usage;
  193.                      relative = foo;
  194.                      relocatable += 2;
  195.                   case '1' :
  196.                      relocatable++;
  197.                   case '0' :
  198.                   case 0   :
  199.                      if( pageflag)
  200.                         pageflag = ++relocatable & 2;   /* **-Port #7-** */
  201.                }
  202.                break;
  203.  
  204.             case 'o' :
  205.                if( ++i == argc)
  206.             default  :
  207.                   goto usage;
  208.                strcpy( outfile, argv[i]);
  209.                break;
  210.  
  211.             case 's' :
  212.                if( ++i >= argc || ! sscanf( argv[i], "%X", &foo))
  213.                   goto usage;
  214.                if( (origin = foo) < 0x100)
  215.                   nwarning("Zeropage destination");
  216.                else
  217.                   if( origin < 0x200)
  218.                      nwarning("Stack destination");
  219.                if( pageflag)
  220.                   pageflag = ! (origin & 0xFF);
  221.                break;
  222.  
  223. #if OS == TOS
  224.             case 't' :
  225.                tossable = ! tossable;
  226.                break;
  227. #endif
  228. #ifdef __DATE__
  229.             case ':' :
  230.                fputs( __DATE__, stderr);
  231. # ifdef __TIME__
  232.                fprintf( stderr, " %s", __TIME__);
  233. # endif                              
  234.                putc( '\n', stderr);
  235.                break;
  236. #endif               
  237.             case 'v' :
  238.                if( Xtolower( argv[ i][2]) == 'f')
  239.                {
  240.                   dumpvalues = ! dumpvalues;
  241.                   if( Xtolower( argv[ i][3]) != 'l')
  242.                      break;
  243.                }
  244.                verbose = ! verbose;
  245.                break;
  246.                
  247.             case 'w' :
  248.                what_the_fuck = ! what_the_fuck;
  249.                break;
  250.                
  251.             case 'x' :
  252.             {
  253.                char  *p = &argv[i][2];
  254.                
  255.                bootable = ! bootable;
  256.                if( *p)
  257.                {
  258.                   if( *p == ':')
  259.                      bootable++;
  260.                   if( ! sscanf( p, "%X", &foo))
  261.                      goto usage;
  262.                   define( "_BOOT_INIT", (word) foo);
  263.                }
  264.             }
  265.          }
  266.       else
  267.          infile[files++] = argv[i];
  268.  
  269.    if( ! infile[0])
  270.       goto usage;
  271.  
  272. #if OS == MSDOS
  273.    _fmode = O_BINARY;
  274. #endif
  275.    Cconws( notice);
  276. #if ! VERSION
  277.    Cconws("unfinished - unstable - unsupported -- untested. Don't use it!\r\n");
  278.    version0();
  279. #endif
  280. #if PORTED
  281.    Cconws( portnoy);
  282. #endif
  283.    if( relocatable && pageflag)
  284.       origin = (origin & 0xFF00) - 3;
  285.    if( moveable)
  286.       mv_offset = relative - origin;
  287.    pro_init();
  288. #if VERSION
  289.    sexp_alloc();
  290. #endif
  291.    for( i = 0; i != files; i++)
  292.       if( (x = strrchr( currfile = infile[ i], '.')) && x[ 1] == 'l')
  293.          lload( currfile);
  294.       else
  295.          aload( currfile, 0);
  296.  
  297.    if( lerr_undefs( 1))
  298.       for( i = 0; i != libs; i++)
  299.          lload( currfile = libraries[ i]);
  300.    if( lerr_undefs( 1))
  301.       lload( currfile = "std.l65");
  302.    currfile = 0;
  303.    /* YOU CAN'T DO ANYTHING BELOW THIS POINT IN TERMS OF LIST */
  304.    /* MANAGEMENT LOADING OF FILES ET.C.                       */
  305.    lerr_undefs( 0);
  306. #if ! VERSION
  307.    if( ! errors)
  308.       lerr_imms();
  309. #endif
  310.    if( relocatable)
  311.    {
  312.       extern word  __pc, r_end, head_off;
  313.  
  314.       r_end = __pc;
  315.       dpoke( __program + head_off - 2, r_end);  /* Fix JSR to RELOC.O65 */
  316.       def_label( "|MEMLO", relative);
  317.       def_label( "|R_END", __pc);
  318.       l_seg = sp;
  319.       if( ! moveable)
  320.       {
  321.          aload( currfile = (pageflag ? "preloc.o65" : "breloc.o65"), 1);
  322.          dump_reloc();
  323.          dump_imm( pageflag); 
  324.       }
  325.       else
  326.          aload( currfile = "mover.o65", 1);
  327. #if ! VERSION
  328.       if( ! errors)
  329.          lerr_undefs( 0);
  330. #endif
  331.    }
  332.    if( dumpvalues)
  333.       show_values();
  334.    pro_exit();
  335.    if( ! outfile[0])
  336.    {
  337.       strcpy( outfile, infile[0]);
  338.       complete( outfile, bootable ? ".boo" : ".com", 1);
  339.    }
  340. #if ! DEBUG
  341.    if( ! errors || what_the_fuck)
  342.    {
  343. #endif
  344.       if( (fdout = (int) Fkreate( outfile, 0x775)) < 0)
  345.          nferror("Can't create output file");
  346.       write_results( fdout);
  347. #if ! DEBUG
  348.    }
  349. #endif
  350.    MESS("OK JUST ABOUT DONE");
  351. #if STATISTICS
  352.    t_finish = clock();
  353.    if( t_start > t_finish)
  354.       t_tmp = t_start - t_finish;
  355.    else
  356.       t_tmp = t_finish - t_start;
  357.    t_result = (t_finish - t_start) / (word) CLK_TCK;
  358.    finalstats(1);
  359.    printf("Link took %ld.%lds\n", t_result,
  360.                            (t_tmp - (t_result * (word) CLK_TCK)) >> 1 );
  361.    stats();
  362. #endif
  363.    LEAVE();
  364.    nexit( errors ? 1 : 0);
  365.  
  366. usage:
  367.    fputs( _usage, ESTREAM);
  368.    fputs( "\
  369. \t-v         : verbose\n\
  370. \t-i         : append RUNAD for DOS 2.X\n\
  371. \t-x[binit]  : create boot sectors (restrictions may apply)\n\
  372. \t-w         : write output file anyway (W.T.F.)\n\
  373. \t-m[0]      : mover to (LOMEM) [Default]\n\
  374. \t-m1        : mover to (LOMEM) page aligned\n\
  375. \t-m2 <xxxx> : mover to (xxxx)\n\
  376. \t-m3 <xxxx> : mover to (xxxx)  page aligned\n\
  377. \t-mm <xxxx> : mover to xxxx\n\
  378. \t-s  <xxxx> : origin to load/run binary at\n\
  379. \t-d  <path> : default directory\n\
  380. \t-o  <file> : output file\n\
  381. \t-b  <batch>: take input files from batchfile\n\
  382. \t-l  <libs> : libraries to use\n", ESTREAM);
  383. #if OS == TOS
  384.    fputs( "\
  385. \t-t         : wait for keypress before exit\n", ESTREAM);
  386. #endif
  387.    LEAVE();
  388.    nexit( 1);
  389. }
  390.  
  391. void  fixheader()
  392. {
  393.    static char foo[] = { DIRSLASH, 0 };
  394.  
  395.    ENTER("fixheader");
  396.    if( header[ strlen( header)] != DIRSLASH)
  397.       strcat( header, foo);
  398. #if DEBUG
  399.    printf("Current include-path : \"%s\" \n", header);
  400. #endif
  401.    LEAVE();
  402. }
  403.  
  404.  
  405.