Trailing-Edge
-
PDP-10 Archives
-
BB-X117B-SB_1986
-
10,7/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) DIGITAL EQUIPMENT CORPORATION 1980,1981,1982,1986. ALL RIGHTS RESERVED.
!
!
!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: