Google
 

Trailing-Edge - PDP-10 Archives - BB-P363B-SM_1985 - t20/nmlt20/ncporn.b36
There is 1 other file named ncporn.b36 in the archive. Click here to see a list.
! UPD ID= 201, SNARK:<6.1.NML>NCPORN.B36.4,  10-Dec-84 15:18:56 by HALPIN
! Get MONSYM Library file out of default directory, not BLI:
!
! UPD ID= 83, SLICE:<6.1.NML>NCPORN.B36.3,  18-Sep-84 14:56:21 by GUNN
! WORK:<GUNN.NML>NCPORN.B36.2 21-Aug-84 12:02:44, Edit by GUNN
!
! Change to accomodate new LIBRARY conventions. MONSYM.L36 and JLNKG.L36
! are now explicity declared here rather than in NMULIB.
!
! UPD ID= 57, SNARK:<6.1.NML>NCPORN.B36.2,  14-Jun-84 09:56:29 by GLINDELL
! Undeclare conditionals like Jim did in NCPCEX
!
! NET:<GUNN.DEVELOPMENT>NCPORN.B36.3 11-Jan-82 18:09:13, Edit by GUNN
!
! Ident 03.
! Update copyright date to 1982.
! Fix P$NUM to also allow .CMNUX to be recognized as a number.
!
! 1-Dec-81 14:18:56, Edit by GROSSMAN, Ident = X03.02
!
! Fix this module so that it can work on Tops-10. Make it search NCPLIB in
! order to get definitions of $TOPS10 and $TOPS20 feature tests instead of
! figuring them out from FTJSYS and FTUUOS. Also, remove search of MONSYM, as
! that is included in NCPLIB.
!
! NET:<DECNET20-V3P1.NCP.SOURCES>NCPORN.B36.2 10-Mar-81 09:23:45, Edit by GUNN
!
! Ident 01.
! Fix TRANSLATE_TO_SIXBIT routine to return null bytes at end of string
! if shorter than six bytes.
!
module NCPORN	(
		ident = 'X03.03'
		) =
begin

!
!                    COPYRIGHT (c) 1981, 1982 BY
!	      DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.
!
! 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:	DECnet-10/20 V3.0 Network Control Program (NCP)
!
! ABSTRACT:
!
!	This module contains the routines to parse the ORION IPCF command
!	message. These routines are the functional duplicate of the same
!	named routines which exist in the GALAXY module OPRPAR. Note that
!	this module is not reentrant.
!
! ENVIRONMENT:	TOPS-10/20 User mode under NML
!
! AUTHOR: Dale C. Gunn , CREATION DATE: 13-Feb-81
!
! MODIFIED BY:
!
!	, : VERSION
! 01	-
!--
!
! INCLUDE FILES:
!

library 'NCPLIB' ;			! NCP definitions

library 'MONSYM';			! Monitor symbols

library 'JLNKG';			! JSYS linkage definitions

undeclare $TOPS10,$TOPS20,$X25,$MCB;    ! Undeclare these names, because GALAXY
                                        ! gets SYSTYP.REQ also
library 'GALAXY' ;                      ! GALAXY interface definitions 

!
! TABLE OF CONTENTS
!

forward routine
	P$SETUP:    GALXYS,
	P$CURR:     GALXYS,
	P$PREV:     GALXYS,
	P$NEXT:     GALXYO,
	P$NFLD:     GALXYS,
	P$NARG:     GALXYS,
	P$CFM:      GALXYS,
	P$COMMA:    GALXYS,
	P$KEYW:     GALXYS,
	P$SWIT:     GALXYS,
	P$USER:     GALXYS,
	P$FLOT:     GALXYS,
	P$DIR:      GALXYS,
	P$TIME:     GALXYS,
	P$NUM:      GALXYS,
	P$FILE:     GALXYS,
	P$IFIL:     GALXYS,
	P$OFIL:     GALXYS,
	P$FLD:      GALXYS,
	P$TOK:      GALXYS,
	P$NODE:     GALXYS,
	P$SIXF:     GALXYS,
        TRANSLATE_TO_SIXBIT: GALXYO,
	P$RNGE:     GALXYS,
	P$TEXT:     GALXYS,
	P$DEV:      GALXYS,
	P$QSTR:     GALXYS,
	P$UQSTR:    GALXYS,
	P$ACCT:     GALXYS ;

!
! MACROS:
!

macro
     PB_BLOCK =
         block [PFD$SZ] field (PB_FIELDS) % ;

!
! EQUATED SYMBOLS:
!

field PB_FIELDS =
    set
    HD$PFD = [PFD$HD,0,36,0],           ! Header word for PB block
    TYP$PF = [PFD$HD,$P$S(PF$TYP),0],   ! PB type
    LEN$PF = [PFD$HD,$P$S(PF$LEN),0],   ! PB length
    D1$PFD = [PFD$D1,0,36,0],           ! First PB data value
    D2$PFD = [PFD$D2,0,36,0]            ! Second PB data value
    tes;

literal
       TTRUE = -1 ;

!
! OWN STORAGE:
!

own
   CURRPB,                              ! Current PB address
   PREVPB ;                             ! Last PB address

!
! EXTERNAL REFERENCES:
!
global routine P$SETUP (PB) : GALXYS =

!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS
!
!	NONE.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	NONE.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin

    CURRPB = .PB ;                      ! Set current PB address
    PREVPB = 0 ;                        ! No previous PB

    return TTRUE

    end;				!End of P$SETUP
global routine P$CURR : GALXYS =

!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS
!
!	NONE.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	NONE.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin

    register
            S1 = 1 ;

    S1 = .CURRPB ;                      ! Get current PB address

    return TTRUE

    end;				!End of P$CURR
global routine P$PREV : GALXYS =

!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS
!
!	NONE.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	NONE.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin

    register
            S1 = 1 ;

    if .PREVPB eql 0                    ! Fails if no previous PB address
    then return FALSE ;

    S1 = CURRPB = .PREVPB ;             ! Get previous PB address

    return TTRUE

    end;				!End of P$PREV
global routine P$NEXT : GALXYO =

!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS
!
!	NONE.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	NONE.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin

    global register
           S1 = 1,
           S2 = 2 ;

    local
         PB: ref PB_BLOCK ;

    PB = PREVPB = .CURRPB ;             ! Remember the current PB

    CURRPB = .CURRPB + .PB[LEN$PF] ;    ! Point to next PB

    return TTRUE

    end;				!End of P$NEXT
global routine P$NFLD : GALXYS =

!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS
!
!	NONE.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	NONE.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin

    global register
            S1 = 1,
            S2 = 2 ;

    local
         PB: ref PB_BLOCK ;

    S2 = PB = .CURRPB ;                 ! Get current PB address
    S1 = .PB[TYP$PF] ;                  ! And its type

    return P$NEXT ()                    ! Advance to next PB

    end;				!End of P$NFLD
global routine P$NARG : GALXYS =

!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS
!
!	NONE.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	NONE.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin

    register
            S1 = 1,
            S2 = 2 ;

    local
         PB: ref PB_BLOCK ;

    S2 = PB = .CURRPB ;                 ! Get current PB address
    S1 = .PB[TYP$PF] ;                  ! And its type

    return TTRUE

    end;				!End of P$NARG
global routine P$CFM : GALXYS =

!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS
!
!	NONE.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	NONE.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin

    global register
            S1 = 1,
            S2 = 2 ;

    local
         PB: ref PB_BLOCK ;

    P$NARG () ;                         ! Get address and type of next PB

    if .S1 neq $CMCFM
    then return FALSE                   ! Error if not confirm
    else return P$NEXT ()               ! Advance to next PB and return

    end;				!End of P$CFM
global routine P$COMMA : GALXYS =

!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS
!
!	NONE.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	NONE.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin

    global register
            S1 = 1,
            S2 = 2 ;

    local
         PB: ref PB_BLOCK ;

    P$NARG () ;                         ! Get address and type of next PB

    if .S1 neq $CMCMA
    then return FALSE                   ! Error if not comma
    else return P$NEXT ()               ! Advance to next PB and return

    end;				!End of P$COMMA
global routine P$KEYW : GALXYS =

!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS
!
!	NONE.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	NONE.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin

    global register
            S1 = 1,
            S2 = 2 ;

    map
       S2: ref PB_BLOCK ;

    P$NARG () ;                         ! Get address and type of next PB

    if .S1 neq $CMKEY
    then return FALSE                   ! Error if not keyword
    else S1 = .S2[D1$PFD] ;             ! Pick up the keyword code

    return P$NEXT ()                    ! Advance to next PB and return

    end;				!End of P$KEYW
global routine P$SWIT : GALXYS =

!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS
!
!	NONE.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	NONE.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin

    global register
            S1 = 1,
            S2 = 2 ;

    map
       S2: ref PB_BLOCK ;

    P$NARG () ;                         ! Get address and type of next PB

    if .S1 neq $CMSWI
    then return FALSE                   ! Error if not switch
    else S1 = .S2[D1$PFD] ;             ! Pick up the switch code

    return P$NEXT ()                    ! Advance to next PB and return

    end;				!End of P$SWIT
global routine P$USER : GALXYS =

!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS
!
!	NONE.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	NONE.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin

    global register
            S1 = 1,
            S2 = 2 ;

    map
       S2: ref PB_BLOCK ;

    P$NARG () ;                         ! Get address and type of next PB

    if .S1 neq $CMUSR
    then return FALSE                   ! Error if not user id
    else S1 = .S2[D1$PFD] ;             ! Pick up the data

    return P$NEXT ()                    ! Advance to next PB and return

    end;				!End of P$USER
global routine P$FLOT : GALXYS =

!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS
!
!	NONE.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	NONE.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin

    global register
            S1 = 1,
            S2 = 2 ;

    map
       S2: ref PB_BLOCK ;

    P$NARG () ;                         ! Get address and type of next PB

    if .S1 neq $CMFLT
    then return FALSE                   ! Error if not floating point number
    else S1 = .S2[D1$PFD] ;             ! Pick up the value

    return P$NEXT ()                    ! Advance to next PB and return

    end;				!End of P$FLOT
global routine P$DIR : GALXYS =

!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS
!
!	NONE.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	NONE.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin

    global register
            S1 = 1,
            S2 = 2 ;

    map
       S2: ref PB_BLOCK ;

    P$NARG () ;                         ! Get address and type of next PB

    if .S1 neq $CMDIR
    then return FALSE                   ! Error if not directory
    else S1 = .S2[D1$PFD] ;             ! Pick up the data

    return P$NEXT ()                    ! Advance to next PB and return

    end;				!End of P$DIR
global routine P$TIME : GALXYS =

!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS
!
!	NONE.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	NONE.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin

    global register
            S1 = 1,
            S2 = 2 ;

    map
       S2: ref PB_BLOCK ;

    P$NARG () ;                         ! Get address and type of next PB

    if .S1 neq $CMTAD
    then return FALSE                   ! Error if not time & date
    else S1 = .S2[D1$PFD] ;             ! Pick up the data

    return P$NEXT ()                    ! Advance to next PB and return

    end;				!End of P$TIME
global routine P$NUM : GALXYS =

!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS
!
!	NONE.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	NONE.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin

    global register
            S1 = 1,
            S2 = 2 ;

    map
       S2: ref PB_BLOCK ;

    P$NARG () ;                         ! Get address and type of next PB

    if (.S1 neq $CMNUM) and (.S1 neq $CMNUX)
    then return FALSE                   ! Error if not a number
    else begin
         S1 = .S2[D1$PFD] ;             ! Pick up the data
         S2 = .S2[D2$PFD] ;
         end;

    return P$NEXT ()                    ! Advance to next PB and return

    end;				!End of P$NUM
global routine P$FILE : GALXYS =

!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS
!
!	NONE.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	NONE.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin

    global register
            S1 = 1,
            S2 = 2 ;

    map
       S1: ref PB_BLOCK ;

    P$NARG () ;                         ! Get address and type of next PB

    if .S1 neq $CMFIL
    then return FALSE                   ! Error if not general file spec
    else begin
         S1 = .CURRPB ;                 ! Address of FD block
         S2 = .S1[LEN$PF] ;             ! Length of the FD and header
         end;

    return P$NEXT ()                    ! Advance to next PB and return

    end;				!End of P$FILE
global routine P$IFIL : GALXYS =

!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS
!
!	NONE.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	NONE.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin

    global register
            S1 = 1,
            S2 = 2 ;

    map
       S1: ref PB_BLOCK ;

    P$NARG () ;                         ! Get address and type of next PB

    if .S1 neq $CMIFI
    then return FALSE                   ! Error if not input file spec
    else begin
         S1 = .CURRPB ;                 ! Address of FD block
         S2 = .S1[LEN$PF] ;             ! Length of the FD and header
         end;

    return P$NEXT ()                    ! Advance to next PB and return

    end;				!End of P$IFIL
global routine P$OFIL : GALXYS =

!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS
!
!	NONE.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	NONE.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin

    global register
            S1 = 1,
            S2 = 2 ;

    map
       S1: ref PB_BLOCK ;

    P$NARG () ;                         ! Get address and type of next PB

    if .S1 neq $CMOFI
    then return FALSE                   ! Error if not output file spec
    else begin
         S1 = .CURRPB ;                 ! Address of FD block
         S2 = .S1[LEN$PF] ;             ! Length of the FD and header
         end;

    return P$NEXT ()                    ! Advance to next PB and return

    end;				!End of P$OFIL
global routine P$FLD : GALXYS =

!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS
!
!	NONE.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	NONE.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin

    global register
            S1 = 1,
            S2 = 2 ;

    map
       S1: ref PB_BLOCK ;

    P$NARG () ;                         ! Get address and type of next PB

    if .S1 neq $CMFLD
    then return FALSE                   ! Error if not field
    else begin
         S1 = .CURRPB ;                 ! Address of text block
         S2 = .S1[LEN$PF] ;             ! Length of the text and header
         end;

    return P$NEXT ()                    ! Advance to next PB and return

    end;				!End of P$FLD
global routine P$TOK : GALXYS =

!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS
!
!	NONE.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	NONE.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin

    global register
            S1 = 1,
            S2 = 2 ;

    map
       S1: ref PB_BLOCK ;

    P$NARG () ;                         ! Get address and type of next PB

    if .S1 neq $CMTOK
    then return FALSE                   ! Error if not token
    else begin
         S1 = .CURRPB ;                 ! Address of text block
         S2 = .S1[LEN$PF] ;             ! Length of the text and header
         end;

    return P$NEXT ()                    ! Advance to next PB and return

    end;				!End of P$TOK
global routine P$NODE : GALXYS =

!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS
!
!	NONE.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	NONE.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin

    global register
            S1 = 1,
            S2 = 2 ;

    map
       S2: ref PB_BLOCK ;

    P$NARG () ;                         ! Get address and type of next PB

    if .S1 neq $CMNOD
    then return FALSE                   ! Error if not node name
    else begin
         %if $TOPS20                    ! TOPS20 requires conversion 
         %then S1 = TRANSLATE_TO_SIXBIT (S2[D1$PFD]) ! From ASCII to sixbit
         %else S1 = .S2[D1$PFD]         ! TOPS10 has sixbit node name
         %fi ;
         end;

    return P$NEXT ()                    ! Advance to next PB and return

    end;				!End of P$NODE
global routine P$SIXF : GALXYS =

!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS
!
!	NONE.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	NONE.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin

    global register
            S1 = 1,
            S2 = 2 ;

    map
       S2: ref PB_BLOCK ;

    P$NARG () ;                         ! Get address and type of next PB

    if .S1 neq $CMFLD
    then return FALSE                   ! Error if not field
    else begin
         S1 = TRANSLATE_TO_SIXBIT (S2[D1$PFD]) ; ! Make sixbit 
         end;

    return P$NEXT ()                    ! Advance to next PB and return

    end;				!End of P$SIXF
routine TRANSLATE_TO_SIXBIT (ADDR) : GALXYO =

!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS
!
!	NONE.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	NONE.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin

    global register
           S1 = 1,
           S2 = 2 ;

    local
         CHAR,
         SIXBIT,
         TXT_PTR,
         SIX_PTR ;

    bind
        SIX_MAX = ch$ptr (SIXBIT,6,6) ; ! Pointer to 7th character in six bit

    SIXBIT = 0 ;                        ! Clear sixbit string to all nulls
    TXT_PTR = ch$ptr (.ADDR) ;          ! Point to text to be converted
    SIX_PTR = ch$ptr (SIXBIT,,6) ;      ! Point to sixbit string

    while (CHAR = ch$rchar_a (TXT_PTR)) neq 0
    do begin
       if .CHAR geq %C'a' and .CHAR leq %C'z'
       then CHAR = .CHAR - %O'40' ;     ! Convert lower case to upper case
       CHAR = .CHAR - %O'40' ;
       if .SIX_PTR neq SIX_MAX ! Convert maximum of six characters
       then ch$wchar_a (.CHAR,SIX_PTR) ; ! Stash sixbit character
       end;

    return .SIXBIT ;

    end;				!End of TRANSLATE_TO_SIXBIT
global routine P$RNGE : GALXYS =

!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS
!
!	NONE.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	NONE.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin

    local
         LO,
         HI ;

    if P$NUM () neq TTRUE
    then return FALSE ;

        begin
        register
                S1 = 1 ;
        LO = .S1 ;                      ! Save low range value
        end;

    begin
    if P$TOK () neq TTRUE
    then begin
         LO = 0 ;                       ! Low range is zero
         HI = .LO ;                     ! Single number is high range
         end
    else begin
         if P$NUM () neq TTRUE
         then return FALSE
         else begin
              register
                      S1 = 1 ;
              HI = .S1 ;
              end;
         end;
    end;

        begin
        register
                S1 = 1,
                S2 = 2 ;
        S1 = .LO ;                      ! Set low range
        S2 = .HI ;                      ! and high range
        end;

    return TTRUE

    end;				!End of P$RNGE
global routine P$TEXT : GALXYS =

!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS
!
!	NONE.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	NONE.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin

    global register
            S1 = 1,
            S2 = 2 ;

    map
       S2: ref PB_BLOCK ;

    P$NARG () ;                         ! Get address and type of next PB

    if .S1 neq $CMTXT
    then return FALSE                   ! Error if not text
    else begin
         S2 = .S2[LEN$PF] ;             ! Length of the text and header
         S1 = .CURRPB ;                 ! Address of header
         end;

    return P$NEXT ()                    ! Advance to next PB and return

    end;				!End of P$TEXT
global routine P$DEV : GALXYS =

!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS
!
!	NONE.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	NONE.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin

    global register
            S1 = 1,
            S2 = 2 ;

    map
       S2: ref PB_BLOCK ;

    P$NARG () ;                         ! Get address and type of next PB

    if .S1 neq $CMDEV
    then return FALSE                   ! Error if not device
    else begin
         S2 = .S2[LEN$PF] ;             ! Length of the text and header
         S1 = .CURRPB ;                 ! Address of header
         end;

    return P$NEXT ()                    ! Advance to next PB and return

    end;				!End of P$DEV
global routine P$QSTR : GALXYS =

!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS
!
!	NONE.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	NONE.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin

    global register
            S1 = 1,
            S2 = 2 ;

    map
       S2: ref PB_BLOCK ;

    P$NARG () ;                         ! Get address and type of next PB

    if .S1 neq $CMQST
    then return FALSE                   ! Error if not quoted string
    else begin
         S2 = .S2[LEN$PF] ;             ! Length of the text and header
         S1 = .CURRPB ;                 ! Address of header
         end;

    return P$NEXT ()                    ! Advance to next PB and return

    end;				!End of P$QSTR
global routine P$UQSTR : GALXYS =

!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS
!
!	NONE.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	NONE.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin

    global register
            S1 = 1,
            S2 = 2 ;

    map
       S2: ref PB_BLOCK ;

    P$NARG () ;                         ! Get address and type of next PB

    if .S1 neq $CMUQS
    then return FALSE                   ! Error if not unquoted string
    else begin
         S2 = .S2[LEN$PF] ;             ! Length of the text and header
         S1 = .CURRPB ;                 ! Address of header
         end;

    return P$NEXT ()                    ! Advance to next PB and return

    end;				!End of P$UQSTR
global routine P$ACCT : GALXYS =

!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS
!
!	NONE.
!
! IMPLICIT INPUTS
!
!	NONE.
!
! ROUTINE VALUE:
!
!	NONE.
!
! SIDE EFFECTS:
!
!	NONE.
!
!--

    begin

    global register
            S1 = 1,
            S2 = 2 ;

    map
       S2: ref PB_BLOCK ;

    P$NARG () ;                         ! Get address and type of next PB

    if .S1 neq $CMACT
    then return FALSE                   ! Error if not account string
    else begin
         S2 = .S2[LEN$PF] ;             ! Length of the text and header
         S1 = .CURRPB ;                 ! Address of header
         end;

    return P$NEXT ()                    ! Advance to next PB and return

    end;				!End of P$ACCT
end				!End of Module NCPORN
eludom
! Local Modes:
! Mode:BLISS
! Auto Save Mode:0
! Comment Column:40
! Comment Rounding:+1
! End: