home *** CD-ROM | disk | FTP | other *** search
- /* ---------------------------------------------------------------------- */
- /* Copyright (C) 1991 by Natürlich! */
- /* This file is copyrighted! */
- /* Refer to the documentation for details. */
- /* ---------------------------------------------------------------------- */
- #define LINKER 1
- #define WRITE_TABLE 0
- #if WRITE_TABLE
- # include <stdio.h>
- #endif
- #include "defines.h"
- #include "nasm.h"
- #include OSBIND
- #include "debug.h"
- #include "seg.h"
- #include "labels.h"
- #include "imm.h"
- #include "process.h"
-
- extern imm huge *hip;
- extern seg huge *h_seg, huge *l_seg;
- seg huge *f_seg;
- extern word r_end, r_start, rcode_off;
-
- #define xdeposit( x) deposit( x)
- #define xwdeposit( x) wdeposit( x)
-
-
- void def_label( s, val)
- char *s;
- word val;
- {
- label huge *q;
-
- if( ! (q = find_label( s)))
- {
- #if ! VERSION
- extern char *str_alloc();
-
- s = strcpy( str_alloc( strlen( s) + 1), s);
- #endif
- enter_llabel( s, val, L_PC); /* Shouldn't really happen */
- }
- else
- if( ! q->refs)
- nierror("Linker internal label twice defined");
- else
- {
- q->val = val; /* Case: Label has refs, we got the value */
- entrefer( q);
- }
- }
-
- static int countem( p, ourpage, type)
- register imm huge *p;
- word ourpage;
- int type;
- {
- register int i;
- register word tmp;
-
- for( i = 0; p; p = p->next)
- if( p->type == type && p->block != f_seg)
- {
- if( (tmp = p->offset + p->block->offset - rcode_off + r_start)
- >= r_end ||
- (tmp & 0xFF00) > ourpage)
- break;
- i++;
- }
- return( i);
- }
-
- /* ---------------------------------------------------------- */
- /* This dumps the immediate table down into the file write */
- /* space. The flag tells us whether we are gonna be */
- /* page-aligned or not (then we need plenty more info) */
- /* ---------------------------------------------------------- */
- #define MSB 1
- #define LSB 0
-
- void dump_imm( flag)
- int flag;
- {
- register imm huge *p = hip;
- register word i;
- word pages, ourpage,
- factor = (r_start & 0xFF) - rcode_off;
- #if WRITE_TABLE
- word aux, cnt;
- #endif
-
- f_seg = l_seg->next;
- def_label("|IMMTAB", __pc);
-
- /* incorporate .DS holes into index */
- /* {
- register seg huge *p;
- register word plus = 0;
-
- for( p = h_seg; p != f_seg; p = p->next)
- {
- p->index += plus;
- if( p->type == S_DS)
- plus += p->size;
- }
- }*/
-
- pages = ( ((r_end & 0xFF00) - (ourpage = r_start & 0xFF00)) >> 8) + 1;
- #if WRITE_TABLE
- printf( "%d pages total\n", pages);
- #endif
- xdeposit( pages);
-
- if( ! flag)
- {
- int ipages = pages;
-
- #if WRITE_TABLE
- printf( "LSB patch bytes:");
- aux = r_start & 0xFF00;
- #endif
- while( ipages--)
- {
- i = countem( p, ourpage, LSB);
- xdeposit( i);
- #if WRITE_TABLE
- printf( "\n%4d bytes to patch\n", i);
- cnt = 0;
- #endif
- while( i--)
- {
- while( p->type)
- p = p->next;
- xdeposit( p->offset + p->block->offset + factor);
- #if WRITE_TABLE
- if( cnt++ == 8)
- {
- putchar('\n');
- cnt = 0;
- }
- printf( " $%04X", __p[ -1] + ourpage);
- if( i && cnt != 8)
- putchar( ',');
- #endif
- p = p->next;
- }
- ourpage += 0x100;
- #if WRITE_TABLE
- putchar('\n');
- #endif
- }
- p = hip;
- ourpage = r_start & 0xFF00;
- }
-
- #if WRITE_TABLE
- printf( "\n\nMSB patch bytes:");
- #endif
- while( pages--)
- {
- i = countem( p, ourpage, MSB);
- xdeposit( i);
- #if WRITE_TABLE
- printf( "\n%4d bytes to patch\n", i);
- cnt = 0;
- #endif
- while( i--)
- {
- while( ! p->type)
- p = p->next;
- xdeposit( p->offset + p->block->offset + factor);
- #if WRITE_TABLE
- if( cnt++ == 3)
- {
- putchar('\n');
- cnt = 1;
- }
- printf( " $%04X (LSB: $%02X)", __p[ -1] + ourpage,
- p->val & 0xFF);
- if( i && cnt != 3)
- putchar( ',');
- #endif
- if( ! flag)
- {
- xdeposit( p->val);
- }
- p = p->next;
- }
- ourpage += 0x100;
- #if WRITE_TABLE
- putchar('\n');
- #endif
- }
- }
-
-
- void dump_reloc()
- {
- register seg huge *p = h_seg;
-
- def_label( "|RELTAB", __pc);
- for(;;)
- {
- if( p->type == S_DS)
- {
- xdeposit( S_SDATA);
- }
- else
- {
- xdeposit( p->type);
- while( p != l_seg && p->next->type == p->type)
- {
- p->next->size += p->size;
- p = p->next;
- }
- }
- xwdeposit( p->size);
- if( p == l_seg)
- {
- xdeposit( 128); /* dump EOP */
- return;
- }
- p = p->next;
- }
- }
-
-