/* ---------------------------------------------------------------------- */ /* Copyright (C) 1992 by Natrlich! */ /* This file is copyrighted! */ /* Refer to the documentation for details. */ /* if you add to the options, remember NASM.TTP too */ /* ---------------------------------------------------------------------- */ #include "defines.h" #include "nasm.h" #include OSBIND #include "debug.h" #include "buffer.h" #include #include #include #include #if STATISTICS #include NMALLOC_H #endif static char infile[ 256], outfile[ 256], #if OS == TOS _usage[] = "Usage: nasm65 [-{brstw}][-a xx][-e #][-o binary][-h includedir] \n", #else _usage[] = "Usage: nasm65 [-{brsw}][-a xx][-e #][-o binary][-h includedir] \n", # if PORTED portnote[] = { # 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',' ','b','y',' ',PORTER,'\n',0 }, # endif #endif notice[] = { 'N','a','s','m','6','5',' ',' ','v',VERSION+'0','.', ASMREVISION/10+'0',ASMREVISION%10+'0',' ', 'b','y',' ',AUTHOR,' ',' ','C','o','p','y','r','i','g','h','t',' ', '(','c',')',' ','1','9','9','2',' ',ORGANIZATION, #if OS == TOS '\r','\n', #else '\n', #endif 0 }; char header[128]; word alignment; int runnable, better, show_open, show_expansion, show_mload, #if OS == TOS tossable, # if WITHNOISY noisytok, # endif #endif pssst, what_the_fuck, /* cited from "Everybody wants some" */ fdout, maxerrors = 30; char buf[ 128], *realname; extern int freshflag, errors; main( argc, argv) int argc; char **argv; { #if STATISTICS clock_t t_start, t_finish, t_result, t_tmp; #endif char huge *x; int foo; /* portability */ int i = 0; ENTER("main"); #if STATISTICS t_start = clock(); #endif if( x = getenv( "INC65")) { 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 #if VERSION /* need this up here for -D defs */ sexp_alloc(); /* reserve space for exprfast */ str_alloc(1); /* reserve space for yy_txt2val */ #endif while( ++i < argc) { if( *argv[i] == '-') switch( Xtolower( argv[i][1])) { case '_' : if( ++i == argc) nierror("wrong arg given by CPP"); realname = argv[ i]; break; case 'a' : if( ++i == argc || ! sscanf( argv[i], "%X", &foo)) goto usage; if( (alignment = (word) foo) >= 0x100) nferror("Only alignment values less than $100"); { register word i = alignment; for(; i & 1; i >>= 1); if( i) nwarning("Alignment value H I G H L Y unusual"); } break; case 'b' : better = ! better; break; case 'd' : /* maybe we should use the env. as well */ if( ++i < argc) { word val = 0; char *x, *y; x = argv[i]; upcase( x); if( y = strrchr( x, '=')) { *y = 0; sscanf( y + 1, "%d", &val); } def_label( x, val); } else goto usage; break; case 'e' : if( ++i == argc || ! sscanf( argv[i], "%d", &maxerrors)) goto usage; break; case 'h' : if( ++i == argc) goto usage; strcpy( header, argv[i]); fixheader(); break; #if OS == TOS # if WITHNOISY case 'n' : noisytok = ! noisytok; break; # endif case 't' : tossable = ! tossable; break; #else case 't' : case 'n' : break; #endif case 'o' : if( ++i == argc) default : goto usage; strcpy( outfile, argv[i]); break; case 'q' : pssst = ! pssst; break; case 'r' : runnable = ! runnable; break; case 's' : show_expansion = ! show_expansion; if( argv[ i][ 2]) show_mload = ! show_mload; break; #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' || Xtolower( argv[i][3]) != 'l') goto usage; { extern char is_where[]; extern byte is_what[]; is_where[ '|'] = 1; is_what[ '|'] = 0x10; #if VERSION if( (rand() & 0x100)/*Random()*/ & 0x1) print_secret(); else print2_secret(); #endif } break; case 'w' : what_the_fuck = ! what_the_fuck; break; case 'x' : show_open = ! show_open; } else { if( infile[0]) goto usage; strcpy( infile, argv[i]); } } if( ! infile[0]) goto usage; if( ! pssst) { Cconws( notice); #if PORTED Cconws( portnote); #endif } #if OS == /* fucking */ MSDOS _fmode = O_BINARY; #endif #if ! VERSION Cconws("unfinished - unstable - unsupported - untested. Don't use it!\r\n"); version0(); #endif MESS("Starting the INCLUDE"); include( infile, ".s65"); { extern buffer *bp; inc_line(); } if( ! outfile[0]) { strcpy( outfile, infile); complete( outfile, runnable ? ".com" : ".o65", 1); } pro_init(); /* alloc dump space */ if( runnable) def_label( "__RUN", 1); def_label(" __NASM65", 1); #if YACCDEBUG { extern int yydebug; yydebug = 1; } #endif yyparse(); MESS("we are back"); do_local(); /* clean up and dump unrefs */ err_undefs(); pro_exit(); #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 #if STATISTICS MESS("OK JUST ABOUT DONE"); 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) / (int) CLK_TCK; finalstats(1); printf("Assembly took %ld.%lds\n", t_result, (t_tmp - (t_result * (word) CLK_TCK)) >> 1 ); stats(); #endif ALEAVE(); nexit( errors ? 1 : 0); usage: errors = 1; fputs( _usage, ESTREAM); fputs( "\ \t-x : list unresolved references\n\ \t-w : write output file anyway (W.T.F.)\n\ \t-h : \"system\" include file directory\n\ \t-o : output file specifier\n\ \t-r : create runnable binary file\n\ \t-e : set maximal number of errors before aborting\n\ \t-s : show calling of macros and include files\n\ \t-d [=] : defines label . optionally assigns as value to it\n\ \t-a : alignment value (1->even 255->page)\n\ \t-q : quiet flag\n\ \t-b : optimize small segments\n", ESTREAM); #if OS == TOS fputs( "\ \t-t : wait for keypress before exit\n\ \t-n : noisy tokens\n", ESTREAM); #endif ALEAVE(); nexit( 1); } void fixheader() { static char foo[] = { DIRSLASH, 0 }; if( header[ strlen( header)] != DIRSLASH) strcat( header, foo); #if DEBUG printf("Current include path : \"%s\"\n", header); #endif } void yyerror() { } void print_char( c) char c; { #if OS != AMIGA || defined( __hp9000s300) static clock_t tick; Bconout( 2, (int) c); tick = clock() + ((int) CLK_TCK >> 2); while( tick > clock()); #else Bconout( 2, (int) c); sleep( 1); #endif } void print_secret() { static char vfl1[] = "Dqn~B~a-$es oRhTmW}lEe^ _az(n/w8r ", vfl2[] = "e l*u4W*iCsHBHcIuM ha|zfrtn}e i9 "; char huge *p = vfl1, *q = vfl2; do { print_char( *p++); print_char( *++q); } while( *++q && *++p); print_char('\r'); print_char('\n'); } #ifdef __hp9000s300 # define UNIT 2 # define KURZ 1 # define MITTEL 2 # define LANG 3 #else # if OS == AMIGA # undef CLK_TCK # define CLK_TCK 50 # endif # define UNIT ((int) CLK_TCK >> 1) # define KURZ ((int) CLK_TCK / 3) # define MITTEL ((int) CLK_TCK >> 1) # define LANG ((int) CLK_TCK - 1) #endif void takt( s, flag, len) char huge *s; { int c; while( c = *s++) Bconout( 2, c ^ 0x5F); if( flag) Bconout(2, ' '); #if ! defined( __hp9000s300) && OS != AMIGA { clock_t tick; tick = clock() + len; while( tick > clock()); } #else sleep( len); #endif } static char secret[] = { 0x1B, 0x3A, 0x31, 0, 0x1D, 0x33, 0x3E, 0x2A, 0, 0x72, 0x8, 0x3A, 0x36, 0x2C, 0x2C, 0, 0x1D, 0x30, 0, 0x3C, 0x37, 0x2A, 0x32, 0, 0x8, 0x3E, 0x33, 0, 0x25, 0x3A, 0x2D, 0, 0x2B, 0x3E, 0x31, 0, 0x25, 0x3A, 0x31, 0, 0x28, 0x36, 0x2D, 0x71, 0x71, 0x71, 0 }; void print2_secret() { char huge *p = secret; takt( p, 1, KURZ); takt( p += 4, 0, LANG); takt( p += 5, 1, MITTEL); takt( p += 7, 0, LANG); takt( p += 3, 1, MITTEL); takt( p += 5, 0, MITTEL); takt( p += 4, 1, KURZ); takt( p += 4, 0, MITTEL); takt( p += 4, 1, KURZ); takt( p + 4, 0, KURZ); Bconout( 2, '\r'); Bconout( 2, '\n'); } void upcase( s) register char *s; { register char c; while( c = *s) *s++ = toupper( c); }