Google
 

Trailing-Edge - PDP-10 Archives - TOPS-20_V6.1_DECnetSrc_7-23-85 - mcb/vnp36/vnp36.bli
There are 2 other files named vnp36.bli in the archive. Click here to see a list.
!DSKT:VNP36.BLI[10,6026,VNP36], 15-Mar-84 14:04:20, Edit by DAVENPORT
!
! 3A(6)
!	VNP36	- Fix macro CH$LEN in LOAD_MCBS to search the first
!		  four characters of a process name rather than the
!		  first three characters.  This avoids computing a
!		  negative length which used later in CH$COPY causes
!		  an illegal instruction trap from newer KL ucodes.
!
!DSKT:VNP36.BLI[10,6026,VNP36],  6-Mar-84 10:33:31, Edit by DAVENPORT
!
! 3A(5)
!	VNP36	- Add version to module declaration.
!	BLOCKT	- Fix undeclare statement to only undeclare symbols
!		  if they are already defined.
!
!NET:<DECNET20-V3P0.TKB-VNP.BIGVNP>VNP36.BLI.52 28-Sep-82 16:14:27, Edit by PECKHAM
!NET:<DECNET20-V3P0.TKB-VNP.BIGVNP>VNP36.BLI.51  5-Jun-82 11:15:37, Edit by PECKHAM
!NET:<DECNET20-V3P0.TKB-VNP.BIGVNP>VNP36.BLI.49 26-Mar-82 17:23:05, Edit by PECKHAM
!NET:<DECNET20-V3P0.TKB-VNP.BIGVNP>VNP36.BLI.48 26-Mar-82 16:11:52, Edit by PECKHAM
!NET:<DECNET20-V3P0.TKB-VNP.BIGVNP>VNP36.BLI.46 26-Aug-81 10:03:28, Edit by SROBINSON
!NET:<DECNET20-V3P0.TKB-VNP.VNPV3>VNP36.BLI.41  4-Feb-81 09:07:04, Edit by SROBINSON
!<DECNET20-V3P0.TKB-VNP.VNPV3>VNP36.BLI.39 10-Dec-80 10:50:30, Edit by SROBINSON
!<DECNET20-V3P0.TKB-VNP.VNPV3>VNP36.BLI.2, 29-Apr-80 11:45:29, Edit by SROBINSON
MODULE VNP36 (					!Main Program for VNP
		IDENT = 'X03040',
		VERSION = '3A(6)',
		MAIN = VNP20
		) =
BEGIN
!
!
!
!                    COPYRIGHT (c) 1980, 1981, 1982
!                    DIGITAL EQUIPMENT CORPORATION
!                        Maynard, Massachusetts
!
!     This software is furnished under a license and may  be  used
!     and copied only in accordance with the terms of such license
!     and with the inclusion of the above copyright notice.   This
!     software  or any other copies thereof may not be provided or
!     otherwise made available to any other person.  No  title  to
!     and ownership of the software is hereby transferred.
!
!     The information  in  this  software  is  subject  to  change
!     without  notice  and should not be construed as a commitment
!     by DIGITAL EQUIPMENT CORPORATION.
!
!     DIGITAL assumes no responsibility for the use or reliability
!     of  its  software  on  equipment  which  is  not supplied by
!     DIGITAL.
!

!++
! FACILITY: MCB Configuration Facility, VNP20
!
! ABSTRACT:
!
!	This module is the main program for the MCB System Builder
!	which is part of the MCB Configuration Facility.
!
! ENVIRONMENT: TOPS-20 User Mode
!
! AUTHOR: Scott G. Robinson, Creation: 14-APR-80
!
! MODIFIED BY:
!
!	Scott G. Robinson, 10-DEC-80 : VERSION 03xx0
!
! 01	- Add Changes for MCB V3.1 Systems
! 02    - Add Changes for MCB V3.2 Systems
! 03	- Make Big System Changes (>124K Systems)
! 04	- Make all partition names to M_PCB be 6 character ASCIZ names.
!--

!
! TABLE OF CONTENTS:
!

FORWARD ROUTINE
    VNP20 : NOVALUE,				!Main Program
    DEL_BLK,
    DEL_DEV,
    DEL_CTL,
    DEL_UNT,
    LOAD_TSKS,
    LOAD_MCBS;

!
! INCLUDE FILES:
!

LIBRARY 'VNPLIB';

!
! MACROS:
!
!	NONE
!
! EQUATED SYMBOLS:
!

LITERAL
    DEBUG = 0;

!
! OWN STORAGE:
!
!	NONE
!
! EXTERNAL REFERENCES:
!

EXTERNAL ROUTINE
    RCOR : NOVALUE,				!Read Core Image
    WCOR : NOVALUE,				!Write Out Core Image
    FCOR : NOVALUE,				!Free A Core Image
    RSTB : NOVALUE,				!Read Symbol Table
    RCET : NOVALUE,				!Read CETAB.MAC
    MCEX : NOVALUE,				!Merge CEX Into Core Image
    GETSYM : NOVALUE,				!Get Symbols From Symbol Tables
    M_PCB,					!Make A Partition Control Block
    INSTAL : NOVALUE,				!Install A Task
    LOADD : NOVALUE,				!Load A Device Driver
    LD_DCB,					!Load a Process Driver
    LODMCB : NOVALUE,				!Load Process's data base
    FCLEAN : NOVALUE,				!Do Final Cleanup Of The Kernel
    TELLK : NOVALUE,				!Tell About The Core Image
    OPEN,					!OPEN A File
    OUTPUT : NOVALUE,				!Output a Character
    OUTSTR : NOVALUE,				!Output a String
    PCRLF : NOVALUE,				!Output a CR/LF
    ERRMSG : NOVALUE,				!Error Message
    CLOSE : NOVALUE,				!CLOSE A File
    INISTG : NOVALUE,				!Initialize Storage Manager
    FND_CHAIN,					!Find A Block In A Chain
    GETBLK,					!Get A Storage Block
    FREBLK : NOVALUE,				!Free A Storage Block
    RESET_ALL,					!Reset All I/O
    DEL_PTRS : NOVALUE,				!Delete Pointer Blocks
    PUTBYT : NOVALUE,				!Put A Byte Into A TSK Image
    GETBYT,					!Get A Byte From A TSK Image
    PUTWRD : NOVALUE,				!Put A Word Into A TSK Image
    GETWRD,					!Get A Word From A TSK Image
    R50TOA,					!Convert RADIX-50 To ASCII
    ALOCB,					!Allocate Some Storage (EXEC DSR)
    SYM_VAL;					!Lookup a symbol in symbol table
ROUTINE VNP20 : NOVALUE = 			!Main Program

!++
! FUNCTIONAL DESCRIPTION:
!
!	Top level program for MCB System Builder.
!
! FORMAL PARAMETERS:
!
!	NONE
!
! IMPLICIT INPUTS:
!
!	NONE
!
! IMPLICIT OUTPUTS:
!
!	NONE
!
! ROUTINE VALUE:
!
!	NONE
!
! SIDE EFFECTS
!
!	Creates the MCB System's Image on disk.
!
!--

    BEGIN

    BIND
	ROUTINE_NAME = UPLIT (%STRING (' VNP36 - ',
	,' Conjuror for MCB V3.2 Systems',
	%IF %SWITCHES(TOPS20) %THEN ' (TOPS-20 Environment Only)',%FI
	%CHAR(0)));

    LOCAL
	CETAB_FILE : REF FILE_BLOCK,
	CEXCOM_FILE : REF FILE_BLOCK,
	KERNEL_FILE : REF FILE_BLOCK,
	LOGGING_FILE : REF FILE_BLOCK,
	RSXMS_FILE : REF FILE_BLOCK,
	MODU_PTR : REF MODU_BLOCK,
	POOL_PCB,
	POOL_PAR_BASE,
	BUF_PCB,
	BUF_PAR_BASE,
	GEN_PCB,
	GEN_PAR_BASE,
	PAR_BLK : VECTOR [4],
	VALUES : REF VNPVAL_BLOCK;

!
! Startout by initializing the support routines, and then allocate static
!  data structures 'stamp coupled' to other levels in the system builder.
!
    RESET_ALL ();
    INISTG (7000);
    VALUES = GETBLK (VNPVAL_TYP, VNPVAL_LEN);
    KERNEL_FILE = GETBLK (FILE_TYP, FILE_LEN);
    LOGGING_FILE = GETBLK (FILE_TYP, FILE_LEN);
    CETAB_FILE = GETBLK (FILE_TYP, FILE_LEN);
    CEXCOM_FILE = GETBLK (FILE_TYP, FILE_LEN);
    RSXMS_FILE = GETBLK (FILE_TYP, FILE_LEN);
!
! Open the terminal Logging File: All output through channel 0 will go
! here also...
!
    CH$MOVE (10, CH$PTR (UPLIT (%ASCIZ'MCBMAP.TXT')), CH$PTR (LOGGING_FILE [FILE_NAME]));
    OPEN (1, LOGGING_FILE [FILE_NAME], 1, 1, UPLIT (%ASCIZ'TXT'));
!
! Say who we are...
!
    OUTSTR (0, ROUTINE_NAME);
    PCRLF (0);
!
! Read CETAB.MAC to determine the configuration of the system being
!  constructed and store the textual information in our data bases.
!
    OUTSTR (0, UPLIT (%ASCIZ'[Reading Configuration File]'));
    PCRLF (0);
    CH$MOVE (10, CH$PTR (UPLIT (%ASCIZ'CETAB.MAC')), CH$PTR (CETAB_FILE [FILE_NAME]));
    RCET (2, .CETAB_FILE, .VALUES);
    FCOR (.CETAB_FILE);
!
! Next we read in the RSX11-S Executive which forms the base for the
!  MCB system.
!
    OUTSTR (0, UPLIT (%ASCIZ'[Loading Base Executive	--> '));
    CH$MOVE (7, CH$PTR (UPLIT (%ASCIZ'RSX11S')), CH$PTR (KERNEL_FILE [FILE_NAME]));
    RSTB (2, .KERNEL_FILE);			!READ SYMBOL TABLE
    RCOR (.KERNEL_FILE, 2, 160*2048);		!READ IMAGE
    KERNEL_FILE [FILE_HWM] = 0;			!INITIALIZE HIGH WATER MARK
    MODU_PTR = .KERNEL_FILE [FILE_MODU];
    OUTSTR (0, MODU_PTR [MODU_NAME]);
    OUTPUT (0, %C' ');
    OUTSTR (0, MODU_PTR [MODU_IDENT]);
    OUTSTR (0, UPLIT (%ASCIZ' ]'));
    PCRLF (0);
!
! Read the CEXCOM partition contents.
!
    OUTSTR (0, UPLIT (%ASCIZ'[Loading MCB Executive	--> '));
    CH$MOVE (7, CH$PTR (UPLIT (%ASCIZ'CEXCOM')), CH$PTR (CEXCOM_FILE [FILE_NAME]));
    RSTB (2, .CEXCOM_FILE);			!READ COMM EXEC SYMBOL TABLE
    RCOR (.CEXCOM_FILE, 2, 16*2048);		!READ CEXCOM.TSK
    MODU_PTR = .CEXCOM_FILE [FILE_MODU];
    OUTSTR (0, MODU_PTR [MODU_NAME]);
    OUTPUT (0, %C' ');
    OUTSTR (0, MODU_PTR [MODU_IDENT]);
    OUTSTR (0, UPLIT (%ASCIZ' ]'));
    PCRLF (0);
!
!  Read symbol table from RSXMS.STB, which contains all the useful
!   symbols from EXEMC.MLB
!
    CH$MOVE (6, CH$PTR (UPLIT (%ASCIZ'RSXMS')), CH$PTR (RSXMS_FILE [FILE_NAME]));
    RSTB (2, .RSXMS_FILE);
!
! Get useful symbols from various symbol table files and store them
!  in the VALUES array. This is done to increase the efficiency of
!  accessing symbol values.
!
    GETSYM (.KERNEL_FILE, .CEXCOM_FILE, .RSXMS_FILE, .VALUES);
!
! We are done with the symbol table file(s), so throw them out of memory.
!
    FCOR (.RSXMS_FILE);
!
! Generate the CEXCOM partition and store the file in it.
!
    MCEX (.KERNEL_FILE, .CEXCOM_FILE, .VALUES);
!
! We don't need the CEXCOM file any more so delete it.
!
    FCOR (.CEXCOM_FILE);
!
! Construct the GEN partition which will contain all MCB Tasks, Processes,
!  and the POOL.
!
    GEN_PAR_BASE = .KERNEL_FILE [FILE_HWM] + 1;
    GEN_PCB = M_PCB (.KERNEL_FILE, UPLIT (%ASCIZ'GEN   '), 0, .GEN_PAR_BASE, 0, %O'100200', .VALUES [PS_SYS],
	0, .VALUES);
!
! First Install Tasks indicated in CETAB.MAC
!
    PAR_BLK [0] = .GEN_PCB;
    PAR_BLK [1] = .KERNEL_FILE;
    PAR_BLK [2] = .VALUES;
    PAR_BLK [3] = 2;
    FND_CHAIN (.VALUES [TSK_CHAIN], LOAD_TSKS, PAR_BLK);
!
! Return storage associated with the loaded tasks in our data base.
!
    FND_CHAIN (.VALUES [TSK_CHAIN], DEL_BLK, 0);
    DEL_PTRS (.VALUES [TSK_CHAIN]);
!
! Load the MCB Processes into memory.
!
    FND_CHAIN (.VALUES [MCB_CHAIN], LOAD_MCBS, PAR_BLK);
!
! Complete the GEN partition by filling in the size field
!
    PUTWRD (.KERNEL_FILE, .GEN_PCB + .VALUES [P_SIZE], (.KERNEL_FILE [FILE_HWM] - .GEN_PAR_BASE + 1)/64);
!
! Generate the CEXDAT partition to contain storage for the MCB processes' data
!  bases.
!
    POOL_PAR_BASE = .KERNEL_FILE [FILE_HWM] + 1;
    POOL_PCB = M_PCB (.KERNEL_FILE, UPLIT (%ASCIZ'CEXDAT'), 0, .POOL_PAR_BASE, 0, %O'100200',
	.VALUES [PS_COM], 0, .VALUES);
!
! Now load the MCB processes' data base elements that tie this system
!  together.
!
    LODMCB (.KERNEL_FILE, .POOL_PCB, 2, .VALUES);
!
! Finish the CEXDAT partition by filling in its size
!
    PUTWRD (.KERNEL_FILE, .POOL_PCB + .VALUES [P_SIZE], (.KERNEL_FILE [FILE_HWM] - .POOL_PAR_BASE + 1)/64);
!
! Delete information blocks kept around from reading CETAB.MAC, we are done
!  with them.
!
    FND_CHAIN (.VALUES [LLC_CHAIN], DEL_BLK, 0);
    DEL_PTRS (.VALUES [LLC_CHAIN]);
    FND_CHAIN (.VALUES [DEV_CHAIN], DEL_DEV, 0);
    DEL_PTRS (.VALUES [DEV_CHAIN]);
    FND_CHAIN (.VALUES [SLT_CHAIN], DEL_BLK, 0);
    DEL_PTRS (.VALUES [SLT_CHAIN]);
!
! Return storage held to list MCB processes.
!
    FND_CHAIN (.VALUES [MCB_CHAIN], DEL_BLK, 0);
    DEL_PTRS (.VALUES [MCB_CHAIN]);
!
! Now generate the CEXBUF main partition as the last one in memory.
!
    BUF_PAR_BASE = .KERNEL_FILE [FILE_HWM] + 1;
    BUF_PCB = M_PCB (.KERNEL_FILE, UPLIT (%ASCIZ'CEXBUF'), 0, .BUF_PAR_BASE, 0, %O'100200', .VALUES [PS_COM],
	0, .VALUES);
!
! Cleanup the KERNEL
!
    FCLEAN (.KERNEL_FILE, .VALUES);
!
! Print some information about the configuration of this system.
!
    TELLK (.KERNEL_FILE, 0, .VALUES);
!
! Tell we are writing the system image now
!
    OUTSTR (0, UPLIT (%ASCIZ'[Writing '));
    OUTSTR (0, KERNEL_FILE[FILE_NAME]);
    OUTSTR (0, UPLIT (%ASCIZ'.SYS]'));
    PCRLF (0);
!
! We have the MCB system image in our memory, write it to disk.
!
    WCOR (2, .KERNEL_FILE);
!
! Free the KERNEL File, Since We Don't Need It Any Longer.
!
    FCOR (.KERNEL_FILE);
!
! Free the VALUES Block, Since We Don't Need It Any More Either.
!
    FREBLK (.VALUES);
!
! Tell user we are done
!
    OUTSTR (0, UPLIT (%ASCIZ'[Poof! MCB Conjuration Complete]'));
    PCRLF (0);
!
    CLOSE (1);
    END;					!OF VNP20
ROUTINE DEL_BLK (BLK_PTR, UNUSED) = 		!FREE ANY BLOCK OF MEMORY

!++
! FUNCITONAL DESCRIPTION:
!
!	CALLS FREBLK TO FREE ANY BLOCK OF MEMORY
!
! FORMAL PARAMETERS:
!
!	BLK_PTR - ADDRESS OF BLOCK TO FREE
!
! IMPLICIT INPUTS:
!
!	NONE
!
! IMPLICIT OUTPUTS:
!
!	NONE
!
! ROUTINE VALUE:
!
!	ALWAYS 0
!
! SIDE EFFECTS:
!
!	SOME MEMORY IS RETURNED TO FREE CORE
!--

    BEGIN

    MAP
	BLK_PTR : REF ANY_BLOCK;

    FREBLK (.BLK_PTR);
    0
    END;					!END OF DEL_BLK
ROUTINE DEL_DEV (DEV_PTR, UNUSED) = 		!FREE A DEV BLOCK

!++
! FUNCITONAL DESCRIPTION:
!
!	CALLS FREBLK TO FREE DEV AND FIND_CHAIN TO REMOVE CONTROLLERS ETC.
!
! FORMAL PARAMETERS:
!
!	DEV_PTR - ADDRESS OF DEV BLOCK TO FREE
!
! IMPLICIT INPUTS:
!
!	NONE
!
! IMPLICIT OUTPUTS:
!
!	NONE
!
! ROUTINE VALUE:
!
!	ALWAYS 0
!
! SIDE EFFECTS:
!
!	SOME MEMORY IS RETURNED TO FREE CORE
!--

    BEGIN

    MAP
	DEV_PTR : REF DEV_BLOCK;

    FND_CHAIN (.DEV_PTR [DEV_CTL], DEL_CTL, 0);
    DEL_PTRS (.DEV_PTR [DEV_CTL]);
    FREBLK (.DEV_PTR);
    0
    END;					!END OF DEL_DEV
ROUTINE DEL_CTL (CTL_PTR, UNUSED) = 		!FREE CTL BLOCKS

!++
! FUNCITONAL DESCRIPTION:
!
!	CALLS FREBLK TO FREE CTL BLOCK RELATED MEMORY
!
! FORMAL PARAMETERS:
!
!	CTL_PTR - ADDRESS OF CTL BLOCK TO FREE
!
! IMPLICIT INPUTS:
!
!	NONE
!
! IMPLICIT OUTPUTS:
!
!	NONE
!
! ROUTINE VALUE:
!
!	ALWAYS 0
!
! SIDE EFFECTS:
!
!	SOME MEMORY IS RETURNED TO FREE CORE
!--

    BEGIN

    MAP
	CTL_PTR : REF CTL_BLOCK;

    FND_CHAIN (.CTL_PTR [CTL_UNT], DEL_UNT, 0);	!FIND AND DELETE UNITS
    DEL_PTRS (.CTL_PTR [CTL_UNT]);
    FREBLK (.CTL_PTR);
    0
    END;					!END OF DEL_CTL
ROUTINE DEL_UNT (UNT_PTR, UNUSED) = 		!FREE UNT BLOCKS

!++
! FUNCITONAL DESCRIPTION:
!
!	CALLS FREBLK TO FREE UNT BLOCK RELATED MEMORY
!
! FORMAL PARAMETERS:
!
!	UNT_PTR - ADDRESS OF UNT BLOCK TO FREE
!
! IMPLICIT INPUTS:
!
!	NONE
!
! IMPLICIT OUTPUTS:
!
!	NONE
!
! ROUTINE VALUE:
!
!	ALWAYS 0
!
! SIDE EFFECTS:
!
!	SOME MEMORY IS RETURNED TO FREE CORE
!--

    BEGIN

    MAP
	UNT_PTR : REF UNT_BLOCK;

    FND_CHAIN (.UNT_PTR [UNT_TRB], DEL_BLK, 0);	!FIND AND DELETE TRIBUTARIES
    DEL_PTRS (.UNT_PTR [UNT_TRB]);
    FREBLK (.UNT_PTR);
    0
    END;					!END OF DEL_UNT
ROUTINE LOAD_TSKS (TSKB_PTR, PAR_BLK) = 	!LOAD TASKS INTO THE GEN PARTITION

!++
! FUNCTIONAL DESCRIPTION:
!
!	LOAD TASKS INTO THE GEN PARTITION.
!
! FORMAL PARAMETERS:
!
!	TSKB_PTR - POINTS TO THE VNPTSK BLOCK FOR THIS TASK
!	PAR_BLK - A VECTOR OF USEFUL LOCATIONS
!
! IMPLICIT INPUTS:
!
!	NONE
!
! IMPLICIT OUTPUTS:
!
!	NONE
!
! ROUTINE VALUE:
!
!	ALWAYS 0
!
! SIDE EFFECTS:
!
!	NONE
!
!--

    BEGIN

    BIND
	ROUTINE_NAME = UPLIT (%ASCIZ'LOAD_TSKS');

    MAP
	TSKB_PTR : REF VNPTSK_BLOCK,
	PAR_BLK : REF VECTOR;

    BIND
	GEN_PCB = PAR_BLK [0],
	KERNEL_FILE = PAR_BLK [1] : REF FILE_BLOCK,
	VALUES = PAR_BLK [2] : REF VNPVAL_BLOCK,
	FILE_CHAN = PAR_BLK [3];

    LOCAL
	TSK_FILE : REF FILE_BLOCK,
	TSK_LABEL : REF VECTOR [1024],
	TSK_BASE,
	TSK_TOP,
	TSK_SIZE,
	TSK_PCB,
	TSK_R50,
	TASK_NAME : VECTOR [CH$ALLOCATION (7)],
	PARTITION_NAME : VECTOR [CH$ALLOCATION (7)],
	PARTITION_BASE,
	MODU_PTR : REF MODU_BLOCK,
	CLK_ADDR;

    IF (.TSKB_PTR [TSK_TYPE] EQL TSK_TASK_TYPE)
    THEN
	BEGIN
!
! GET FILE FIRST
!

	IF ((TSK_FILE = GETBLK (FILE_TYP, FILE_LEN)) EQL 0)
	THEN
	    ERRMSG (0, 1, ROUTINE_NAME, 0, 0, 0, 0)
	ELSE
	    BEGIN
	    OUTSTR (0, UPLIT (%ASCIZ'[Loading Task '));
	    OUTSTR (0, TSKB_PTR [TSK_NAME]);
	    OUTSTR (0, UPLIT (%ASCIZ'	--> '));
	    CH$MOVE (LEN_TSK_NAME, CH$PTR (TSKB_PTR [TSK_NAME]), CH$PTR (TSK_FILE [FILE_NAME]));
	    RSTB (.FILE_CHAN, .TSK_FILE);
	    RCOR (.TSK_FILE, .FILE_CHAN, 32*2048);
	    TSK_LABEL = .TSK_FILE [FILE_LABEL];
	    TSK_BASE = .TSK_LABEL [L$BSA] + (.TSK_LABEL [L$BSA + 1]*256);
	    TSK_TOP = .TSK_LABEL [L$BHGV] + (.TSK_LABEL [L$BHGV + 1]*256);
	    TSK_SIZE = .TSK_TOP - .TSK_BASE + 1;
	    MODU_PTR = .TSK_FILE [FILE_MODU];
	    OUTSTR (0, MODU_PTR [MODU_NAME]);
	    OUTPUT (0, %C' ');
	    OUTSTR (0, MODU_PTR [MODU_IDENT]);
	    OUTSTR (0, UPLIT (%ASCIZ' ]'));
	    PCRLF (0);
!
! FORM THE PARTITION
!
	    begin
	    macro CH$LEN (PTR) = ch$diff (ch$find_ch (6, PTR, 0), PTR) %;
	    ch$wchar (0, CH$COPY (CH$LEN (CH$PTR (TSKB_PTR [TSK_NAME])),
		CH$PTR (TSKB_PTR [TSK_NAME]),
		%c' ', 6, CH$PTR (PARTITION_NAME)));
	    end;
	    PARTITION_BASE = .KERNEL_FILE [FILE_HWM] + 1;
	    TSK_PCB = M_PCB (.KERNEL_FILE, PARTITION_NAME, .GEN_PCB, .PARTITION_BASE,
		.PARTITION_BASE + .TSK_SIZE - 1, %O'004010', .VALUES [PS_SYS], 0, .VALUES);
!
! COPY THE TASK IN
!

	    INCR COUNTER FROM 0 TO .TSK_SIZE - 1 DO
		PUTBYT (.KERNEL_FILE, .PARTITION_BASE + .COUNTER, GETBYT (.TSK_FILE, .TSK_BASE + .COUNTER));

!
! BUILD THE TASK NAME
!
	    TSK_R50 = (.TSK_LABEL [L$BTSK]^16) + (.TSK_LABEL [L$BTSK + 1]^24) + (.TSK_LABEL [L$BTSK + 2]) + (
	    .TSK_LABEL [L$BTSK + 3]^8);
	    R50TOA (.TSK_R50, TASK_NAME);
!
! INSTALL THE TASK
!
	    INSTAL (.KERNEL_FILE, .TSK_FILE, TASK_NAME, .TSK_PCB, .VALUES);
!
! DETERMINE WHETHER THIS TASK REQUIRES A CLOCK QUEUE ENTRY AND BUILD ONE IF
!  APPROPRIATE.

	    IF (.TSKB_PTR [TSK_TIME] NEQ 0)
	    THEN
		BEGIN
		CLK_ADDR = ALOCB (.KERNEL_FILE, .VALUES [CLK_LGTH], 0, .VALUES);
		PUTWRD (.KERNEL_FILE, .CLK_ADDR + .VALUES [CLK_TIM],
		    GETWRD (.KERNEL_FILE, .VALUES [ABTIM]) + (.TSKB_PTR [TSK_TIME]*GETWRD (.KERNEL_FILE,
			.VALUES [TKPS])));
		PUTWRD (.KERNEL_FILE, .CLK_ADDR + .VALUES [CLK_RQT], .VALUES [CLK_SSHT]);
		PUTWRD (.KERNEL_FILE, .CLK_ADDR + .VALUES [CLK_TCB],
		    GETWRD (.KERNEL_FILE,
			.TSK_PCB + .VALUES [P_TCB]));
		PUTWRD (.KERNEL_FILE, .CLK_ADDR + .VALUES [CLK_LNK], GETWRD (.KERNEL_FILE, .VALUES [CLKHD]));
		PUTWRD (.KERNEL_FILE, .VALUES [CLKHD], .CLK_ADDR);
		END;

!
! FREE THE FILE ETC.
!
	    FCOR (.TSK_FILE);
	    END;

	END
    ELSE
	BEGIN
!
! GET THE DRIVER FILE
!

	IF ((TSK_FILE = GETBLK (FILE_TYP, FILE_LEN)) EQL 0)
	THEN
	    ERRMSG (0, 1, ROUTINE_NAME, 0, 0, 0, 0)
	ELSE
	    BEGIN
	    OUTSTR (0, UPLIT (%ASCIZ'[Loading Driver '));
	    OUTSTR (0, TSKB_PTR [TSK_NAME]);
	    OUTSTR (0, UPLIT (%ASCIZ':	--> '));
	    CH$COPY (LEN_DRV_NAME, CH$PTR (TSKB_PTR [TSK_NAME]), 3, CH$PTR (UPLIT (%ASCIZ'DRV')), 0, 6,
		CH$PTR (TSK_FILE [FILE_NAME]));
	    RSTB (.FILE_CHAN, .TSK_FILE);
	    RCOR (.TSK_FILE, .FILE_CHAN, 4*2048);
	    MODU_PTR = .TSK_FILE [FILE_MODU];
	    OUTSTR (0, MODU_PTR [MODU_NAME]);
	    OUTPUT (0, %C' ');
	    OUTSTR (0, MODU_PTR [MODU_IDENT]);
	    OUTSTR (0, UPLIT (%ASCIZ' ]'));
	    PCRLF (0);
	    LOADD (.KERNEL_FILE, .TSK_FILE, UPLIT (%ASCIZ'GEN   '), .GEN_PCB, .VALUES);
	    FCOR (.TSK_FILE)
	    END;

	END;

    0
    END;					!OF LOAD_TSKS
ROUTINE LOAD_MCBS (MCB_PTR, PAR_BLK) = 		!Load Processes into GEN partition

!++
! FUNCTIONAL DESCRIPTION:
!
!	Load MCB processes into GEN partition. The processes loaded are those
!	 indicated in the PDV$DF line in CETAB.MAC.
!
! FORMAL PARAMETERS:
!
!	MCB_PTR - Points to the VNPMCB block for this task
!	PAR_BLK - A vector of useful locations
!
! IMPLICIT INPUTS:
!
!	NONE
!
! IMPLICIT OUTPUTS:
!
!	NONE
!
! ROUTINE VALUE:
!
!	ALWAYS 0
!
! SIDE EFFECTS:
!
!	GEN partition is filled with processes.
!
!--

    BEGIN

    BIND
	ROUTINE_NAME = UPLIT (%ASCIZ'LOAD_MCBS');

    MAP
	MCB_PTR : REF VNPMCB_BLOCK,
	PAR_BLK : REF VECTOR;

    BIND
	GEN_PCB = PAR_BLK [0],
	KERNEL_FILE = PAR_BLK [1] : REF FILE_BLOCK,
	VALUES = PAR_BLK [2] : REF VNPVAL_BLOCK,
	FILE_CHAN = PAR_BLK [3];

    LOCAL
	TSK_FILE : REF FILE_BLOCK,
	TSK_LABEL : REF VECTOR [1024],
	TSK_BASE,
	TSK_TOP,
	TSK_SIZE,
	TSK_PCB,
	TSK_R50,
	TASK_NAME : VECTOR [CH$ALLOCATION (7)],
	PARTITION_NAME : VECTOR [CH$ALLOCATION (7)],
	PARTITION_BASE,
	MODU_PTR : REF MODU_BLOCK,
	DCB_ADDR,
	XXXNAME : VECTOR [CH$ALLOCATION (7)];

    IF (CH$NEQ (1, CH$PTR (MCB_PTR [PROCESS_NAME]), 1, CH$PTR (UPLIT (0)), 0))
    THEN
	BEGIN
!
! Get the file first
!

	IF ((TSK_FILE = GETBLK (FILE_TYP, FILE_LEN)) EQL 0)
	THEN
	    ERRMSG (0, 1, ROUTINE_NAME, 0, 0, 0, 0)
	ELSE
	    BEGIN
	    OUTSTR (0, UPLIT (%ASCIZ'[Loading Process '));
	    OUTSTR (0, MCB_PTR [PROCESS_NAME]);
	    OUTSTR (0, UPLIT (%ASCIZ'	--> '));
	    CH$MOVE (LEN_MCB_NAME, CH$PTR (MCB_PTR [PROCESS_NAME]), CH$PTR (TSK_FILE [FILE_NAME]));
	    RSTB (.FILE_CHAN, .TSK_FILE);
	    RCOR (.TSK_FILE, .FILE_CHAN, 10*2048);
	    TSK_LABEL = .TSK_FILE [FILE_LABEL];
	    TSK_BASE = .TSK_LABEL [L$BSA] + (.TSK_LABEL [L$BSA + 1]*256);
	    TSK_TOP = .TSK_LABEL [L$BHGV] + (.TSK_LABEL [L$BHGV + 1]*256);
	    TSK_SIZE = .TSK_TOP - .TSK_BASE + 1;
	    MODU_PTR = .TSK_FILE [FILE_MODU];
	    OUTSTR (0, MODU_PTR [MODU_NAME]);
	    OUTPUT (0, %C' ');
	    OUTSTR (0, MODU_PTR [MODU_IDENT]);
	    OUTSTR (0, UPLIT (%ASCIZ' ]'));
	    PCRLF (0);
!
! Form the partition
!
	    begin
	    macro CH$LEN (PTR) = ch$diff (ch$find_ch (4, PTR, 0), PTR) %;
	    ch$wchar (0, CH$COPY (3, CH$PTR (UPLIT (%ASCIZ'NT.')),
		CH$LEN (CH$PTR (MCB_PTR [PROCESS_NAME])), CH$PTR (MCB_PTR [PROCESS_NAME]),
		%c' ', 6, CH$PTR (PARTITION_NAME)));
	    end;
	    PARTITION_BASE = .KERNEL_FILE [FILE_HWM] + 1;
	    TSK_PCB = M_PCB (.KERNEL_FILE, PARTITION_NAME, .GEN_PCB, .PARTITION_BASE,
		.PARTITION_BASE + .TSK_SIZE - 1, %O'000000',
		.VALUES [PS_SYS] OR .VALUES [PS_COM] OR .VALUES [PS_NSF], 0, .VALUES);
!
! Copy the task into it
!

	    INCR COUNTER FROM 0 TO .TSK_SIZE - 1 DO
		PUTBYT (.KERNEL_FILE, .PARTITION_BASE + .COUNTER, GETBYT (.TSK_FILE, .TSK_BASE + .COUNTER));

!
! If the process supplies a device then load its' DCB/UCB/SCB structure and
! update UCBxxx.
!

	    IF (CH$NEQ (1, CH$PTR (MCB_PTR [DEVICE_NAME]), 1, CH$PTR (UPLIT (0)), 0))
	    THEN
		BEGIN
		DCB_ADDR = LD_DCB (.KERNEL_FILE, .FILE_CHAN, .TSK_PCB, .MCB_PTR [DEVICE_NAME], .VALUES);
!
! Store the address of the UCB in UCBxxx.
!
		CH$COPY (3, CH$PTR (UPLIT (%ASCIZ'UCB')), LEN_MCB_NAME, CH$PTR (MCB_PTR [PROCESS_NAME]), 0,
		    7, CH$PTR (XXXNAME));
		PUTWRD (.KERNEL_FILE, .VALUES [CE_DATA_BASE] + SYM_VAL (.VALUES [CE_DATA_FILE], XXXNAME, 0),
		    GETWRD (.KERNEL_FILE, .DCB_ADDR + .VALUES [D_UCB]));
		END;
!
! We used to store the PCB address in PCBxxx but for MCB V3.1 we don't
! need to do that so code has been commented out.
!
!	    CH$COPY (3, CH$PTR (UPLIT (%ASCIZ'PCB')), LEN_MCB_NAME, CH$PTR (MCB_PTR [PROCESS_NAME]), 0, 7,
!		CH$PTR (XXXNAME));
!	    PUTWRD (.KERNEL_FILE, .VALUES [CE_DATA_BASE] + SYM_VAL (.VALUES [CE_DATA_FILE], XXXNAME, 0),
!		.TSK_PCB);
!
!
! Free the file storage
!
	    FCOR (.TSK_FILE);
	    END;

	END;

    0
    END;					!OF LOAD_MCBS
END

ELUDOM
! Local Modes:
! Comment Column:36
! Comment Start:!
! Mode:Fundamental
! Auto Save Mode:2
! End: