Trailing-Edge
-
PDP-10 Archives
-
TOPS-20_V6.1_DECnetSrc_7-23-85
-
mcb/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) 1980, 1981, 1982
! DIGITAL EQUIPMENT CORPORATION
! Maynard, Massachusetts
!
! This software is furnished under a license and may be used
! and copied only in accordance with the terms of such license
! and with the inclusion of the above copyright notice. This
! software or any other copies thereof may not be provided or
! otherwise made available to any other person. No title to
! and ownership of the software is hereby transferred.
!
! The information in this software is subject to change
! without notice and should not be construed as a commitment
! by DIGITAL EQUIPMENT CORPORATION.
!
! DIGITAL assumes no responsibility for the use or reliability
! of its software on equipment which is not supplied by
! DIGITAL.
!
!++
! FACILITY: MCB Configuration Facility, 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