1.1.1. Introduction
2.1.1. Linker specification file
2.2.1. Comments
2.3.1. Numbers and expressions
2.3.2. Unary operators
2.3.3. Binary operators
2.3.4. Number bases
2.4.1. Creating new global variables
2.4.2. Partitions
2.4.3. Overlays
2.4.4. Regions
2.4.5. Attributes
2.4.6. Example
3.1.1. Map file
4.1.1. Output file
5.1.1. Input data file
6.1.1. Command line


1.1.1. Introduction

The purpose of LINK is to combine relocatable object files generated 
by language translators.  The model used by LINK input files consists of a 
number of named sections, each with a size and other attributes.  Sections 
may have references to other sections or to global variables in them.  
When LINK is executed on a set of input files it combines all sections 
from all input file which have the same name into a distinct unit; there 
is one unit for each named section.  An address is selected for each unit, 
and then the linker proceeds to evaluate the values ofglobal references 
and 'fixes up' such references so that they point to the appropriate place 
in memory.  By default LINK arranges sections starting at address zero in 
the order it first encounters section names; each section starts where 
the last one left off.  The assembler generates linker directives that 
ensure that program code will always be located on an even address 
boundary if that is required by the processor.

The linker is also capable of accepting a specification file which defines
the exact location and other parameters of where each section is loaded 
into memory.  This allows design of programs that have an arbitrary memory 
map.  Another option is to combine all the sections but to generate a
relocatable output file which can be further linked with other input files.

In addition the linker will accept input from an input data file; this is 
useful when there are too many input files for MS-DOS to handle on the 
command line or when it is desirable to give specific names to the output 
or map files.

The linker will accept libraries in addition to accepting relocatable 
object files; such libraries are created and maintained with LB68K.

The linker is FText compatible and allows some standard FText extensions.

2.1.1. Linker specification file

The linker specification file is optional.  It allows the programmer to
control the exact placement of sections in memory.  This makes the linker 
useful in programming systems where the exact layout of the hardware is 
possibly non-linear.  Another good use of linker specification files is
when code is to be maintained for several hardware platforms which differ 
in memory layout; the addresses do not need to be coded in the assembly 
files but can be maintained with seperate specification files.

The simplest specifier format looks like:

        partition {
                overlay {
                        region {} regionname[specifiers];
                } overlay_name;
        } partion_name[specifiers];

There can be as many partitions, overlays, regions as necessary, as long as 
they are concatenated in the appropriate place.  Regions always go inside 
overlays; overlays always go inside partitions.  Within a partition each 
declared overlay will be mapped to the partition base address; they are 
called overlays because the programs defined in successive overlays 
utilize the same region of memory and thus may be bank-switched, overlayed 
from a disk, etc...

Also definitions can be made virtually anywhere, for example:

my_label = 5.  

These will be declared as 'PUBLIC' values and for use in the link.  
Definitions can use a wide range of mathematical functions.


2.2.1. Comments

The linker supports 2 styles of comments in the specification file.  One
is available for ASCII input files, the other becomes available if the
intput file is FText.

The first comment style is the standard C comment style.  A comment begins
when a '/*' sequence is discovered, and ends when a '*/' sequence is
discovered.  Comments may span multiple lines but may not be nested.

The second comment style utilizes FText Double boxes.  Text enclosed in
a double box will be treated as a comment.

Examples:

/*
 * This is a comment
 */
       +------------------+
       |This is a comment |
       +------------------+


2.3.1. Numbers and expressions

Numbers are integer values in the linker; the size may be as much as 32 
bits.  By default numbers are in base 10 representation, however other       
bases may be selected.

Expressions are combinations of numbers, mathematical functions, and
global symbols.  Any symbol which has been defines as global by the 
language translator may be used in an expression; and new global symbols 
may be defined in the specification file.  L68K will accept an expression 
any place it will accept a number.

2.3.2, Unary operators

Two unary operators are supported by L68K:

       +----------------------------------------+
       |-       unary minus (negation)          |
       |~       binary not (bitwise complement) |
       +----------------------------------------+

2.3.3. Binary operators

L68K supports the following binary operators:

       +---------------------------+
       |+       Addition           |
       |-       Subtraction        |
       |*       Multiplication     |
       |/       Division           |
       +---------------------------+

In addition there is an operator '$' which returns the current value of the 
program counter, as specified by any base addresses specified in the 
specification file and the sizes of any sections which have been 
previously allocated.  This will be discussed more in a later section.

2.3.4. Number bases

By default numbers are assumed to be in base 10.  Numbers may be preceded 
with a prefix to generate numbers in another base.  Available prefixes are:

       +------------------------+
       |% or           Base 2  |
       |               Base 8  |
       |               Base 10 |
       |$ or 0x         Base 16 |
       +------------------------+

Note that the usage of '$' can be ambiguous; it can either denote the
current program counter or it can denote a hexadecimal number.  The linker 
will assume that it is a hexadecimal number if the following character is 
a legal hexadecimal digit; thus a good strategy is to always follow it by a 
space when it is intended to mean the program counter.

2.4.1. Creating new global variables

New variables may be created with the following syntax:

name = expression

Such variables are declared as XDEFs (public) for purposes of the link and 
may be referenced as XREFS from assembly code.

2.4.2. Partitions

Partitions denote completely seperate areas of memory.  For example if the 
ROM is to be located at address 0 and the RAM is to be located at address 
$10000 the following set of partitions may be used.

partition {
        ...
} ROM [addr = 0];

partition {
        ...
} RAM [addr = $10000]

In these declarations 'addr = value' is used to set the value of the 
starting point of the partition.  Other such attributes may be used and 
will be discussed in a later section.  The name used to name a partition 
is for readability only and is not used by the linker.

If a partition does not have an 'addr' attribute it inherits the address
in effect at the end of the last partition; or address 0 if it is the
first partition.  Partitions MUST be listed in the same order they will
appear in memory.

2.4.3. Overlays

Overlays are used to assign two seperate sets of sections to the same 
address in memory.  For example if there are two seperate sets of diskette
drivers that may be loaded but only one is needed at a time, the 
declaration below may be used:

partition {
  overlay {
    <declaration for 1.2MB drive driver>
  } DISK12;
  overlay {
    <declaration for 1.44MB drive driver>
  } DISK144;
} project [addr = $4000];

This will place both drivers at the same location in memory, $4000.  The 
actual object code for each driver will be available to the downloader,
DL, and seperate binary files may be created for each overlay.  It is
then up to the system designer to be sure that the correct driver gets 
moved to address $4000 in some manner prior to executing the code.

Another example is bank switching.  Sometimes memory is banked 
deliberately; in other cases a processor such as the M68000 defines 
different banks such as system code, system data, user code, user data 
which may be implemented in hardware.  The overlay mechanism allows an
efficient means for associating different sections of code with different
memory banks.


Overlays may not have explicit attributes; each overlay in a partion
inherits all the attributes from the partition.

2.4.4. Regions

A REGION in the linker is the same as a SECTION in the assembler.  Regions 
may be manipulated independently of one another; however LINK scans 
through all input files looking for sections of the same name and groups 
them together prior to operating on the linker specification file.

Just as it is beneficial to seperate code into partitions because of memory 
segmentation, and into overlays so that memory can be shared, it is 
sometimes convenient to split code into seperate sections so that it can be 
manipulated efficiently with the linker.  For example on the MC68000 the
restart vector is at address 0, followed by the trap vectors.  Now 
assuming that ROM starts at address zero a seperate section could be 
defined which only has the restart and vector information in it.  Such a
section might be called 'vectors'.  Normal code which starts immediately
after the vector memory might be placed in a section called code.  The
following example illustrates a way to specify where each section goes.

partition {
  overlay {
    region {} vectors;
    region {} code[addr = $400];
  } ROM;
} project;

This example makes use of attributes on a region; such attributes override
the current setting of the program counter.  Also the project partition 
has no addr attribute and so it defaults to address 0.

When multiple regions are defined within an overlay, each region inherits
the PC indicated by the end of the last region; or in the case of the 
first region it inherits the PC from the enclosing overlay.  This fact can 
be used in a variety of ways; for example to determine the size of an 
overlay one may do the following:

partition {
  overlay {
    BEGINNING = $;
    region {} region1;
    ENDR1 = $;
    region {} region2;
    region {} region3;
    ENDING = $;
    SIZE = ENDING - BEGINNING;
  } ROM;
} project;

Note that the ENDR1 symbol is defined and will be the value that is the
end of region1 and the start of region 2.

Another use of $ is to locate a stack at the end of RAM, as in:

partition {
  Overlay {
    region {} data[size = $1000];
    STACKTOP = $;
  } RAM;
} r1;

This declares a region 'data' which may have a maximum size of $1000; zeros
will be added to expand the size to $1000 if it is less than that.  The 
stacktop is then located at the top of RAM.

Region names may be defined which do not actually occur in any of the       
input files.  All attributes (including size and placement) of such empty 
regions will be honored by the linker before it continues processing the
next region.

2.4.5. Attributes

Attributes may be used on Partition and Region names; overlays inherit
the attributes of the enclosing partition and the first region in an overlay
inherits the PC of the enclosing overlay.  Attributes are totally optional;
they specify placement, alignement, and sizing.

Available attributes are:

        addr=value      -       the PC at the start of this region
                                or partition is 'value'.  Default is 0 for 
                                the first partition and the next available
                                address for successive partitions.
        size=value      -       Generate an error if the region
                                or partition gets larger than value.  Force
                                region or partition up to this size.
        roundsize = value -     round the size of the region
                                or partion up to the next multiple
                                of value
        align=value     -       Make sure the region or partition
                                is aligned on a multiple of value bytes
        virtual = value         Offsets relative to this region are to
                                be calculated with respect to 'value'.
                                This attribute is used so that data
                                may be loaded at the address given by 'addr'
                                but is known to be accessed via a base
                                register set to the value of 'virtual'.
                                The address may be left off this attribute;
                                in which case it defaults to the
                                address given in the 'addr' attribute.
                                This attribute may only be used on
                                partitions.
                                
        
Attributes are enclosed in brackets [].  Multiple attributes may be 
specified; seperate them with commas.

2.4.6. Example

Assume the following hardware layout: 
        ROM at $18000000 and extending for $8000 bytes 
        RAM at $0 and extending for $4000 bytes
        RAM at $20000000 and extending for $400 bytes; to be used as stack.

        The hardware maps the first eight bytes of ROM into RAM for a 
        sufficient period of time to allow booting; then replaces it with
        RAM.
                                                                                
The following sections have been defined in the assembler source:

        VectorData      - Data that goes in the MC68000 vector table
        Data            - user pre-initialized RAM
        Code            - code
        Restart         - Eight bytes of restart vector

The program expects a global variable STACKPOINTER to be defined; it will 
use this to initialize the stack pointer at power up.  One of the problems 
to be resolved in this case is that user RAM and the vector tables must be 
pre-initialized by the program startup routine.  Code has been written to 
do this, and expects that in the ROM there will be an image starting at a 
global address called RAMDATA.  It expects the size of this image to be 
specified by RAMSIZE.  If we define the section:

        MCRAM   - actual location of the beginning of RAM

we can fulfill these needs as follows:


RAMSIZE = $4000

partition {
  overlay {
    region {} MCRAM [addr = 0]; 
  } RAM;
} pt1;

partition {
  overlay {
    region {} Restart [size = 8];
    region {} Code;
    RAMDATA = $;
    region {} VectorData[size = $400, align = 4];
    region {} Data[size = RAMSIZE - $400];
  } ROM;
} pt2 [addr = $18000000];

partition {
  overlay {
    region {} Stack[size = $400];
    STACKPOINTER = $;
  } STACK;
} pt3 [addr = $20000000]

Partition p1 doesn't really need to be defined at all, since it doesn't 
group any usefule regions together or define any labels.

Partition p2 is the heart of the specification; it groups all of the 
program code and data into the PROM memory for use in burning eproms.  
Note that the size of Restart was specified.  This is to tell the 
programmer if he is trying to pack too much data into the region.  The 
sizing on VectorData serves the same purpose; it also allows for 
incomplete specification of all vectors while still maintaining space for 
the ones that are unspecified.  The align is used in this case to speed up 
the 'move' code that moves data from ROM to RAM; although it isn't really 
necessary.

Partition p3 defines the variable STACKPOINTER.



3.1.1. Map file

By default, the map file lists all regions found in the inputfile along 
with their size and location.  if /f is present on the command line the 
default file also has a list of partitions, overlays, regions with their 
sizes and locations.

If /p is specified the map file also has a list of all publics along with 
their values, and if the output file is relocatable (/r) it lists the 
region they are found in.  The list is given first in alphabetic order, 
then in descending order by value.

If /s is specified the map file gives a listing simliar to the default 
region listing, however, it lists all regions gathered from all files with 
their size and location.

The map file will be the name of the first input file or alternately it can 
be specified in a data file.  Any path present will be ignored and the map 
file will appear in the present directory with a .MAP extension.

4.1.1. Output file

The output file is in IEEE695 format; thus a seperate utility is used to 
convert data to binary format for use in programming eproms or other 
purposes.  This utility is called DL.

Two output formats are provided.  The output may be relocatable, which
means it can be further linked with other input files.  In this case the 
output file name will appear in the current directory and will be the 
name of the first input file, with the extension .OUT.  Alternately the 
name of the output file can be specified in the input data file.

The other output format is absolute.  This format has all global addresses 
resolved to their proper location in preparation for downloading to the
target.  It is the default output format.  Absolute files follow the same 
naming conventions as relocatable files except that they have the extension .ABS.

When overlays are specified in the specification file, the linker will 
produce section declaration names which match the overlay names so that 
the overlays will be available to the downloader.  Otherwise the linker 
produces section names corresponding to the section names found in the 
input files.

5.1.1. Input data file

The input data file specifies the input and output file names.  Input file 
names found on the command line will also be processed.

The first line of the input data file specifies the name of the output 
file.  

The second line specifies the name of the map file.

The remaining may each specify one or more input files.  Input files may be 
relocatable (.O extension) or libraries (.LIB extension).


6.1.1. Command line

LINK [/a/c/f/o/p/r/s/v/x/E/L] <list of object files> @input

In the simplest form L68K will take a list of files and produce a linked
version:

LINK q r s a.lib

links q.o, r.o, s.o, a.lib and creates q.abs and q.map

Valid switches are

/a
        Produce dependency informatiion in the output file.
/c
        Specify a case sensitive link

/ffilename
        Use a link specifier file to taylor the output of the .abs file.
        If /r is present the /r will be ignored
/ofile
        set the name of the .out or .abs file
/p
        include a list of publics in the map file
/r
        output a .out file; this file has is relocatable and is thus
        suitable for further linking.  This switch is ignored if /f is
        present
/s
        include a list of all regions (sections) gathered from all input
        files in the map file
/v
        pass debugging info through the link process.
/x
        don't output a map file
/E#
        quit after # errors posted.  Default is 25.  Some errors are        
        fatal and cause immediate exit.
/Lpath[;path[;path[...]]]
        specify library search paths.  Libraries that do not have an
        associated path will be searched along all the paths specified
        until found.

@filename
        specify an input data file.


        
