APM C Compiler                                               Frank Cringle

The Bell Labs portable C compiler, with M68000 code generator added at MIT, is
available on the APM.

This compiler conforms to "The C Programming Language" by Kernighan & Ritchie,
with the addition of enumerated type and in-line assembly.

A large proportion of the UNIX(tm) run-time library exists, and porting of
programs from UNIX to the APM and vice versa is possible for programs which do
not rely on multiple processes.

!<Compiling and linking C programs
A number of command files are provided in the directory C:, for compiling C
programs.  These can be used to compile simple one-module programs, or used as
prototypes to construct customised command files for more complex programs.

@C:CC    - calls the preprocessor, compiler and assembler to convert a C source
           file (XXX.c) into a linkable object file (XXX.b).
@C:CCO   - like C:CC, but runs the peep-hole optimiser before the assembler.
@C:CCT   - like C:CC, but generates code with line number traps (cf imp -TRACE)
@C:CCL   - like C:CC, but runs the linker to produce a runnable program
           (XXX.mob)
@C:CCTL  - compile with line number traps and link
@C:CCOL  - compile, optimise and link.

Example:        @C:CCOL,prog        -- compile prog.c to prog.mob

!>
!<Details of the compile and link phases
!<cpp - preprocessor
The preprocessor expands '#' directives in the source file, and produces an
output acceptable to the compiler.

        C:CPP -ofile.i file.c

        Flags:  -c              do not delete comments
                -dname=val      define name, as if by #define
                -dname          define name=1
                -idirectory     search directory for #include files         
                -ofile          output goes to file, not stdout
                -p              do not insert line directives (#line 12, foo.c)
                                in the output
                -r              allow macro recursion
                -uname          remove any built-in definition of name

!PAGE
The symbol apm is predefined in this version of the preprocessor, so machine
dependant code can be expressed as:
        #ifdef apm
        /* do one thing */
        #else
        /* do another */
        #endif
!>
!<c68 - C compiler
The compiler reads a 'pure' C source file (after preprocessing) and produces an
assembler file suitable for the MIT assembler a68.

        C:C68 <file.i >file.a68
        Flags:  -l              generate code to update the line number at
                                address 0x1000 (displayed in run-time error
                                messages).
                -L              generate line number traps, so the program can
                                be traced using the software front panel.
                -Xp             generate profiling code (count procedure calls)

There is no run-time support for profiling code (yet).

Assembler instructions can be included in the source file using the asm(..)
directive.  Example:

        asm("trap #15"); asm(".word 1000");     /* line trap 1000 for sfp */

The instructions must correspond to MIT's idea of the M68000 op-codes - see
C:A68.DOC
!>
!<o68 - optimiser
The optimiser endeavours to reduce the size of an assembler file.  This applies
not only to the code section, but also involves removing redundant symbol
information, which would otherwise persist through to the linkable object
file to be finally removed by the linker.  Removing it as soon as possible
speeds up the compile-link process.  The optimiser is not bug-free. It will
occasionally produce bad code, although most programs can successfully be
optimised.

        C:O68 infile outfile
!>
!<a68 - assembler
The assembler processes the output of the compiler, or user written assembler
programs, and produces a UNIX-like linkable object file.  The object file
includes information about global symbols and relocation directives, and must be
processed by the loader ld68 to get an APM-executable file.

        C:A68 file              -- assemble file.a68 to file.b

Details of the instruction formats accepted by the assembler can be found in
C:A68.DOC
!>
!<ld68 - linker
The linker combines a set of linkable files to produce either an aggregate
linkable file or an executable file.

        C:LD68 -po file.mob file.b -llibc

Individual linkable files are loaded unconditionally in the order specified
on the command line, whereas library files are searched and only those modules
which satisfy unresolved external references are loaded.  This means that the
order of names on the command line is significant, as is the internal order of
members in libraries.  In general one or more xxx.b files created by the user
will be specified, followed by the standard library libc.  A suitable ordering
for more complicated situations can be calculated using the utility xrefb (q.v.)

Most of the numerous flags can be ignored when using the program on the APM.
"-p" produces a smaller .mob file than "-m", by replacing subroutine calls to 4
byte relocatable addresses by pc-relative calls.  This saves 4 bytes in the
relocation table.

        Flags:  -D    next argument is used as the size of the data segment
                -d    defines common symbols even if the -r option is specified
                -e    next argument is used as the entry point of the image
                -L    next argument is used instead of C: as library directory
                -llib the library lib.a is searched
                -m    generate a .mob file for execution on the APM
                -n    create a 410 file (shared code on UNIX)
                -o    next argument is used as output filename
                -p    like -m but replace "jsr xxxxxxxx" by "bsr xxxx, nop"
                -R    next argument is used as the size of the generated image
                -r    generate relocation commands in output file
                -S    discards all symbols except locals and globals
                -s    discard all symbols and relocation commands to save space
                -u    next argument is treated as an initially undefined symbol
                -v    verbose (list names of modules loaded)
                -X    discards all local symbols beginning with .L
                -x    discards local symbols, preserving only externals


The output goes to b.out (or b.mob if -p or -m is specified), unless a filename
is provided explicitly.
!>
!<Filename extensions
        .a      an archive (library file) containing .b files
        .aa     an archive containing .a files
        .ac     an archive containing .c files
        .a68    an assembler source file
        .b      a linkable object file (see b.out.man for format)
        .c      a C source file
        .h      a C include (header) file
        .i      a preprocessed C source file
!>
!>
!<Libraries
Libraries are collections of linkable object (xxx.b) files constructed by
ar(1), which can be searched by the linker.  The standard system library is
c:libc.a, and this should always be specified as the last thing on the linker
command line, as it includes basic machine support like fixed and floating point
arithmetic routines.  Transcendental maths functions are available in c:libm.a,
which will generally not be required.

!<System calls
Simulations of the UNIX system calls have been written for the APM:

access(2)       existence and executability are equated to mode 4 (read)
acct(2)         not available
alarm(2)        dummy routine - could be implemented later
brk(2)          fully implemented
chdir(2)        change filestore default directory
chmod(2)        set owner and world protection on filestore file
chown(2)        not available
close(2)        fully implemented
creat(2)        mode interpreted as per chmod(2)
dup(2)          fully implemented
exec(2)         dummy routines
exit(2)         fully implemented
fork(2)         dummy routine
getpid(2)       returns filestore user number
getuid(2)       dummy routines
indir(2)        not implemented
ioctl(2)        dummy routine, returns 0 for a tty, -1 otherwise
kill(2)         dummy routine
link(2)         dummy routine
lock(2)         not implemented
lseek(2)        seek past end of file not supported
mknod(2)        not implemented
mount(2)        not implemented
mpx(2)          not implemented
nice(2)         dummy routine
open(2)         .t, .T, :t and :T are interpreted as stream 0 (usually console),
                other names are passed to the filestore
pause(2)        dummy routine
phys(2)         not implemented
pipe(2)         dummy routine
pkon(2)         not implemented
profil(2)       dummy routine, may be provided later
ptrace(2)       not implemented
read(2)         fully implemented
setuid(2)       dummy routine
signal(2)       partially implemented - see C:ALERT
stat(2)         only st_mode and st_size filled in, other fields 0
stime(2)        not implemented
sync(2)         not implemented
time(2)         dummy routine
times(2)        tms_utime set to 50 * seconds since APM boot, others 0
umask(2)        dummy routine
unlink(2)       interpreted as delete file
utime(2)        not implemented
wait(2)         dummy routine
write(2)        fully implemented
!>
!<C Subroutines
The C subroutines, as documented in section 3 of the UNIX manuals, have been
compiled from UNIX source code, so they should be complete.  Any which rely on
unavailable system calls or UNIX-specialities, e.g. the password file, will of
course not work.
!>
!<Maths routines
The standard UNIX maths library for calculating transcendental functions is
available in c:libm.a
!>
!>
!<Utilities
!<ar - archive and library maintainer
This is a version of the standard UNIX utility, and is documented in the manuals
!>
!<nm68 - print name list
This corresponds to UNIX nm(1), and prints the symbol table of a reloacatble
object (xxx.b) file.
!>
!<pr68 - print contents of xxx.b file
This utility can be used to analyse a linkable object file.  It dumps the
segments of the file to stdout, with suitable interpretation of the symbol and
relocation information.

        c:pr68 file.b {flags}

The optional flags are a string of 6 1's and 0's, signifying which segments are
desired (header, text, data, symbol table, text relocation directives and data
relocation directives).  This must be an all-time record for an abysmal user
interface!

Example:        c:pr68 file.b 100100      -- print header and symbol table
!>
!<size68 - size of a linkable object file
Corresponds to UNIX size(1), giving the sizes of the various segments in a named
xxx.b file.

Additional flags in this version:
        -h      display sizes in hex
        -l      long output format
!>
!<text68 - disassemble the text segment of an object file
Disassembles an xxx.b file to MIT assembler format.
!>
!<xrefb - cross-referencer
This utility takes a list of linkable object files and libraries, and
analyses the interdependancies of symbol reference and definition among them.

        c:xrefb {flags} files

        Flags:  -f      three column output consisting of filename, symbols
                        defined, symbols referenced.
                -o      list the names of all the object files, both those
                        specified explicitly or as members of libraries, in an
                        order suitable for one-pass linking.  Circular reference
                        chains are broken by duplicating a filename in the
                        output list.
                default three column output of symbol name, defining file,
                        referencing files.
!>
!>
