Trailing-Edge
-
PDP-10 Archives
-
BB-R595B-SM_11-9-85
-
mcb/vnp36/mcbfnc.bli
There are 2 other files named mcbfnc.bli in the archive. Click here to see a list.
!NET:<DECNET20-V3P0.TKB-VNP.VNPV3>MCBFNC.BLI.162 13-Feb-81 14:16:19, Edit by SROBINSON
!NET:<DECNET20-V3P0.TKB-VNP.VNPV3>MCBFNC.BLI.160 10-Dec-80 11:50:07, Edit by SROBINSON
!<DECNET20-V3P0.TKB-VNP.VNPV3>MCBFNC.BLI.158, 26-Aug-80 13:12:53, Edit by SROBINSON
!<DECNET20-V3P0.TKB-VNP.VNPV3>MCBFNC.BLI.157, 25-Aug-80 14:44:48, Edit by SROBINSON
!<DECNET20-V3P0.TKB-VNP.VNPV3>MCBFNC.BLI.155, 21-Jul-80 07:47:31, Edit by SROBINSON
!<DECNET20-V3P0.TKB-VNP.VNPV3>MCBFNC.BLI.38, 3-Jul-80 09:28:27, Edit by SROBINSON
MODULE MCBFNC ( !MCB Related Functions
IDENT = 'X03020'
) =
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, VNP36
!
! ABSTRACT:
!
! This module contains all routines associated with MCB process database
! construction.
!
! ENVIRONMENT: TOPS-20 or TOPS-10 User Mode
!
! AUTHOR: Scott G. Robinson , CREATION DATE: 14-Apr-80
!
! MODIFIED BY:
!
! , : VERSION
! 01 - Change COMMLINK usage to LINE
! 02 - Add CTL$DF parameters
!--
!
! TABLE OF CONTENTS
!
FORWARD ROUTINE
LODMCB : NOVALUE,
LLC_LOADS,
DLC_LOADS : NOVALUE,
DDM_LOADS : NOVALUE,
BLOCK_LOAD : NOVALUE,
GET_VARIABLE,
NEXT_LIX,
MCEX : NOVALUE,
ALOC_POOL,
LD_DCB;
!
! INCLUDE FILES:
!
LIBRARY 'VNPLIB';
!
! MACROS:
!
! None
!
! EQUATED SYMBOLS:
!
LITERAL
TRUE = 1 EQL 1,
FALSE = 0 EQL 1,
DEBUG = FALSE;
!
! OWN STORAGE:
!
OWN
!
! Variables used by BLOCK_LOAD
!
CURBLK, !Current Allocated Block Addr
CURBAS, !Current Block Base Address
CURMAX, !Current Maximum Address
CURLIX, !Current Line Index
CURSLT : REF SLT_BLOCK, !Pointer to Current SLT
CURDEV : REF DEV_BLOCK, !Pointer to Current DEV
CURCTL : REF CTL_BLOCK, !Pointer to Current CTL
CURUNT : REF UNT_BLOCK, !Pointer to Current UNT
CURTRB : REF TRB_BLOCK; !Pointer to Current TRB
!
! EXTERNAL REFERENCES:
!
EXTERNAL ROUTINE
ALOCB, !Allocate some Executive Storage
DEACB, !Deallocate some Executive Storage
GETBLK, !Allocate a 'typed' block
FND_CHAIN, !Search a Chain
M_PCB, !Build a Partition Control Block
ERRMSG : NOVALUE, !Write an error message
ERROR : NOVALUE, !Write a fatal error message
GETWRD, !Get a word of PDP-11 Memory
PUTWRD : NOVALUE, !Write into a word of PDP-11 Memory
GETBYT, !Get a byte of PDP-11 Memory
PUTBYT : NOVALUE, !Write into a byte of PDP-11 Memory
OUTNUM : NOVALUE, !Output a Number
OUTPUT : NOVALUE, !Output a Character
OUTSTR : NOVALUE, !Output a String
R50TOA : NOVALUE, !Conver R50 to ASCII
PCRLF : NOVALUE, !Output a CR/LF
RCOR : NOVALUE, !Read a task's image
FCOR : NOVALUE, !Free the memory used by RCOR
RSTB : NOVALUE, !Read a task's symbol table
SYM_VAL, !Return a symbols value
LNKDCB : NOVALUE, !Link a DCB into executive
$CBOMG; !Convert Binary to Octal ASCII
GLOBAL ROUTINE LODMCB (KERNEL_FILE, GEN_PCB, FILE_CHAN, VALUES) : NOVALUE =
!++
! FUNCTIONAL DESCRIPTION:
!
! Load MCB process's data bases according to system configuration
!
! FORMAL PARAMETERS
!
! NONE.
!
! IMPLICIT INPUTS
!
! NONE.
!
! ROUTINE VALUE:
! COMPLETION CODES:
!
! NONE.
!
! SIDE EFFECTS:
!
! NONE.
!
!--
BEGIN
BIND
ROUTINE_NAME = UPLIT (%ASCIZ'LOAD_MCB');
MAP
KERNEL_FILE : REF FILE_BLOCK,
VALUES : REF VNPVAL_BLOCK;
LOCAL
PAR_BLK : VECTOR [4]; !Global Parameter Block
!
! Initialize Variables
!
CURBLK = 0; !Current Allocated Block Addr
CURBAS = 0; !Current Block Base Address
CURMAX = 0; !Current Maximum Address
CURLIX = 0; !Current Line Index
CURSLT = 0; !Pointer to Current SLT
CURDEV = 0; !Pointer to Current DEV
CURCTL = 0; !Pointer to Current CTL
CURUNT = 0; !Pointer to Current UNT
CURTRB = 0; !Pointer to Current TRB
!
KERNEL_FILE [FILE_HWM] = (.KERNEL_FILE [FILE_HWM] + 1) AND ( NOT 1);
!
! Start by loading the LLC data bases
!
PAR_BLK [0] = .GEN_PCB;
PAR_BLK [1] = .KERNEL_FILE;
PAR_BLK [2] = .VALUES;
PAR_BLK [3] = .FILE_CHAN;
FND_CHAIN (.VALUES [LLC_CHAIN], LLC_LOADS, PAR_BLK);
!
! Load the DLC data bases
!
DLC_LOADS (.KERNEL_FILE, .FILE_CHAN, .VALUES);
!
! Load the DDM data bases
!
DDM_LOADS (.KERNEL_FILE, .FILE_CHAN, .VALUES);
!
! We are done loading data base items, round up the high water mark
! of the KERNEL so that the database partition size can be set
! correctly.
!
KERNEL_FILE [FILE_HWM] = ((.KERNEL_FILE [FILE_HWM] + 64) AND ( NOT 63)) - 1;
!
END; ! of LODMCB
ROUTINE LLC_LOADS (LLC_PTR, PAR_BLK) =
!++
! FUNCTIONAL DESCRIPTION:
!
! Load the LLC Data Bases for an MCB.
!
! FORMAL PARAMETERS
!
! LLC_PTR = Pointer to LLC_BLOCK
! PAR_VECTOR = Pointer to Parameter Vector
!
! IMPLICIT INPUTS
!
! NONE.
!
! ROUTINE VALUE:
!
! Always 0, so as to scan all LLC blocks
!
! SIDE EFFECTS:
!
! NONE.
!
!--
BEGIN
BIND
ROUTINE_NAME = UPLIT (%ASCIZ'LLC_LOADS');
MAP
LLC_PTR : REF LLC_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
CB_ADDRESS,
DB_FILE : REF FILE_BLOCK,
DB_POINTER,
LB_POINTER,
MCB_NAME : VECTOR [CH$ALLOCATION (7)],
MODU_PTR : REF MODU_BLOCK,
PRIMARY_COMMAND,
XXXNAME : VECTOR [CH$ALLOCATION (7)];
!
! Tell someone what we are doing
!
OUTSTR (0, UPLIT (%ASCIZ'[Loading LLC Data Base for '));
OUTSTR (0, LLC_PTR [LLC_NAME]);
!
! Get data base file
!
IF ((DB_FILE = GETBLK (FILE_TYP, FILE_LEN)) EQL 0)
THEN
ERRMSG (0, 1, ROUTINE_NAME, 0, 0, 0, 0)
ELSE
BEGIN
!
! Build xxxLLC file name
!
CH$MOVE (LEN_MCB_NAME, CH$PTR (LLC_PTR [LLC_NAME]), CH$PTR (DB_FILE [FILE_NAME]));
CH$MOVE (3, CH$PTR (UPLIT (%ASCIZ'LLC')),
CH$FIND_CH (LEN_FILE_STRING, CH$PTR (DB_FILE [FILE_NAME]),
0));
RSTB (.FILE_CHAN, .DB_FILE);
RCOR (.DB_FILE, .FILE_CHAN, 8*2048);
!
! Printout Identification Information
!
R50TOA (GETWRD (.DB_FILE, 0), MCB_NAME);
CH$MOVE (4, CH$PTR (MCB_NAME, 3), CH$PTR (MCB_NAME));
OUTSTR (0, UPLIT (%ASCIZ' ('));
OUTSTR (0, MCB_NAME);
OUTPUT (0, %C' ');
OUTNUM (0, GETBYT (.DB_FILE, 2), 10, 0);
OUTPUT (0, %C'.');
OUTNUM (0, GETBYT (.DB_FILE, 3), 10, 0);
OUTSTR (0, UPLIT (%ASCIZ') --> '));
!
! Process Primary Load Block Command
!
DB_POINTER = 4;
PRIMARY_COMMAND = GETBYT (.DB_FILE, .DB_POINTER);
SELECTONE .PRIMARY_COMMAND OF
SET
[CMD_ALLOC_DB_DSR] :
CURBLK = ALOCB (.KERNEL_FILE, GETWRD (.DB_FILE, .DB_POINTER + 2), 0, .VALUES);
[CMD_ALLOC_DB_POOL] :
CURBLK = ALOC_POOL (.KERNEL_FILE, GETWRD (.DB_FILE, .DB_POINTER + 2), 0, .VALUES);
[OTHERWISE] :
;
TES;
CURBAS = (.CURBLK AND ( NOT 63));
CURMAX = .CURBLK + GETWRD (.DB_FILE, .DB_POINTER + 2);
!
! Process the Load Block associated with this Primary Request
!
LB_POINTER = GETWRD (.DB_FILE, .DB_POINTER + 4);
BLOCK_LOAD (.KERNEL_FILE, .DB_FILE, .LB_POINTER, .VALUES);
!
! Store data base address in LLCxxx
!
CH$COPY (3, CH$PTR (UPLIT (%ASCIZ'LLC')), LEN_MCB_NAME, CH$PTR (LLC_PTR [LLC_NAME]), 0, 7,
CH$PTR (XXXNAME));
CB_ADDRESS = .VALUES [CE_DATA_BASE] + SYM_VAL (.VALUES [CE_DATA_FILE], XXXNAME, 0);
PUTWRD (.KERNEL_FILE, .CB_ADDRESS, (IF (.CURBLK GEQ %O'120000') THEN .CURBAS<6, 12, 0> ELSE 0));
PUTWRD (.KERNEL_FILE, .CB_ADDRESS + 2,
(IF (.CURBLK GEQ %O'120000') THEN ((.CURBLK - .CURBAS) + %O'140000') ELSE .CURBLK));
!
! Printout Task information
!
MODU_PTR = .DB_FILE [FILE_MODU];
OUTSTR (0, MODU_PTR [MODU_NAME]);
OUTPUT (0, %C' ');
OUTSTR (0, MODU_PTR [MODU_IDENT]);
OUTSTR (0, UPLIT (%ASCIZ' ]'));
PCRLF (0);
FCOR (.DB_FILE);
END;
0
END; ! of LLC_LOADS
ROUTINE DLC_LOADS (KERNEL_FILE, FILE_CHAN, VALUES) : NOVALUE =
!++
! FUNCTIONAL DESCRIPTION:
!
! Load DLC Process Data Bases for each SLT in the MCB.
!
! FORMAL PARAMETERS
!
! KERNEL_FILE - System Image File Descriptor
! FILE_CHAN - Channel to use for I/O
! VALUES - Misc Data Items
!
! IMPLICIT INPUTS
!
! NONE.
!
! ROUTINE VALUE:
!
! NONE.
!
! SIDE EFFECTS:
!
! NONE.
!
!--
BEGIN
BIND
ROUTINE_NAME = UPLIT (%ASCIZ'DLC_LOADS');
MAP
KERNEL_FILE : REF FILE_BLOCK,
VALUES : REF VNPVAL_BLOCK;
LOCAL
CB_ADDRESS,
CTL_LENGTH,
DB_FILE : REF FILE_BLOCK,
DB_POINTER,
DB_VARIABLE_1,
DB_VARIABLE_2,
LB_POINTER,
MCB_NAME : VECTOR [CH$ALLOCATION (7)],
MODU_PTR : REF MODU_BLOCK,
PRIMARY_COMMAND,
TEMPORARY_PTR,
UNT_LENGTH,
XXXNAME : VECTOR [CH$ALLOCATION (7)];
!
! Start by initializing some of the data items
!
CURLIX = 0;
CURSLT = 0;
CURCTL = 0;
NEXT_LIX (VAR_CURRENT_CTL, .VALUES);
!
IF (.CURSLT NEQ 0)
THEN
DO
IF (.CURSLT [SLT_DLC] NEQ 0)
THEN
BEGIN
!
! Tell someone what we are doing
!
OUTSTR (0, UPLIT (%ASCIZ'[Loading '));
OUTSTR (0, CURSLT [SLT_DLC]);
OUTSTR (0, UPLIT (%ASCIZ' data base for LINE '));
OUTSTR (0, (IF (.CURSLT [SLT_DEV] NEQ 0) THEN CURSLT [SLT_DEV] ELSE CURSLT [SLT_DLC]));
OUTPUT (0, %C'-');
OUTNUM (0, .CURSLT [SLT_CTL], 10, 0);
OUTPUT (0, %C'-');
OUTNUM (0, .CURSLT [SLT_UNT], 10, 0);
!
! Get data base file
!
IF ((DB_FILE = GETBLK (FILE_TYP, FILE_LEN)) EQL 0)
THEN
ERRMSG (0, 1, ROUTINE_NAME, 0, 0, 0,
0)
ELSE
BEGIN
!
! Build xxxDLC file name
!
CH$MOVE (LEN_MCB_NAME, CH$PTR (CURSLT [SLT_DLC]), CH$PTR (DB_FILE [FILE_NAME]));
CH$MOVE (3, CH$PTR (UPLIT (%ASCIZ'DLC')),
CH$FIND_CH (LEN_FILE_STRING,
CH$PTR (DB_FILE [FILE_NAME]), 0));
RSTB (.FILE_CHAN, .DB_FILE);
RCOR (.DB_FILE, .FILE_CHAN, 4*2048);
!
! Printout Identification Information
!
R50TOA (GETWRD (.DB_FILE, 0), MCB_NAME);
CH$MOVE (4, CH$PTR (MCB_NAME, 3), CH$PTR (MCB_NAME));
OUTSTR (0, UPLIT (%ASCIZ' ('));
OUTSTR (0, MCB_NAME);
OUTPUT (0, %C' ');
OUTNUM (0, GETBYT (.DB_FILE, 2), 10, 0);
OUTPUT (0, %C'.');
OUTNUM (0, GETBYT (.DB_FILE, 3), 10, 0);
OUTSTR (0, UPLIT (%ASCIZ') --> '));
!
! Process Primary Load Block Command
!
DB_POINTER = 4;
PRIMARY_COMMAND = GETBYT (.DB_FILE, .DB_POINTER);
DB_VARIABLE_1 = GETBYT (.DB_FILE, .DB_POINTER + 1);
DB_VARIABLE_2 = 0;
SELECTONE .PRIMARY_COMMAND OF
SET
[CMD_ALLOC_DB_DSR, CMD_ALLOC_DB_POOL] :
BEGIN
CURBLK = (IF (.PRIMARY_COMMAND EQL CMD_ALLOC_DB_DSR) THEN ALOCB (.KERNEL_FILE,
GETWRD (.DB_FILE, .DB_POINTER + 2), 0, .VALUES) ELSE ALOC_POOL (
.KERNEL_FILE, GETWRD (.DB_FILE, .DB_POINTER + 2), 0, .VALUES));
CURBAS = (.CURBLK AND ( NOT 63));
CURMAX = .CURBLK + GETWRD (.DB_FILE, .DB_POINTER + 2);
!
! Process the Load Block associated with this Primary Request
!
LB_POINTER = GETWRD (.DB_FILE, .DB_POINTER + 4);
BLOCK_LOAD (.KERNEL_FILE, .DB_FILE, .LB_POINTER, .VALUES);
!
! Store data base address in DLCnnn
!
DO
BEGIN
CH$MOVE (3, CH$PTR (UPLIT (%ASCIZ'DLC')), CH$PTR (XXXNAME));
TEMPORARY_PTR = CH$PTR (XXXNAME, 3);
$CBOMG (TEMPORARY_PTR, .CURLIX, 0);
CH$WCHAR (0, .TEMPORARY_PTR);
CB_ADDRESS = .VALUES [CE_DATA_BASE] + SYM_VAL (.VALUES [CE_DATA_FILE],
XXXNAME, 0);
PUTWRD (.KERNEL_FILE, .CB_ADDRESS,
(IF (.CURBLK GEQ %O'120000') THEN .CURBAS<6, 12, 0> ELSE 0));
PUTWRD (.KERNEL_FILE, .CB_ADDRESS + 2,
(IF (.CURBLK GEQ %O'120000') THEN ((.CURBLK - .CURBAS) + %O'140000') ELSE
.CURBLK));
END
UNTIL NEXT_LIX (.DB_VARIABLE_1, .VALUES);
END;
[CMD_ALLOC_MUX_DSR, CMD_ALLOC_MUX_POOL] :
BEGIN
DB_VARIABLE_2 = GETBYT (.DB_FILE, .DB_POINTER + 2);
CTL_LENGTH = GETWRD (.DB_FILE, .DB_POINTER + 4);
UNT_LENGTH = GETWRD (.DB_FILE, .DB_POINTER + 8);
CURMAX = .CTL_LENGTH + (GET_VARIABLE (.DB_VARIABLE_2, .VALUES)*.UNT_LENGTH);
CURBLK = (IF (.PRIMARY_COMMAND EQL CMD_ALLOC_MUX_DSR) THEN ALOCB (.KERNEL_FILE,
.CURMAX, 0, .VALUES) ELSE ALOC_POOL (.KERNEL_FILE, .CURMAX, 0, .VALUES));
CURBAS = (.CURBLK AND ( NOT 63));
CURMAX = .CURMAX + .CURBLK;
!
! Load the Controller block
!
LB_POINTER = GETWRD (.DB_FILE, .DB_POINTER + 6);
BLOCK_LOAD (.KERNEL_FILE, .DB_FILE, .LB_POINTER, .VALUES);
!
! Load each unit's block
!
CURBLK = .CURBLK + .CTL_LENGTH;
LB_POINTER = GETWRD (.DB_FILE, .DB_POINTER + 10);
DECR DUMMY FROM GET_VARIABLE (.DB_VARIABLE_2, .VALUES) TO 1 DO
BEGIN
BLOCK_LOAD (.KERNEL_FILE, .DB_FILE, .LB_POINTER, .VALUES);
!
! Plug Addresses into Data Structures
!
DO
BEGIN
CH$MOVE (3, CH$PTR (UPLIT (%ASCIZ'DLC')), CH$PTR (XXXNAME));
TEMPORARY_PTR = CH$PTR (XXXNAME, 3);
$CBOMG (TEMPORARY_PTR, .CURLIX, 0);
CH$WCHAR (0, .TEMPORARY_PTR);
CB_ADDRESS = .VALUES [CE_DATA_BASE] + SYM_VAL (.VALUES [CE_DATA_FILE],
XXXNAME, 0);
PUTWRD (.KERNEL_FILE, .CB_ADDRESS,
(IF (.CURBLK GEQ %O'120000') THEN .CURBAS<6, 12, 0> ELSE 0));
PUTWRD (.KERNEL_FILE, .CB_ADDRESS + 2,
(IF (.CURBLK GEQ %O'120000') THEN ((.CURBLK - .CURBAS) + %O'140000')
ELSE .CURBLK));
END
UNTIL NEXT_LIX (.DB_VARIABLE_1, .VALUES);
CURBLK = .CURBLK + .UNT_LENGTH;
END;
END;
[OTHERWISE] :
;
TES;
!
! Printout Task information
!
MODU_PTR = .DB_FILE [FILE_MODU];
OUTSTR (0, MODU_PTR [MODU_NAME]);
OUTPUT (0, %C' ');
OUTSTR (0, MODU_PTR [MODU_IDENT]);
OUTSTR (0, UPLIT (%ASCIZ' ]'));
PCRLF (0);
FCOR (.DB_FILE);
END;
END
ELSE
NEXT_LIX (VAR_CURRENT_CTL, .VALUES)
WHILE (.CURLIX LEQ .VALUES [SLTNUM]);
END; ! of DLC_LOADS
ROUTINE DDM_LOADS (KERNEL_FILE, FILE_CHAN, VALUES) : NOVALUE =
!++
! FUNCTIONAL DESCRIPTION:
!
! Load DDM Process Data Bases for each SLT in the MCB.
!
! FORMAL PARAMETERS
!
! KERNEL_FILE - System Image File Descriptor
! FILE_CHAN - Channel to use for I/O
! VALUES - Misc Data Items
!
! IMPLICIT INPUTS
!
! NONE.
!
! ROUTINE VALUE:
!
! NONE.
!
! SIDE EFFECTS:
!
! NONE.
!
!--
BEGIN
BIND
ROUTINE_NAME = UPLIT (%ASCIZ'DDM_LOADS');
MAP
KERNEL_FILE : REF FILE_BLOCK,
VALUES : REF VNPVAL_BLOCK;
LOCAL
CB_ADDRESS,
CTL_LENGTH,
DB_FILE : REF FILE_BLOCK,
DB_POINTER,
DB_VARIABLE_1,
DB_VARIABLE_2,
LB_POINTER,
MCB_NAME : VECTOR [CH$ALLOCATION (7)],
MODU_PTR : REF MODU_BLOCK,
PRIMARY_COMMAND,
TEMPORARY_PTR,
UNT_LENGTH,
XXXNAME : VECTOR [CH$ALLOCATION (7)];
!
! Start by initializing some of the data items
!
CURLIX = 0;
CURSLT = 0;
CURCTL = 0;
NEXT_LIX (VAR_CURRENT_CTL, .VALUES);
!
IF (.CURSLT NEQ 0)
THEN
DO
IF (.CURSLT [SLT_DEV] NEQ 0)
THEN
BEGIN
!
! Tell someone what we are doing
!
OUTSTR (0, UPLIT (%ASCIZ'[Loading data base for LINE '));
OUTSTR (0, CURSLT [SLT_DEV]);
OUTPUT (0, %C'-');
OUTNUM (0, .CURSLT [SLT_CTL], 10, 0);
OUTPUT (0, %C'-');
OUTNUM (0, .CURSLT [SLT_UNT], 10, 0);
!
! Get data base file
!
IF ((DB_FILE = GETBLK (FILE_TYP, FILE_LEN)) EQL 0)
THEN
ERRMSG (0, 1, ROUTINE_NAME, 0, 0, 0,
0)
ELSE
BEGIN
!
! Build xxxDDM file name
!
CH$MOVE (LEN_MCB_NAME, CH$PTR (CURSLT [SLT_DEV]), CH$PTR (DB_FILE [FILE_NAME]));
CH$MOVE (3, CH$PTR (UPLIT (%ASCIZ'DDM')),
CH$FIND_CH (LEN_FILE_STRING,
CH$PTR (DB_FILE [FILE_NAME]), 0));
RSTB (.FILE_CHAN, .DB_FILE);
RCOR (.DB_FILE, .FILE_CHAN, 4*2048);
!
! Printout Identification Information
!
R50TOA (GETWRD (.DB_FILE, 0), MCB_NAME);
CH$MOVE (4, CH$PTR (MCB_NAME, 3), CH$PTR (MCB_NAME));
OUTSTR (0, UPLIT (%ASCIZ' ('));
OUTSTR (0, MCB_NAME);
OUTPUT (0, %C' ');
OUTNUM (0, GETBYT (.DB_FILE, 2), 10, 0);
OUTPUT (0, %C'.');
OUTNUM (0, GETBYT (.DB_FILE, 3), 10, 0);
OUTSTR (0, UPLIT (%ASCIZ') --> '));
!
! Process Primary Load Block Command
!
DB_POINTER = 4;
PRIMARY_COMMAND = GETBYT (.DB_FILE, .DB_POINTER);
DB_VARIABLE_1 = GETBYT (.DB_FILE, .DB_POINTER + 1);
DB_VARIABLE_2 = 0;
SELECTONE .PRIMARY_COMMAND OF
SET
[CMD_ALLOC_DB_DSR, CMD_ALLOC_DB_POOL] :
BEGIN
CURBLK = (IF (.PRIMARY_COMMAND EQL CMD_ALLOC_DB_DSR) THEN ALOCB (.KERNEL_FILE,
GETWRD (.DB_FILE, .DB_POINTER + 2), 0, .VALUES) ELSE ALOC_POOL (
.KERNEL_FILE, GETWRD (.DB_FILE, .DB_POINTER + 2), 0, .VALUES));
CURBAS = (.CURBLK AND ( NOT 63));
CURMAX = .CURBLK + GETWRD (.DB_FILE, .DB_POINTER + 2);
!
! Process the Load Block associated with this Primary Request
!
LB_POINTER = GETWRD (.DB_FILE, .DB_POINTER + 4);
BLOCK_LOAD (.KERNEL_FILE, .DB_FILE, .LB_POINTER, .VALUES);
!
! Store data base address in DDMnnn
!
DO
BEGIN
CH$MOVE (3, CH$PTR (UPLIT (%ASCIZ'DDM')), CH$PTR (XXXNAME));
TEMPORARY_PTR = CH$PTR (XXXNAME, 3);
$CBOMG (TEMPORARY_PTR, .CURLIX, 0);
CH$WCHAR (0, .TEMPORARY_PTR);
CB_ADDRESS = .VALUES [CE_DATA_BASE] + SYM_VAL (.VALUES [CE_DATA_FILE],
XXXNAME, 0);
PUTWRD (.KERNEL_FILE, .CB_ADDRESS,
(IF (.CURBLK GEQ %O'120000') THEN .CURBAS<6, 12, 0> ELSE 0));
PUTWRD (.KERNEL_FILE, .CB_ADDRESS + 2,
(IF (.CURBLK GEQ %O'120000') THEN ((.CURBLK - .CURBAS) + %O'140000') ELSE
.CURBLK));
END
UNTIL NEXT_LIX (.DB_VARIABLE_1, .VALUES);
END;
[CMD_ALLOC_MUX_DSR, CMD_ALLOC_MUX_POOL] :
BEGIN
DB_VARIABLE_2 = GETBYT (.DB_FILE, .DB_POINTER + 2);
CTL_LENGTH = GETWRD (.DB_FILE, .DB_POINTER + 4);
UNT_LENGTH = GETWRD (.DB_FILE, .DB_POINTER + 8);
CURMAX = .CTL_LENGTH + (GET_VARIABLE (.DB_VARIABLE_2, .VALUES)*.UNT_LENGTH);
CURBLK = (IF (.PRIMARY_COMMAND EQL CMD_ALLOC_MUX_DSR) THEN ALOCB (.KERNEL_FILE,
.CURMAX, 0, .VALUES) ELSE ALOC_POOL (.KERNEL_FILE, .CURMAX, 0, .VALUES));
CURBAS = (.CURBLK AND ( NOT 63));
CURMAX = .CURMAX + .CURBLK;
!
! Load the Controller block
!
LB_POINTER = GETWRD (.DB_FILE, .DB_POINTER + 6);
BLOCK_LOAD (.KERNEL_FILE, .DB_FILE, .LB_POINTER, .VALUES);
!
! Load each unit's block
!
CURBLK = .CURBLK + .CTL_LENGTH;
LB_POINTER = GETWRD (.DB_FILE, .DB_POINTER + 10);
DECR DUMMY FROM GET_VARIABLE (.DB_VARIABLE_2, .VALUES) TO 1 DO
BEGIN
BLOCK_LOAD (.KERNEL_FILE, .DB_FILE, .LB_POINTER, .VALUES);
!
! Plug Addresses into Data Structures
!
DO
BEGIN
CH$MOVE (3, CH$PTR (UPLIT (%ASCIZ'DDM')), CH$PTR (XXXNAME));
TEMPORARY_PTR = CH$PTR (XXXNAME, 3);
$CBOMG (TEMPORARY_PTR, .CURLIX, 0);
CH$WCHAR (0, .TEMPORARY_PTR);
CB_ADDRESS = .VALUES [CE_DATA_BASE] + SYM_VAL (.VALUES [CE_DATA_FILE],
XXXNAME, 0);
PUTWRD (.KERNEL_FILE, .CB_ADDRESS,
(IF (.CURBLK GEQ %O'120000') THEN .CURBAS<6, 12, 0> ELSE 0));
PUTWRD (.KERNEL_FILE, .CB_ADDRESS + 2,
(IF (.CURBLK GEQ %O'120000') THEN ((.CURBLK - .CURBAS) + %O'140000')
ELSE .CURBLK));
END
UNTIL NEXT_LIX (.DB_VARIABLE_1, .VALUES);
CURBLK = .CURBLK + .UNT_LENGTH;
END;
END;
[OTHERWISE] :
;
TES;
!
! Printout Task information
!
MODU_PTR = .DB_FILE [FILE_MODU];
OUTSTR (0, MODU_PTR [MODU_NAME]);
OUTPUT (0, %C' ');
OUTSTR (0, MODU_PTR [MODU_IDENT]);
OUTSTR (0, UPLIT (%ASCIZ' ]'));
PCRLF (0);
FCOR (.DB_FILE);
END;
END
ELSE
NEXT_LIX (VAR_CURRENT_CTL, .VALUES)
WHILE (.CURLIX LEQ .VALUES [SLTNUM]);
END; ! of DDM_LOADS
ROUTINE BLOCK_LOAD (KERNEL_FILE, DB_FILE, LB_POINTER, VALUES) : NOVALUE =
!++
! FUNCTIONAL DESCRIPTION:
!
! Process Data Base Load Blocks actually constructing the data base
! in the Kernel_File.
!
! FORMAL PARAMETERS
!
! KERNEL_FILE - RSX Kernel File
! DB_FILE - Process Data Base File
! LB_POINTER - Pointer to Load Block in DB_FILE
! VALUES - Misc. Important Locations for VNP
!
! IMPLICIT INPUTS
!
! NONE.
!
! ROUTINE VALUE:
!
! NONE.
!
! SIDE EFFECTS:
!
! Can call itself recursively!
!
!--
BEGIN
BIND
ROUTINE_NAME = UPLIT (%ASCIZ'BLOCK_LOAD');
MAP
KERNEL_FILE : REF FILE_BLOCK,
DB_FILE : REF FILE_BLOCK,
VALUES : REF VNPVAL_BLOCK;
LOCAL
CB_ADDRESS, !Physical Address of current memory block
CB_LENGTH,
CB_SAVE_BASE, !Save location for Current Block Base
CB_SAVE_MAX, !Save location for Maximum Extent of block
CB_SAVE, !Save location for current block pointer
LB_ADDRESS,
LB_COMMAND, !Current command
LB_LENGTH,
LB_PC, !Pointer to current command word
LB_VARIABLE, !Current Variable from command
FATAL_ERROR; !Aborts processing on error
!
! Initialize processing loop
!
FATAL_ERROR = FALSE;
LB_PC = .LB_POINTER;
CB_SAVE = .CURBLK;
CB_SAVE_BASE = .CURBAS;
CB_SAVE_MAX = .CURMAX;
DO ! Main Processing Loop
BEGIN
LB_COMMAND = GETBYT (.DB_FILE, .LB_PC);
LB_VARIABLE = GETBYT (.DB_FILE, .LB_PC + 1);
LB_PC = .LB_PC + 2;
IF DEBUG
THEN
BEGIN
PCRLF (0);
OUTSTR (0, UPLIT (%ASCIZ'Command, Variable # = '));
OUTNUM (0, .LB_COMMAND, 8, 0);
OUTPUT (0, %C',');
OUTNUM (0, .LB_VARIABLE, 8, 0);
END;
SELECTONE .LB_COMMAND OF
SET
[CMD_END] :
;
[CMD_MOVE_WORD] :
BEGIN
CB_ADDRESS = .CURBLK + GETWRD (.DB_FILE, .LB_PC);
PUTWRD (.KERNEL_FILE, .CB_ADDRESS, GET_VARIABLE (.LB_VARIABLE, .VALUES));
LB_PC = .LB_PC + 2;
END;
[CMD_MOVE_BYTE] :
BEGIN
CB_ADDRESS = .CURBLK + GETWRD (.DB_FILE, .LB_PC);
PUTBYT (.KERNEL_FILE, .CB_ADDRESS, GET_VARIABLE (.LB_VARIABLE, .VALUES));
LB_PC = .LB_PC + 2;
END;
[CMD_ADD_WORD] :
BEGIN
CB_ADDRESS = .CURBLK + GETWRD (.DB_FILE, .LB_PC);
PUTWRD (.KERNEL_FILE, .CB_ADDRESS,
GETWRD (.KERNEL_FILE, .CB_ADDRESS) + GET_VARIABLE (.LB_VARIABLE, .VALUES));
LB_PC = .LB_PC + 2;
END;
[CMD_ADD_BYTE] :
BEGIN
CB_ADDRESS = .CURBLK + GETWRD (.DB_FILE, .LB_PC);
PUTBYT (.KERNEL_FILE, .CB_ADDRESS,
GETBYT (.KERNEL_FILE, .CB_ADDRESS) + GET_VARIABLE (.LB_VARIABLE, .VALUES));
LB_PC = .LB_PC + 2;
END;
[CMD_MOVE_TEXT] :
BEGIN
CB_ADDRESS = .CURBLK + GETWRD (.DB_FILE, .LB_PC);
LB_LENGTH = GETWRD (.DB_FILE, .LB_PC + 2);
LB_ADDRESS = GETWRD (.DB_FILE, .LB_PC + 4);
IF ((.CB_ADDRESS + .LB_LENGTH) GTR .CURMAX)
THEN
ERRMSG (0, 25, ROUTINE_NAME,
.CB_ADDRESS + .LB_LENGTH, DB_FILE [FILE_NAME], 0, 0);
IF (.LB_LENGTH GTR 0)
THEN
INCR BYTE_NUMBER FROM 0 TO .LB_LENGTH - 1 DO
PUTBYT (.KERNEL_FILE, .CB_ADDRESS + .BYTE_NUMBER,
GETBYT (.DB_FILE,
.LB_ADDRESS + .BYTE_NUMBER));
LB_PC = .LB_PC + 6;
END;
[CMD_VERIFY_VALUES] :
BEGIN
IF (GETWRD (.DB_FILE, .LB_PC) NEQU GETWRD (.DB_FILE, .LB_PC + 2))
THEN
BEGIN
PCRLF (0);
OUTSTR (0, UPLIT (%ASCIZ'? Database Verification Error, Value 1='));
OUTNUM (0, GETWRD (.DB_FILE, .LB_PC), 8, 0);
OUTSTR (0, UPLIT (%ASCIZ', Value 2 ='));
OUTNUM (0, GETWRD (.DB_FILE, .LB_PC + 2), 8, 0);
FATAL_ERROR = TRUE;
END;
LB_PC = .LB_PC + 4;
END;
[CMD_ALLOC_DSR] :
BEGIN
CB_LENGTH = GETWRD (.DB_FILE, .LB_PC + 2);
CB_ADDRESS = ALOCB (.KERNEL_FILE, .CB_LENGTH, 0, .VALUES);
PUTWRD (.KERNEL_FILE, .CURBLK + GETWRD (.DB_FILE, .LB_PC), .CB_ADDRESS);
CURMAX = .CB_ADDRESS + .CB_LENGTH;
CURBLK = .CB_ADDRESS;
CURBAS = (.CURBLK AND ( NOT 63));
IF ((LB_ADDRESS = GETWRD (.DB_FILE, .LB_PC + 4)) NEQ 0)
THEN
BLOCK_LOAD (.KERNEL_FILE,
.DB_FILE, .LB_ADDRESS, .VALUES);
CURBLK = .CB_SAVE;
CURBAS = .CB_SAVE_BASE;
CURMAX = .CB_SAVE_MAX;
LB_PC = .LB_PC + 6;
END;
[CMD_ALLOC_POOL] :
BEGIN
CB_LENGTH = GETWRD (.DB_FILE, .LB_PC + 2);
CB_ADDRESS = ALOC_POOL (.KERNEL_FILE, .CB_LENGTH, 0, .VALUES);
PUTWRD (.KERNEL_FILE, .CURBLK + GETWRD (.DB_FILE, .LB_PC), .CB_ADDRESS<6, 12, 0>);
PUTWRD (.KERNEL_FILE, .CURBLK + GETWRD (.DB_FILE, .LB_PC) + 2,
((.CB_ADDRESS AND 63) + %O'140000'));
CURMAX = .CB_ADDRESS + .CB_LENGTH;
CURBLK = .CB_ADDRESS;
CURBAS = (.CURBLK AND ( NOT 63));
IF ((LB_ADDRESS = GETWRD (.DB_FILE, .LB_PC + 4)) NEQ 0)
THEN
BLOCK_LOAD (.KERNEL_FILE,
.DB_FILE, .LB_ADDRESS, .VALUES);
CURBLK = .CB_SAVE;
CURBAS = .CB_SAVE_BASE;
CURMAX = .CB_SAVE_MAX;
LB_PC = .LB_PC + 6;
END;
[OTHERWISE] :
FATAL_ERROR = TRUE;
TES;
END
UNTIL ((.LB_COMMAND EQL CMD_END) OR .FATAL_ERROR);
IF (.FATAL_ERROR) THEN ERROR (UPLIT (%ASCIZ'Fatal Database Format Error -- BLOCK_LOAD'));
END; ! of BLOCK_LOAD
ROUTINE GET_VARIABLE (VAR_NUMBER, VALUES) =
!++
! FUNCTIONAL DESCRIPTION:
!
! Return the value of a Load Block Variable
! to the caller.
!
! FORMAL PARAMETERS
!
! VAR_NUMBER - the variable number to return
! VALUES - Misc info maintained by VNP
!
! IMPLICIT INPUTS
!
! NONE.
!
! ROUTINE VALUE:
!
! The variable's contents or 0.
!
! SIDE EFFECTS:
!
! NONE.
!
!--
BEGIN
BIND
ROUTINE_NAME = UPLIT (%ASCIZ'GET_LOAD_BLOCK_VARIABLES');
MAP
VALUES : REF VNPVAL_BLOCK;
LOCAL
RESULT;
RESULT = 0;
SELECTONE .VAR_NUMBER OF
SET
[VAR_CURRENT_ADDRESS] :
IF (.CURBLK LSS %O'120000') THEN RESULT = .CURBLK ELSE RESULT = (.CURBLK - .CURBAS) + %O'140000';
[VAR_CURRENT_LIX] :
RESULT = .CURLIX;
[VAR_CURRENT_CTL] :
IF .CURSLT NEQ 0 THEN RESULT = .CURSLT [SLT_CTL];
[VAR_CURRENT_UNT] :
IF .CURSLT NEQ 0 THEN RESULT = .CURSLT [SLT_UNT];
[VAR_CURRENT_TRB] :
IF .CURSLT NEQ 0 THEN RESULT = .CURSLT [SLT_TRB];
[VAR_NUMBER_SLTS] :
RESULT = .VALUES [SLTNUM];
[VAR_NUMBER_CTLS] :
IF .CURDEV NEQ 0 THEN RESULT = .CURDEV [DEV_NUM_OF_CTLS];
[VAR_NUMBER_UNTS] :
IF .CURCTL NEQ 0 THEN RESULT = .CURCTL [CTL_NUM_OF_UNTS];
[VAR_NUMBER_TRBS] :
IF .CURUNT NEQ 0 THEN RESULT = .CURUNT [UNT_NUM_OF_TRBS];
[VAR_CTL_CHARS_0 TO VAR_CTL_CHARS_7] :
IF .CURCTL NEQ 0
THEN
CASE .VAR_NUMBER FROM VAR_CTL_CHARS_0 TO VAR_CTL_CHARS_7 OF
SET
[VAR_CTL_CHARS_0] :
RESULT = .CURCTL [CTL_PAR_0];
[VAR_CTL_CHARS_1] :
RESULT = .CURCTL [CTL_PAR_1];
[VAR_CTL_CHARS_2] :
RESULT = .CURCTL [CTL_PAR_2];
[VAR_CTL_CHARS_3] :
RESULT = .CURCTL [CTL_PAR_3];
[VAR_CTL_CHARS_4] :
RESULT = .CURCTL [CTL_PAR_4];
[VAR_CTL_CHARS_5] :
RESULT = .CURCTL [CTL_PAR_5];
[VAR_CTL_CHARS_6] :
RESULT = .CURCTL [CTL_PAR_6];
[VAR_CTL_CHARS_7] :
RESULT = .CURCTL [CTL_PAR_7];
TES;
[VAR_UNT_CHARS_0 TO VAR_UNT_CHARS_7] :
IF .CURUNT NEQ 0
THEN
CASE .VAR_NUMBER FROM VAR_UNT_CHARS_0 TO VAR_UNT_CHARS_7 OF
SET
[VAR_UNT_CHARS_0] :
RESULT = .CURUNT [UNT_PAR_0];
[VAR_UNT_CHARS_1] :
RESULT = .CURUNT [UNT_PAR_1];
[VAR_UNT_CHARS_2] :
RESULT = .CURUNT [UNT_PAR_2];
[VAR_UNT_CHARS_3] :
RESULT = .CURUNT [UNT_PAR_3];
[VAR_UNT_CHARS_4] :
RESULT = .CURUNT [UNT_PAR_4];
[VAR_UNT_CHARS_5] :
RESULT = .CURUNT [UNT_PAR_5];
[VAR_UNT_CHARS_6] :
RESULT = .CURUNT [UNT_PAR_6];
[VAR_UNT_CHARS_7] :
RESULT = .CURUNT [UNT_PAR_7];
TES;
[VAR_TRB_CHARS_0 TO VAR_TRB_CHARS_7] :
IF .CURTRB NEQ 0
THEN
CASE .VAR_NUMBER FROM VAR_TRB_CHARS_0 TO VAR_TRB_CHARS_7 OF
SET
[VAR_TRB_CHARS_0] :
RESULT = .CURTRB [TRB_PAR_0];
[VAR_TRB_CHARS_1] :
RESULT = .CURTRB [TRB_PAR_1];
[VAR_TRB_CHARS_2] :
RESULT = .CURTRB [TRB_PAR_2];
[VAR_TRB_CHARS_3] :
RESULT = .CURTRB [TRB_PAR_3];
[VAR_TRB_CHARS_4] :
RESULT = .CURTRB [TRB_PAR_4];
[VAR_TRB_CHARS_5] :
RESULT = .CURTRB [TRB_PAR_5];
[VAR_TRB_CHARS_6] :
RESULT = .CURTRB [TRB_PAR_6];
[VAR_TRB_CHARS_7] :
RESULT = .CURTRB [TRB_PAR_7];
TES;
[OTHERWISE] :
RESULT = 0;
TES;
IF DEBUG
THEN
BEGIN
PCRLF (0);
OUTSTR (0, UPLIT (%ASCIZ' Variable #'));
OUTNUM (0, .VAR_NUMBER, 8, 0);
OUTSTR (0, UPLIT (%ASCIZ' = '));
OUTNUM (0, .RESULT, 8, 0);
END;
.RESULT
END; ! of GET_VARIABLE
ROUTINE NEXT_LIX (VAR_NUMBER, VALUES) =
!++
! FUNCTIONAL DESCRIPTION:
!
! Keep the BLOCK_LOAD data base up to date based upon the current
! system line. Return an indication if data items associated with
! the CTL, UNT, or TRB parameters have been changed.
!
! FORMAL PARAMETERS
!
! VAR_NUMBER - the Variable Set to return indication on
! VALUES - Misc info maintained by VNP
!
! IMPLICIT INPUTS
!
! NONE.
!
! ROUTINE VALUE:
!
! TRUE - if the set of parameters for VAR_NUMBER have changed or no
! next line exists.
! FALSE - otherwise
!
! SIDE EFFECTS:
!
! NONE.
!
!--
BEGIN
BIND
ROUTINE_NAME = UPLIT (%ASCIZ'NEXT_LIX');
MAP
VALUES : REF VNPVAL_BLOCK;
LOCAL
NEW_DEV : REF DEV_BLOCK,
NEW_CTL : REF CTL_BLOCK,
NEW_UNT : REF UNT_BLOCK,
NEW_TRB : REF TRB_BLOCK,
RESULT,
TEMP_LIX;
!
! These set of support routines allow for searching VNP's data structures
! for the data items we want.
!
ROUTINE SEL_SLT (SLT_PTR, LIX_NUM) =
BEGIN
MAP
SLT_PTR : REF SLT_BLOCK;
IF ((.LIX_NUM = ..LIX_NUM - 1) LEQ 0) THEN .SLT_PTR ELSE 0
END;
!
ROUTINE SEL_DEV (DEV_PTR, DEV_NAM) =
BEGIN
MAP
DEV_PTR : REF DEV_BLOCK;
IF (CH$EQL (3, CH$PTR (DEV_PTR [DEV_NAME]), 3, CH$PTR (.DEV_NAM))) THEN .DEV_PTR ELSE 0
END;
!
ROUTINE SEL_CTL (CTL_PTR, CTL_NUM) =
BEGIN
MAP
CTL_PTR : REF CTL_BLOCK;
IF (.CTL_PTR [CTL_CONT] EQL .CTL_NUM) THEN .CTL_PTR ELSE 0
END;
!
ROUTINE SEL_UNT (UNT_PTR, UNT_NUM) =
BEGIN
MAP
UNT_PTR : REF UNT_BLOCK;
IF (.UNT_PTR [UNT_UNIT] EQL .UNT_NUM) THEN .UNT_PTR ELSE 0
END;
!
ROUTINE SEL_TRB (TRB_PTR, TRB_NUM) =
BEGIN
MAP
TRB_PTR : REF TRB_BLOCK;
IF (.TRB_PTR [TRB_LADDR] EQL .TRB_NUM) THEN .TRB_PTR ELSE 0
END;
!
! The start of NEXT_LIX
!-
!
! Setup default new values for the next SLT
!
NEW_DEV = 0;
NEW_CTL = 0;
NEW_UNT = 0;
NEW_TRB = 0;
RESULT = TRUE; !Default response is TRUE
!
! Get next SLT based upon line index and setup pointers to it's associated
! data structures. Upon completion, RESULT will be TRUE if an
! important change occured otherwise it will be FALSE.
!
CURLIX = .CURLIX + 1; !Update the Line Index
TEMP_LIX = .CURLIX; !Used to find correct LIX
CURSLT = FND_CHAIN (.VALUES [SLT_CHAIN], SEL_SLT, TEMP_LIX);
IF (.CURSLT NEQ 0)
THEN
BEGIN
NEW_DEV = FND_CHAIN (.VALUES [DEV_CHAIN], SEL_DEV,
(IF (.CURSLT [SLT_DEV] NEQ 0) THEN CURSLT [SLT_DEV] ELSE CURSLT [SLT_DLC]));
IF (.NEW_DEV NEQ 0)
THEN
BEGIN
NEW_CTL = FND_CHAIN (.NEW_DEV [DEV_CTL], SEL_CTL, .CURSLT [SLT_CTL]);
IF (.NEW_CTL NEQ 0)
THEN
BEGIN
NEW_UNT = FND_CHAIN (.NEW_CTL [CTL_UNT], SEL_UNT, .CURSLT [SLT_UNT]);
IF (.NEW_UNT NEQ 0)
THEN
BEGIN
NEW_TRB = FND_CHAIN (.NEW_UNT [UNT_TRB], SEL_TRB, .CURSLT [SLT_TRB]);
END;
END;
END;
END;
IF ((.NEW_CTL NEQ .CURCTL) AND (.VAR_NUMBER EQL VAR_CURRENT_CTL))
THEN
RESULT = TRUE
ELSE
IF ((.NEW_UNT NEQ .CURUNT) AND (.VAR_NUMBER EQL VAR_CURRENT_UNT))
THEN
RESULT = TRUE
ELSE
IF ((.NEW_TRB NEQ .CURTRB) AND (.VAR_NUMBER EQL VAR_CURRENT_TRB))
THEN
RESULT = TRUE
ELSE
RESULT = FALSE;
CURDEV = .NEW_DEV;
CURCTL = .NEW_CTL;
CURUNT = .NEW_UNT;
CURTRB = .NEW_TRB;
.RESULT
END; ! of NEXT_LIX
GLOBAL ROUTINE MCEX (KERNEL_FILE, CEX_FILE, VALUES) : NOVALUE = !MERGE THE COMM EXEC
!++
! FUNCTIONAL DESCRIPTION:
!
! MERGE THE COMM EXEC INTO THE KERNEL. THIS REQUIRES SETTING
! UP A COMMON PARTITION. INFORMATION ON THE PARTITION IS
! TAKEN FROM THE COMM EXEC'S LABEL AND HEADER BLOCKS,
! AND FROM CETAB.MAC.
!
! FORMAL PARAMETERS:
!
! KERNEL_FILE - FILE BLOCK FOR THE KERNEL
! CEX_FILE - FILE BLOCK FOR THE COMM EXEC
! VALUES - VALUES READ FROM CETAB.MAC AND THE SYMBOL TABLES
!
! IMPLICIT INPUTS:
!
! NONE
!
! IMPLICIT OUTPUTS:
!
! NONE
!
! ROUTINE VALUE:
!
! NONE
!
! SIDE EFFECTS
!
! CHANGES THE CORE IMAGE
!
!--
BEGIN
BIND
ROUTINE_NAME = UPLIT (%ASCIZ'MCEX');
MAP
KERNEL_FILE : REF FILE_BLOCK,
CEX_FILE : REF FILE_BLOCK,
VALUES : REF VNPVAL_BLOCK;
LOCAL
PCB_ADDR,
CEX_LABEL : REF VECTOR [1024],
KERNEL_LABEL : REF VECTOR [1024],
HIGH_EXEC_ADDR,
FLAGS,
CEX_BASE,
CEX_TOP,
TEMP1,
TEMP2,
TEMP3,
R50VAL : VECTOR [4];
CEX_LABEL = .CEX_FILE [FILE_LABEL];
KERNEL_LABEL = .KERNEL_FILE [FILE_LABEL];
!
! FIND THE FLAGS FROM THIS CORE IMAGE, AND CHECK THAT ALL NECESSARY
! OPTIONS AND NO BAD OPTIONS ARE SELECTED.
!
FLAGS = GETWRD (.KERNEL_FILE, .VALUES [FMASK]);
!
! VERIFY THAT FE_EXT (22-BIT ADDRESSING) IS CLEAR.
! ALSO, FE_CEX (COMM EXEC LOADED) SHOULD BE CLEAR.
!
IF ((.FLAGS AND .VALUES [FE_EXT]) NEQ 0)
THEN
ERRMSG (0, 28, ROUTINE_NAME, KERNEL_FILE [FILE_NAME], 0, 0,
0);
IF ((.FLAGS AND .VALUES [FE_CEX]) NEQ 0)
THEN
ERRMSG (0, 30, ROUTINE_NAME, KERNEL_FILE [FILE_NAME], 0, 0,
0);
!
! SINCE WE HAVE NOT REALLY CHECKED OUT PLAS SUPPORT, DONT ALLOW IT.
!
IF ((.FLAGS AND .VALUES [FE_PLA]) NEQ 0)
THEN
ERRMSG (0, 33, ROUTINE_NAME, KERNEL_FILE [FILE_NAME], 0, 0,
0);
!
! EXTEND THE EXECUTIVE POOL TO THE BOTTOM OF THE COMM EXEC PARTITION
!
CEX_BASE = .CEX_LABEL [L$BSA] + (256*.CEX_LABEL [L$BSA + 1]);
CEX_TOP = .CEX_LABEL [L$BHGV] + (256*.CEX_LABEL [L$BHGV + 1]);
IF ((.FLAGS AND .VALUES [FE_EXV]) EQL 0) THEN HIGH_EXEC_ADDR = 16*2048 ELSE HIGH_EXEC_ADDR = 20*2048;
IF (.CEX_TOP GTR .HIGH_EXEC_ADDR)
THEN
ERRMSG (0, 31, ROUTINE_NAME, CEX_FILE [FILE_NAME], .CEX_TOP,
.HIGH_EXEC_ADDR, 0);
!
! ROUND THE BASE OF THE EXEC STORAGE POOL UP TO A MULTIPLE OF 4 BYTES
!
TEMP1 = GETWRD (.KERNEL_FILE, .VALUES [CRAVL]); !BASE OF POOL
TEMP2 = GETWRD (.KERNEL_FILE, .TEMP1 + 2); !CURRENT LENGTH OF POOL
PUTWRD (.KERNEL_FILE, .TEMP1 + 2, 0); !CLEAR OLD LENGTH WORD
TEMP3 = ((.TEMP1 + 3) AND ( NOT 3)); !ROUND UP BASE TO MULT. OF 4
TEMP2 = .TEMP2 - (.TEMP3 - .TEMP1); !ADJUST LENGTH WORD
PUTWRD (.KERNEL_FILE, .VALUES [CRAVL], .TEMP3); !STORE NEW BASE
PUTWRD (.KERNEL_FILE, .TEMP3, 0); !CLEAR NEW POINTER WORD
PUTWRD (.KERNEL_FILE, .TEMP3 + 2, .TEMP2); !STORE NEW LENGTH
!
! INCREASE THE SIZE OF THE EXEC
!
TEMP1 = GETWRD (.KERNEL_FILE, .VALUES [EXSIZ]); !REMEMBER OLD SIZE
PUTWRD (.KERNEL_FILE, .VALUES [EXSIZ], .CEX_BASE); !STORE NEW SIZE
!
! FREE THE NEW SPACE, THUS PLACING IT IN THE EXEC STORAGE POOL
!
DEACB (.KERNEL_FILE, .TEMP1,
(.CEX_BASE - .TEMP1) AND ( NOT (GETWRD (.KERNEL_FILE, .VALUES [CRAVL] - 2))), .VALUES);
!
! CREATE A PARTITION CONTROL BLOCK
!
PCB_ADDR = M_PCB (.KERNEL_FILE, UPLIT (%ASCIZ'CEXCOM'), 0, .CEX_BASE, .CEX_TOP, %O'100200',
.VALUES [PS_COM], 0, .VALUES);
!
! NOW COPY THE COMM EXEC INTO THE KERNEL IMAGE
!
INCR ADDRESS FROM .CEX_BASE TO .CEX_TOP DO
PUTBYT (.KERNEL_FILE, .ADDRESS, GETBYT (.CEX_FILE, .ADDRESS));
!
! NOW SET THE BIT IN THE FLAGS WORD WHICH MEANS THAT WE HAVE
! LOADED THE COMM EXEC.
!
FLAGS = .FLAGS OR .VALUES [FE_CEX];
PUTWRD (.KERNEL_FILE, .VALUES [FMASK], .FLAGS);
!
END; !OF MCEX
ROUTINE ALOC_POOL (KERNEL_FILE, AMOUNT, DUMMY, DUMMY2) = !ALLOCATE FROM POOL PARTITION
!++
! FUNCTIONAL DESCRIPTION:
!
! ALLOCATE "AMOUNT" BYTES FROM THE CEXDAT PARTITION
!
! FORMAL PARAMETERS:
!
! KERNEL_FILE - THE RSX KERNEL
! AMOUNT - THE NUMBER OF BYTES TO ALLOCATE
! DUMMY - Dummy Parameter to Make CALL look like ALOCB Routine
! DUMMY2 - Dummy Parameter to Make CALL look like ALOCB Routine
!
! IMPLICIT INPUTS:
!
! FILE_HWM for KERNEL_FILE
!
! IMPLICIT OUTPUTS:
!
! NONE
!
! ROUTINE VALUE:
!
! Address of start of allocated area
!
! SIDE EFFECTS
!
! Expands the size of the SYSTEM image
!
!--
BEGIN
BIND
ROUTINE_NAME = UPLIT (%ASCIZ'ALLOCATE_FROM_POOL');
MAP
KERNEL_FILE : REF FILE_BLOCK;
LOCAL
REAL_AMOUNT,
RESULT;
!
! Round amount to two word boundary
!
REAL_AMOUNT = (.AMOUNT + 3) AND ( NOT 3);
!
! Allocate by Moving the KERNEL_FILE's High Water Mark
!
RESULT = .KERNEL_FILE [FILE_HWM];
KERNEL_FILE [FILE_HWM] = .KERNEL_FILE [FILE_HWM] + .REAL_AMOUNT;
!
.RESULT
END; !OF ALOC_POOL
GLOBAL ROUTINE LD_DCB (KERNEL_FILE, FILE_CHAN, PCB_ADDR, DEV_NAME, VALUES) =
!BUILD A DCB FOR AN LLC
!++
! FUNCTIONAL DESCRIPTION
!
! ALLOCATE AND INSERT A DCB FOR A PARTICULAR LLC.
!
! FORMAL PARAMETERS:
!
! KERNEL_FILE - POINTER TO FILE THAT HOLDS THE KERNAL IMAGE
! FILE_CHAN - CHANNEL FOR PERFORMING I/O AT THIS LEVEL
! PCB_ADDR - PDP-11 ADDRESS OF PCB FOR THIS LLC
! DEV_NAME - LOCATION CONTAINING 2 CHARACTER DEVICE NAME
! VALUES - BLOCK OF LOTS OF GOOD THAINGS FOR VNP20
!
! IMPLICIT INPUTS:
!
! NONE
!
! IMPLICIT OUTPUTS:
!
! NONE
!
! ROUTINE VALUE:
!
! NONE
!
! SIDE EFFECTS
!
! THE KERNEL IS MODIFIED
!
!--
BEGIN
BIND
ROUTINE_NAME = UPLIT (%ASCIZ'LD_DCB');
MAP
KERNEL_FILE : REF FILE_BLOCK,
VALUES : REF VNPVAL_BLOCK;
LOCAL
LOC,
DCB_FILE : REF FILE_BLOCK,
DCB_NAME : VECTOR [CH$ALLOCATION (7)],
XXBEG,
XXEND,
DCB_DATA_ADDR,
DCB_ADDR,
LAST_DCB_ADDR,
UCB_ADDR,
FIRST_UCB_ADDR,
UCB_LENGTH,
SCB_ADDR,
LAST_SCB_ADDR,
NUNITS,
MODU_PTR : REF MODU_BLOCK;
!
! GET FILE BLOCK TO READ IN FILE
!
DCB_FILE = GETBLK (FILE_TYP, FILE_LEN);
!
! Tell someone what we are doing
!
OUTSTR (0, UPLIT (%ASCIZ'[Loading Device '));
OUTSTR (0, DEV_NAME);
OUTSTR (0, UPLIT (%ASCIZ': --> '));
!
! SETUP FILENAME AS ??TAB
!
CH$COPY (2, CH$PTR (DEV_NAME), 3, CH$PTR (UPLIT (%ASCIZ'TAB')), 0, 6, CH$PTR (DCB_FILE [FILE_NAME]));
!
! READ IN THE CORE FILE AND SYMBOL TABLE
!
RSTB (.FILE_CHAN, .DCB_FILE);
RCOR (.DCB_FILE, .FILE_CHAN, 2*1024);
!
MODU_PTR = .DCB_FILE [FILE_MODU];
OUTSTR (0, MODU_PTR [MODU_NAME]);
OUTPUT (0, %C' ');
OUTSTR (0, MODU_PTR [MODU_IDENT]);
OUTSTR (0, UPLIT (%ASCIZ' ]'));
PCRLF (0);
!
! NOW LOOK UP THE STARTING AND ENDING SYMBOLS FOR COPYING
!
CH$COPY (1, CH$PTR (UPLIT (%ASCIZ'$')), 2, CH$PTR (DEV_NAME), 0, 7, CH$PTR (DCB_NAME));
CH$MOVE (3, CH$PTR (UPLIT (%ASCIZ'DAT')), CH$PTR (DCB_NAME, 3));
XXBEG = SYM_VAL (.DCB_FILE, DCB_NAME, 0);
CH$MOVE (3, CH$PTR (UPLIT (%ASCIZ'END')), CH$PTR (DCB_NAME, 3));
XXEND = SYM_VAL (.DCB_FILE, DCB_NAME, 0);
!
! ALLOCATE THE DCB STRUCTURES
!
DCB_DATA_ADDR = ALOCB (.KERNEL_FILE, .XXEND - .XXBEG, 1, .VALUES);
!
! COPY IN THE DATA STRUCTURE
!
INCR COUNTER FROM .XXBEG TO .XXEND - 1 DO
PUTBYT (.KERNEL_FILE, .DCB_DATA_ADDR + .COUNTER - .XXBEG, GETBYT (.DCB_FILE, .COUNTER));
!
! NOW RELOCATE SOME OF THE DATA STRUCTURE LOCATIONS
!
!
! PROCESS EACH DCB, WITH ITS UCBS AND SCBS.
!
SCB_ADDR = 0;
DCB_ADDR = .DCB_DATA_ADDR;
WHILE (.DCB_ADDR NEQ 0) DO
BEGIN
LAST_DCB_ADDR = .DCB_ADDR;
!
! COMPUTE THE NUMBER OF UNITS AND THE LENGTH OF EACH UCB
!
NUNITS = GETBYT (.KERNEL_FILE, .DCB_ADDR + .VALUES [D_UNIT] + 1) - GETBYT (.KERNEL_FILE,
.DCB_ADDR + .VALUES [D_UNIT]) + 1;
UCB_LENGTH = GETWRD (.KERNEL_FILE, .DCB_ADDR + .VALUES [D_UCBL]);
!
! RELOCATE THE DCB, UCB AND SCB.
!
FIRST_UCB_ADDR = GETWRD (.KERNEL_FILE, .DCB_ADDR + .VALUES [D_UCB]) - .XXBEG + .DCB_ADDR;
PUTWRD (.KERNEL_FILE, .DCB_ADDR + .VALUES [D_UCB], .FIRST_UCB_ADDR);
PUTWRD (.KERNEL_FILE, .DCB_ADDR + .VALUES [D_PCB], .PCB_ADDR);
INCR COUNTER FROM 0 TO .NUNITS - 1 DO
BEGIN !EACH UCB
UCB_ADDR = .FIRST_UCB_ADDR + (.UCB_LENGTH*.COUNTER);
PUTWRD (.KERNEL_FILE, .UCB_ADDR + .VALUES [U_DCB],
GETWRD (.KERNEL_FILE,
.UCB_ADDR + .VALUES [U_DCB]) - .XXBEG + .DCB_ADDR);
PUTWRD (.KERNEL_FILE, .UCB_ADDR + .VALUES [U_RED],
GETWRD (.KERNEL_FILE,
.UCB_ADDR + .VALUES [U_RED]) - .XXBEG + .DCB_ADDR);
LAST_SCB_ADDR = .SCB_ADDR;
SCB_ADDR = GETWRD (.KERNEL_FILE, .UCB_ADDR + .VALUES [U_SCB]) - .XXBEG + .DCB_ADDR;
PUTWRD (.KERNEL_FILE, .UCB_ADDR + .VALUES [U_SCB], .SCB_ADDR);
IF (.SCB_ADDR NEQ .LAST_SCB_ADDR)
THEN
BEGIN
PUTWRD (.KERNEL_FILE, .SCB_ADDR + .VALUES [S_LHD] + 2,
GETWRD (.KERNEL_FILE,
.SCB_ADDR + .VALUES [S_LHD] + 2) - .XXBEG + .DCB_ADDR);
END;
END;
DCB_ADDR = GETWRD (.KERNEL_FILE, .DCB_ADDR + .VALUES [D_LNK]);
END;
!
! LINK THE DCB INTO THE SYSTEM'S LIST OF DCBS
!
LNKDCB (.KERNEL_FILE, .DCB_DATA_ADDR, .VALUES);
!
! If this is for the CE: Device then we special case and store the data
! base address for use in loading other processes.
!
IF (CH$EQL (2, CH$PTR (DEV_NAME), 2, CH$PTR (UPLIT (%ASCIZ'CE')), 0))
THEN
BEGIN
VALUES [CE_DATA_BASE] = .DCB_DATA_ADDR;
VALUES [CE_DATA_FILE] = .DCB_FILE;
END
ELSE
!
! FREE SOME DATA STRUCTURES
!
FCOR (.DCB_FILE);
!
! Return Address of Start of Data Base
!
.DCB_DATA_ADDR
END; !OF LD_DCB
END
ELUDOM
! Local Modes:
! Comment Column:36
! Comment Start:!
! Mode:Fundamental
! Auto Save Mode:2
! End: