--
-- (c) Inmos 1989
--
-- Assembly file for the Primary bootstrap T4 HALT mode
--
-- G.S.Panesar! 14/11/89
--
--
--
-- VAL   BASE            IS  1 :        -- loop index
-- VAL   COUNT           IS  2 :        -- loop count
-- 
-- VAL   LOAD_START      IS  0 :        -- start of loader
-- VAL   LOAD_LENGTH     IS  1 :        -- loader block length
-- VAL   NEXT_ADDRESS    IS  2 :        -- start of next block to load
-- VAL   BOOTLINK        IS  3 :        -- link booted from
-- VAL   NEXT_WPTR       IS  4 :        -- work space of loaded code
-- VAL   RETURN_ADDRESS  IS  5 :        -- return address from loader
-- VAL   TEMP_WORKSPACE  IS  RETURN_ADDRESS : -- workspace used by both
--                                      -- preamble and loader
-- VAL   NOTPROCESS      IS  6 :        -- copy of MinInt
-- VAL   LINKS           IS  NOTPROCESS : -- 1st param to loader (MinInt)
-- VAL   BOOTLINK_IN_PARAM  IS  7 :        -- 2nd parameter to loader
-- VAL   BOOTLINK_OUT_PARAM IS  8 :        -- 3nd parameter to loader
-- VAL   MEMORY          IS  9 :        -- 4th parameter to loader
-- VAL   BUFFER          IS 10 :        -- 5th parameter to loader

-- VAL   ENTRY_POINT     IS 11 :        -- 6th parameter to loader
-- VAL   DATA_POINT	 IS 12 :        -- 7th parameter to loader
-- VAL   NEXT_POINT      IS 13 :        -- 8th parameter to loader

-- VAL   ENTRY_ADDRESS   IS 14 :        -- referenced from entry point
-- VAL   DATA_ADDRESS    IS 15 :        -- referneced from Data point
-- VAL   NEXT_ADDRESS    IS 16 :        -- start of boot part 2
-- VAL   MEMSTART        IS 17 :        -- 
--
-- 
-- The initial workspace requirement is found by reading the workspace
-- requirement from the loader \occam\ and subtracting the size of the workspace
-- used by both the loader and the bootstrap (\verb|temp.workspace|). This value
-- is incremented by 4 to accomodate the workspace adjustment by the call
-- instruction used to preserve the processor registers.
-- 
-- initial.adjustment := (loader.workspace + 4) - temp.workspace
-- occam work space, + 4 for call to save registers, - adjustment made
-- when entering occam. Must be at least 4
-- IF
--   initial.adjustment < 4
--     initial.adjustment := 4
--   TRUE
--     SKIP
-- 
-- set up work space, save registers,
-- save MemStart and NotProcess

    align

    byte (Endprimary-Primary)

Primary:

global Primary

    ajw    (9+20)                -- INITIAL_ADJUSTMENT -- see above
    call   0                -- save registers

    ldc    Primary - Addr0    -- distance to start byte
    ldpi                    -- address of start
Addr0:
    stl    17               -- MEMSTART         -- save for later use

    mint
    stl    6                -- NOTPROCESS       -- save for later use

-- initialise process queues and clear error
    ldl    6                -- NOTPROCESS
    stlf                    -- reset low priority queue

    ldl    6                -- NOTPROCESS
    sthf                    -- reset high priority queue

-- use clrhalterr here to create bootstrap for REDUCED application
    sethalterr              -- set halt on error
    testerr                 -- read and clear error bit

-- initialise T8 error and rounding
--    fpu.clearerr            -- floating clear error instruction
--    fpuclrerr            -- floating clear error instruction
-- initialise link and event words
    ldc    0
    stl    1                -- BASE             -- index to words to initialise
    ldc    11               -- no. words to initialise
    stl    2                -- COUNT            -- count of words left
Startloop:
    ldl    6                -- NOTPROCESS
    ldl    1                -- BASE             -- index
    ldl    6                -- NOTPROCESS
    wsub                    -- point to next address
    stnl   0                -- put NotProcess into addressed word
    ldlp   1                -- BASE             -- address of loop control info
    ldc    Endloop - Startloop -- return jump
    lend                    -- go back if more
Endloop:

-- set up some loader parameters. See the parameter
-- structure of the loader Done here so that the secondary is smaller
--
    ldlp   14               -- DATA_ADDRESS    -- address of entry word
    stl    13               -- DATA_POINT      -- store in param 7

    ldlp   15               -- ENTRY_ADDRESS    -- address of entry word
    stl    12               -- ENTRY_POINT      -- store in param 6

    ldlp   16                 -- Next code address (to be used to overlay loader)
    stl    11                -- NEXT_ADDRESS     -- buffer offset in param 5

    ldl    17               -- MEMSTART         -- start of memory
    stl    9                -- MEMORY           -- store in param 4

    ldl    3                -- BOOTLINK         -- copy of bootlink
    stl    7                -- BOOTLINK_IN_PARAM   -- store in param 2

--  Now find the corresponding output link and place in the parameter

    ldl	   3		    -- BOOTLINK	
    ldnlp  -4		    -- Calculate the output link address
    stl    8		    -- BOOTLINK_OUT_PARAM  -- store in param 3

    pfix   0
    pfix   0
    pfix   0
    pfix   0
    pfix   0
    pfix   0
    pfix   0
    pfix   0
    pfix   0
    pfix   0
    pfix   0
    pfix   0
    pfix   0
    pfix   0
    pfix   0
    pfix   0
    pfix   0
    pfix   0
    pfix   0
    pfix   0
    pfix   0
    pfix   0
    pfix   0
    pfix   0
    pfix   0
    pfix   0
    pfix   0
    pfix   0
    pfix   0
    pfix   0
    pfix   0
    pfix   0
    pfix   0
    pfix   0
    pfix   0
    pfix   0
    pfix   0
    pfix   0
    pfix   0
    pfix   0
    pfix   0
    pfix   0
    pfix   0
    pfix   0
    pfix   0
    pfix   0
    pfix   0
    pfix   0
    pfix   0
    pfix   0

-- load bootloader over bootstrap
-- code must be 2 bytes shorter than bootstrap

    ldlp   1                -- LOAD_LENGTH      -- packet size word
    ldl    3                -- BOOTLINK         -- address of link
    ldc    1                -- bytes to load
    in                      -- input length byte

    ldl    17               -- MEMSTART         -- area to load bootloader
    ldl    3                -- BOOTLINK         -- address of link
    ldl    1                -- LOAD_LENGTH      -- message length
    in                      -- input bootloader

-- enter code just loaded


    ldl    17               -- MEMSTART         -- start of loaded code
    gcall                   -- enter bootloader

    align
Endprimary:




--
-- (c) Inmos 1989
-- Assembly file for the secondary loader T4 IGNORE mode
--
-- G.S.Panesar! 14/11/89
--
--
-- VAL   BASE            IS  1 :        -- loop index
-- VAL   COUNT           IS  2 :        -- loop count
--
-- VAL   LOAD_START      IS  0 :        -- start of loader
-- VAL   LOAD_LENGTH     IS  1 :        -- loader block length
-- VAL   NEXT_ADDRESS    IS  2 :        -- start of next block to load
-- VAL   BOOTLINK        IS  3 :        -- link booted from
-- VAL   NEXT_WPTR       IS  4 :        -- work space of loaded code
-- VAL   RETURN_ADDRESS  IS  5 :        -- return address from loader
-- VAL   TEMP_WORKSPACE  IS  RETURN_ADDRESS : -- workspace used by both
--                                      -- preamble and loader
-- VAL   NOTPROCESS      IS  6 :        -- copy of MinInt
-- VAL   LINKS           IS  NOTPROCESS : -- 1st param to loader (MinInt)
-- VAL   BOOTLINK_IN_PARAM  IS  7 :        -- 2nd parameter to loader
-- VAL   BOOTLINK_OUT_PARAM IS  8 :        -- 3nd parameter to loader
-- VAL   MEMORY          IS  9 :        -- 4th parameter to loader
-- VAL   BUFFER          IS 10 :        -- 5
-- VAL   NEXT_POINT      IS 11 :        -- 6th parameter to loader
-- VAL   ENTRY_POINT     IS 12 :        -- 7th parameter to loader
-- VAL   DATA_POINT      IS 13 :        -- 8th parameter to loader
-- VAL   ENTRY_ADDRESS   IS 14 :        -- referenced from entry point
-- VAL   DATA_ADDRESS    IS 15 :        -- referneced from Data point
-- VAL   NEXT_ADDRESS    IS 16 :        -- referenced from Nexat point
-- VAL   MEMSTART        IS 17 :        -- start of boot part 2
--
--
-- VAL   PACKET_LENGTH   IS 60 :
-- 

    byte Endsecondary-Secondary
Secondary:

global Secondary

-- initialise bootloader workspace
--    ldc    60               -- PACKET_LENGTH    -- buffer size
    ldc    120               -- PACKET_LENGTH    -- buffer size
    ldlp   18               -- MEMSTART+1         -- buffer start address
    bsub                    -- end of buffer address
    stl    2                -- next.address     -- start of area to load loader

    ldl    2
--    ldl    17

    ldlp   18               -- MEMSTART+1         -- buffer start address
    stl    9                -- MEMORY           -- Earlest place to load

    ldlp   5                -- TEMP_WORKSPACE   -- pointer to loader's work space zero
    stl    4                -- NEXT_WPTR        -- work space pointer of loaded code

    ldc    0
    stl    10               -- Where to buffer

    ldc    0
    stl    1                -- clear bytes to load

Loadcode:
    ldl    2                -- NEXT_ADDRESS     -- adddress to load loader
    stl    0                -- LOAD_START       -- current load point

-- load code until terminator
Startload:
    ldlp   1                -- LOAD_LENGTH      -- packet length
    ldl    3                -- BOOTLINK         -- address of link
    ldc    1                -- bytes to load
    in                      -- input length byte

    ldl    1                -- LOAD_LENGTH      -- message length
    cj     Endload          -- quit if 0 bytes

    ldl    2                -- NEXT_ADDRESS     -- start of area to load loader
    ldl    3                -- BOOTLINK         -- address of link
    ldl    1                -- LOAD_LENGTH      -- message length
    in                      -- input code block
    ldl    1                -- LOAD_LENGTH      -- message length
    ldl    2                -- NEXT_ADDRESS     -- area to load
    bsub                    -- new area to load
    stl    2                -- next.address     -- save area to load

    j      Startload        -- go back for next block
Endload:

-- initialise return address and enter loaded code
    ldc    Return - Addr1   -- offset to return address
    ldpi                    -- return address
Addr1:
    stl    5                -- RETURN_ADDRESS   -- save in W0


    ldl    3                -- Get bootlink and save for later
    stl    -25

    ldl    4                -- NEXT_WPTR        -- wspace of loaded code
    gajw                    -- set up his work space
    ldnl   0                -- LOAD_START       -- address of first load packet
    gcall                   -- enter loaded code

Return:

-- Now set up invocation stack for the Init_system

    ajw    -(5 + 4)         -- TEMP_WORKSPACE + 4)-- reset work space after return

    ldl    -25               -- get back boot link
    stl    3

    ldl    14		    -- DATA_ADDRESS -- get address of processor structure
    ldl    9                -- MEMORY
    bsub
    stl    12               -- DATA point


    ldl    15		    -- ENTRY_ADDRESS -- convert to real entry address
    ldl    9		    -- MEMORY
    bsub
--    stl    14
    stl    0

    ldl    6                -- NOTPROCESS
    stl    11

    ldl    9                -- make DATA base offset and CODE base offset the same
    stl    10

    ldl    14
    stl    6

    ldl    16                -- convert returned address of next sequence to 
    ldl    9                -- a real address
    bsub
    stl    2

    ldc    0
    stl    1                -- clear bytes to load

    ldlp   6
    stl    4
    
-- start clock

    ldc    0
    sttimer

    j      Startload 

    align
Endsecondary:
