#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of shell archive."
# Contents:  README boot.shar boot_load.pas data_move.asm fault.ins.asm
#   float.ins.pas float.pas image.doc makefile start_t.asm
#   start_t.asm~
# Wrapped by mohr@structor on Wed Jul 11 14:26:13 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'README' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'README'\"
else
echo shar: Extracting \"'README'\" \(918 characters\)
sed "s/^X//" >'README' <<'END_OF_FILE'
XThis directory contains the source files for T's boot loader for Apollo
Xsystems.  Building the boot loader should be straightforward using the
Xmakefile. 
X
XNotes:
X    - In an early release of SR10 (Domain OS), the boot loader didn't compile
X      correctly because of a bug in the Pascal compiler.  Using the -opt 0
X      flag corrected the problem.  At this time (11Jul90) I do not know
X      whether this bug has been corrected, so the makefile uses -opt 0.
X    - The boot loader depends on the Domain OS proprietary include file
X      /os/ins/fault.ins.asm which defines where various registers are stored
X      in a fault frame.  A version of that file is included here for SR10.2,
X      supplied by Nat Mishkin of Apollo.  If Apollo changes the fault frame
X      format in a future OS release, we will need to get a new copy of the
X      file. 
X
XQuestions or problems to mohr@cs.yale.edu or t3-bugs@cs.yale.edu
X
X
X
END_OF_FILE
if test 918 -ne `wc -c <'README'`; then
    echo shar: \"'README'\" unpacked with wrong size!
fi
# end of 'README'
fi
if test -f 'boot.shar' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'boot.shar'\"
else
echo shar: Extracting \"'boot.shar'\" \(0 characters\)
sed "s/^X//" >'boot.shar' <<'END_OF_FILE'
END_OF_FILE
if test 0 -ne `wc -c <'boot.shar'`; then
    echo shar: \"'boot.shar'\" unpacked with wrong size!
fi
# end of 'boot.shar'
fi
if test -f 'boot_load.pas' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'boot_load.pas'\"
else
echo shar: Extracting \"'boot_load.pas'\" \(20706 characters\)
sed "s/^X//" >'boot_load.pas' <<'END_OF_FILE'
XPROGRAM boot_load;
X
X%NOLIST;
X
X%INCLUDE '/us/ins/ubase.ins.pas';
X
X%INCLUDE '/sys/ins/time.ins.pas';
X%INCLUDE '/sys/ins/cal.ins.pas';
X%INCLUDE '/sys/ins/vfmt.ins.pas';
X%INCLUDE '/sys/ins/error.ins.pas';
X%INCLUDE '/sys/ins/pgm.ins.pas';
X%INCLUDE '/sys/ins/name.ins.pas';
X
X{ FROM /sys/ins/base.ins.pas - ??? }
X
XCONST
X    ios_$max = 127;                     { [0..ios_$max] valid range for ios_$id_t when in use }
X
XTYPE
X    ios_$id_t = 0..ios_$max;            { open stream identifier }
X
X    ios_$seek_key_t = RECORD
X        rec_adr:  integer32;
X        byte_adr: integer32;
X        END;
X
X{ FROM /sys/ins/base.ins.pas - ??? }
X
X%INCLUDE '/sys/ins/ios.ins.pas';
X
X%INCLUDE '/us/ins/as.ins.pas';          { for as_$get_info }
X%INCLUDE '/us/ins/loader.ins.pas';      { for pm_$load, kg_$lookup }
X%INCLUDE '/us/ins/cl.ins.pas';          { for cl_$... }
X%INCLUDE '/us/ins/lib.ins.pas';         { for lib_$data_move }
X%INCLUDE '/us/ins/mst.ins.pas';         { for mst_$get_uid }
X%INCLUDE '/us/ins/file.ins.pas';        { for file_$create, file_$delete_when_unlocked }
X%INCLUDE '/us/ins/ms.ins.pas';          { for ms_$mapl_uid }
X
X%LIST;
X
X{*
XPROCEDURE ms_$mk_temporary(
X  in va: univ_ptr;
X  out status: status_$t
X  ); extern;
X*}
X
XPROCEDURE relocate
X    ( count: linteger
X    ; relocs: univ_ptr
X    ; base: univ_ptr
X    ; at: univ_ptr
X    );
X    VAL_PARAM; EXTERN;
X
X    { from /us/com/las/las.pas  }
X
XCONST
X    machine_types = 8;
X
XVAR
X    max_va: ARRAY [ -1..machine_types ] OF linteger
X       := [ 16#03D00000
X           , 16#00D00000
X           , 16#00D00000
X           , 16#00D00000
X           , 16#00D00000
X           , 16#0F800000
X           , 16#00D00000
X           , 16#78000000
X           , 0
X           , 16#03B00000
X         ];
X
XCONST
X    hdr_size = 32;      { Bad news:  assumption about the amount of crud at
X                          the top of UASC files }
X
XVAR
X    debug: boolean;
X    verbose: boolean;
X    use_streams: boolean;
X    timing: boolean;
X    times: ARRAY[1..20] OF time_$clock_t;
X    time_nest: pinteger := 0;
X
X
XPROCEDURE start_timing;
X
XBEGIN
X    IF NOT timing THEN
X        RETURN;
X
X    time_nest := time_nest + 1;
X    time_$clock( times[ time_nest ] );
X    END;
X
X
XPROCEDURE stop_timing
X    ( IN  s: string
X    );
X
XVAR
X    t: time_$clock_t;
X    tf: double;                                   
X    db: boolean;
X
XBEGIN   
X    IF NOT timing THEN
X        RETURN;
X
X    time_$clock( t );
X    db := cal_$sub_clock( t, times[ time_nest ] ) ;
X    cal_$float_clock( t, tf );
X    vfmt_$write2( s, 0, 0 );
X    vfmt_$write2( ' = %f%.', tf, 0 );
X
X    time_nest := time_nest - 1;
X
X    END;
X
X
XPROCEDURE die
X    ( IN str: string
X    ; IN st: UNIV status_$t
X    );
X
XBEGIN
X    vfmt_$write2( 'error loading t: %$', 0, 0 );
X    vfmt_$write2( str, 0, 0 );
X    vfmt_$write2( ' - %.', 0, 0 );
X    error_$print( st );
X    pgm_$exit();
X    END;
X
X
XFUNCTION crtemp
X    ( IN len: linteger
X    ; OUT st: status_$t
X    )
X    : univ_ptr;
X
XVAR
X    maplen: linteger;
X    p: univ_ptr;
X    xst: status_$t;
X    uid: uid_$t;
X
XBEGIN
X    file_$create( uid_$nil, uid, st );
X
X    p := ms_$mapl_uid( uid, 0, len, ms_$nr_xor_1w, ms_$wrx, true, maplen, st );
X
X    file_$delete_when_unlocked( uid, xst );
X
X    crtemp := p;   
X    END;
X
X{
X    T object file format:
X     header
X       entry (relative offset in data section)
X       bytes of text relocation (each item is a four byte address to be relocated)
X       bytes of data relocation                      "
X       bytes of foreign relocation (each item is a four byte address followed by
X                                a two byte size followed by characters)
X       size of text section (bytes)
X       size of data section (bytes)
X     text section
X     data section
X     text relocations
X     data relocations
X     xeno relocations
X}
X
XPROCEDURE load_t_object_file
X    ( IN t_name:  string
X    ; IN t_namel: integer16
X    ; OUT start_address: univ_ptr
X    ; OUT data_address: univ_ptr
X    );
X
X    TYPE
X        memarray_t =
X            ARRAY [ 0 .. 1000000 ] OF linteger;
X        p_memarray_t  =
X            ^ memarray_t;
X
X        xeno_item_t =
X            RECORD
X            addr:  linteger;
X            name:  PACKED ARRAY [ 1..32 ] OF char;  { blank padded, too! }
X
X            END;
X
X        p_xeno_item_t =
X            ^ xeno_item_t;
X
X        header_t =
X            RECORD
X            entry:           linteger;
X            text_reloc_size: linteger;
X            data_reloc_size: linteger;
X            foreign_size:    linteger;
X            text_size:       linteger;
X            data_size:       linteger;
X            END;
X
X    VAR
X        header:    header_t;
X        header_p: ^header_t;
X
X        d_at     : ^string;
X
X        st:    status_$t;
X
X        d_p,
X        t_p,
X        t_at,
X        r_at     : univ_ptr;
X
X        len,
X        t_maplen,
X        r_maplen : linteger;
X
X        t_relocs,
X        d_relocs,
X        data_p      : p_memarray_t;
X
X        xeno_p      : p_xeno_item_t;
X        xeno_limit  : linteger;
X
X        t_item_count,
X        d_item_count: linteger;
X
X        i,
X        ds_index    : linteger;
X
X        relocation_size,
X        relocation_offset: linteger;
X
X        global_address: linteger;
X
X        id          : ios_$id_t;
X
XBEGIN
X    start_timing();
X
X        { open object file }
X
X        { use_streams vs. not:  The logically correct way to copy the
X          impure data from the object file is via Streams.  
X
X          Not only that, at sr9.5 it turns out to be better to slog the
X          data in via Streams, rather than by mapping the whole file
X          and doing one mongo data copy.  This is because the latter
X          will result in more good pages being tossed from memory.  Streams
X          does a piecewise copy -- mapping and copying piece of the file.
X          This will result in a minimal number of good pages pages being
X          tossed.
X
X          Unfortunately, due to a misfeature in Streams, the fact that
X          a "seek" occurs on the stream (to position to the impure data)
X          causes Streams to think that the file is being accessed
X          non-sequentially.  As a result, Streams backs off some memory
X          management optimization (specifically "touch ahead") to something
X          less than the max value.
X
X          In the end, I couldn't decide whether the Streams or non-Streams
X          approach was better, so I left in both mechanisms.  If/when
X          the Streams misfeature is fixed, "use_streams" mode should
X          be the only one, and the mapping code should be flushed from
X          here. }
X
X    IF use_streams THEN BEGIN
X        id := ios_$open( t_name, t_namel, [], st );
X        IF st.all <> 0 THEN
X            die( 'opening object file%$', st );
X
X        len := ios_$get( id, [ios_$no_rec_bndry_opt], header, sizeof( header ), st );
X        END
X    ELSE BEGIN
X        header_p := ms_$mapl( t_name, t_namel, hdr_size + 0, sizeof( header ), ms_$nr_xor_1w, ms_$rx
X                            , false, len, st );
X        IF st.all <> 0 THEN
X            die( 'opening object file%$', st );
X
X            { Copy header... }
X
X        ms_$advice( header_p, sizeof( header ), ms_$random, [], 0, st );
X        header := header_p^;
X        END;
X
X    IF verbose THEN
X        WITH header DO BEGIN
X            vfmt_$write5( ';Text = %d, data = %d, text reloc = %d, data reloc = %d%.',
X                          text_size, data_size, text_reloc_size, data_reloc_size, 0 );
X            vfmt_$write2( ';Foreign_reloc_size = %d, entry = %LH%.',
X                          foreign_size, entry );
X        END;
X
X        { create map data section file }
X
X    d_at := crtemp( header.data_size, st );
X    IF st.all <> 0 THEN
X        die( 'creating/mapping data section temporary file%$', st );
X
X    ms_$advice( d_at, header.data_size, ms_$sequential, [], 0, st );
X
X        { seek to data section }
X
X    IF use_streams THEN BEGIN
X        ios_$seek( id, ios_$absolute, ios_$byte_seek, sizeof( header ) + header.text_size, st );
X
X        start_timing();
X        len := ios_$get( id, [ios_$no_rec_bndry_opt], d_at^, header.data_size, st );
X        stop_timing( ';Time to copy data section%$' );
X    
X        ios_$close( id, st );
X
X            { map text section of object file }
X    
X        t_at := ms_$mapl( t_name, t_namel, hdr_size + sizeof( header ), header.text_size, ms_$nr_xor_1w, ms_$rx
X                            , false, len, st );    
X        END
X    ELSE BEGIN
X        d_p := ms_$remap( header_p, hdr_size + sizeof( header ) + header.text_size, header.data_size, len, st );
X    
X        IF st.all <> 0 THEN
X            die( 'seeking for data section%$', st );
X    
X            { ... and copy data section into mapped temporary file }
X    
X        ms_$advice( d_p,  header.data_size, ms_$sequential, [], 0, st );
X    
X        start_timing();
X        lib_$data_move( d_p, d_at, header.data_size );
X        stop_timing( ';Time to copy data section%$' );
X
X            { map text section of object file }
X
X        t_at := ms_$remap( d_p, hdr_size + sizeof( header ), header.text_size, t_maplen, st );
X
X        IF verbose OR debug THEN
X            vfmt_$write2( ';Text section_at: %LH%.', t_at, 0 );
X
X        END;
X    
X    IF st.all <> 0 THEN
X        die( 'mapping procedure section%$', st );
X
X    IF debug THEN
X    BEGIN
X            { read in text section }
X
X        t_p := t_at;
X
X        t_at := crtemp( header.text_size, st );
X        IF st.all <> 0 THEN
X            die( 'mapping writable text section temporary file%$', st );
X
X        lib_$data_move( t_p, t_at, header.text_size );
X
X        ms_$unmap( t_p, header.text_size, st );
X        END;
X
X        { mark the pure text access pattern as being "random" }
X
X    ms_$advice( t_at, header.text_size, ms_$random, [], 0, st );
X
X        { number of bytes of relocation information }
X
X    relocation_size := header.text_reloc_size
X                       + header.data_reloc_size
X                       + header.foreign_size;
X
X        { offset from beginning of file to relocation information }
X
X    relocation_offset := sizeof( header ) + header.text_size + header.data_size;
X
X        { map relocation information }
X
X    r_at := ms_$mapl( t_name, t_namel, hdr_size + relocation_offset, relocation_size
X                    , ms_$nr_xor_1w, ms_$r, false, r_maplen, st );
X
X    IF verbose OR debug THEN
X        vfmt_$write2( 'relocation_size = %d%.',
X                      relocation_size, 0 );
X
X    IF st.all <> 0 THEN
X        die( 'mapping relocation information%$', st );
X
X        { t_items are offsets in the data section where the address of
X          the text section must be added; analogously for d_items }
X
X    t_item_count := header.text_reloc_size DIV 4;
X    d_item_count := header.data_reloc_size DIV 4;
X
X    t_relocs := p_memarray_t( r_at );
X    d_relocs := p_memarray_t( linteger( r_at ) + header.text_reloc_size );
X    data_p   := p_memarray_t( d_at ); { pointer to beginning of data section }
X        
X            { for each addr in t_reloc (d+addr) <- (d+addr) + t }
X    
X    start_timing();
X    relocate( t_item_count, t_relocs, data_p, t_at );
X    stop_timing( ';Text relocation time%$' );
X    
X            { for each addr in d_reloc (d+addr) <- (d+addr) + d }
X    
X    start_timing();
X    relocate( d_item_count, d_relocs, data_p, d_at );
X    stop_timing( ';Data relocation time%$' );
X        
X        { for each addr, name in f_reloc (d+addr) <- lookup(name) }
X    
X    IF verbose OR debug THEN
X        vfmt_$write2( 'relocation_size = %d%.',
X                      relocation_size, 0 );
X
X    xeno_p := p_xeno_item_t( linteger( d_relocs ) + header.data_reloc_size );
X    xeno_limit := linteger( r_at ) + relocation_size;
X
X    IF verbose OR debug THEN
X        vfmt_$write2( ';Foreign relocs at: (%LH, %LH)%.', xeno_p, xeno_limit );
X    IF verbose OR debug THEN
X        vfmt_$write2( ';r_at = %LH, relocation_size = %d%.',
X                      r_at, relocation_size );
X
X    start_timing();
X
X    WHILE linteger( xeno_p ) < xeno_limit DO BEGIN
X
X        ds_index := xeno_p^.addr DIV 4;
X        global_address := linteger( kg_$lookup( xeno_p^.name ) );
X        data_p^[ds_index] := global_address;
X
X        IF global_address = 0 THEN
X            vfmt_$write2( ';Warning: global %A not found%.', xeno_p^.name, 32 );
X
X        xeno_p := p_xeno_item_t( linteger( xeno_p ) + sizeof( xeno_item_t ) );
X        END;
X
X    stop_timing( ';Foreign relocation time%$' );
X
X    start_address := univ_ptr( header.entry + linteger( d_at ) );
X    data_address := d_at;
X
X    IF verbose OR debug THEN
X        vfmt_$write2( ';Data section_at: %LH%.', d_at, 0 );
X
X    ms_$advice( d_at, header.data_size, ms_$random, [], 0, st );
X
X    stop_timing( ';Load time%$' );
X    END;
X
X    { ------------------------------------------------------- Heap allocation }
X
X
X
X    { the following use of unreleased stuff is only to determine the biggest
X  hole in the address space, so we have the freedom to allocate heaps
X  as big as that.  I think this stuff is all localized to BIGGEST_HOLE and
X  MACHINE_VAS }
X
X
XFUNCTION machine_vas
X   : linteger;
X
X    TYPE
X        { from /us/ins/md_if.ins.pas }
X
X        aux_info_t =
X            SET OF
X                ( crash_eps                  { bit 0 => log_error, crash eps exist }
X
X                , m68020_board
X                );              { bit 1 => M68020 }
X
X
X            { from /us/ins/asknode.ins.pas }
X
X        asknode_$reply_t =
X            RECORD
X            version: pinteger;
X            kind   : integer16;
X            status : status_$t;
X            CASE integer OF
X            0: (
X                config_valid_cnt: integer;
X                config_mach_id:   integer;
X                config_aux_info:  aux_info_t;
X                );
X            1: (
X                foo: ARRAY [ 1..25 ] OF integer;
X                );
X            END;
X
X    PROCEDURE asknode_$info
X        ( IN kind: integer16
X        ; IN x
X        , y: linteger
X        ; OUT reply: asknode_$reply_t
X        ; OUT status: status_$t
X        );
X        EXTERN;
X
X    VAR
X        status: status_$t;
X        reply: asknode_$reply_t;
X
X            { from /sources/us/com/las/las.pas  }
X
X        my_machine: integer;
X
XBEGIN
X    asknode_$info( 39, 0, 0, reply, status );
X
X    IF status.all <> status_$ok THEN
X        my_machine := 1
X    ELSE
X        my_machine := reply.config_mach_id;
X
X    IF my_machine > machine_types THEN
X    BEGIN
X        vfmt_$write2( '%;Unknown machine type: %WD%.', my_machine, 0 );
X        my_machine := 1;
X        END;
X
X    IF my_machine IN [ 2, 3, 5 ] AND THEN
X       m68020_board IN reply.config_aux_info
X    THEN
X        my_machine := -1;
X
X    machine_vas := max_va[my_machine];
X
X    END;
X
X    { scan address space to find biggest hole }
X
XFUNCTION biggest_hole
X   : integer;
X
X    VAR
X        muid: uid_$t;
X        va,
X        start: linteger;
X        status: status_$t;
X        total,
X        max: integer;
X        max_va: linteger;
X
XBEGIN
X    max_va := machine_vas();
X    va := 0;
X    max := 0;
X    total := 0;
X
X    WHILE va < max_va DO
X    BEGIN
X        mst_$get_uid( va, muid, start, status );
X
X        IF status.all <> 0 THEN
X            total := total + 1 
X        ELSE
X        BEGIN
X            IF total > max THEN
X                max := total;
X            total := 0;
X            END;
X
X        va := va + seg_size;
X        END;
X
X    IF total > max THEN
X        max := total;
X
X    biggest_hole := max;
X    END;
X
X
XPROCEDURE compute_heap_size
X    ( heap_wanted
X    , leave_wanted: linteger
X    ; heap_wanted_given
X    , leave_wanted_given: boolean
X    ; OUT heap_size: linteger
X    );
X
X    CONST
X        min_heap_size     = 16#80000;  { 512K }
X        default_heap_size = 16#400000; { 4Mb }
X        minimum_leave     = 16#80000;  { 512K - to leave free after heap alloc }
X
X    VAR
X        max:      linteger;
X        status:   status_$t;
X        max_heap_size:  linteger; { choosing heap size }
X        space_to_leave: linteger;
X        i: integer;               { iteration }
X
X
XBEGIN
X
X    IF leave_wanted_given THEN
X        space_to_leave := leave_wanted
X    ELSE
X        space_to_leave := minimum_leave + leave_wanted;
X
X    max := biggest_hole();      { maximum possible heap size }
X
X    max_heap_size := ((lshft( max, 15 ) - space_to_leave) DIV 2) & 16#FFFF8000;  { 32k align }
X
X    IF (max_heap_size < min_heap_size) THEN
X    BEGIN
X        vfmt_$write2( 'Not enough space to allocate minimum heaps%.', 0 , 0 );
X        pgm_$exit;
X        END;
X
X        { pick a heap size }
X
X    IF (NOT heap_wanted_given) THEN
X        IF default_heap_size < max_heap_size THEN
X            heap_size := default_heap_size
X        ELSE
X            heap_size := max_heap_size
X    ELSE
X    BEGIN
X        IF heap_wanted = 0 THEN
X            heap_wanted := max_heap_size;
X
X        heap_wanted := (heap_wanted + 16#7FFF) & 16#FFFF8000;  { 32k align }
X
X        IF (heap_wanted > max_heap_size) THEN
X        BEGIN
X            vfmt_$write2( ';Heap allocated smaller than requested.%.', 0, 0 );
X            heap_size := max_heap_size;
X            END
X        ELSE IF (heap_wanted < min_heap_size) THEN
X        BEGIN
X            vfmt_$write2( ';Heap allocated larger than requested.%.', 0, 0 );
X            heap_size := min_heap_size;
X            END
X        ELSE
X            heap_size := heap_wanted;
X        END;
X
X        { report size chosen }
X
X    IF heap_wanted_given OR leave_wanted_given THEN
X        vfmt_$write2( ';%LD bytes per heap, %LD bytes reserved%.'
X                    , heap_size, space_to_leave );
X
X    END;
X
X
X    { --------------------------------------------------------------------------- }
X
X
X    { assembly code to do the jump to a random address }
X
XPROCEDURE jump_to_t
X    ( IN    start_address:         univ_ptr
X    ; data_address:          univ_ptr
X    ; sfh_xenoid_dummy_slot: linteger
X    ; stack_low:             univ_ptr
X    ; guard1
X    , guard2:        univ_ptr
X    ; p1:                    name_$pname_t
X    ; lp1:                   linteger
X    ; at1:                   univ_ptr
X    ; p2:                    name_$pname_t
X    ; lp2:                   linteger
X    ; at2:                   univ_ptr
X    ; heap_size:             linteger
X    ; debug:                 boolean
X    );
X    VAL_PARAM; EXTERN;
X
XPROCEDURE start_t;
X
X    CONST
X        float_file = '~/tsystem/float.bin';
X
X    VAR
X            { command line processing }
X
X        t_name: string;
X        t_namel: integer16;
X
X        cnt: integer;
X        heap_wanted, leave_wanted: linteger;
X        heap_p,
X        leave_p: boolean;
X
X            { returned from loading t image }
X
X        start_address: univ_ptr;
X        data_address: univ_ptr;
X
X            { heap allocation }
X
X        heap_size: linteger;
X        at1, at2: univ_ptr;
X
X        st: status_$t;
X
X            { as inquiry }
X
X        dummy: integer;
X        as: as_$info_rec_t;
X
X            { for pm_$load }
X
X        info: pm_$load_info;
X
XBEGIN
X    cl_$init( [], 'bl', 2 );
X
X    debug       := cl_$get_flag( '-d[ebug]', cnt );
X    verbose     := cl_$get_flag( '-v[erbose]', cnt );
X    timing      := cl_$get_flag( '-time[]', cnt );
X    use_streams := cl_$get_flag( '-streams[]', cnt );
X
X    heap_wanted := 0;
X    IF cl_$get_flag( '-h[eap]', cnt ) THEN
X    BEGIN
X        heap_p := true;
X        IF (cnt = 1) AND THEN (NOT cl_$get_num( heap_wanted )) THEN
X            heap_wanted := 0;
X        END
X    ELSE
X        heap_p := false;
X
X    leave_wanted := 0;
X    IF cl_$get_flag( '-l[eave]', cnt ) THEN
X    BEGIN
X        leave_p := true;
X        IF (cnt = 1) AND THEN (NOT cl_$get_num( leave_wanted )) THEN
X            leave_wanted := 0;
X        END
X    ELSE
X        leave_p := false;
X
X    IF NOT cl_$get_arg( cl_$first, t_name, t_namel, sizeof( string ) ) THEN
X        vfmt_$write2( 'Expecting T object file name%.', 0, 0 );
X
X    pm_$load( float_file, sizeof( float_file ), [pm_$install], 0, info, st );
X    IF st.all <> 0 THEN
X        die( 'installing floating point%$', st );
X
X           { relocate t object file }
X
X    load_t_object_file( t_name, t_namel, start_address, data_address );
X
X           { allocate heaps }
X
X    compute_heap_size( heap_wanted, leave_wanted, heap_p, leave_p, heap_size );
X
X    at1 := crtemp( heap_size, st );
X    IF st.all <> 0 THEN
X        die( 'creating/mapping first heap%$', st );
X
X    at2 := crtemp( heap_size, st );
X    IF st.all <> 0 THEN
X        die( 'creating/mapping first heap%$', st );
X
X    as_$get_info( as, sizeof( as ), dummy {actual size} );
X
X    vfmt_$write2( 'Jumping to t...%', 0, 0 );
X
X    jump_to_t( start_address
X             , data_address
X             , 0
X             , as.stack_low, as.guard1, as.guard2
X             , '', 0, at1                               { ++++  flush it}
X             , '', 0, at2                               { ++++  flush it}
X             , heap_size
X             , debug );
X
X    END;
X
XBEGIN
X    start_t();
X    END.
END_OF_FILE
if test 20706 -ne `wc -c <'boot_load.pas'`; then
    echo shar: \"'boot_load.pas'\" unpacked with wrong size!
fi
# end of 'boot_load.pas'
fi
if test -f 'data_move.asm' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'data_move.asm'\"
else
echo shar: Extracting \"'data_move.asm'\" \(1868 characters\)
sed "s/^X//" >'data_move.asm' <<'END_OF_FILE'
X*  PROCEDURE data_move(in from, dest : byte_ptr_t; lgth : linteger);
X*
X            module  data_move
X*
Xsource      equ     4(SP)               source ptr
Xdest        equ     8(SP)               destination ptr
Xlen         equ     12(SP)              length (32 bits)
X*
X            entry.p data_move
Xdata_move ds.w 0
X*
X            move.l  len,D0
X            beq.s   retrn
X            move.l  source,A1
X            move.l  dest,A2
X            move.l  D0,D1
X            sub.l   #4,D0
X            lsr.l   #5,D0
Xnextw       move.l  (A1)+,(A2)+
X            move.l  (A1)+,(A2)+
X            move.l  (A1)+,(A2)+
X            move.l  (A1)+,(A2)+
X            move.l  (A1)+,(A2)+
X            move.l  (A1)+,(A2)+
X            move.l  (A1)+,(A2)+
X            move.l  (A1)+,(A2)+
X            dbra D0,nextw
Xretrn       rts
X
X*
X* PROCEDURE relocate( count: linteger; relocs: univ_ptr; base: univ_ptr; at: univ_ptr );
X*
X* BEGIN
X*    i := 0;
X*    WHILE i < count DO BEGIN
X*        ds_index := relocs^[i] DIV 4;
X*        data_p^[ds_index] := data_p^[ds_index] + integer32( at );
X*        i := i + 1;
X*        END;
X* END;
X* 
X
Xcount       equ     4(SP)               how many?
Xrelocs      equ     8(SP)               array of longwords to change
Xbase        equ     12(SP)              abs pointer to add
Xat          equ     16(SP)              (memory)        
X
X*
X            entry.p relocate
Xrelocate ds.w 0
X*
X        move.l  count,d0
X        subq.l  #1,d0
X        move.l  at,d1  
X        move.l  relocs,a0
X        move.l  base,a1 
X*                               * Index is d2
X
X        bra.s   top
X
Xttop
X        swap    d0              * tricky!
X
Xtop
X        move.l  (a0)+,d2        * d2 is index
X        add.l   d1,0(a1,d2.l)   * add at to index off of base
X*
X        dbra    d0,top
X        swap    d0              * check high word (stupid machine)
X        dbra    d0,ttop
X
X        rts
X
X
END_OF_FILE
if test 1868 -ne `wc -c <'data_move.asm'`; then
    echo shar: \"'data_move.asm'\" unpacked with wrong size!
fi
# end of 'data_move.asm'
fi
if test -f 'fault.ins.asm' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'fault.ins.asm'\"
else
echo shar: Extracting \"'fault.ins.asm'\" \(9794 characters\)
sed "s/^X//" >'fault.ins.asm' <<'END_OF_FILE'
X*   FAULT.INS.ASM, /us/ins, jrw, 12/16/89
X*   exception handler data & table definitions
X*
X%IFDEF us_fault_ins_asm %THEN
X    %EXIT
X%ELSE
X    %VAR us_fault_ins_asm
X%ENDIF
X
X***************************************************************************
X*                                                                         *
X*  WARNING: Aegis depends on this include file; modify with trepidation.  *
X*                                                                         *
X***************************************************************************
X
X* Changes
X*   12/16/89 gordon added fault_$bad_bus_err_frame, fault_$cache_push_bus_err
X*   09/07/89 gms    updated hopelessly out-of-date AT version.
X*   11/30/88 gms    added fault_$fp_data_check.
X*   06/29/88 gms    added fault_$unaligned_inst.
X*   03/01/88 gms    added 43-45.
X*   10/30/87 mills  added 42 (New for A88K)
X*   10/29/87 joew   out of synch with /us/sys/ins/fault.ins.pas.
X*   10/06/87 gms    merged at branch into mainline; added at version of fault_$diag_t.
X*   10/05/87 tonyd  s/m68k/isp_$m68k/.
X*   09/16/87 gms    merged mainline into /at version.
X*   03/11/87 dcm    Add infor to fault frame for new signals.
X*   01/28/86 sekhar Banshee fpx changes: added df_fpx_state_ptr to diagnostic frame template
X*                   got rid of df_fsave_done bit.
X*   11/13/86 sekhar Fpa on banshee: changed bit defn df_fpa_exception to df_fsave_done;
X*                   cuz fsave done on more than just fpa exceptions; added df_m68020;
X*   10/22/86 sjm  Added fault_$be_on_be for double VME bus error.
X*   10/17/86 sekhar Banshee - added fault_$fp_unknown_vec for unknown fpa vector exceptions
X*   08/20/86 sekhar Banshee - added fault_$fp_parity for fpa parity errors
X*   08/05/86 sekhar Banshee - added bit defn df_fpa_exception in df_misc word
X*                             for fpa exceptions. 
X*   07/18/86 knw  added pwr_fail for banshee
X*   03/15/86 gms  added fault_$cold_start_bus_error; removed fault_table_tm.
X*   12/02/85 gms  added fault_$cpub_bus_error, fault_$spurious_interrupt.
X*   12/28/84 gms  added codes 1C-2F.
X*   07/03/82 jrw  added async flag definition for df_misc.
X*   03/19/82 jrw  added codes 17-1B
X*   02/22/81 pjl  added fault_$quit constant
X*
X*
X*    --------------------------------------------------------------------------
X*   |   THE FOLLOWING PROGRAMS ARE THE SOLE PROPERTY OF APOLLO COMPUTER INC.   |
X*   |         AND CONTAIN ITS PROPRIETARY AND CONFIDENTIAL INFORMATION.        |
X*    --------------------------------------------------------------------------
X*
X*
X*
Xfault_$address_error       equ  $00120001
Xfault_$illegal_inst        equ  $00120002
Xfault_$zero_divide         equ  $00120003
Xfault_$chk_inst            equ  $00120004
Xfault_$trapv_inst          equ  $00120005
Xfault_$priv_violation      equ  $00120006
Xfault_$illegal_svc_code    equ  $00120007
Xfault_$illegal_svc_name    equ  $00120008
Xfault_$undefined_trap      equ  $00120009
Xfault_$unimplemented_inst  equ  $0012000A
Xfault_$prot_violation      equ  $0012000B
Xfault_$bus_timeout         equ  $0012000C
Xfault_$illegal_usp         equ  $0012000D
Xfault_$eccc                equ  $0012000E
Xfault_$eccu                equ  $0012000F
Xfault_$quit                equ  $00120010
Xfault_$access_violation    equ  $00120011
Xfault_$not_valid           equ  $00120012
Xfault_$nullproc_onb        equ  $80120013
Xfault_$display_quit        equ  $00120014
Xfault_$single_step         equ  $00120015
Xfault_$invalid_user_fault  equ  $00120016
Xfault_$pbu_user_int_fault  equ  $00120017
Xfault_$stop                equ  $00120018
Xfault_$blast               equ  $00120019
Xfault_$cache_parity        equ  $0012001A
Xfault_$wcs_parity          equ  $0012001B
Xfault_$not_implemented     equ  $0012001C
Xfault_$invalid_stack       equ  $0012001D
Xfault_$parity              equ  $0012001E
Xfault_$interrupt           equ  $0012001F
Xfault_$while_lock_set      equ  $00120020
Xfault_$spurious_parity     equ  $00120021
Xfault_$fp_inexact          equ  $00120022
Xfault_$fp_div_zero         equ  $00120023
Xfault_$fp_undflo           equ  $00120024
Xfault_$fp_op_err           equ  $00120025
Xfault_$fp_ovrflo           equ  $00120026
Xfault_$suspend_proc        equ  $00120027
Xfault_$suspend_proc_kbd    equ  $00120028 
Xfault_$suspend_proc_br     equ  $00120029
Xfault_$suspend_proc_bw     equ  $0012002A
Xfault_$continue_proc       equ  $0012002B 
Xfault_$fault_lost          equ  $0012002C
Xfault_$illegal_coproc      equ  $0012002D
Xfault_$fp_bsun             equ  $0012002E
Xfault_$fp_sig_nan          equ  $0012002F
Xfault_$parity_bad_thread   equ  $00120030
Xfault_$illegal_page_fault  equ  $00120031
Xfault_$cpub_bus_error      equ  $00120032
Xfault_$spurious_interrupt  equ  $00120033
Xfault_$cold_start_bus_error equ $00120034
Xfault_$cleanup_set         equ  $00120035
Xfault_$cleanup_rls_out_order equ $00120036
Xfault_$ac_power_fail       equ  $00120037
Xfault_$fp_parity           equ  $00120038
Xfault_$fp_unknown_vec      equ  $00120039
Xfault_$be_on_be            equ  $0012003A
Xfault_$io_chan_chk         equ  $0012003b
Xfault_$breakpoint          equ  $0012003C 
Xfault_$translate_error     equ  $0012003D 
Xfault_$illegal_lock        equ  $0012003E 
Xfault_$lock_timeout        equ  $0012003F 
Xfault_$unknown_status      equ  $00120040 
Xfault_$fp_exception        equ  $00120041 
Xfault_$fp_fpu_internal_error equ $00120042 
Xfault_$pause               equ  $00120043
Xfault_$halt                equ  $00120044
Xfault_$trap_on_trap        equ  $00120045
Xfault_$unaligned_inst      equ  $00120046
Xfault_$fp_data_check       equ  $00120047
X*                          equ  $00120048
Xfault_$bad_bus_err_frame   equ  $00120049
Xfault_$cache_push_bus_err  equ  $0012004A
X
X
X
X
Xdf_pattern_val equ $DFDF
X
X%IF ISP_$M68K %THEN
X
X*
X*   Diagnostic frame template:
X*
X           defs    0(a6)
Xdf_start   equ     *
Xdf_pattern ds.w    1                   pattern used to find diag frame
Xdf_status  ds.l    1                   standard format status code
Xdf_regs    equ     *                   register save area
Xdf_d0      ds.l    1
Xdf_d1      ds.l    1
Xdf_d2      ds.l    1
Xdf_d3      ds.l    1
Xdf_d4      ds.l    1
Xdf_d5      ds.l    1
Xdf_d6      ds.l    1
Xdf_d7      ds.l    1
Xdf_a0      ds.l    1
Xdf_a1      ds.l    1
Xdf_a2      ds.l    1
Xdf_a3      ds.l    1
Xdf_a4      ds.l    1
Xdf_a5      ds.l    1
Xdf_a6      ds.l    1
Xdf_a7      ds.l    1
Xdf_fcode   ds.w    1                   function code, etc (from addr/bus err)
Xdf_addr    ds.l    1                   access address
Xdf_ireg    ds.w    1                   instruction register (from addr error)
Xdf_misc    ds.w    1                   miscellaneous flags, see below
Xdf_sup_ecb ds.l    1                   pointer to supervisor routine ecb
Xdf_sup_sr  ds.w    1                   supervisor status register at fault time
Xdf_sup_pc  ds.l    1                   supervisor return pc
Xdf_sr      ds.w    1                   user status register at fault time
Xdf_fpx_state_ptr ds.l 1                pointer to fpx state saved on user stack.
Xdf_signo   ds.w    1                   unix signal number
Xdf_hmask   ds.l    1                   mask of held unix signals
Xdf_pc      ds.l    1                   user return pc (must be last)
Xdf_end     equ     *
X           ends
X*
Xdf_size    equ     df_end-df_start
X
X%ELSE   { else isp_$a88k version }
X
X*
X*   Diagnostic frame template:
X*
X           defs    0
Xdf_start   equ     *
Xdf_prev    ds.l    1                   ; pointer to previous frame
Xdf_pattern ds.w    1                   ; pattern used to find diag frame
Xdf_version ds.w    1                   ; frame version
Xdf_ret     ds.l    1                   ; space for return reg
Xdf_link    ds.l    1                   ; pointer to previous fault frame (maintained by pfm)  
Xdf_args    ds.l    6                   ; space for args
Xdf_status  ds.l    1                   ; standard format status code
Xdf_pad     ds.l    1                   ; keep FP regs aligned
Xdf_regs    ds.l    24                  ; register save area
Xdf_fregs   ds.l    64                  ; fp regs at fault
Xdf_misc    ds.l    1                   ; miscellaneous flags, see below
Xdf_hmask   ds.l    1                   ; mask of held unix signals
X*                                      ; state:
Xdf_sr      ds.l    1                   ;    user status register at fault time
Xdf_pc      ds.l    1                   ;    user pc
Xdf_npc     ds.l    1                   ;    user next pc
Xdf_fp_stat ds.l    1                   ;    level 1 FPSTATUS register
Xdf_fp_cond ds.l    1                   ;    level 1 FPCONDITION register
X*                                      ; sup state:
Xdf_sup_sr      ds.l    1               ;    status register at fault time
Xdf_sup_pc      ds.l    1               ;    pc
Xdf_sup_npc     ds.l    1               ;    next pc
Xdf_sup_fp_stat ds.l    1               ;    level 1 FPSTATUS register
Xdf_sup_fp_cond ds.l    1               ;    level 1 FPCONDITION register
Xdf_fault_info   ds.l   1               ; ptr to info pertaining to fault
Xdf_ip_state_ptr ds.l   1               ; ip state ptr if non-nil
Xdf_fp_state_ptr ds.l   1               ; fp state ptr if non-nil
Xdf_end     equ     *
X           ends
X*
Xdf_size    equ     df_end-df_start
X
X%ENDIF
X*
X*---"Miscellaneous" word bit definitions:
X*
Xdf_rtnp_bit equ    7                   1 if return permitted
Xdf_in_sup_bit equ  6                   1 if fault occurred w/in supervisor
Xdf_regs_valid equ  5                   1 if all regs valid, 0 if only a6-a7
Xdf_ab_valid   equ  4                   1 if addr/bus info valid
Xdf_async      equ  3                   1 if async fault
Xdf_m68020     equ  2                   1 if 68020 processor
Xdf_fsave_done equ  1                   1 if fsave was done. must do a frestore on return
Xdf_onstack  equ    0                   1 if on signal stack
END_OF_FILE
if test 9794 -ne `wc -c <'fault.ins.asm'`; then
    echo shar: \"'fault.ins.asm'\" unpacked with wrong size!
fi
# end of 'fault.ins.asm'
fi
if test -f 'float.ins.pas' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'float.ins.pas'\"
else
echo shar: Extracting \"'float.ins.pas'\" \(1153 characters\)
sed "s/^X//" >'float.ins.pas' <<'END_OF_FILE'
X
XPROCEDURE gc_interrupt;
X    EXTERN;
X
XPROCEDURE t_$fladd(IN a,b: DOUBLE; OUT c: DOUBLE);
X    EXTERN;
X
XPROCEDURE t_$flsubtract(IN a,b: DOUBLE; OUT c: DOUBLE);
X    EXTERN;
X
XPROCEDURE t_$flmultiply(IN a,b: DOUBLE; OUT c: DOUBLE);
X    EXTERN;
X
XPROCEDURE t_$fldivide(IN a,b: DOUBLE; OUT c: DOUBLE);
X    EXTERN;
X
XPROCEDURE t_$sin(IN a: DOUBLE; OUT b: DOUBLE);
X    EXTERN;
X
XPROCEDURE t_$cos(IN a: DOUBLE; OUT b: DOUBLE);
X    EXTERN;
X
XPROCEDURE t_$tan(IN a: DOUBLE; OUT b: DOUBLE);
X    EXTERN;
X
XPROCEDURE t_$atan(IN a: DOUBLE; OUT b: DOUBLE);
X    EXTERN;
X
XPROCEDURE t_$exp(IN a: DOUBLE; OUT b: DOUBLE);
X    EXTERN;
X
XPROCEDURE t_$log(IN a: DOUBLE; OUT b: DOUBLE);
X    EXTERN;
X
XPROCEDURE t_$sqrt(IN a: DOUBLE; OUT b: DOUBLE);
X    EXTERN;
X
XFUNCTION t_$flless(IN a,b: DOUBLE): INTEGER;
X    EXTERN;
X
XFUNCTION t_$flequal(IN a,b: DOUBLE): INTEGER;
X    EXTERN;
X
XFUNCTION t_$flgreater(IN a,b: DOUBLE): INTEGER;
X    EXTERN;
X
XFUNCTION t_$fix (IN a: DOUBLE): INTEGER32;
X    EXTERN;
X
XPROCEDURE t_$float (IN a: INTEGER32; OUT c: DOUBLE);
X    EXTERN;
X
XPROCEDURE t_$atod (IN a: STRING; OUT c: DOUBLE);
X    EXTERN;
X
XPROCEDURE t_$dtoa (OUT a: STRING; IN c: DOUBLE);
X    EXTERN;
X
END_OF_FILE
if test 1153 -ne `wc -c <'float.ins.pas'`; then
    echo shar: \"'float.ins.pas'\" unpacked with wrong size!
fi
# end of 'float.ins.pas'
fi
if test -f 'float.pas' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'float.pas'\"
else
echo shar: Extracting \"'float.pas'\" \(2428 characters\)
sed "s/^X//" >'float.pas' <<'END_OF_FILE'
XMODULE assist;
X
X%nolist;
X
X%INCLUDE '/sys/ins/base.ins.pas';
X%INCLUDE '/sys/ins/vfmt.ins.pas';
X%INCLUDE '/sys/ins/pgm.ins.pas';
X%INCLUDE '/sys/ins/pfm.ins.pas';
X
XPROCEDURE disk_full;
XVAR
X    buff:   STRING;
XBEGIN
X    write( 'Disk is full.  Type Y when files are deleted. ' );        
X    read( buff );
X
X    IF ( buff[ 1 ] <> 'Y' ) AND ( buff[ 1 ] <> 'y' ) THEN
X        pgm_$exit();
XEND;
X
X
X
X
XPROCEDURE gc_interrupt;
XVAR
X    buff:   STRING;
XBEGIN
X    write( 'Interrupt during GC.  Exit (Y/N)? ' );        
X    read( buff );
X
X    IF ( buff[ 1 ] = 'Y' ) OR ( buff[ 1 ] = 'y' ) THEN
X        pgm_$exit()
X    ELSE
X        pfm_$enable();
XEND;
X
X
X{ **** Hack-o floating point }
X
XPROCEDURE t_$fladd(IN a,b: DOUBLE; OUT c: DOUBLE);
XBEGIN
X    c := a + b;
XEND;
X
XPROCEDURE t_$flsubtract(IN a,b: DOUBLE; OUT c: DOUBLE);
XBEGIN
X    c := a - b;
XEND;
X
XPROCEDURE t_$flmultiply(IN a,b: DOUBLE; OUT c: DOUBLE);
XBEGIN
X    c := a * b;
XEND;
X
XPROCEDURE t_$fldivide(IN a,b: DOUBLE; OUT c: DOUBLE);
XBEGIN
X    c := a / b;
XEND;
X
XPROCEDURE t_$sin(IN a: DOUBLE; OUT b: DOUBLE);
XBEGIN
X    b := sin(a);
XEND;
X
XPROCEDURE t_$cos(IN a: DOUBLE; OUT b: DOUBLE);
XBEGIN
X    b := cos(a);
XEND;
X
XPROCEDURE t_$tan(IN a: DOUBLE; OUT b: DOUBLE);
XBEGIN
X    b := sin(a)/cos(a);
XEND;
X
XPROCEDURE t_$atan(IN a: DOUBLE; OUT b: DOUBLE);
XBEGIN
X    b := arctan(a);
XEND;
X                    
XPROCEDURE t_$exp(IN a: DOUBLE; OUT b: DOUBLE);
XBEGIN
X    b := exp(a);
XEND;
X
XPROCEDURE t_$log(IN a: DOUBLE; OUT b: DOUBLE);
XBEGIN
X    b := ln(a);
XEND;
X
XPROCEDURE t_$sqrt(IN a: DOUBLE; OUT b: DOUBLE);
XBEGIN
X    b := sqrt(a);
XEND;
X
XFUNCTION t_$flless(IN a,b: DOUBLE): INTEGER;
XBEGIN
X    IF (a < b) THEN t_$flless := 1 ELSE t_$flless := 0;
XEND;
X
XFUNCTION t_$flequal(IN a,b: DOUBLE): INTEGER;
XBEGIN
X    IF (a = b) THEN t_$flequal := 1 ELSE t_$flequal := 0;
XEND;
X
XFUNCTION t_$flgreater(IN a,b: DOUBLE): INTEGER;
XBEGIN
X    IF (a > b) THEN t_$flgreater := 1 ELSE t_$flgreater := 0;
XEND;
X
XFUNCTION t_$fix (IN a: DOUBLE): INTEGER32;
XBEGIN
X    t_$fix := trunc(a);
XEND;
X
XPROCEDURE t_$float (IN a: INTEGER32; OUT c: DOUBLE);
XBEGIN
X    c := a;
XEND;
X
XPROCEDURE t_$atod (IN a: STRING; OUT c: DOUBLE);
XVAR
X    st: status_$t;
X    dummy: integer;
XBEGIN
X    dummy := vfmt_$decode2( '%50ELF%$', a, 50, dummy, st, c, 0);
XEND;
X
XPROCEDURE t_$dtoa (OUT a: STRING; IN c: DOUBLE);
XVAR
X    st: status_$t;                             
X    dummy: integer;
XBEGIN
X    vfmt_$encode2( '%23.15JLE%$', a, 23, dummy, c, 0 );
XEND;
X
X
X
END_OF_FILE
if test 2428 -ne `wc -c <'float.pas'`; then
    echo shar: \"'float.pas'\" unpacked with wrong size!
fi
# end of 'float.pas'
fi
if test -f 'image.doc' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'image.doc'\"
else
echo shar: Extracting \"'image.doc'\" \(1017 characters\)
sed "s/^X//" >'image.doc' <<'END_OF_FILE'
XDefinition of a T3 image -- 
X
Xheader -- 24 bytes
X  entry (relative offset in data section)             (four bytes)
X  bytes of text relocation (each item is a four byte address to be relocated)
X  bytes of data relocation                      "
X  bytes of foreign relocation (each item is a four byte address followed by
X                               a 32 byte space-padded string)
X  size of text section (bytes)
X  size of data section (bytes)
Xtext section
Xdata section
Xtext relocation items
Xdata relocation items
Xforeign relocation items
X
X
XThe T entry program (stub loader) must:
X
X1) allocate heaps
X2) map the text and copy data section
X3) relocate the data section
X4) lookup and relocate foreign routines
X5) jump to the entry passing arguments
X
X
X
XVARS
Xentry t_reloc d_reloc f_reloc text data
X
Xt = map(file,text_start)
Xd = map(file,data_start)
X
Xfor each addr in t_reloc (d+addr) <- (d+addr) + t
Xfor each addr in d_reloc (d+addr) <- (d+addr) + d
Xfor each addr,name in f_reloc (d+addr) <- lookup(name)
Xjump to d+entry
END_OF_FILE
if test 1017 -ne `wc -c <'image.doc'`; then
    echo shar: \"'image.doc'\" unpacked with wrong size!
fi
# end of 'image.doc'
fi
if test -f 'makefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'makefile'\"
else
echo shar: Extracting \"'makefile'\" \(294 characters\)
sed "s/^X//" >'makefile' <<'END_OF_FILE'
Xall: bl 
X
Xboot_load.bin: boot_load.pas
X        pas boot_load -opt 0
X
Xdata_move.bin: data_move.asm
X        asm data_move -nl
X
Xstart_t.bin: start_t.asm
X        asm start_t -nl
X
Xbl: boot_load.bin data_move.bin start_t.bin
X        bind -bin bl start_t.bin boot_load.bin data_move.bin -map >bl.map
X
END_OF_FILE
if test 294 -ne `wc -c <'makefile'`; then
    echo shar: \"'makefile'\" unpacked with wrong size!
fi
# end of 'makefile'
fi
if test -f 'start_t.asm' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'start_t.asm'\"
else
echo shar: Extracting \"'start_t.asm'\" \(5075 characters\)
sed "s/^X//" >'start_t.asm' <<'END_OF_FILE'
X* Stack when we get control:
X*
X* 0: sp ->  return address to t startup code
X* 4:        argument 1 to T (start_address)
X* 8:        argument 2 to T (data_address)
X* C:        argument 3 to T (fault_handler_xenoid)
X* ...
X*
X* JUMP_TO_T is called by value.  The first three arguments are 
X* start_addresss, data_address, and sfh_xenoid.  The sfh_xenoid is 
X* in this file, and the third argument to JUMP_TO_T is clobbered
X* with a pointer to it.
X
X* The slink is assumed to be the first thing in the data section,
X* and is saved into the fault handler's ecb, so that we may regain
X* addressibility to T after a fault.
X
X    module jtt
X
X
X********  T system dependencies
X
Xp          equ a0
Xtp         equ a5
Xnil_reg    equ d7
X
Xnil_tag    equ 3
X
Xxenoid_header                  equ 57
X
Xexception_handler_slink_offset equ 49
X
X******** 
X
X*
X*  PROCEDURE jump_to_t(start, data_address, sfh_dummy, ....); OPTIONS(VAL_PARAM);
X*
X    data
Xdata_start equ *
Xjump_to_t equ *
X    dc.w    $4ef9                   * jump long absolute instruction
X    ac      pure_jump_to_t          * pure code entry point
X    ac      data_start              * data section pointer
X    dc.w    0                       * flag word (unused)
X
X    proc                 
X    entry jump_to_t
Xpure_jump_to_t equ *
X    move.l db,d2
X    move.l 4(sp),d1                       * t start routine (arg 1)
X    move.l 6(a0),db                       * addressibility to local data
X    move.l db,4(sp)                       * save db
X    move.l d2,saved_db
X    move.l sb,saved_sb                    * save sb
X    move.l (sp)+,saved_return             * pop return address and save
X    move.l 4(sp),d0                       * get data area address (arg 2)
X    addq.l #nil_tag,d0                    * ..add nil tag to make slink
X    move.l d0,the_saved_slink             * ..cache slink pointer for fault handler
X
X    lea    2+sfh_xenoid-data_start(db),a1 * fault handler xenoid extend pointer
X    move.l a1,8(sp)                       * ...pass to t (arg 3)
X    move.l d1,p
X    move.l -2(p),tp                       * t calling sequence
X
X    jsr    (tp)
X    move.l (sp),db                               
X    move.l saved_return,-(sp)
X    move.l saved_sb,sb
X    move.l saved_db,db
X    rts     
X
X
X* Fault Handling
X
X* This is how we get control of machine synchronous & asynchronous faults
X* The Aegis nucleus fim catches  fault & sets up the diagnostic frame on our
X* stack, then it calls the static fault handler passing a pointer to the
X* diagnostic frame and a deferred? flag.  We align the stack and then 
X* format the fault frame for T.  
X*
X* 100 dc.l alignment area size (offset to diag frame)  <== SP
X* 000 dc.l old SP
X* 100 dc.l fault SP (redundant for interrupt dispatcher ease)
X* 000 some number of bytes for alignment
X* ... some randomness in here, old SP points into this
X*      old SP ->  0: saved db
X*                 4: saved sb
X*                 8: return address of caller
X*                12: argument 1 (frame)
X*                16: argument 2 (deferred?)
X* ... dc.w $DFDF                <---- Apollo dignostic frame begins
X* ... dc.l fault status
X* ... dc.l D0
X
X*%include '/os/ins/fault.ins.asm'
X%include 'fault.ins.asm'
X
X    data
Xsfh_ecb
X    dc.w $4ef9
X    ac sfh_pure
Xthe_saved_slink
X    ac 0                    * this is filled in with a pointer to the slink
X*                           * (which is the first thing in the data section)
Xsaved_return
X    ac 0
Xsaved_sb
X    ac 0
Xsaved_db
X    ac 0
X    dc.w 0
X
Xsfh_procedure
X    ac sfh_ecb
X    ac sfh_ecb
X
X* do long word alignment !!!  (we got it here by accident, if we got it)
X* 
Xsfh_xenoid
X    dc.l xenoid_header                * xenoid header
X    ac sfh_procedure
X
X* when control here, we save DB & SB, then stack looks like
X*
X*    sp->  0: saved db
X*          4: saved sb
X*          8: return address of caller
X*          12: argument 1 (frame)
X*          16: argument 2 (deferred?)
X
X      proc
Xsfh_pure
X     move.l sb,-(sp)
X     move.l db,-(sp)              * save regs needed to resume from fault
X
X     move.l 6(a0),a1              * restore slink for T
X     move.l a1,nil_reg
X
X     move.l 12(sp),a0           * diagnostic frame
X     move.l sp,d2               * saved sp
X
X* A0 points to top of diagnostic frame
X* D6 points into stack at a known spot so that we can find our way
X*    past the alignment bytes when we try to return (old SP)
X
X
X    move.l sp,d0           * copy sp
X    andi.b #255-3,d0       * d0 is longword aligned version of sp
X
X    exg d0,sp              * put aligned sp into effect
X
X    move.l df_a7-df_start(a0),-(sp)   * get fault time SP
X    move.l d2,-(sp)          * save a spot after alignment (old SP), to return
X
X    move.l a0,-(sp)          * slot for diag frame offset (init to diag frame)
X    move.l sp,d0             * (copy sp to data reg because 68k is a loser)
X    sub.l d0,(sp)            * ... sub makes slot = displacement to diag frame
X
X    move.l nil_reg,a1               * slink into address reg
X
X    move.l df_status-df_start(a0),d5
X    move.l exception_handler_slink_offset(a1),p
X    move.l -2(p),tp
X    jmp (tp)
X
X
X
X
END_OF_FILE
if test 5075 -ne `wc -c <'start_t.asm'`; then
    echo shar: \"'start_t.asm'\" unpacked with wrong size!
fi
# end of 'start_t.asm'
fi
if test -f 'start_t.asm~' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'start_t.asm~'\"
else
echo shar: Extracting \"'start_t.asm~'\" \(5049 characters\)
sed "s/^X//" >'start_t.asm~' <<'END_OF_FILE'
X* Stack when we get control:
X*
X* 0: sp ->  return address to t startup code
X* 4:        argument 1 to T (start_address)
X* 8:        argument 2 to T (data_address)
X* C:        argument 3 to T (fault_handler_xenoid)
X* ...
X*
X* JUMP_TO_T is called by value.  The first three arguments are 
X* start_addresss, data_address, and sfh_xenoid.  The sfh_xenoid is 
X* in this file, and the third argument to JUMP_TO_T is clobbered
X* with a pointer to it.
X
X* The slink is assumed to be the first thing in the data section,
X* and is saved into the fault handler's ecb, so that we may regain
X* addressibility to T after a fault.
X
X    module jtt
X
X
X********  T system dependencies
X
Xp          equ a0
Xtp         equ a5
Xnil_reg    equ d7
X
Xnil_tag    equ 3
X
Xxenoid_header                  equ 57
X
Xexception_handler_slink_offset equ 49
X
X******** 
X
X*
X*  PROCEDURE jump_to_t(start, data_address, sfh_dummy, ....); OPTIONS(VAL_PARAM);
X*
X    data
Xdata_start equ *
Xjump_to_t equ *
X    dc.w    $4ef9                   * jump long absolute instruction
X    ac      pure_jump_to_t          * pure code entry point
X    ac      data_start              * data section pointer
X    dc.w    0                       * flag word (unused)
X
X    proc                 
X    entry jump_to_t
Xpure_jump_to_t equ *
X    move.l db,d2
X    move.l 4(sp),d1                       * t start routine (arg 1)
X    move.l 6(a0),db                       * addressibility to local data
X    move.l db,4(sp)                       * save db
X    move.l d2,saved_db
X    move.l sb,saved_sb                    * save sb
X    move.l (sp)+,saved_return             * pop return address and save
X    move.l 4(sp),d0                       * get data area address (arg 2)
X    addq.l #nil_tag,d0                    * ..add nil tag to make slink
X    move.l d0,the_saved_slink             * ..cache slink pointer for fault handler
X
X    lea    2+sfh_xenoid-data_start(db),a1 * fault handler xenoid extend pointer
X    move.l a1,8(sp)                       * ...pass to t (arg 3)
X    move.l d1,p
X    move.l -2(p),tp                       * t calling sequence
X
X    jsr    (tp)
X    move.l (sp),db                               
X    move.l saved_return,-(sp)
X    move.l saved_sb,sb
X    move.l saved_db,db
X    rts     
X
X
X* Fault Handling
X
X* This is how we get control of machine synchronous & asynchronous faults
X* The Aegis nucleus fim catches  fault & sets up the diagnostic frame on our
X* stack, then it calls the static fault handler passing a pointer to the
X* diagnostic frame and a deferred? flag.  We align the stack and then 
X* format the fault frame for T.  
X*
X* 100 dc.l alignment area size (offset to diag frame)  <== SP
X* 000 dc.l old SP
X* 100 dc.l fault SP (redundant for interrupt dispatcher ease)
X* 000 some number of bytes for alignment
X* ... some randomness in here, old SP points into this
X*      old SP ->  0: saved db
X*                 4: saved sb
X*                 8: return address of caller
X*                12: argument 1 (frame)
X*                16: argument 2 (deferred?)
X* ... dc.w $DFDF                <---- Apollo dignostic frame begins
X* ... dc.l fault status
X* ... dc.l D0
X
X%include '/os/ins/fault.ins.asm'
X
X    data
Xsfh_ecb
X    dc.w $4ef9
X    ac sfh_pure
Xthe_saved_slink
X    ac 0                    * this is filled in with a pointer to the slink
X*                           * (which is the first thing in the data section)
Xsaved_return
X    ac 0
Xsaved_sb
X    ac 0
Xsaved_db
X    ac 0
X    dc.w 0
X
Xsfh_procedure
X    ac sfh_ecb
X    ac sfh_ecb
X
X* do long word alignment !!!  (we got it here by accident, if we got it)
X* 
Xsfh_xenoid
X    dc.l xenoid_header                * xenoid header
X    ac sfh_procedure
X
X* when control here, we save DB & SB, then stack looks like
X*
X*    sp->  0: saved db
X*          4: saved sb
X*          8: return address of caller
X*          12: argument 1 (frame)
X*          16: argument 2 (deferred?)
X
X      proc
Xsfh_pure
X     move.l sb,-(sp)
X     move.l db,-(sp)              * save regs needed to resume from fault
X
X     move.l 6(a0),a1              * restore slink for T
X     move.l a1,nil_reg
X
X     move.l 12(sp),a0           * diagnostic frame
X     move.l sp,d2               * saved sp
X
X* A0 points to top of diagnostic frame
X* D6 points into stack at a known spot so that we can find our way
X*    past the alignment bytes when we try to return (old SP)
X
X
X    move.l sp,d0           * copy sp
X    andi.b #255-3,d0       * d0 is longword aligned version of sp
X
X    exg d0,sp              * put aligned sp into effect
X
X    move.l df_a7-df_start(a0),-(sp)   * get fault time SP
X    move.l d2,-(sp)          * save a spot after alignment (old SP), to return
X
X    move.l a0,-(sp)          * slot for diag frame offset (init to diag frame)
X    move.l sp,d0             * (copy sp to data reg because 68k is a loser)
X    sub.l d0,(sp)            * ... sub makes slot = displacement to diag frame
X
X    move.l nil_reg,a1               * slink into address reg
X
X    move.l df_status-df_start(a0),d5
X    move.l exception_handler_slink_offset(a1),p
X    move.l -2(p),tp
X    jmp (tp)
X
X
X
X
END_OF_FILE
if test 5049 -ne `wc -c <'start_t.asm~'`; then
    echo shar: \"'start_t.asm~'\" unpacked with wrong size!
fi
# end of 'start_t.asm~'
fi
echo shar: End of shell archive.
exit 0
