Trailing-Edge
-
PDP-10 Archives
-
BB-X117B-SB_1986
-
10,7/vnp36/rsxfnc.bli
There are 2 other files named rsxfnc.bli in the archive. Click here to see a list.
!NET:<DECNET20-V3P0.TKB-VNP.BIGVNP>RSXFNC.BLI.44 29-Sep-82 11:41:38, Edit by PECKHAM
!NET:<DECNET20-V3P0.TKB-VNP.BIGVNP>RSXFNC.BLI.42 29-Sep-82 10:14:27, Edit by PECKHAM
!NET:<DECNET20-V3P0.TKB-VNP.BIGVNP>RSXFNC.BLI.40 28-Sep-82 16:11:16, Edit by PECKHAM
!NET:<DECNET20-V3P0.TKB-VNP.BIGVNP>RSXFNC.BLI.39 26-Mar-82 16:13:43, Edit by PECKHAM
MODULE RSXFNC ( !Provide RSX Functions
IDENT = 'X3.3' !edit 29Sep82
) =
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, VNP-20
!
! ABSTRACT:
!
! This module contains all routines which manipulate RSX-11S Data
! Structures.
!
!
! ENVIRONMENT: TOPS-10 or TOPS-20 User Mode
!
! AUTHOR: Scott G. Robinson, Creation Date: 16-APR-80
!
! MODIFIED BY:
! , : VERSION
! 01 -
! 03 - Change MCBMAP text in TELLK.
!--
!
! TABLE OF CONTENTS:
!
FORWARD ROUTINE
RCOR : NOVALUE, !READ CORE IMAGE
WCOR : NOVALUE, !WRITE CORE IMAGE
FCOR : NOVALUE, !FREE CORE IMAGE
DEL_MODU, !DELETE A MODULE
DEL_PSECT, !DELETE A PSECT
DEL_GLOBAL, !DELETE A GLOBAL
GETSYM : NOVALUE, !READ SYMBOLS INTO VALUE BLOCK
GETSYM_1 : NOVALUE, !READ RSX RELATED SYMBOLS
GETBYT, !GET A PDP-11 BYTE
GETWRD, !GET A WORD
PUTBYT : NOVALUE, !STORE A BYTE
PUTWRD : NOVALUE, !STORE A WORD
ALOCB, !ALLOCATE PDP-11 CORE
DEACB : NOVALUE, !DEALLOCATE PDP-11 CORE
M_PCB, !MAKE A PCB
INSTAL : NOVALUE, !INSTALL A TASK
LOADD : NOVALUE, !LOAD A DRIVER
LNKDCB : NOVALUE, !LINK A DCB INTO KERNEL
VRBL_SYM, !MAKE A SYMBOL AND GET VALUE
FCLEAN : NOVALUE, !PERFORM FINAL EXEC CLEANUP
TELLK : NOVALUE, !TELL USER ABOUT CONFIG
TELLP : NOVALUE; !TELL USER ABOUT PARTITIONS
!
! INCLUDE FILES:
!
LIBRARY 'VNPLIB';
!REQUIRE 'BLOCKH.REQ'; !PREPARE TO DEFINE STORAGE BLOCKS
!REQUIRE 'FILE.REQ'; !DEFINE FILE BLOCK
!REQUIRE 'FILSW.REQ'; !DEFINE FILE SWITCHES
!REQUIRE 'GLOBL.REQ'; !DEFINE GLOBAL BLOCK
!REQUIRE 'MODU.REQ'; !DEFINE MODULE BLOCK
!REQUIRE 'PSECT.REQ'; !DEFINE PSECT BLOCK
!REQUIRE 'VNPVAL.REQ'; !VALUE BLOCK FOR VNP20
!REQUIRE 'LLC.REQ'; !DEFINE LLC BLOCK
!REQUIRE 'DLC.REQ'; !DEFINE DLC BLOCK
!REQUIRE 'DDM.REQ'; !DEFINE DDM BLOCK
!REQUIRE 'BLOCKT.REQ'; !END OF DEFINING STORAGE BLOCKS
!REQUIRE 'TSKDEF.REQ'; !DEFINE TASK OFFSETS
!
! MACROS:
!
! NONE
!
! EQUATED SYMBOLS:
!
LITERAL
DEBUG = 0;
!
! OWN STORAGE:
!
! NONE
!
! EXTERNAL REFERENCES:
!
EXTERNAL ROUTINE
ATOR50 : NOVALUE, !CONVERT ASCII TO RADIX50_11
R50TOA : NOVALUE, !CONVERT RADIX50_11 TO ASCII
OPEN, !OPEN A FILE
CLOSE : NOVALUE, !CLOSE A FILE
INPUT, !READ FROM A FILE
OUTPUT : NOVALUE, !WRITE ON A FILE
RSTB : NOVALUE, !READ SYMBOL TABLE
PCRLF : NOVALUE, !PRINT CR THEN LF
OUTSTR : NOVALUE, !PRINT A STRING
OUTNUM : NOVALUE, !PRINT A NUMBER
ERROR : NOVALUE, !SIGNAL PROGRAMMING ERROR
ERRMSG : NOVALUE, !ERROR MESSAGE
SYM_VAL, !OBTAIN VALUE OF A SYMBOL
GETSTG, !GET STORAGE FROM FREE LIST
GETBLK, !GET A BLOCK OF STORAGE
FRESTG : NOVALUE, !RETURN STORAGE TO FREE LIST
FREBLK : NOVALUE, !RETURN A BLOCK OF STORAGE
FND_CHAIN, !"FIND" AN ITEM IN A CHAIN
DEL_PTRS : NOVALUE; !DELETE CHAIN BLOCKS
GLOBAL ROUTINE RCOR (FILE_PTR, FILE_CHAN, CORE_LEN) : NOVALUE = !READ CORE IMAGE
!++
! FUNCTIONAL DESCRIPTION:
!
! READ A CORE IMAGE FOR CORE IMAGE BUILDER (VNP20)
! THIS INCLUDES THE KERNEL AND TASK IMAGES.
!
! FORMAL PARAMETERS:
!
! FILE_PTR - POINTER TO THE FILE BLOCK WHICH DESCRIBES
! THE CORE IMAGE FILE TO BE READ
! FILE_CHAN - THE CHANNEL NUMBER TO USE WHEN READING THE FILE.
! CORE_LEN - LENGTH OF THE CORE IMAGE, IN 8-BIT BYTES.
!
! IMPLICIT INPUTS:
!
! NONE
!
! IMPLICIT OUTPUTS:
!
! FILLS THE 'CORE_IMAGE' ARRAY WITH THE CORE IMAGE
! AND STORES POINTERS IN THE FILE BLOCK
!
! ROUTINE VALUE:
!
! NONE
!
! SIDE EFFECTS
!
! OPENS, READS AND CLOSES THE SPECIFIED FILE
! OBTAINS TWO ARRAYS FROM FREE SPACE
!
!--
BEGIN
BIND
ROUTINE_NAME = UPLIT (%ASCIZ'RCOR');
MAP
FILE_PTR : REF FILE_BLOCK;
LOCAL
CHAR,
CORE_IMAGE : REF VECTOR,
CORE_WORD,
LABEL_IMAGE : REF VECTOR [1024],
LOCN,
READ_DONE;
!
! GET SPACE FOR THE CORE IMAGE AND LABELS FROM FREE STORAGE
!
IF ((CORE_IMAGE = GETSTG (.CORE_LEN/4)) EQL 0)
THEN
ERRMSG (0, 1, ROUTINE_NAME, 0, 0, 0, 0)
ELSE
BEGIN
IF ((LABEL_IMAGE = GETSTG (1024)) EQL 0)
THEN
ERRMSG (0, 1, ROUTINE_NAME, 0, 0, 0, 0)
ELSE
BEGIN
!
! CLEAR THE CORE ARRAY, SO ANY LOCATIONS NOT FILLED WILL BE
! ZERO.
!
INCR COUNTER FROM 0 TO ((.CORE_LEN/4) - 1) DO
CORE_IMAGE [.COUNTER] = 0;
!
! OPEN THE FILE CONTAINING THE KERNEL.
!
IF (OPEN (.FILE_CHAN, FILE_PTR [FILE_NAME], 2, 0, UPLIT (%ASCIZ'TSK')) NEQ 0)
THEN
BEGIN !SUCCESSFUL INPUT OPEN
READ_DONE = 0;
LOCN = 0;
!
! RECORD THE LABEL BLOCK SEPARATELY
!
INCR COUNTER FROM 0 TO 1023 DO
LABEL_IMAGE [.COUNTER] = INPUT (.FILE_CHAN);
!
! READ THE DATA INTO THE CORE IMAGE ARRAY
!
WHILE (.READ_DONE EQL 0) DO
BEGIN
CHAR = INPUT (.FILE_CHAN);
IF (.CHAR LSS 0)
THEN
READ_DONE = -1
ELSE
BEGIN
CORE_WORD = .CORE_IMAGE [.LOCN/4];
CORE_WORD<(CASE (.LOCN AND 3) FROM 0 TO 3 OF
SET
[0] : 18;
[1] : 26;
[2] : 0;
[3] : 8;
TES), 8> = .CHAR;
CORE_IMAGE [.LOCN/4] = .CORE_WORD;
LOCN = .LOCN + 1;
IF (.LOCN GTR .CORE_LEN) THEN READ_DONE = -1;
END;
END;
!
! NOW STORE POINTERS TO THE CORE IMAGE AND LABEL IMAGE IN THE FILE
! BLOCK, FOR CONVENIENT REFERENCE.
!
FILE_PTR [FILE_CORE] = .CORE_IMAGE;
FILE_PTR [FILE_CORE_LEN] = .CORE_LEN;
FILE_PTR [FILE_LABEL] = .LABEL_IMAGE;
CLOSE (.FILE_CHAN);
END;
END;
END;
END; !OF RCOR
GLOBAL ROUTINE WCOR (FILE_CHAN, FILE_PTR) : NOVALUE = !WRITE CORE IMAGE
!++
! FUNCTIONAL DESCRIPTION:
!
! WRITE A CORE IMAGE FOR THE CORE IMAGE BUILDER (VNP20).
!
! FORMAL PARAMETERS:
!
! FILE_CHAN - THE CHANNEL NUMBER TO USE WHEN READING THE FILE.
! FILE_PTR - POINTER TO THE FILE BLOCK WHICH DESCRIBES
! THE CORE IMAGE FILE TO BE READ
!
! IMPLICIT INPUTS:
!
! NONE
!
! IMPLICIT OUTPUTS:
!
! NONE
!
! ROUTINE VALUE:
!
! NONE
!
! SIDE EFFECTS
!
! OPENS, WRITES AND CLOSES THE SPECIFIED FILE
!
!--
BEGIN
BIND
ROUTINE_NAME = UPLIT (%ASCIZ'WCOR');
MAP
FILE_PTR : REF FILE_BLOCK;
LOCAL
CORE_IMAGE : REF VECTOR,
LABEL_IMAGE : REF VECTOR [1024],
CHAR,
CORE_LEN,
CORE_WORD,
LOCN,
WRITE_DONE;
!
! OPEN THE FILE WHICH IS TO CONTAIN THE CORE IMAGE
!
IF (OPEN (.FILE_CHAN, FILE_PTR [FILE_NAME], 2, 1, UPLIT (%ASCIZ'SYS')) NEQ 0)
THEN
BEGIN !SUCCESSFUL OUTPUT OPEN
CORE_IMAGE = .FILE_PTR [FILE_CORE];
CORE_LEN = .FILE_PTR [FILE_CORE_LEN];
LABEL_IMAGE = .FILE_PTR [FILE_LABEL];
WRITE_DONE = 0;
LOCN = 0;
!
! FIRST WRITE OUT THE LABEL BLOCK
!
INCR COUNTER FROM 0 TO 1023 DO
OUTPUT (.FILE_CHAN, .LABEL_IMAGE [.COUNTER]);
!
! WRITE THE DATA FROM THE CORE IMAGE ARRAY
!
WHILE (.WRITE_DONE EQL 0) DO
BEGIN
CORE_WORD = .CORE_IMAGE [.LOCN/4];
CHAR = .CORE_WORD<(CASE (.LOCN AND 3) FROM 0 TO 3 OF
SET
[0] : 18;
[1] : 26;
[2] : 0;
[3] : 8;
TES), 8>;
OUTPUT (.FILE_CHAN, .CHAR);
LOCN = .LOCN + 1;
IF (.LOCN GEQ .CORE_LEN) THEN WRITE_DONE = -1;
END;
CLOSE (.FILE_CHAN);
END;
END; !OF WCOR
GLOBAL ROUTINE FCOR (FILE_PTR) : NOVALUE = !FREE CORE IMAGE
!++
! FUNCTIONAL DESCRIPTION:
!
! PURGE A CORE IMAGE - DISCARD ITS FILE BLOCK AND ALL THAT
! IT POINTS TO.
!
! FORMAL PARAMETERS:
!
! FILE_PTR - POINTER TO THE FILE BLOCK WHICH DESCRIBES
! THE CORE IMAGE FILE TO BE FREED
!
! IMPLICIT INPUTS:
!
! NONE
!
! IMPLICIT OUTPUTS:
!
! NONE
!
! ROUTINE VALUE:
!
! NONE
!
! SIDE EFFECTS
!
! RETURNS SPACE TO FREE STORAGE
!
!--
BEGIN
BIND
ROUTINE_NAME = UPLIT (%ASCIZ'FCOR');
MAP
FILE_PTR : REF FILE_BLOCK;
LOCAL
CORE_IMAGE : REF VECTOR,
LABEL_IMAGE : REF VECTOR [1024],
CORE_LEN;
!
! EXTRACT POINTERS AND SO ON FROM THE FILE BLOCK
!
LABEL_IMAGE = .FILE_PTR [FILE_LABEL];
CORE_LEN = .FILE_PTR [FILE_CORE_LEN];
CORE_IMAGE = .FILE_PTR [FILE_CORE];
!
! FREE THE CORE IMAGE AND THE LABEL IMAGE
!
IF (.CORE_LEN NEQ 0) THEN FRESTG (.CORE_IMAGE, .CORE_LEN/4);
IF (.LABEL_IMAGE NEQ 0) THEN FRESTG (.LABEL_IMAGE, 1024);
!
! SCAN THROUGH THE SYMBOL TABLE, FREEING IT.
!
FND_CHAIN (.FILE_PTR [FILE_DOWN], DEL_MODU, 0);
!
! NOW FREE THE CHAIN BLOCKS
!
DEL_PTRS (.FILE_PTR [FILE_DOWN]);
!
! NEW FREE THE FILE BLOCK ITSELF
!
FREBLK (.FILE_PTR);
!
END; !OF FCOR
ROUTINE DEL_MODU (MODU_PTR, UNUSED) = !DELETE A MODULE
!++
! FUNCTIONAL DESCRIPTION:
!
! DELETE A MODULE AFTER DELETEING THE PSECTS IT POINTS TO.
! USED IN CALL TO FND_CHAIN.
!
! FORMAL PARAMETERS:
!
! MODU_PTR - POINTER TO THE MODULE BLOCK TO BE DELETED
! UNUSED - NOT USED
!
! IMPLICIT INPUTS:
!
! NONE
!
! IMPLICIT OUTPUTS:
!
! NONE
!
! ROUTINE VALUE:
!
! ALWAYS 0 TO CONTINUE THE SCAN
!
! SIDE EFFECTS
!
! RETURNS SPACE TO FREE STORAGE
!
!--
BEGIN
BIND
ROUTINE_NAME = UPLIT (%ASCIZ'DEL_MODU');
MAP
MODU_PTR : REF MODU_BLOCK;
!
! FREE ALL THE PSECTS FIRST
!
IF (.MODU_PTR [MODU_PSECTS] NEQ 0)
THEN
BEGIN
FND_CHAIN (.MODU_PTR [MODU_PSECTS], DEL_PSECT, 0);
DEL_PTRS (.MODU_PTR [MODU_PSECTS]);
END;
!
! FREE ALL THE GLOBALS NEXT
!
IF (.MODU_PTR [MODU_GLOBALS] NEQ 0)
THEN
BEGIN
FND_CHAIN (.MODU_PTR [MODU_GLOBALS], DEL_GLOBAL, 0);
DEL_PTRS (.MODU_PTR [MODU_GLOBALS]);
END;
!
! NOW FREE THE MODULE BLOCK
!
FREBLK (.MODU_PTR);
!
! ALWAYS RETURN 0 TO CONTINUE THE SCAN
!
0
END; !OF DEL_MODU
ROUTINE DEL_PSECT (PSECT_PTR, UNUSED) = !DELETE A PSECT
!++
! FUNCTIONAL DESCRIPTION:
!
! DELETE A PSECT AFTER DELETEING THE GLOBALS IT POINTS TO.
! USED IN CALL TO FND_CHAIN.
!
! FORMAL PARAMETERS:
!
! PSECT_PTR - POINTER TO THE PSECT BLOCK TO BE DELETED
! UNUSED - NOT USED
!
! IMPLICIT INPUTS:
!
! NONE
!
! IMPLICIT OUTPUTS:
!
! NONE
!
! ROUTINE VALUE:
!
! ALWAYS 0 TO CONTINUE THE SCAN
!
! SIDE EFFECTS
!
! RETURNS SPACE TO FREE STORAGE
!
!--
BEGIN
BIND
ROUTINE_NAME = UPLIT (%ASCIZ'DEL_PSECT');
MAP
PSECT_PTR : REF PSECT_BLOCK;
!
! FREE ALL THE GLOBALS FIRST
!
FND_CHAIN (.PSECT_PTR [PSECT_GLOBALS], DEL_GLOBAL, 0);
!
! FREE THE POINTERS
!
DEL_PTRS (.PSECT_PTR [PSECT_GLOBALS]);
!
! NOW FREE THE PSECT BLOCK
!
FREBLK (.PSECT_PTR);
!
! ALWAYS RETURN 0 TO CONTINUE THE SCAN
!
0
END; !OF DEL_PSECT
ROUTINE DEL_GLOBAL (GLOBAL_PTR, UNUSED) = !DELETE A GLOBAL
!++
! FUNCTIONAL DESCRIPTION:
!
! DELETE A GLOBAL BLOCK.
! USED IN CALL TO FND_CHAIN.
!
! FORMAL PARAMETERS:
!
! GLOBAL_PTR - POINTER TO THE GLOBAL BLOCK TO BE DELETED
! UNUSED - NOT USED
!
! IMPLICIT INPUTS:
!
! NONE
!
! IMPLICIT OUTPUTS:
!
! NONE
!
! ROUTINE VALUE:
!
! ALWAYS 0 TO CONTINUE THE SCAN
!
! SIDE EFFECTS
!
! RETURNS SPACE TO FREE STORAGE
!
!--
BEGIN
BIND
ROUTINE_NAME = UPLIT (%ASCIZ'DEL_GLOBAL');
MAP
GLOBAL_PTR : REF GLOBL_BLOCK;
!
! FREE THE GLOBAL BLOCK.
!
FREBLK (.GLOBAL_PTR);
!
! ALWAYS RETURN 0 TO CONTINUE THE SCAN
!
0
END; !OF DEL_GLOBAL
GLOBAL ROUTINE GETSYM (KERNEL_FILE, CEX_FILE, RSXMS_FILE, VALUES) : NOVALUE = !FETCH SYMBOL VALUES
!++
! FUNCTIONAL DESCRIPTION:
!
! FETCH SYMBOL VALUES FROM THE VARIOUS SYMBOL TABLES, CHECKING
! FOR CONSISTENCY. THIS IS DONE ONCE RATHER THAN WHENEVER
! A SYMBOL VALUE IS NEEDED BECAUSE LOOKING UP A SYMBOL IS
! QUITE SLOW.
!
! FORMAL PARAMETERS:
!
! KERNEL_FILE - FILE BLOCK FOR THE KERNEL
! CEX_FILE - FILE BLOCK FOR THE COMM EXEC
! RSXMS_FILE - FILE BLOCK FOR THE EXEMC SYMBOLS
! VALUES - BLOCK INTO WHICH TO STORE SYMBOL VALUES
!
! IMPLICIT INPUTS:
!
! THE SYMBOL VALUES IN THE SYMBOL TABLES
!
! IMPLICIT OUTPUTS:
!
! NONE
!
! ROUTINE VALUE:
!
! NONE
!
! SIDE EFFECTS
!
! FILLS IN SYMBOLS IN 'VALUES'
!
!--
BEGIN
BIND
ROUTINE_NAME = UPLIT (%ASCIZ'GETSYM');
MAP
KERNEL_FILE : REF FILE_BLOCK,
CEX_FILE : REF FILE_BLOCK,
RSXMS_FILE : REF FILE_BLOCK,
VALUES : REF VNPVAL_BLOCK;
GETSYM_1 (.KERNEL_FILE, .RSXMS_FILE, .VALUES);
IF (.VALUES [P_LGTH] NEQ SYM_VAL (.KERNEL_FILE, UPLIT (%ASCIZ'P.LGTH'), 0))
THEN
ERRMSG (0, 29,
ROUTINE_NAME, UPLIT (%ASCIZ'P.LGTH'), KERNEL_FILE [FILE_NAME], RSXMS_FILE [FILE_NAME], 0);
IF (SYM_VAL (.KERNEL_FILE, UPLIT (%ASCIZ'$CLRMV'), 0) NEQ SYM_VAL (.CEX_FILE, UPLIT (%ASCIZ'$CLRMV'), 0))
THEN
ERRMSG (0, 29, ROUTINE_NAME, UPLIT (%ASCIZ'$CLRMV'), KERNEL_FILE [FILE_NAME], CEX_FILE [FILE_NAME], 0)
;
IF (SYM_VAL (.KERNEL_FILE, UPLIT (%ASCIZ'$HEADR'), 0) NEQ SYM_VAL (.CEX_FILE, UPLIT (%ASCIZ'$HEADR'), 0))
THEN
ERRMSG (0, 29, ROUTINE_NAME, UPLIT (%ASCIZ'$HEADR'), KERNEL_FILE [FILE_NAME], CEX_FILE [FILE_NAME], 0)
;
IF (SYM_VAL (.KERNEL_FILE, UPLIT (%ASCIZ'$INTX1'), 0) NEQ SYM_VAL (.CEX_FILE, UPLIT (%ASCIZ'$INTX1'), 0))
THEN
ERRMSG (0, 29, ROUTINE_NAME, UPLIT (%ASCIZ'$INTX1'), KERNEL_FILE [FILE_NAME], CEX_FILE [FILE_NAME], 0)
;
END; !OF GETSYM
ROUTINE GETSYM_1 (KERNEL_FILE, RSXMS_FILE, VALUES) : NOVALUE = !FETCH SYMBOL VALUES
!++
! FUNCTIONAL DESCRIPTION:
!
! FETCH THE SYMBOLS
!
! FORMAL PARAMETERS:
!
! KERNEL_FILE - FILE BLOCK FOR THE KERNEL
! RSXMS_FILE - FILE BLOCK FOR THE EXEMC SYMBOLS
! VALUES - BLOCK INTO WHICH TO STORE SYMBOL VALUES
!
! IMPLICIT INPUTS:
!
! THE SYMBOL VALUES IN THE SYMBOL TABLES
!
! IMPLICIT OUTPUTS:
!
! NONE
!
! ROUTINE VALUE:
!
! NONE
!
! SIDE EFFECTS
!
! FILLS IN SYMBOLS IN 'VALUES'
!
!--
BEGIN
BIND
ROUTINE_NAME = UPLIT (%ASCIZ'GETSYM_1');
MAP
KERNEL_FILE : REF FILE_BLOCK,
RSXMS_FILE : REF FILE_BLOCK,
VALUES : REF VNPVAL_BLOCK;
VALUES [CRAVL] = SYM_VAL (.KERNEL_FILE, UPLIT (%ASCIZ'$CRAVL'), 0);
VALUES [EXSIZ] = SYM_VAL (.KERNEL_FILE, UPLIT (%ASCIZ'$EXSIZ'), 0);
VALUES [POOL] = SYM_VAL (.KERNEL_FILE, UPLIT (%ASCIZ'$POOL '), 0);
VALUES [FMASK] = SYM_VAL (.KERNEL_FILE, UPLIT (%ASCIZ'$FMASK'), 0);
VALUES [SYSIZ] = SYM_VAL (.KERNEL_FILE, UPLIT (%ASCIZ'$SYSIZ'), 0);
VALUES [PARHD] = SYM_VAL (.KERNEL_FILE, UPLIT (%ASCIZ'$PARHD'), 0);
VALUES [TSKHD] = SYM_VAL (.KERNEL_FILE, UPLIT (%ASCIZ'$TSKHD'), 0);
VALUES [CLKHD] = SYM_VAL (.KERNEL_FILE, UPLIT (%ASCIZ'$CLKHD'), 0);
VALUES [DEVHD] = SYM_VAL (.KERNEL_FILE, UPLIT (%ASCIZ'$DEVHD'), 0);
VALUES [ABTIM] = SYM_VAL (.KERNEL_FILE, UPLIT (%ASCIZ'$ABTIM'), 0);
VALUES [TKPS] = SYM_VAL (.KERNEL_FILE, UPLIT (%ASCIZ'$TKPS '), 0);
VALUES [P_LGTH] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'P.LGTH'), 0);
VALUES [P_LNK] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'P.LNK '), 0);
VALUES [P_PRI] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'P.PRI '), 0);
VALUES [P_IOC] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'P.IOC '), 0);
VALUES [P_NAM] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'P.NAM '), 0);
VALUES [P_SUB] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'P.SUB '), 0);
VALUES [P_MAIN] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'P.MAIN'), 0);
VALUES [P_REL] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'P.REL '), 0);
VALUES [P_SIZE] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'P.SIZE'), 0);
VALUES [P_WAIT] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'P.WAIT'), 0);
VALUES [P_BUSY] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'P.BUSY'), 0);
VALUES [P_TCB] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'P.TCB '), 0);
VALUES [P_STAT] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'P.STAT'), 0);
VALUES [P_HDR] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'P.HDR '), 0);
VALUES [P_PRO] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'P.PRO '), 0);
VALUES [P_ATT] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'P.ATT '), 0);
VALUES [FE_EXT] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'FE.EXT'), 0);
VALUES [FE_MUP] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'FE.MUP'), 0);
VALUES [FE_EXV] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'FE.EXV'), 0);
VALUES [FE_DRV] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'FE.DRV'), 0);
VALUES [FE_PLA] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'FE.PLA'), 0);
VALUES [FE_CAL] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'FE.CAL'), 0);
VALUES [FE_PKT] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'FE.PKT'), 0);
VALUES [FE_EXP] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'FE.EXP'), 0);
VALUES [FE_LSI] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'FE.LSI'), 0);
VALUES [FE_CEX] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'FE.CEX'), 0);
VALUES [FE_NLG] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'FE.NLG'), 0);
VALUES [FE_NLG] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'FE.NLG'), 0);
VALUES [PS_OUT] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'PS.OUT'), 0);
VALUES [PS_CKP] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'PS.CKP'), 0);
VALUES [PS_CKR] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'PS.CKR'), 0);
VALUES [PS_CHK] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'PS.CHK'), 0);
VALUES [PS_FXD] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'PS.FXD'), 0);
VALUES [PS_PER] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'PS.PER'), 0);
VALUES [PS_LIO] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'PS.LIO'), 0);
VALUES [PS_NSF] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'PS.NSF'), 0);
VALUES [PS_COM] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'PS.COM'), 0);
VALUES [PS_PIC] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'PS.PIC'), 0);
VALUES [PS_SYS] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'PS.SYS'), 0);
VALUES [PS_DRV] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'PS.DRV'), 0);
VALUES [PS_DEL] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'PS.DEL'), 0);
VALUES [PS_APR] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'PS.APR'), 0);
VALUES [T_PRI] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'T.PRI '), 0);
VALUES [T_NAM] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'T.NAM '), 0);
VALUES [T_RCVL] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'T.RCVL'), 0);
VALUES [T_ASTL] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'T.ASTL'), 0);
VALUES [T_TCBL] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'T.TCBL'), 0);
VALUES [T_STAT] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'T.STAT'), 0);
VALUES [T_ST2] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'T.ST2 '), 0);
VALUES [T_ST3] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'T.ST3 '), 0);
VALUES [T_DPRI] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'T.DPRI'), 0);
VALUES [T_LBN] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'T.LBN '), 0);
VALUES [T_LDV] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'T.LDV '), 0);
VALUES [T_PCB] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'T.PCB '), 0);
VALUES [T_MXSZ] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'T.MXSZ'), 0);
VALUES [T_LGTH] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'T.LGTH'), 0);
VALUES [H_HDLN] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'H.HDLN'), 0);
VALUES [H_WND] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'H.WND '), 0);
VALUES [H_GARD] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'H.GARD'), 0);
VALUES [H_NLUN] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'H.NLUN'), 0);
VALUES [H_LUN] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'H.LUN '), 0);
VALUES [TS_EXE] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'TS.EXE'), 0);
VALUES [TS_RDN] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'TS.RDN'), 0);
VALUES [TS_MSG] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'TS.MSG'), 0);
VALUES [TS_NRP] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'TS.NRP'), 0);
VALUES [TS_RUN] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'TS.RUN'), 0);
VALUES [TS_OUT] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'TS.OUT'), 0);
VALUES [TS_CKP] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'TS.CKP'), 0);
VALUES [TS_CKR] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'TS.CKR'), 0);
VALUES [T2_AST] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'T2.AST'), 0);
VALUES [T2_DST] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'T2.DST'), 0);
VALUES [T2_CHK] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'T2.CHK'), 0);
VALUES [T2_CKD] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'T2.CKD'), 0);
VALUES [T2_BFX] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'T2.BFX'), 0);
VALUES [T2_FXD] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'T2.FXD'), 0);
VALUES [T2_TIO] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'T2.TIO'), 0);
VALUES [T2_CAF] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'T2.CAF'), 0);
VALUES [T2_HLT] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'T2.HLT'), 0);
VALUES [T2_ABO] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'T2.ABO'), 0);
VALUES [T2_STP] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'T2.STP'), 0);
VALUES [T2_SPN] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'T2.SPN'), 0);
VALUES [T2_WFR] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'T2.WFR'), 0);
VALUES [T3_ACP] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'T3.ACP'), 0);
VALUES [T3_PMD] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'T3.PMD'), 0);
VALUES [T3_REM] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'T3.REM'), 0);
VALUES [T3_PRV] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'T3.PRV'), 0);
VALUES [T3_MCR] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'T3.MCR'), 0);
VALUES [T3_SLV] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'T3.SLV'), 0);
VALUES [T3_CLI] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'T3.CLI'), 0);
VALUES [T3_RST] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'T3.RST'), 0);
VALUES [T3_NSD] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'T3.NSD'), 0);
VALUES [T3_CAL] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'T3.CAL'), 0);
VALUES [T3_ROV] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'T3.ROV'), 0);
VALUES [T3_NET] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'T3.NET'), 0);
VALUES [D_LNK] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'D.LNK '), 0);
VALUES [D_UCB] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'D.UCB '), 0);
VALUES [D_NAM] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'D.NAM '), 0);
VALUES [D_UNIT] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'D.UNIT'), 0);
VALUES [D_UCBL] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'D.UCBL'), 0);
VALUES [D_DSP] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'D.DSP '), 0);
VALUES [D_MSK] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'D.MSK '), 0);
VALUES [D_PCB] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'D.PCB '), 0);
VALUES [S_LHD] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'S.LHD '), 0);
VALUES [S_VCT] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'S.VCT '), 0);
VALUES [S_FRK] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'S.FRK '), 0);
VALUES [U_DCB] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'U.DCB '), 0);
VALUES [U_RED] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'U.RED '), 0);
VALUES [U_CW1] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'U.CW1 '), 0);
VALUES [U_CW2] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'U.CW2 '), 0);
VALUES [U_CW3] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'U.CW3 '), 0);
VALUES [U_CW4] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'U.CW4 '), 0);
VALUES [U_SCB] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'U.SCB '), 0);
VALUES [CLK_LNK] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'C.LNK '), 0);
VALUES [CLK_RQT] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'C.RQT '), 0);
VALUES [CLK_EFN] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'C.EFN '), 0);
VALUES [CLK_TCB] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'C.TCB '), 0);
VALUES [CLK_TIM] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'C.TIM '), 0);
VALUES [CLK_LGTH] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'C.LGTH'), 0);
VALUES [CLK_MRKT] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'C.MRKT'), 0);
VALUES [CLK_SCHD] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'C.SCHD'), 0);
VALUES [CLK_SSHT] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'C.SSHT'), 0);
VALUES [CLK_SYST] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'C.SYST'), 0);
VALUES [CLK_SYTK] = SYM_VAL (.RSXMS_FILE, UPLIT (%ASCIZ'C.SYTK'), 0);
END; !OF GETSYM_1
GLOBAL ROUTINE GETBYT (FILE_PTR, LOCN) = !GET A BYTE FROM A CORE OR TASK IMAGE
!++
! FUNCTIONAL DESCRIPTION:
!
! FETCH A SPECIFIED BYTE FROM A CORE IMAGE OR TASK IMAGE.
!
! FORMAL PARAMETERS:
!
! FILE_PTR - FILE BLOCK WHICH CONTAINS POINTERS TO THE IMAGE
! LOCN - ADDRESS OF LOCATION TO FETCH
!
! IMPLICIT INPUTS:
!
! NONE
!
! IMPLICIT OUTPUTS:
!
! NONE
!
! ROUTINE VALUE:
!
! THE 8-BIT BYTE AT THE LOCATION, OR -1 IF ERROR.
!
! SIDE EFFECTS
!
! NONE
!
!--
BEGIN
BIND
ROUTINE_NAME = UPLIT (%ASCIZ'GETBYT');
MAP
FILE_PTR : REF FILE_BLOCK;
LOCAL
CORE_IMAGE : REF VECTOR,
LABEL_IMAGE : REF VECTOR,
CORE_LEN,
CORE_WORD,
RESULT,
BASE_ADDRESS;
IF (DEBUG GEQ 3)
THEN
BEGIN !DEBUG
PCRLF (1);
OUTPUT (1, %O'11');
OUTPUT (1, %O'11');
OUTSTR (1, UPLIT (%ASCIZ'GETBYT: '));
OUTNUM (1, .LOCN, 8, 6);
END; !DEBUG
!
! GET POINTERS TO THE MEMORY INFORMATION
!
CORE_IMAGE = .FILE_PTR [FILE_CORE];
CORE_LEN = .FILE_PTR [FILE_CORE_LEN];
LABEL_IMAGE = .FILE_PTR [FILE_LABEL];
!
! VALIDATE THE ADDRESS
!
BASE_ADDRESS = .LABEL_IMAGE [L$BSA] + (.LABEL_IMAGE [L$BSA + 1]*256);
IF (((.LOCN - .BASE_ADDRESS) GEQ .CORE_LEN) OR (.LOCN LSS .BASE_ADDRESS))
THEN
BEGIN
ERRMSG (0, 25, ROUTINE_NAME, .LOCN, FILE_PTR [FILE_NAME], 0, 0);
RESULT = -1;
END
ELSE
BEGIN
!
! FETCH THE DATA
!
CORE_WORD = .CORE_IMAGE [(.LOCN - .BASE_ADDRESS)/4];
RESULT = .CORE_WORD<(CASE ((.LOCN - .BASE_ADDRESS) AND 3) FROM 0 TO 3 OF
SET
[0] : 18;
[1] : 26;
[2] : 0;
[3] : 8;
TES), 8>
END;
IF (DEBUG GEQ 3)
THEN
BEGIN !DEBUG
OUTSTR (1, UPLIT (%ASCIZ', '));
OUTNUM (1, .RESULT, 8, 6);
END; !DEBUG
.RESULT
END; !OF GETBYT
GLOBAL ROUTINE GETWRD (FILE_PTR, LOCN) = !GET A WORD FROM A CORE OR TASK IMAGE
!++
! FUNCTIONAL DESCRIPTION:
!
! FETCH A SPECIFIED WORD FROM A CORE IMAGE OR TASK IMAGE.
!
! FORMAL PARAMETERS:
!
! FILE_PTR - FILE BLOCK WHICH CONTAINS POINTERS TO THE IMAGE
! LOCN - ADDRESS OF LOCATION TO FETCH
!
! IMPLICIT INPUTS:
!
! NONE
!
! IMPLICIT OUTPUTS:
!
! NONE
!
! ROUTINE VALUE:
!
! THE 16-BIT WORD AT THE LOCATION, OR -1 IF ERROR.
!
! SIDE EFFECTS
!
! NONE
!
!--
BEGIN
BIND
ROUTINE_NAME = UPLIT (%ASCIZ'GETWRD');
MAP
FILE_PTR : REF FILE_BLOCK;
LOCAL
CORE_IMAGE : REF VECTOR,
LABEL_IMAGE : REF VECTOR,
CORE_LEN,
CORE_WORD,
RESULT,
BASE_ADDRESS;
IF (DEBUG GEQ 3)
THEN
BEGIN !DEBUG
PCRLF (1);
OUTPUT (1, %O'11');
OUTPUT (1, %O'11');
OUTSTR (1, UPLIT (%ASCIZ'GETWRD: '));
OUTNUM (1, .LOCN, 8, 6);
END; !DEBUG
!
! GET POINTERS TO THE MEMORY INFORMATION
!
CORE_IMAGE = .FILE_PTR [FILE_CORE];
CORE_LEN = .FILE_PTR [FILE_CORE_LEN];
LABEL_IMAGE = .FILE_PTR [FILE_LABEL];
!
! VALIDATE THE ADDRESS
!
BASE_ADDRESS = .LABEL_IMAGE [L$BSA] + (.LABEL_IMAGE [L$BSA + 1]*256);
IF (((.LOCN - .BASE_ADDRESS) GEQ .CORE_LEN) OR (.LOCN LSS .BASE_ADDRESS)) OR ((.LOCN AND %O'1') NEQ 0)
THEN
BEGIN
ERRMSG (0, 25, ROUTINE_NAME, .LOCN, FILE_PTR [FILE_NAME], 0, 0);
RESULT = -1;
END
ELSE
BEGIN
!
! FETCH THE DATA
!
CORE_WORD = .CORE_IMAGE [(.LOCN - .BASE_ADDRESS)/4];
RESULT = .CORE_WORD<(CASE ((.LOCN - .BASE_ADDRESS) AND 3) FROM 0 TO 2 OF
SET
[0] : 18;
[1] : -1;
[2] : 0;
TES), 8> + !
(.CORE_WORD<(CASE ((.LOCN + 1 - .BASE_ADDRESS) AND 3) FROM 1 TO 3 OF
SET
[1] : 26;
[2] : -1;
[3] : 8;
TES), 8>*256);
END;
IF (DEBUG GEQ 3)
THEN
BEGIN !DEBUG
OUTSTR (1, UPLIT (%ASCIZ', '));
OUTNUM (1, .RESULT, 8, 6);
END; !DEBUG
.RESULT
END; !OF GETWRD
GLOBAL ROUTINE PUTBYT (FILE_PTR, LOCN, VAL) : NOVALUE = !PUT A BYTE IN A CORE IMAGE
!++
! FUNCTIONAL DESCRIPTION:
!
! STORE A SPECIFIED BYTE IN A CORE IMAGE.
!
! FORMAL PARAMETERS:
!
! FILE_PTR - FILE BLOCK WHICH CONTAINS POINTERS TO THE IMAGE
! (WILL ALWAYS BE THE KERNEL)
! LOCN - ADDRESS OF LOCATION TO STORE
! VAL - VALUE TO BE STORED; ONLY THE LOW-ORDER 8 BITS ARE STORED
!
! IMPLICIT INPUTS:
!
! NONE
!
! IMPLICIT OUTPUTS:
!
! NONE
!
! ROUTINE VALUE:
!
! NONE
!
! SIDE EFFECTS
!
! CHANGES THE CORE IMAGE
!
!--
BEGIN
BIND
ROUTINE_NAME = UPLIT (%ASCIZ'PUTBYT');
MAP
FILE_PTR : REF FILE_BLOCK;
LOCAL
CORE_IMAGE : REF VECTOR,
LABEL_IMAGE : REF VECTOR,
CORE_LEN,
CORE_WORD,
BASE_ADDRESS;
IF (DEBUG GEQ 3)
THEN
BEGIN !DEBUG
PCRLF (1);
OUTPUT (1, %O'11');
OUTPUT (1, %O'11');
OUTSTR (1, UPLIT (%ASCIZ'PUTBYT: '));
OUTNUM (1, .LOCN, 8, 6);
OUTSTR (1, UPLIT (%ASCIZ', '));
OUTNUM (1, .VAL, 8, 6);
END; !DEBUG
!
! GET POINTERS TO THE MEMORY INFORMATION
!
CORE_IMAGE = .FILE_PTR [FILE_CORE];
CORE_LEN = .FILE_PTR [FILE_CORE_LEN];
LABEL_IMAGE = .FILE_PTR [FILE_LABEL];
!
! VALIDATE THE ADDRESS
!
BASE_ADDRESS = .LABEL_IMAGE [L$BSA] + (.LABEL_IMAGE [L$BSA + 1]*256);
IF (((.LOCN - .BASE_ADDRESS) GEQ .CORE_LEN) OR (.LOCN LSS .BASE_ADDRESS))
THEN
ERRMSG (0, 25,
ROUTINE_NAME, .LOCN, FILE_PTR [FILE_NAME], 0, 0)
ELSE
BEGIN
!
! STORE THE DATA
!
CORE_WORD = .CORE_IMAGE [(.LOCN - .BASE_ADDRESS)/4];
CORE_WORD<(CASE ((.LOCN - .BASE_ADDRESS) AND 3) FROM 0 TO 3 OF
SET
[0] : 18;
[1] : 26;
[2] : 0;
[3] : 8;
TES), 8> = .VAL;
CORE_IMAGE [(.LOCN - .BASE_ADDRESS)/4] = .CORE_WORD;
END;
END; !OF PUTBYT
GLOBAL ROUTINE PUTWRD (FILE_PTR, LOCN, VAL) : NOVALUE = !PUT A WORD IN A CORE IMAGE
!++
! FUNCTIONAL DESCRIPTION:
!
! STORE A 16-BIT WORD IN A CORE IMAGE
!
! FORMAL PARAMETERS:
!
! FILE_PTR - FILE BLOCK WHICH CONTAINS POINTERS TO THE IMAGE
! (WILL ALWAYS BE KERNEL)
! LOCN - ADDRESS OF LOCATION TO STORE
! VAL - VALUE TO STORE; ONLY THE LOW-ORDER 16 BITS ARE STORED
!
! IMPLICIT INPUTS:
!
! NONE
!
! IMPLICIT OUTPUTS:
!
! NONE
!
! ROUTINE VALUE:
!
! NONE
!
! SIDE EFFECTS
!
! CHANGES THE CORE IMAGE
!
!--
BEGIN
BIND
ROUTINE_NAME = UPLIT (%ASCIZ'PUTWRD');
MAP
FILE_PTR : REF FILE_BLOCK;
LOCAL
CORE_IMAGE : REF VECTOR,
LABEL_IMAGE : REF VECTOR,
CORE_LEN,
CORE_WORD,
BASE_ADDRESS;
IF (DEBUG GEQ 3)
THEN
BEGIN !DEBUG
PCRLF (1);
OUTPUT (1, %O'11');
OUTPUT (1, %O'11');
OUTSTR (1, UPLIT (%ASCIZ'PUTWRD: '));
OUTNUM (1, .LOCN, 8, 6);
OUTSTR (1, UPLIT (%ASCIZ', '));
OUTNUM (1, .VAL, 8, 6);
END; !DEBUG
!
! GET POINTERS TO THE MEMORY INFORMATION
!
CORE_IMAGE = .FILE_PTR [FILE_CORE];
CORE_LEN = .FILE_PTR [FILE_CORE_LEN];
LABEL_IMAGE = .FILE_PTR [FILE_LABEL];
!
! VALIDATE THE ADDRESS
!
BASE_ADDRESS = .LABEL_IMAGE [L$BSA] + (.LABEL_IMAGE [L$BSA + 1]*256);
IF (((.LOCN - .BASE_ADDRESS) GEQ .CORE_LEN) OR (.LOCN LSS .BASE_ADDRESS) OR ((.LOCN AND %O'1') NEQ 0))
THEN
ERRMSG (0, 25, ROUTINE_NAME, .LOCN, FILE_PTR [FILE_NAME], 0, 0)
ELSE
BEGIN
!
! STORE THE DATA
!
CORE_WORD = .CORE_IMAGE [(.LOCN - .BASE_ADDRESS)/4];
CORE_WORD<(CASE ((.LOCN - .BASE_ADDRESS) AND 3) FROM 0 TO 2 OF
SET
[0] : 18;
[1] : -1;
[2] : 0;
TES), 8> = .VAL<0, 8>;
CORE_WORD<(CASE ((.LOCN + 1 - .BASE_ADDRESS) AND 3) FROM 1 TO 3 OF
SET
[1] : 26;
[2] : -1;
[3] : 8;
TES), 8> = .VAL<8, 8>;
CORE_IMAGE [(.LOCN - .BASE_ADDRESS)/4] = .CORE_WORD;
END;
END; !OF PUTWRD
GLOBAL ROUTINE ALOCB (FILE_PTR, AMOUNT, DUMMY, VALUES) = !ALLOCATE PDP-11 CORE
!++
! FUNCTIONAL DESCRIPTION:
!
! ALLOCATE SPACE FROM THE PDP-11'S SYSTEM POOL
! (TRANSLATED FROM RSX-11M VERSION 3.1, MODULE CORAL)
! (MODIFIED BASED ON VMR TO ALLOCATE TOP-DOWN.)
! (Modified to remove Allocation from MCB partition)
!
! FORMAL PARAMETERS:
!
! FILE_PTR - FILE BLOCK WHICH CONTAINS POINTERS TO THE IMAGE
! AND SYMBOL TABLE
! AMOUNT - THE NUMBER OF BYTES TO GET
! DUMMY - Unused in this version was:
! (WHERE - 1 = COMM EXEC PARTITION OR SYSTEM POOL,
! 0 = SYSTEM POOL ONLY)
! VALUES - BLOCK WHICH HOLDS SYMBOL VALUES
!
! IMPLICIT INPUTS:
!
! NONE
!
! IMPLICIT OUTPUTS:
!
! MODIFIES THE CORE IMAGE TO ALLOCATE THE SPACE
!
! ROUTINE VALUE:
!
! PDP-11 ADDRESS OF WHERE CORE HAS BEEN ALLOCATED, OR 0
!
! SIDE EFFECTS
!
! PRINTS AN ERROR MESSAGE IF PDP-11 SYSTEM POOL IS EXHAUSTED
!
!--
BEGIN
BIND
ROUTINE_NAME = UPLIT (%ASCIZ'ALOCB');
MAP
FILE_PTR : REF FILE_BLOCK,
VALUES : REF VNPVAL_BLOCK;
LOCAL
R0,
R1,
R2,
SCAN_DONE,
TEMP,
RESULT;
IF (DEBUG GEQ 2)
THEN
BEGIN !DEBUG
PCRLF (1);
OUTPUT (1, %O'11');
OUTSTR (1, UPLIT (%ASCIZ'ALOCB: '));
OUTNUM (1, .AMOUNT, 8, 6);
OUTSTR (1, UPLIT (%ASCIZ', '));
END; !DEBUG
RESULT = -1;
R1 = .AMOUNT; !SIZE OF CORE BUFFER TO ALLOCATE IN BYTES
R0 = .VALUES [CRAVL] - 2; !POINT TO ALLOCATION MASK WORD
R1 = .R1 + GETWRD (.FILE_PTR, .R0); !ROUND TO NEXT BOUNDRY
R1 = .R1 AND ( NOT (GETWRD (.FILE_PTR, .R0))); !CLEAR EXCESS
R0 = .R0 + 2;
IF (.R1 NEQ 0)
THEN
!ASSUME ZERO LENGTH BLOCK; IF EQ ZERO LENGTH REQUEST
BEGIN
SCAN_DONE = 0;
WHILE (.SCAN_DONE EQL 0) DO
BEGIN
R2 = .R0; !SAVE ADDRESS OF CURRENT BLOCK
R0 = GETWRD (.FILE_PTR, .R2); !GET ADDRESS OF NEXT BLOCK
IF (.R0 EQL 0)
THEN
SCAN_DONE = -1 !IF EQ END OF CHAIN
ELSE
BEGIN
TEMP = GETWRD (.FILE_PTR, .R0 + 2);
IF (.TEMP GEQ .R1)
THEN
!BLOCK BIG ENOUGH? IF LO NO
BEGIN
IF (.TEMP GTR .R1)
THEN
!IF EQ, BLOCK IS EXACT SIZE
BEGIN
PUTWRD (.FILE_PTR, .R0 + 2, .TEMP - .R1); !REDUCE SIZE OF FREE BLOCK
R0 = .R0 + .TEMP - .R1; !CALCULATE ADDRESS OF ALLOCATED BLOCK
END !.TEMP GTR .R1
ELSE
PUTWRD (.FILE_PTR, .R2, GETWRD (.FILE_PTR, .R0)); !LINK AROUND ALLOCATED BLOCK
SCAN_DONE = 1;
END; !.TEMP GEQ .R1
END; !.R0 EQL 0
END; !.SCAN_DONE EQL 0
END !.R1 NEQ 0
ELSE
SCAN_DONE = -1;
IF (.SCAN_DONE GTR 0) THEN RESULT = .R0;
IF (.RESULT LSS 0) THEN ERRMSG (0, 26, ROUTINE_NAME, FILE_PTR [FILE_NAME], .AMOUNT, 0, 0);
IF (DEBUG GEQ 2)
THEN
BEGIN !DEBUG
OUTSTR (1, UPLIT (%ASCIZ', '));
OUTNUM (1, .RESULT, 8, 6);
END; !DEBUG
.RESULT
END; !OF ALOCB
GLOBAL ROUTINE DEACB (FILE_PTR, LOCN, AMOUNT, VALUES) : NOVALUE = !DEALLOCATE PDP-11 CORE
!++
! FUNCTIONAL DESCRIPTION:
!
! DEALLOCATE SPACE FROM THE PDP-11'S SYSTEM POOL
!
! FORMAL PARAMETERS:
!
! FILE_PTR - FILE BLOCK WHICH CONTAINS POINTERS TO THE IMAGE
! AND SYMBOL TABLE
! LOCN - THE STARTING ADDRESS OF THE SPACE TO BE DEALLOCATED
! AMOUNT - THE NUMBER OF BYTES TO FREE
! VALUES - BLOCK WHICH HOLDS SYMBOL VALUES
!
! IMPLICIT INPUTS:
!
! NONE
!
! IMPLICIT OUTPUTS:
!
! MODIFIES THE CORE IMAGE TO DEALLOCATE THE SPACE
!
! ROUTINE VALUE:
!
! NONE
!
! SIDE EFFECTS
!
! NONE
!
!--
BEGIN
BIND
ROUTINE_NAME = UPLIT (%ASCIZ'DEACB');
MAP
FILE_PTR : REF FILE_BLOCK,
VALUES : REF VNPVAL_BLOCK;
LOCAL
R0,
R1,
R2,
R3,
SAVE,
SCAN_DONE,
TEMP;
IF (DEBUG GEQ 2)
THEN
BEGIN !DEBUG
PCRLF (1);
OUTPUT (1, %O'11');
OUTSTR (1, UPLIT (%ASCIZ'DEACB: '));
OUTNUM (1, .LOCN, 8, 6);
OUTSTR (1, UPLIT (%ASCIZ', '));
OUTNUM (1, .AMOUNT, 8, 6);
END; !DEBUG
R0 = .LOCN; !ADDRESS OF STORAGE TO FREE
R1 = .AMOUNT; !NUMBER OF BYTES TO FREE
R3 = .VALUES [CRAVL] - 2; !POINT TO ALLOCATION MASK WORD
TEMP = GETWRD (.FILE_PTR, .R3); !ROUND TO NEXT BOUNDRY
R1 = .R1 + .TEMP;
R1 = .R1 AND ( NOT .TEMP);
R3 = .R3 + 2;
IF (.R1 NEQ 0) !IF EQ NO BLOCK TO RELEASE
THEN
BEGIN
SCAN_DONE = 0;
WHILE (.SCAN_DONE EQL 0) DO
BEGIN
R2 = .R3; !SAVE ADDRESS OF CURRENT BLOCK
R3 = GETWRD (.FILE_PTR, .R3); !GET ADDRESS OF NEXT BLOCK
IF (.R3 EQL 0) !IF EQ END OF CHAIN
THEN
SCAN_DONE = 1
ELSE
IF (.R0 LSS .R3) !BLOCK GO HERE?
THEN
SCAN_DONE = 1; !IF HIS NO
END; !OF WHILE SCAN_DONE
PUTWRD (.FILE_PTR, .R0, .R3); !ASSUME NO AGLOMERATION
SAVE = .R0; !CALCULATE ADDRESS OF NEW BLOCK
SAVE = .SAVE + .R1;
IF (.SAVE GEQ %O'200000') !IF CS ILLEGAL DEALLOCATION
THEN
ERRMSG (0, 27, ROUTINE_NAME, FILE_PTR [FILE_NAME], .AMOUNT, .LOCN, 1)
ELSE
BEGIN
IF (.R0 LSS .VALUES [POOL]) ! DEALLOCATION BEFORE FRONT OF LIST?
THEN !IF LO, YES
ERRMSG (0, 27, ROUTINE_NAME, FILE_PTR [FILE_NAME], .AMOUNT, .LOCN, 2)
ELSE
BEGIN
TEMP = GETWRD (.FILE_PTR, .VALUES [EXSIZ]);
IF (.SAVE GTR .TEMP) !DEALLOCATION PAST END OF POOL?
THEN !IF HI YES
ERRMSG (0, 27, ROUTINE_NAME, FILE_PTR [FILE_NAME], .AMOUNT, .LOCN, 3)
ELSE
BEGIN
IF ((.R3 LSS .SAVE) !EQUAL TO NEXT IN CHAIN?
AND (.R3 NEQ 0)) !INSERT AT END OF LIST?
THEN !IF EQ YES, OK
ERRMSG (0, 27, ROUTINE_NAME, FILE_PTR [FILE_NAME], .AMOUNT, .LOCN, 4)
ELSE
BEGIN
IF (.R3 EQL .SAVE)
THEN
!IF NE NO
BEGIN
TEMP = GETWRD (.FILE_PTR, .R3); !MOVE LINK WORD TO BLOCK RELEASED
R3 = .R3 + 2;
PUTWRD (.FILE_PTR, .R0, .TEMP);
TEMP = GETWRD (.FILE_PTR, .R3); !MERGE TWO BLOCKS
R1 = .R1 + .TEMP;
END;
SAVE = .R2; !SAVE ADDRESS OF PREVIOUS BLOCK
PUTWRD (.FILE_PTR, .R2, .R0); !ASSUME NO AGLOMERATION
R2 = .R2 + 2;
TEMP = GETWRD (.FILE_PTR, .R2); !CALCULATE ADDRESS OF NEXT BLOCK
SAVE = .SAVE + .TEMP;
IF (.R0 LSS .SAVE) !EQUAL TO BLOCK BEING RELEASED?
THEN !IF HIS, NO OVERLAP
ERRMSG (0, 27, ROUTINE_NAME, FILE_PTR [FILE_NAME], .AMOUNT, .LOCN, 5)
ELSE
BEGIN
IF (.R0 EQL .SAVE) !IF NE NO
THEN
BEGIN
R1 = .R1 + GETWRD (.FILE_PTR, .R2); !MERGE TWO BLOCKS
TEMP = GETWRD (.FILE_PTR, .R0); !MOVE LINK WORD TO PREVIOUS BLOCK
R2 = .R2 - 2;
PUTWRD (.FILE_PTR, .R2, .TEMP);
R0 = .R2; !SET NEW ADDRESS OF BLOCK
END;
PUTWRD (.FILE_PTR, .R0 + 2, .R1); !SET SIZE OF BLOCK RELEASED
END;
END;
END;
END;
END;
END;
END; !OF DEACB
GLOBAL ROUTINE M_PCB (KERNEL_FILE, PAR_NAME, PAR_MAIN, PAR_BASE, PAR_TOP, BUSY_FLAGS, STAT_FLAGS,
MIN_PCB_LEN, VALUES) = !CREATE A PCB
!++
! FUNCTIONAL DESCRIPTION:
!
! CREATE A PARTITION CONTROL BLOCK (PCB). FILL IN ITS FIELDS
! AND PUT IT ON THE KERNEL'S LIST OF PCBS. THIS ROUTINE WILL
! CREATE EITHER A MAIN PARTITION OR A SUB PARTITION.
!
! FORMAL PARAMETERS:
!
! KERNEL_FILE - FILE BLOCK FOR THE KERNEL
! PAR_NAME - PARTITION NAME, SIX ASCII CHARACTERS
! PAR_MAIN - MAIN PCB FOR SUB-PARTITION, OR 0 FOR MAIN PARTITION
! PAR_BASE - BASE ADDRESS OF THIS PARTITION
! PAR_TOP - HIGHEST ADDRESS OF THIS PARTITION, OR 0
! BUSY_FLAGS - FLAGS FOR THE P.BUSY WORD
! STAT_FLAGS - FLAGS FOR THE P.STAT WORD
! MIN_PCB_LEN - MINIMUM LENGTH PCB TO CREATE
! VALUES - VALUES READ FROM CETAB.MAC AND THE SYMBOL TABLES
!
! IMPLICIT INPUTS:
!
! NONE
!
! IMPLICIT OUTPUTS:
!
! MAY STORE TOP OF PARTITION IN .KERNEL_FILE[FILE_HWM] FOR THE
! SAKE OF THE NEXT CALL TO M_PCB.
!
! ROUTINE VALUE:
!
! PDP-11 ADDRESS OF THE PCB CREATED
!
! SIDE EFFECTS
!
! CHANGES THE CORE IMAGE
!
!--
BEGIN
BIND
ROUTINE_NAME = UPLIT (%ASCIZ'M_PCB');
MAP
KERNEL_FILE : REF FILE_BLOCK,
VALUES : REF VNPVAL_BLOCK;
LOCAL
PCB_ADDR,
HIGH_EXEC_ADDR,
FLAGS,
TEMP1,
TEMP2,
DYNAMIC_PAR,
R50VAL : VECTOR [4];
IF (DEBUG GEQ 1)
THEN
BEGIN !DEBUG
PCRLF (1);
OUTSTR (1, UPLIT (%ASCIZ'MAKE PCB: '));
OUTSTR (1, .PAR_NAME);
OUTSTR (1, UPLIT (%ASCIZ', '));
OUTNUM (1, .PAR_BASE, 8, 6);
OUTSTR (1, UPLIT (%ASCIZ', '));
OUTNUM (1, .PAR_TOP, 8, 6);
END; !DEBUG
!
! STORE TOP OF PARTITION IN THE HIGH-WATER-MARK (HWM) CELL.
! IT CAN BE USED AS THE BASE FOR THE NEXT CALL TO M_PCB
! OR AS THE LIMIT FOR WHAT TO WRITE OUT OF THE CORE IMAGE.
! NOTE THAT THE HWM IS ONLY STORED IF THE NEW VALUE IS LARGER THAN
! THE VALUE ALREADY IN THE CELL. THIS IS BECAUSE OF SUB-PARTITIONS
! AND SYSTEM-CONTROLLED PARTITIONS.
!
IF (.KERNEL_FILE [FILE_HWM] LSS (.PAR_TOP OR 63)) THEN KERNEL_FILE [FILE_HWM] = .PAR_TOP OR 63;
!
! FIND THE FLAGS FROM THIS CORE IMAGE.
! WE NEED THEM TO SUPPORT PLAS.
!
FLAGS = GETWRD (.KERNEL_FILE, .VALUES [FMASK]);
!
! DETERMINE IF THIS IS A DYNAMIC PARTITION
! (THAT IS, IF IT IS A SUB-PARTITION OF A SYSTEM-CONTROLLED PARTITION)
!
IF (.PAR_MAIN EQL 0)
THEN
DYNAMIC_PAR = 0
ELSE
BEGIN !SUB-PARTITION
DYNAMIC_PAR = 0;
IF ((GETWRD (.KERNEL_FILE, .PAR_MAIN + .VALUES [P_STAT]) AND .VALUES [PS_SYS]) NEQ 0)
THEN
DYNAMIC_PAR = 1;
END;
!
! NOW ALLOCATE A PARTITION CONTROL BLOCK.
!
PCB_ADDR = ALOCB (.KERNEL_FILE, MAX (.VALUES [P_LGTH], .MIN_PCB_LEN), 0, .VALUES);
!
! NEXT, STORE APPROPRIATE VALUES IN IT
!
PUTWRD (.KERNEL_FILE, .PCB_ADDR + .VALUES [P_LNK], 0);
PUTBYT (.KERNEL_FILE, .PCB_ADDR + .VALUES [P_PRI], 0);
PUTBYT (.KERNEL_FILE, .PCB_ADDR + .VALUES [P_IOC], 0);
ATOR50 (.PAR_NAME, R50VAL);
INCR COUNTER FROM 0 TO 3 DO
PUTBYT (.KERNEL_FILE, .PCB_ADDR + .VALUES [P_NAM] + .COUNTER, .R50VAL [.COUNTER]);
PUTWRD (.KERNEL_FILE, .PCB_ADDR + .VALUES [P_SUB], 0);
IF (.PAR_MAIN NEQ 0)
THEN
BEGIN !LINK SUB-PARTITION TO PARTITION'S LIST
TEMP1 = .PAR_MAIN;
WHILE (.TEMP1 NEQ 0) DO
BEGIN
TEMP2 = .TEMP1;
TEMP1 = GETWRD (.KERNEL_FILE, .TEMP2 + .VALUES [P_SUB]);
END;
PUTWRD (.KERNEL_FILE, .TEMP2 + .VALUES [P_SUB], .PCB_ADDR);
END;
IF (.PAR_MAIN EQL 0)
THEN
PUTWRD (.KERNEL_FILE, .PCB_ADDR + .VALUES [P_MAIN], .PCB_ADDR)
ELSE
PUTWRD (.KERNEL_FILE, .PCB_ADDR + .VALUES [P_MAIN], .PAR_MAIN);
TEMP1 = .PAR_BASE/64;
PUTWRD (.KERNEL_FILE, .PCB_ADDR + .VALUES [P_REL], .TEMP1);
IF (.PAR_TOP NEQ 0)
THEN
BEGIN
TEMP1 = (.PAR_TOP - .PAR_BASE + 64)/64;
PUTWRD (.KERNEL_FILE, .PCB_ADDR + .VALUES [P_SIZE], .TEMP1);
END;
PUTWRD (.KERNEL_FILE, .PCB_ADDR + .VALUES [P_WAIT], 0);
IF (.DYNAMIC_PAR EQL 0)
THEN
PUTWRD (.KERNEL_FILE, .PCB_ADDR + .VALUES [P_WAIT] + 2,
.PCB_ADDR + .VALUES [P_WAIT])
ELSE
PUTWRD (.KERNEL_FILE, .PCB_ADDR + .VALUES [P_WAIT] + 2, 0);
PUTWRD (.KERNEL_FILE, .PCB_ADDR + .VALUES [P_BUSY], .BUSY_FLAGS);
PUTWRD (.KERNEL_FILE, .PCB_ADDR + .VALUES [P_TCB], 0);
PUTWRD (.KERNEL_FILE, .PCB_ADDR + .VALUES [P_STAT], .STAT_FLAGS);
PUTWRD (.KERNEL_FILE, .PCB_ADDR + .VALUES [P_HDR], 0);
IF (.FLAGS AND .VALUES [FE_PLA])
THEN
BEGIN ! PLAS SUPPORT
PUTWRD (.KERNEL_FILE, .PCB_ADDR + .VALUES [P_PRO], 0);
PUTWRD (.KERNEL_FILE, .PCB_ADDR + .VALUES [P_ATT], 0);
PUTWRD (.KERNEL_FILE, .PCB_ADDR + .VALUES [P_ATT] + 2, .PCB_ADDR + .VALUES [P_ATT]);
END; !OF PLAS SUPPORT
!
! UNLESS THIS IS A SUB-PARTITION OF A SYSTEM-CONTROLLED PARTITION,
! LINK IT INTO THE KERNEL'S LIST OF PARTITIONS.
!
IF (.DYNAMIC_PAR EQL 0)
THEN
BEGIN !LINK IT IN
TEMP1 = .VALUES [PARHD]; !HEADER OF PARTITION LIST
WHILE (.TEMP1 NEQ 0) DO
BEGIN
TEMP2 = .TEMP1;
TEMP1 = GETWRD (.KERNEL_FILE, .TEMP2 + .VALUES [P_LNK]);
END;
PUTWRD (.KERNEL_FILE, .TEMP2 + .VALUES [P_LNK], .PCB_ADDR);
END;
!
! WE ARE DONE, RETURN THE PCB ADDRESS
!
.PCB_ADDR
END; !OF M_PCB
GLOBAL ROUTINE INSTAL (KERNEL_FILE, TASK_FILE, TASK_NAME, PCB_ARG, VALUES) : NOVALUE = !INSTALL A TASK
!++
! FUNCTIONAL DESCRIPTION:
!
! INSTALL A TASK IN A GIVEN PARTITION, OR IN THE
! SYSTEM-CONTROLLED PARTITION. FIX THE TASK IN CORE.
!
! FORMAL PARAMETERS:
!
! KERNEL_FILE - POINTER TO THE FILE BLOCK WHICH DESCRIBES THE
! RSX-11S KERNEL
! TASK_FILE - POINTER TO A SIMILAR FILE BLOCK WHICH DESCRIBES
! THE TASK TO BE INSTALLED
! TASK_NAME - POINTER TO THE TASK NAME, IN ASCII
! PCB_ARG - THE PDP-11 ADDRESS OF THE PARTITION INTO WHICH
! THE TASK IS TO BE INSTALLED. IF 0, THE TASK IS TO BE
! INSTALLED IN THE SYSTEM-CONTROLLED PARTITION.
! VALUES - POINTER TO THE VALUES BLOCK
!
! IMPLICIT INPUTS:
!
! NONE
!
! IMPLICIT OUTPUTS:
!
! NONE
!
! ROUTINE VALUE:
!
! NONE
!
! SIDE EFFECTS
!
! MODIFIES THE KERNEL'S DATA STRUCTURES
!
!--
BEGIN
BIND
ROUTINE_NAME = UPLIT (%ASCIZ'INSTALL');
MAP
KERNEL_FILE : REF FILE_BLOCK,
TASK_FILE : REF FILE_BLOCK,
VALUES : REF VNPVAL_BLOCK;
LOCAL
TCB_ADDR,
PCB_ADDR,
PCB_NAME : VECTOR [CH$ALLOCATION(7)],
HDR_ADDR,
HDR_SIZE,
TASK_LABEL : REF VECTOR [1024],
TEMP1,
TEMP2,
TEMP3,
TASK_BASE,
TASK_TOP,
TASK_SIZE,
ASCVAL : VECTOR [4],
TASK_FLAGS,
PARTITION_BASE,
NLUN,
PRIORITY,
SEARCH_DONE;
IF (DEBUG GEQ 1)
THEN
BEGIN !DEBUG
PCRLF (1);
OUTSTR (1, UPLIT (%ASCIZ'INSTALL: '));
OUTSTR (1, TASK_FILE [FILE_NAME]);
END; !DEBUG
!
! COMPUTE THE SIZE OF THE TASK, AND ITS FLAGS
!
TASK_LABEL = .TASK_FILE [FILE_LABEL];
TASK_BASE = .TASK_LABEL [L$BSA] + (.TASK_LABEL [L$BSA + 1]*256);
TASK_TOP = .TASK_LABEL [L$BHGV] + (.TASK_LABEL [L$BHGV + 1]*256);
TASK_SIZE = .TASK_TOP - .TASK_BASE + 1;
TASK_FLAGS = .TASK_LABEL [L$BFLG] + (.TASK_LABEL [L$BFLG + 1]*256);
!
! ALLOCATE A TCB
!
TCB_ADDR = ALOCB (.KERNEL_FILE, .VALUES [T_LGTH], 0, .VALUES);
!
! COMPUTE THE LENGTH OF THE HEADER, AND ALLOCATE IT.
!
HDR_SIZE = GETWRD (.TASK_FILE, .TASK_BASE + .VALUES [H_HDLN]) + 2;
HDR_ADDR = ALOCB (.KERNEL_FILE, .HDR_SIZE, 0, .VALUES);
!
! FETCH THE NAME OF THE TASK, AND ITS PRIORITY
!
ATOR50 (.TASK_NAME, ASCVAL);
PRIORITY = .TASK_LABEL [L$BPRI];
!
! IF THE TASK'S PRIORITY FIELD IS 0, DEFAULT IT TO 50.
!
IF (.PRIORITY EQL 0) THEN PRIORITY = 50;
!
! FETCH NAME OF PARTITION IN ASCIZ
!
TEMP1 = (.TASK_LABEL [L$BPAR]^16) + (.TASK_LABEL [L$BPAR + 1]^24) + (.TASK_LABEL [L$BPAR + 2]) + (
.TASK_LABEL [L$BPAR + 3]^8);
R50TOA (.TEMP1, PCB_NAME);
!
! IF WE NEED A PCB, ALLOCATE ONE. OTHERWISE USE THE ONE SPECIFIED.
!
IF (.PCB_ARG NEQ 0)
THEN
PCB_ADDR = .PCB_ARG
ELSE
BEGIN !ALLOCATE A PCB
!
! FIND THE SYSTEM-CONTROLLED PARTITION
!
TEMP1 = .VALUES [PARHD];
SEARCH_DONE = 0;
WHILE (.SEARCH_DONE EQL 0) DO
BEGIN
TEMP2 = GETWRD (.KERNEL_FILE, .TEMP1);
IF (.TEMP2 EQL 0)
THEN
SEARCH_DONE = -1
ELSE
BEGIN
TEMP3 = GETWRD (.KERNEL_FILE, .TEMP2 + .VALUES [P_STAT]);
IF ((.TEMP3 AND .VALUES [PS_SYS]) NEQ 0)
THEN
SEARCH_DONE = 1
ELSE
TEMP1 = .TEMP2 + .VALUES [P_LNK];
END;
END;
IF (.SEARCH_DONE LEQ 0) THEN ERROR (UPLIT (%ASCIZ'NO GEN PARTITION - INSTALL'));
!
! NOW ALLOCATE A SUB-PARTITION OF THE SYSTEM-CONTROLLED PARTITION
!
PCB_ADDR = M_PCB (.KERNEL_FILE, PCB_NAME, .TEMP2, .KERNEL_FILE [FILE_HWM],
.KERNEL_FILE [FILE_HWM] + .TASK_SIZE, %O'000000', .VALUES [PS_SYS], 0, .VALUES);
END;
!
! BE SURE THE TCB IS ALL ZERO, SO WE WON'T HAVE TO EXPLICITLY
! CLEAR ZERO FIELDS BELOW.
!
INCR COUNTER FROM 0 TO .VALUES [T_LGTH] DO
PUTBYT (.KERNEL_FILE, .TCB_ADDR + .COUNTER, 0);
!
! FILL IN THE TCB
!
PUTBYT (.KERNEL_FILE, .TCB_ADDR + .VALUES [T_PRI], .PRIORITY);
INCR COUNTER FROM 0 TO 3 DO
PUTBYT (.KERNEL_FILE, .TCB_ADDR + .VALUES [T_NAM] + .COUNTER, .ASCVAL [.COUNTER]);
PUTWRD (.KERNEL_FILE, .TCB_ADDR + .VALUES [T_RCVL] + 2, .TCB_ADDR + .VALUES [T_RCVL]);
PUTWRD (.KERNEL_FILE, .TCB_ADDR + .VALUES [T_ASTL] + 2, .TCB_ADDR + .VALUES [T_ASTL]);
PUTWRD (.KERNEL_FILE, .TCB_ADDR + .VALUES [T_STAT], .VALUES [TS_EXE]);
PUTWRD (.KERNEL_FILE, .TCB_ADDR + .VALUES [T_ST2], .VALUES [T2_CHK] OR .VALUES [T2_FXD]);
PUTWRD (.KERNEL_FILE, .TCB_ADDR + .VALUES [T_ST3], .VALUES [T3_PMD] OR !
(IF ((.TASK_FLAGS AND TS$PRV) NEQ 0) THEN .VALUES [T3_PRV] ELSE 0) OR !
(IF ((.TASK_FLAGS AND TS$ACP) NEQ 0) THEN .VALUES [T3_ACP] ELSE 0) OR !
(IF ((.TASK_FLAGS AND (TS$NSD OR TS$ACP)) NEQ 0) THEN .VALUES [T3_NSD] ELSE 0));
PUTBYT (.KERNEL_FILE, .TCB_ADDR + .VALUES [T_DPRI], .PRIORITY);
!
! SET THE 3-BYTE FIELD WHICH SPECIFIES WHERE ON ITS LOAD DEVICE
! THIS TASK CAME FROM TO 0.
!
INCR COUNTER FROM 0 TO 3 DO
PUTBYT (.KERNEL_FILE, .TCB_ADDR + .VALUES [T_LBN] + .COUNTER, 0);
!
! PRETEND THAT THIS TASK CAME FROM DEVICE LB:
! FIND THE UCB ADDRESS FOR LB, AND STORE IT IN THE TCB.
!
SEARCH_DONE = 0;
TEMP1 = GETWRD (.KERNEL_FILE, .VALUES [DEVHD]);
WHILE (.SEARCH_DONE EQL 0) DO
BEGIN
IF (GETWRD (.KERNEL_FILE, .TEMP1 + .VALUES [D_NAM]) EQL (%C'L' + (256*%C'B')))
THEN
BEGIN
TEMP1 = GETWRD (.KERNEL_FILE, .TEMP1 + .VALUES [D_UCB]);
SEARCH_DONE = 1;
END
ELSE
BEGIN
TEMP1 = GETWRD (.KERNEL_FILE, .TEMP1 + .VALUES [D_LNK]);
IF (.TEMP1 EQL 0) THEN SEARCH_DONE = -1;
END;
END;
IF (.SEARCH_DONE LEQ 0) THEN ERROR (UPLIT (%ASCIZ'NO DEVICE LB - INSTALL'));
!
! WE HAVE THE UCB ADDRESS OF LB IN TEMP1.
!
PUTWRD (.KERNEL_FILE, .TCB_ADDR + .VALUES [T_LDV], .TEMP1);
PUTWRD (.KERNEL_FILE, .TCB_ADDR + .VALUES [T_PCB], .PCB_ADDR);
PUTWRD (.KERNEL_FILE, .TCB_ADDR + .VALUES [T_MXSZ], .TASK_SIZE/64);
!
! THE HEADER IS MOSTLY A COPY OF THE FIRST FEW BYTES OF THE TASK
! IMAGE.
!
INCR COUNTER FROM 0 TO .HDR_SIZE - 1 DO
PUTBYT (.KERNEL_FILE, .HDR_ADDR + .COUNTER, GETBYT (.TASK_FILE, .TASK_BASE + .COUNTER));
!
! SOME FIELDS OF THE HEADER HAVE TO BE RELOCATED
!
PUTWRD (.KERNEL_FILE, .HDR_ADDR + .VALUES [H_WND],
GETWRD (.KERNEL_FILE, .HDR_ADDR + .VALUES [H_WND]) + .HDR_ADDR);
PUTWRD (.KERNEL_FILE, .HDR_ADDR + .VALUES [H_GARD],
GETWRD (.KERNEL_FILE, .HDR_ADDR + .VALUES [H_GARD]) + .HDR_ADDR);
NLUN = GETWRD (.KERNEL_FILE, .HDR_ADDR + .VALUES [H_NLUN]);
PUTWRD (.KERNEL_FILE, .HDR_ADDR + .VALUES [H_LUN] + (.NLUN*4) + 2, .PCB_ADDR);
!
! LINK THE PCB WITH THE TCB AND HDR
!
PUTWRD (.KERNEL_FILE, .PCB_ADDR + .VALUES [P_TCB], .TCB_ADDR);
PUTWRD (.KERNEL_FILE, .PCB_ADDR + .VALUES [P_HDR], .HDR_ADDR);
!
! NOW COPY THE TASK INTO ITS PARTITION
!
PARTITION_BASE = GETWRD (.KERNEL_FILE, .PCB_ADDR + .VALUES [P_REL])*64;
IF (DEBUG GEQ 1)
THEN
BEGIN !DEBUG
OUTSTR (1, UPLIT (%ASCIZ', '));
OUTNUM (1, .PARTITION_BASE, 8, 6);
OUTSTR (1, UPLIT (%ASCIZ', '));
OUTNUM (1, .PARTITION_BASE + .TASK_SIZE - 1, 8, 6);
END; !DEBUG
INCR COUNTER FROM 0 TO .TASK_SIZE - 1 DO
PUTBYT (.KERNEL_FILE, .PARTITION_BASE + .COUNTER, GETBYT (.TASK_FILE, .COUNTER + .TASK_BASE));
!
! LINK THE TCB INTO THE SYSTEM'S LIST OF TCBS
!
TEMP1 = GETWRD (.KERNEL_FILE, .VALUES [TSKHD]);
TEMP3 = 0;
SEARCH_DONE = 0;
WHILE (.SEARCH_DONE EQL 0) DO
BEGIN
TEMP2 = GETBYT (.KERNEL_FILE, .TEMP1 + .VALUES [T_PRI]);
IF (.TEMP2 LSS .PRIORITY)
THEN
SEARCH_DONE = 1
ELSE
BEGIN
TEMP3 = .TEMP1;
TEMP1 = GETWRD (.KERNEL_FILE, .TEMP1 + .VALUES [T_TCBL]);
IF (.TEMP1 EQL 0) THEN SEARCH_DONE = -1;
END;
END;
IF (.SEARCH_DONE LSS 0) THEN ERROR (UPLIT (%ASCIZ'TCB LINKS BAD - INSTALL'));
!
! NOW, TEMP3 POINTS TO THE PREVIOUS TCB AND TEMP1 TO THE NEXT TCB.
! IF TEMP3 IS ZERO, THIS TCB IS TO BE FIRST.
!
IF (.TEMP3 EQL 0)
THEN
PUTWRD (.KERNEL_FILE, .VALUES [TSKHD], .TCB_ADDR)
ELSE
PUTWRD (.KERNEL_FILE,
.TEMP3 + .VALUES [T_TCBL], .TCB_ADDR);
PUTWRD (.KERNEL_FILE, .TCB_ADDR + .VALUES [T_TCBL], .TEMP1);
END; !OF INSTALL
GLOBAL ROUTINE LOADD (KERNEL_FILE, TASK_FILE, TASK_NAME, GEN_PCB, VALUES) : NOVALUE = !INSTALL A DRIVER
!++
! FUNCTIONAL DESCRIPTION:
!
! INSTALL A LOADABLE DRIVER, WITH DATA BASE. IT IS ALWAYS
! INSTALLED IN THE SYSTEM-CONTROLLED PARTITION.
!
! FORMAL PARAMETERS:
!
! KERNEL_FILE - POINTER TO THE FILE BLOCK WHICH DESCRIBES THE
! RSX-11S KERNEL
! TASK_FILE - POINTER TO A SIMILAR FILE BLOCK WHICH DESCRIBES
! THE TASK (DRIVER) TO BE INSTALLED
! TASK_NAME - POINTER TO THE TASK NAME, IN ASCII.
! THIS IS ALWAYS OF THE FORM XXDRV, WHERE XX IS THE DEVICE NAME.
! GEN_PCB - PDP-11 ADDRESS OF THE SYSTEM-CONTROLLED PARTITION
! VALUES - POINTER TO THE VALUES BLOCK
!
! IMPLICIT INPUTS:
!
! NONE
!
! IMPLICIT OUTPUTS:
!
! NONE
!
! ROUTINE VALUE:
!
! NONE
!
! SIDE EFFECTS
!
! MODIFIES THE KERNEL'S DATA STRUCTURES
!
!--
BEGIN
BIND
ROUTINE_NAME = UPLIT (%ASCIZ'LOADD');
MAP
KERNEL_FILE : REF FILE_BLOCK,
TASK_FILE : REF FILE_BLOCK,
VALUES : REF VNPVAL_BLOCK;
LOCAL
PCB_ADDR,
PAR_BASE,
TASK_LABEL : REF VECTOR [1024],
TASK_BASE,
TASK_TOP,
TASK_SIZE,
TASK_FLAGS,
PCB_BASE,
FIRST_DCB_ADDR,
LAST_DCB_ADDR,
DCB_ADDR,
LAST_SCB_ADDR,
SCB_ADDR,
FIRST_UCB_ADDR,
UCB_ADDR,
UCB_LENGTH,
XXEND,
XXDAT,
INPINT,
OUTINT,
VECTOR,
LOC,
NUNITS;
IF (DEBUG GEQ 1)
THEN
BEGIN !DEBUG
PCRLF (1);
OUTSTR (1, UPLIT (%ASCIZ'LOAD DRIVER: '));
OUTSTR (1, TASK_FILE [FILE_NAME]);
END; !DEBUG
!
! COMPUTE THE SIZE OF THE TASK, AND ITS FLAGS
!
TASK_LABEL = .TASK_FILE [FILE_LABEL];
TASK_BASE = .TASK_LABEL [L$BSA] + (.TASK_LABEL [L$BSA + 1]*256);
TASK_TOP = .TASK_LABEL [L$BHGV] + (.TASK_LABEL [L$BHGV + 1]*256);
TASK_SIZE = .TASK_TOP - .TASK_BASE + 1;
TASK_FLAGS = .TASK_LABEL [L$BFLG] + (.TASK_LABEL [L$BFLG + 1]*256);
!
! COMPUTE THE LENGTH OF THE DRIVER'S DATA BASE
! AND ALLOCATE SPACE FOR IT.
!
XXEND = VRBL_SYM (.TASK_FILE, 2, UPLIT (%ASCIZ'$\\END'), 0);
XXDAT = VRBL_SYM (.TASK_FILE, 2, UPLIT (%ASCIZ'$\\DAT'), 0);
FIRST_DCB_ADDR = ALOCB (.KERNEL_FILE, .XXEND - .XXDAT, 0, .VALUES);
!
! COPY THE DATA BASE TO THE KERNEL POOL
!
INCR COUNTER FROM .XXDAT TO .XXEND - 1 DO
PUTBYT (.KERNEL_FILE, .FIRST_DCB_ADDR + .COUNTER - .XXDAT, GETBYT (.TASK_FILE, .COUNTER));
!
! ALLOCATE A PCB IN THE SYSTEM-CONTROLLED AREA TO POINT TO THE
! DRIVER MEMORY.
!
PAR_BASE = .KERNEL_FILE [FILE_HWM] + 1;
PCB_ADDR = M_PCB (.KERNEL_FILE, UPLIT (%ASCIZ'GEN '), .GEN_PCB, .PAR_BASE,
.PAR_BASE + .TASK_SIZE - (.XXEND - .XXDAT), %O'000000', .VALUES [PS_SYS] OR .VALUES [PS_DRV], 0,
.VALUES);
!
! PROCESS EACH DCB, WITH ITS UCBS AND SCBS.
!
SCB_ADDR = 0;
DCB_ADDR = .FIRST_DCB_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]) - .XXDAT + .DCB_ADDR;
PUTWRD (.KERNEL_FILE, .DCB_ADDR + .VALUES [D_UCB], .FIRST_UCB_ADDR);
PUTWRD (.KERNEL_FILE, .DCB_ADDR + .VALUES [D_DSP],
VRBL_SYM (.TASK_FILE, 2, UPLIT (%ASCIZ'$\\TBL'), 0));
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]) - .XXDAT + .DCB_ADDR);
PUTWRD (.KERNEL_FILE, .UCB_ADDR + .VALUES [U_RED],
GETWRD (.KERNEL_FILE,
.UCB_ADDR + .VALUES [U_RED]) - .XXDAT + .DCB_ADDR);
LAST_SCB_ADDR = .SCB_ADDR;
SCB_ADDR = GETWRD (.KERNEL_FILE, .UCB_ADDR + .VALUES [U_SCB]) - .XXDAT + .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) - .XXDAT + .DCB_ADDR);
PUTWRD (.KERNEL_FILE, .SCB_ADDR + .VALUES [S_FRK] + 8, .PAR_BASE/64);
IF ((VECTOR = GETBYT (.KERNEL_FILE, .SCB_ADDR + .VALUES [S_VCT])^2) NEQ 0)
THEN
BEGIN
OUTINT = -1;
IF ((INPINT = VRBL_SYM (.TASK_FILE, 2, UPLIT (%ASCIZ'$\\INT'), 1)) LEQ 0)
THEN
BEGIN
OUTINT = VRBL_SYM (.TASK_FILE, 2, UPLIT (%ASCIZ'$\\OUT'), 0);
INPINT = VRBL_SYM (.TASK_FILE, 2, UPLIT (%ASCIZ'$\\INP'), 0);
END;
IF (INPINT GTR 0)
THEN
BEGIN
LOC = ALOCB (.KERNEL_FILE, 28, 0, .VALUES);
!
! INPUT INTERRUPT VECTOR SETUP
!
PUTWRD (.KERNEL_FILE, .VECTOR, .LOC);
PUTWRD (.KERNEL_FILE, .VECTOR + 2, 7*32);
!
! NOW COMPILE INSTRUCTIONS, AS FOLLOWS:
!
! JSR R5,$INTSV
! .WORD PRIORITY
! MOV @#KIASR5,-(SP)
! MOV #BIAS,@#KIASR5
! JSR PC,@#$??INP OR JSR PC,@#$??INT
! MOV (SP)+,@#KIASR5
! RETURN
!
PUTWRD (.KERNEL_FILE, .LOC, %O'4537');
PUTWRD (.KERNEL_FILE, .LOC + 2, SYM_VAL (.KERNEL_FILE, UPLIT (%ASCIZ'$INTSV'), 0));
LOC = .LOC + 4;
PUTWRD (.KERNEL_FILE, .LOC,
(GETBYT (.KERNEL_FILE, .SCB_ADDR + .VALUES [S_VCT] - 1) XOR %O'340'));
LOC = .LOC + 2;
PUTWRD (.KERNEL_FILE, .LOC, %O'13746');
PUTWRD (.KERNEL_FILE, .LOC + 2, %O'172352');
LOC = .LOC + 4;
PUTWRD (.KERNEL_FILE, .LOC, %O'12737');
PUTWRD (.KERNEL_FILE, .LOC + 2, GETWRD (.KERNEL_FILE, .PCB_ADDR + .VALUES [P_REL]));
PUTWRD (.KERNEL_FILE, .LOC + 4, %O'172352');
LOC = .LOC + 6;
PUTWRD (.KERNEL_FILE, .LOC, %O'4737');
PUTWRD (.KERNEL_FILE, .LOC + 2, .INPINT);
LOC = .LOC + 4;
PUTWRD (.KERNEL_FILE, .LOC, %O'12637');
PUTWRD (.KERNEL_FILE, .LOC + 2, %O'172352');
LOC = .LOC + 4;
PUTWRD (.KERNEL_FILE, .LOC, %O'207');
END;
IF (OUTINT GTR 0)
THEN
BEGIN
LOC = ALOCB (.KERNEL_FILE, 28, 0, .VALUES);
!
! OUTPUT INTERRUPT VECTOR SETUP
!
PUTWRD (.KERNEL_FILE, .VECTOR + 4, .LOC);
PUTWRD (.KERNEL_FILE, .VECTOR + 6, 7*32);
!
! NOW COMPILE INSTRUCTIONS, AS FOLLOWS:
!
! JSR R5,@#$INTSV
! .WORD PRIORITY
! MOV @#KIASR5,-(SP)
! MOV #BIAS,@#KIASR5
! JSR PC,@#$??OUT
! MOV (SP)+,@#KIASR5
! RETURN
!
PUTWRD (.KERNEL_FILE, .LOC, %O'4537');
PUTWRD (.KERNEL_FILE, .LOC + 2, SYM_VAL (.KERNEL_FILE, UPLIT (%ASCIZ'$INTSV'), 0));
LOC = .LOC + 4;
PUTWRD (.KERNEL_FILE, .LOC,
(GETBYT (.KERNEL_FILE, .SCB_ADDR + .VALUES [S_VCT] - 1) XOR %O'340'));
LOC = .LOC + 2;
PUTWRD (.KERNEL_FILE, .LOC, %O'13746');
PUTWRD (.KERNEL_FILE, .LOC + 2, %O'172352');
LOC = .LOC + 4;
PUTWRD (.KERNEL_FILE, .LOC, %O'12737');
PUTWRD (.KERNEL_FILE, .LOC + 2, GETWRD (.KERNEL_FILE, .PCB_ADDR + .VALUES [P_REL]));
PUTWRD (.KERNEL_FILE, .LOC + 4, %O'172352');
LOC = .LOC + 6;
PUTWRD (.KERNEL_FILE, .LOC, %O'4737');
PUTWRD (.KERNEL_FILE, .LOC + 2, .OUTINT);
LOC = .LOC + 4;
PUTWRD (.KERNEL_FILE, .LOC, %O'12637');
PUTWRD (.KERNEL_FILE, .LOC + 2, %O'172352');
LOC = .LOC + 4;
PUTWRD (.KERNEL_FILE, .LOC, %O'207');
END;
IF ((.INPINT LEQ 0) AND (.OUTINT LEQ 0))
THEN
ERRMSG (0, 40, ROUTINE_NAME,
UPLIT (%ASCIZ'Interrupt Setup'), UPLIT (%ASCIZ'for driver in file'),
TASK_FILE [FILE_NAME], 0);
END;
END;
END;
DCB_ADDR = GETWRD (.KERNEL_FILE, .DCB_ADDR + .VALUES [D_LNK]);
END;
!
! STORE IN THE TCB POINTER FIELD OF THE PCB, A POINTER TO
! THE FIRST DCB.
!
PUTWRD (.KERNEL_FILE, .PCB_ADDR + .VALUES [P_TCB], .FIRST_DCB_ADDR);
!
! COPY THE DRIVER CODE INTO THE PARTITION CREATED FOR IT
!
INCR COUNTER FROM 0 TO .TASK_SIZE - 1 DO
PUTBYT (.KERNEL_FILE, .PAR_BASE + .COUNTER, GETBYT (.TASK_FILE, .TASK_BASE + .COUNTER));
!
! LINK THE DCB INTO THE SYSTEM'S LIST OF DCBS
!
LNKDCB (.KERNEL_FILE, .FIRST_DCB_ADDR, .VALUES);
END; !OF LOADD
GLOBAL ROUTINE LNKDCB (KERNEL_FILE, DCB_ADDR, VALUES) : NOVALUE = !LINK DCB INTO KERNEL
!++
! FUNCTIONAL DESCRIPTION:
!
! LINK A DCB INTO THE KERNEL'S LIST OF DCBS. IT IS PLACED
! IN ALPHABETICAL ORDER.
!
! FORMAL PARAMETERS:
!
! KERNEL_FILE - POINTER TO THE FILE BLOCK WHICH DESCRIBES THE
! RSX-11S KERNEL
! DCB_ADDR - PDP-11 ADDRESS OF THE DCB TO BE LINKED
! VALUES - POINTER TO THE VALUES BLOCK
!
! IMPLICIT INPUTS:
!
! NONE
!
! IMPLICIT OUTPUTS:
!
! NONE
!
! ROUTINE VALUE:
!
! NONE
!
! SIDE EFFECTS
!
! MODIFIES THE KERNEL'S DATA STRUCTURES
!
!--
BEGIN
BIND
ROUTINE_NAME = UPLIT (%ASCIZ'LNKDCB');
MAP
KERNEL_FILE : REF FILE_BLOCK,
VALUES : REF VNPVAL_BLOCK;
LOCAL
PREV_DCB,
NEXT_DCB,
SEARCH_DONE;
!
! FIND THE TWO EXISTING DCBS WHICH THIS ONE MUST GO BETWEEN
!
NEXT_DCB = GETWRD (.KERNEL_FILE, .VALUES [DEVHD]);
PREV_DCB = 0;
SEARCH_DONE = 0;
WHILE (.SEARCH_DONE EQL 0) DO
BEGIN
IF (.NEXT_DCB EQL 0)
THEN
SEARCH_DONE = 1
ELSE
BEGIN
IF (GETWRD (.KERNEL_FILE, .NEXT_DCB + .VALUES [D_NAM]) GTRU GETWRD (.KERNEL_FILE,
.DCB_ADDR + .VALUES [D_NAM]))
THEN
SEARCH_DONE = 1
ELSE
BEGIN
PREV_DCB = .NEXT_DCB;
NEXT_DCB = GETWRD (.KERNEL_FILE, .PREV_DCB + .VALUES [D_LNK]);
END;
END;
END;
!
! WE NOW HAVE THE TWO DCBS. IF PREV_DCB IS ZERO THIS DCB IS TO BE FIRST
!
PUTWRD (.KERNEL_FILE, .DCB_ADDR + .VALUES [D_LNK], .NEXT_DCB);
IF (.PREV_DCB EQL 0)
THEN
PUTWRD (.KERNEL_FILE, .VALUES [DEVHD], .DCB_ADDR)
ELSE
PUTWRD (.KERNEL_FILE,
.PREV_DCB + .VALUES [D_LNK], .DCB_ADDR);
END; !OF LNKDCB
GLOBAL ROUTINE VRBL_SYM (FILE_PTR, LEN, SYMBOL_NAME, ERR) = !GET VALUE OF SYMBOL WITH COMPUTED NAME
!++
! FUNCTIONAL DESCRIPTION:
!
! GET THE VALUE OF A PARTIALLY NAMED SYMBOL. PART OF THE NAME OF
! THE FILE MUST BE SUBSTITUTED INTO THE GIVEN NAME.
!
! FORMAL PARAMETERS:
!
! FILE_PTR - THE FILE BLOCK THAT MAY HAVE THE SPECIFIED SYMBOL.
! LEN - NUMBER OF CHARACTERS TO COPY FROM THE FILE NAME
! SYMBOL_NAME - NAME OF THE SYMBOL, "\" STARTS PLACE TO
! SUBSTITUTE FILE NAME.
! ERR - PASSED TO SYM_VAL.
!
! IMPLICIT INPUTS:
!
! NONE
!
! IMPLICIT OUTPUTS:
!
! NONE
!
! ROUTINE VALUE:
!
! VALUE OF THE SYMBOL, OR -1 IF UNDEFINED.
!
! SIDE EFFECTS
!
! NONE
!
!--
BEGIN
BIND
ROUTINE_NAME = UPLIT (%ASCIZ'VRBL_SYM');
MAP
FILE_PTR : REF FILE_BLOCK;
LOCAL
CONVERTED_NAME : VECTOR [(CH$ALLOCATION (7))],
BACKSL,
RESULT;
RESULT = -1;
!
! COPY THE SYMBOL NAME TO LOCAL STORAGE SO IT CAN BE MODIFIED
!
CH$MOVE (7, CH$PTR (.SYMBOL_NAME), CH$PTR (CONVERTED_NAME [0]));
!
! FIND THE BACKSLASH
!
BACKSL = -1;
INCR C_POINTER FROM 0 TO 6 BY 1 DO
IF (CH$RCHAR (CH$PTR (CONVERTED_NAME [0], .C_POINTER)) EQL %C'\')
THEN
BEGIN
BACKSL = .C_POINTER;
EXITLOOP
END;
IF (.BACKSL EQL -1)
THEN
ERROR (UPLIT (%ASCIZ'BACKSLASH MISSING - VRBL_SYM'))
ELSE
BEGIN
CH$MOVE (.LEN, CH$PTR (FILE_PTR [FILE_NAME]), CH$PTR (CONVERTED_NAME [0], .BACKSL));
RESULT = SYM_VAL (.FILE_PTR, CONVERTED_NAME [0], .ERR);
END;
.RESULT
END; !OF VRBL_SYM
GLOBAL ROUTINE FCLEAN (KERNEL_FILE, VALUES) : NOVALUE = !FINAL CLEANUP OF KERNEL
!++
! FUNCTIONAL DESCRIPTION:
!
! DO FINAL CLEANUP OF THE KERNEL. THIS ROUTINE IS CALLED
! AFTER THE LAST TASK HAS BEEN INSTALLED BUT BEFORE THE
! CORE IMAGE IS WRITTEN OUT.
!
! FORMAL PARAMETERS:
!
! KERNEL_FILE - FILE BLOCK FOR THE KERNEL
! VALUES - BLOCK WHICH HOLDS VARIOUS USEFUL VALUES
!
! IMPLICIT INPUTS:
!
! NONE
!
! IMPLICIT OUTPUTS:
!
! NONE
!
! ROUTINE VALUE:
!
! NONE
!
! SIDE EFFECTS
!
! MODIFIES THE KERNEL CORE IMAGE AND LABEL
!
!--
BEGIN
BIND
ROUTINE_NAME = UPLIT (%ASCIZ'FCLEAN');
MAP
KERNEL_FILE : REF FILE_BLOCK,
VALUES : REF VNPVAL_BLOCK;
LOCAL
KERNEL_LABEL : REF VECTOR [1024],
KERNEL_SIZE,
ROUNDED_SIZE;
!
! FETCH POINTERS AND COMPUTE THE SIZE OF THE KERNEL
!
KERNEL_LABEL = .KERNEL_FILE [FILE_LABEL];
KERNEL_SIZE = (.KERNEL_FILE [FILE_HWM] + 64) AND (NOT 63);
ROUNDED_SIZE = (.KERNEL_FILE [FILE_HWM] + 512) AND (NOT 511);
!
! RETURN TO FREE POOL AMOUNT OF MEMORY UNUSED BY THIS SYSTEM
!
FRESTG (.KERNEL_FILE [FILE_CORE] + (.ROUNDED_SIZE/4), (.KERNEL_FILE [FILE_CORE_LEN] - .ROUNDED_SIZE)/4);
KERNEL_FILE [FILE_CORE_LEN] = .ROUNDED_SIZE;
!
! SET SYSTEM SIZE AND THE LABEL TO INDICATE THE NUMBER OF BYTES
! IN THIS CORE IMAGE.
!
PUTWRD (.KERNEL_FILE, .VALUES [SYSIZ], .ROUNDED_SIZE/64);
KERNEL_LABEL [L$BLDZ] = (.ROUNDED_SIZE/64) MOD 256;
KERNEL_LABEL [L$BLDZ + 1] = (.ROUNDED_SIZE/64)/256;
KERNEL_LABEL [L$BMXZ] = (.ROUNDED_SIZE/64) MOD 256;
KERNEL_LABEL [L$BMXZ + 1] = (.ROUNDED_SIZE/64)/256;
!
! Copy node name to kernel_file name
!
CH$COPY (LEN_NODE_NAME, CH$PTR (VALUES [NODNAM]), 0, 7, CH$PTR (KERNEL_FILE [FILE_NAME]));
END; !OF FCLEAN
GLOBAL ROUTINE TELLK (KERNEL_FILE, TELL_CHAN, VALUES) : NOVALUE = !TELL ABOUT CORE IMAGE
!++
! FUNCTIONAL DESCRIPTION:
!
! TELL ABOUT THIS CORE IMAGE, AND CHANGE THE NAME OF THE KERNEL
! FILE TO BE THE NAME OF THE NODE BEING BUILT. THE TYPEOUTS
! ARE FOR THE SAKE OF SOFTWARE SUPPORT ANALYZING A DUMP.
!
! FORMAL PARAMETERS:
!
! KERNEL_FILE - POINTER TO THE FILE BLOCK WHICH DESCRIBES
! THE KERNEL.
! TELL_CHAN - THE CHANNEL NUMBER ON WHICH TO WRITE THE INFO.
! VALUES - A VECTOR OF LOTS OF GOOD THINGS FOR VNP20
!
! IMPLICIT INPUTS:
!
! NONE
!
! IMPLICIT OUTPUTS:
!
! NONE
!
! ROUTINE VALUE:
!
! NONE
!
! SIDE EFFECTS
!
! WRITES ON THE SPECIFIED CHANNEL
!
!--
BEGIN
BIND
ROUTINE_NAME = UPLIT (%ASCIZ'TELLK');
MAP
KERNEL_FILE : REF FILE_BLOCK,
VALUES : REF VNPVAL_BLOCK;
LOCAL
MAIN_PCB_ADDR,
MAIN_SCAN_DONE,
SUB_PCB_ADDR,
SUB_SCAN_DONE,
PCB_ADDR,
KERNEL_SIZE,
IMAGE_KW,
MINIMUM_KW,
SYSTEM_KW,
CHAR;
SYSTEM_KW = GETWRD (.KERNEL_FILE, .VALUES [SYSIZ])^6;
IMAGE_KW = (.SYSTEM_KW + 2047)/2048;
MINIMUM_KW = ((.SYSTEM_KW + .VALUES [COR]) + 2047)/2048;
SYSTEM_KW = ((.SYSTEM_KW + ((.VALUES [COR]*180)/100)) + 2047)/2048;
PCRLF (.TELL_CHAN);
OUTSTR (.TELL_CHAN, UPLIT (%ASCIZ' Node name: '));
OUTSTR (.TELL_CHAN, KERNEL_FILE [FILE_NAME]);
OUTSTR (.TELL_CHAN, UPLIT (%ASCIZ', number: '));
OUTNUM (.TELL_CHAN, .VALUES [NODNM], 10, 0);
OUTSTR (.TELL_CHAN, UPLIT (%ASCIZ'.'));
PCRLF (.TELL_CHAN);
OUTSTR (.TELL_CHAN, UPLIT (%ASCIZ' The conjured system image is '));
OUTNUM (.TELL_CHAN, .IMAGE_KW, 10, 0);
OUTSTR (.TELL_CHAN, UPLIT (%ASCIZ'K words. Considering buffers,'));
PCRLF (.TELL_CHAN);
OUTPUT (.TELL_CHAN, %C' ');
OUTNUM (.TELL_CHAN, .MINIMUM_KW, 10, 0);
OUTSTR (.TELL_CHAN, UPLIT (%ASCIZ'K words of memory will be required during execution.'));
PCRLF (.TELL_CHAN);
IF .SYSTEM_KW GTR 124
THEN
BEGIN
OUTPUT (.TELL_CHAN, %C' ');
OUTNUM (.TELL_CHAN, .SYSTEM_KW, 10, 0);
OUTSTR (.TELL_CHAN, UPLIT (%ASCIZ'K words of memory is recommended for reasonable performance.'));
PCRLF (.TELL_CHAN);
END;
PCRLF (.TELL_CHAN);
OUTSTR (.TELL_CHAN, UPLIT (%ASCIZ' Partition Base Size Task Name'));
PCRLF (.TELL_CHAN);
MAIN_PCB_ADDR = GETWRD (.KERNEL_FILE, .VALUES [PARHD]);
MAIN_SCAN_DONE = 0;
WHILE (.MAIN_SCAN_DONE EQL 0) DO
IF (.MAIN_PCB_ADDR EQL 0)
THEN
MAIN_SCAN_DONE = 1
ELSE
BEGIN
IF (GETWRD (.KERNEL_FILE, .MAIN_PCB_ADDR + .VALUES [P_MAIN]) EQL .MAIN_PCB_ADDR)
THEN
BEGIN
TELLP (.KERNEL_FILE, .TELL_CHAN, .MAIN_PCB_ADDR, .VALUES);
SUB_PCB_ADDR = GETWRD (.KERNEL_FILE, .MAIN_PCB_ADDR + .VALUES [P_SUB]);
SUB_SCAN_DONE = 0;
WHILE (.SUB_SCAN_DONE EQL 0) DO
BEGIN
IF (.SUB_PCB_ADDR EQL 0)
THEN
SUB_SCAN_DONE = 1
ELSE
BEGIN
TELLP (.KERNEL_FILE, .TELL_CHAN, .SUB_PCB_ADDR, .VALUES);
END;
SUB_PCB_ADDR = GETWRD (.KERNEL_FILE, .SUB_PCB_ADDR + .VALUES [P_SUB]);
END;
END;
MAIN_PCB_ADDR = GETWRD (.KERNEL_FILE, .MAIN_PCB_ADDR + .VALUES [P_LNK]);
END;
PCRLF (.TELL_CHAN);
IF .MINIMUM_KW GTR 124
THEN
ERROR (UPLIT (%ASCIZ 'DN20 SYSTEM IS LARGER THAN 124K WORDS'));
END; !OF TELLK
ROUTINE TELLP (KERNEL_FILE, TELL_CHAN, PCB_ADDR, VALUES) : NOVALUE = !TELL ABOUT A PARTITION
!++
! FUNCTIONAL DESCRIPTION:
!
! TELL ABOUT A PARTITION
!
! FORMAL PARAMETERS:
!
! KERNEL_FILE - POINTER TO THE FILE BLOCK WHICH DESCRIBES
! THE KERNEL.
! TELL_CHAN - THE CHANNEL NUMBER ON WHICH TO WRITE THE INFO.
! PCB_ADDR - PDP-11 ADDRESS OF THE PARTITION CONTROL BLOCK
! VALUES - A VECTOR OF LOTS OF GOOD THINGS FOR VNP20
!
! IMPLICIT INPUTS:
!
! NONE
!
! IMPLICIT OUTPUTS:
!
! NONE
!
! ROUTINE VALUE:
!
! NONE
!
! SIDE EFFECTS
!
! WRITES ON THE SPECIFIED CHANNEL
!
!--
BEGIN
BIND
ROUTINE_NAME = UPLIT (%ASCIZ'TELLP');
MAP
KERNEL_FILE : REF FILE_BLOCK,
VALUES : REF VNPVAL_BLOCK;
LOCAL
R50VAL,
ASCVAL : VECTOR [CH$ALLOCATION (7)],
TCB_ADDR;
!
! FIRST TELL THE PARTITION NAME, THEN THE BASE ADDRESS AND SIZE,
! LAST THE NAME OF THE TASK RESIDENT IN THE PARTITION.
!
R50VAL = 0;
R50VAL<16, 16> = GETWRD (.KERNEL_FILE, .PCB_ADDR + .VALUES [P_NAM]);
R50VAL<0, 16> = GETWRD (.KERNEL_FILE, .PCB_ADDR + .VALUES [P_NAM] + 2);
R50TOA (.R50VAL, ASCVAL);
PCRLF (.TELL_CHAN);
OUTSTR (.TELL_CHAN, UPLIT (%ASCIZ' '));
OUTSTR (.TELL_CHAN, ASCVAL);
OUTSTR (.TELL_CHAN, UPLIT (%ASCIZ' '));
OUTNUM (.TELL_CHAN, GETWRD (.KERNEL_FILE, .PCB_ADDR + .VALUES [P_REL])*64, 8, 7);
OUTSTR (.TELL_CHAN, UPLIT (%ASCIZ' '));
OUTNUM (.TELL_CHAN, GETWRD (.KERNEL_FILE, .PCB_ADDR + .VALUES [P_SIZE])*64, 8, 7);
TCB_ADDR = GETWRD (.KERNEL_FILE, .PCB_ADDR + .VALUES [P_TCB]);
IF (.TCB_ADDR NEQ 0)
THEN
BEGIN
IF ((GETWRD (.KERNEL_FILE, .PCB_ADDR + .VALUES [P_STAT]) AND .VALUES [PS_DRV]) EQL 0)
THEN
BEGIN
R50VAL = 0;
R50VAL<16, 16> = GETWRD (.KERNEL_FILE, .TCB_ADDR + .VALUES [T_NAM]);
R50VAL<0, 16> = GETWRD (.KERNEL_FILE, .TCB_ADDR + .VALUES [T_NAM] + 2);
R50TOA (.R50VAL, ASCVAL);
END
ELSE
BEGIN
ASCVAL = 0;
CH$WCHAR (GETBYT (.KERNEL_FILE, .TCB_ADDR + .VALUES [D_NAM]), CH$PTR (ASCVAL, 0));
CH$WCHAR (GETBYT (.KERNEL_FILE, .TCB_ADDR + .VALUES [D_NAM] + 1), CH$PTR (ASCVAL, 1));
CH$WCHAR (%C':', CH$PTR (ASCVAL, 2));
END;
OUTSTR (.TELL_CHAN, UPLIT (%ASCIZ' '));
OUTSTR (.TELL_CHAN, ASCVAL);
END;
END; !OF TELLP
END
ELUDOM
! Local Modes:
! Comment Column:36
! Comment Start:!
! Mode:Fundamental
! Auto Save Mode:2
! Word Abbrev Mode:1