/* ---------------------------------------------------------------------- */ /* Copyright (C) 1991 by Natrlich! */ /* This file is copyrighted! */ /* Refer to the documentation for details. */ /* ---------------------------------------------------------------------- */ #define LINKER 1 #define __BIG_GENERATOR__ #include "defines.h" #include "nasm.h" #include #include OSBIND #include "debug.h" #include NMALLOC_H #include "object.h" #include "process.h" #include "ldebug.h" byte huge *__program, huge *__p, huge *ptohead; byte __c; word __pc, __x; lword __lx; extern char header[], *currfile, trc_loss[]; extern imm huge *hip, huge *cip; extern seg huge *h_seg, huge *sp; extern word origin; extern int relocatable, bootable, verbose, pageflag; extern ref huge *rhead; extern seg huge **pas; extern imm huge **pai; extern expr huge **pae; word endpc, diff, r_end, r_start, head_off, rcode_off; extern lword magic; extern byte huge *pb; extern e_dropped huge *pe; extern s_dropped huge *ps; extern linksymbol huge *py; extern i_dropped huge *pi; extern r_dropped huge *pr; extern f_dropped huge *pf; extern lword magic, bytes, sbytes, ibytes, rbytes, ebytes, ybytes, fbytes; void pro_init() { ENTER("pro_init"); __p = __program = nmalloc( MAXMODULE); __pc = origin; if( ! bootable) { _deposit( 255); /* drop binary header */ _deposit( 255); dpoke( __p, __pc); _advance( 2); /* leave some room */ ptohead = __p; _advance( 2); head_off = rcode_off = 6; } else if( bootable == 1) { _deposit( 0); ptohead = __p; _advance( 1); dpoke( __p, __pc); _advance( 4); head_off = 6; } if( relocatable) { _deposit( 0x4C); /* JMP */ head_off += 3; rcode_off += 3; __pc += 3; _advance( 2); def_label( "|R_START", __pc); } r_start = __pc; LEAVE(); } void pro_exit() { extern int runad; ENTER("pro_exit"); if( ! bootable) { if( ptohead == __p - 2) /* kill trailing empty segment */ __p -= 4; else { dpoke( ptohead, __pc - 1); } if( runad) { wdeposit( 0x2E0); wdeposit( 0x2E1); wdeposit( origin); } } else if( bootable == 1) { label *p; poke( ptohead, 1 + (__pc - dpeek( ptohead + 1)) / 0x80); if( p = find_label( "_BOOT_INIT")) { dpoke( ptohead + 3, p->val); } else nwarning( "_BOOT_INIT was not defined. That might lead to \ problems, if your\nbootcode returns and the OS JSRs thru the init address"); } if( __p == (__program + head_off)) nerror("Not a single byte was generated"); LEAVE(); } void aload( afile, hflag) char *afile; /* 3 'V's: Van Halen, VfL und Veltins! */ { char *x; int fd; ENTER("aload"); INTEGRITY_CHECK(); #if LOWERFILE downcase( afile); #endif IMESS( "Trying to open \"%s\" ", (lword) afile, 4); if( (fd = (int) Fopen( afile, OPEN_R)) < 0) { if( hflag) { INTEGRITY_CHECK(); x = (char *) nmalloc( strlen( afile) + strlen( header) + 2L); strcpy( x, header); strcat( x, afile); INTEGRITY_CHECK(); } else { INTEGRITY_CHECK(); x = (char *) nmalloc( strlen( afile) + 6L); strcpy( x, afile); complete( x, ".o65", 1); INTEGRITY_CHECK(); } if( (fd = (int) Fopen( currfile = x, OPEN_R)) < 0) { if( fd == -35) nferror("Out of GEMDOS file handles (that's strange..) ?)"); nferror( "Object file does not exist"); } } if( verbose) printf( "%-16s ", afile); INTEGRITY_CHECK(); do_load( fd); INTEGRITY_CHECK(); Fclose( fd); LEAVE(); } /* ---------------------------------------------------------- */ /* Wrapup .. Stuff to do, when we are thru with updating */ /* the symbol table and relocating the code. A new file might */ /* be read in after this. */ /* ---------------------------------------------------------- */ void wrapup() { ENTER("wrapup"); nfree( pas); nfree( pai); MESS("pae"); nfree( pae); nfree( pb); MESS("py"); nfree( py); nfree( pe); MESS("pr"); nfree( pr); nfree( pi); MESS("ps"); nfree( ps); nfree( pf); /* v--- The meek shall inherit shit [DLR] */ rhead = (ref *) (pae = (expr **) (pas = (seg **) (pai = (imm **) (ps = (s_dropped *) (pi = (i_dropped *) (pr = (r_dropped *) (pf = (f_dropped *) (pe = (e_dropped *) (pb = (byte *) (py = 0) ))))))))); #if ! VERSION check_trees(); #endif ALEAVE(); } void write_results( fd) /* 4 'V's: Van Halen, VfL, Veltins und Vrauen! y */ { static char err[] = "Write to output file failed (Disk full??)"; long tbytes; ENTER("write_results"); tbytes = (long) (__p - __program); if( bootable) /* make it sector sized */ { word tmp; if( tmp = (word) tbytes & 0x7F) tbytes += (tmp ^ 0x7F) + 1; } if( verbose) printf("\t\t End : $%04X Size:%5ld bytes total\n", __pc - 1, (lword) __pc - origin - 1); if( Fwrite( fd, tbytes, __program) != tbytes) nferror( err); #if STATISTICS fprintf( ESTREAM, "%ld bytes of binary written\n", tbytes); #endif Fclose( fd); LEAVE(); } /* ---------------------------------------------------------- */ /* Mallocer for identifier and other strings */ /* */ /* (Keeping the fingers crossed that this is faster than a) */ /* (simple malloc) */ /* ---------------------------------------------------------- */ typedef struct _str_m { long free; char huge *space; struct _str_m huge *before; } str_m; static str_m huge *st_h; char *str_alloc( size) int size; { register str_m huge *p; register char huge *q; extern word _a_char, _m_char; extern lword _z_char, _s_char; ENTER("str_alloc"); #if STATISTICS _a_char++; _z_char += size; #endif if( (p = st_h) && p->free >= size) { letsdoit: p->free -= size; q = p->space; p->space += size; IMESS("sending $%lX as address", (lword) q, 4); LEAVE(); return( q); } #if STATISTICS _m_char++; _s_char = sizeof(str_m) + STRMAX; #endif p = (str_m *) nmalloc( sizeof(str_m) + STRMAX); p->free = STRMAX; p->space = (char huge *) p + sizeof( str_m); p->before = st_h; st_h = p; if( size > STRMAX) nierror("Unexpected internal problems force NLINK65 to crash"); goto letsdoit; } /* y Har har */