Google
 

Trailing-Edge - PDP-10 Archives - tops20-v7-ft-dist1-clock - 7-sources/rmsuar.b36
There are 3 other files named rmsuar.b36 in the archive. Click here to see a list.
%TITLE 'UARG' ! User argument handling
MODULE UARG (IDENT = '3.0(600)',
	     ENTRY ( UAPointer,
                     TGUPointer,
                     UAddr,
                     UClass,
                     R$Null )
		) =
BEGIN

!
!	COPYRIGHT (C) DIGITAL EQUIPMENT CORPORATION 1984, 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 THAT IS NOT SUPPLIED BY DIGITAL.
!
!
!++
! FACILITY:	RMS
!
! ABSTRACT:
!
!       Routine to handle user arguments
!
! ENVIRONMENT:	User mode
!
! AUTHOR: Andrew Nourse , CREATION DATE: 1-Jul-84
!
! 502   - Put this in its own module
! 504   - Implement UCLASS
! 517   - 0 pointer should stay 0
! 555   - Fix byte pointers that look like global addresses.
!         (Note: this will break if we ever have more than 63 sections)
!         (Jupiter R.I.P.)
!--

!
! TABLE OF CONTENTS
!
!       UAPOINTER   -   globalize & bytepointer-ize a user arg pointer
!       TGUPOINTER  -   globalize & bytepointer-ize a user buffer pointer
!       UADDR       -   globalize a user arg address
!       UCLASS      -   get the file class of the user's file
!       R$NULL      -   do nothing
!
! INCLUDE FILES:
!

REQUIRE 'rmsreq';				! Standard definitions

!REQUIRE 'rmsosd';				! OS-dependent definitions

!
! PURE DATA:
!
PSECT OWN=$HIGH$;

OWN DefTyp: $Typ();                     ! Default file class setup
GLOBAL ROUTINE uapointer (ptr) =
!++
! FUNCTIONAL DESCRIPTION
!
!   In this routine, we will make a byte pointer
!   (global if in nonzero section) out of
!    one of four types of pointer that
!    the user could pass us in the FNA field:
!
!	1)  a local byte pointer.  If he gives us a
!	    local byte pointer in section 0,
!	    everything is fine.  If we get a local
!	    byte pointer in a non-zero section, then
!	    move the address field of the pointer
!	    into a spare register, setting the left
!	    half to the section number of the user
!	    control blocks.  Change the bytepointer
!	    to index off of that register, which
!	    will contain a global address.
!
!	2)  a halfword address.  A halfword address
!	    will be built into a local byte pointer,
!	    which will then receive the same
!	    treatment as above.
!
!	3)  a global address (if we are in a
!	    non-zero section).  Build a global byte
!	    pointer therefrom by dumping octal 61 in
!	    front of the 30-bit address.
!
!	4)  a global byte pointer (again, if we are
!	    in a non-zero section).  Use as is.
!
! FORMAL PARAMETERS:
!
!   ptr: an address or byte pointer (see above)
!
! RETURNED VALUE:
!
!   a global byte pointer (if nonzero section)
!   a local byte pointer otherwise
! 
!--

    BEGIN
    !+
    !   If pointer is 0 it should stay that way
    !-
    IF .ptr EQL 0 THEN RETURN 0; !m517

    !+
    !   If the address is zero in the
    !   left half, make it into an ASCII byte pointer.
    !   If in a non-zero section the user said
    !   "-1,,ADDR", then pretend that he said
    !   "BLKSEC,,ADDR".
    !-

    IF .ptr<lh> EQL 0			! Whole word pointer?
    THEN
        ptr<lh> = %O'440700';		! No - make byte pointer

    IF .rmssec NEQ 0			! If non-zero sections
    THEN
        BEGIN

        !+
        !	"-1,,ADDR" is equivalent to a global address.
        !-

        IF .ptr<lh> EQL %O'777777'	! -1,,ADDR?
        THEN
            ptr = .ptr<rh> OR .blksec;

        !+
        !	We have now either a global address, a
        !	global byte pointer, or a local byte
        !	pointer.  Convert a global address into a
        !	global byte pointer; use a global byte
        !	pointer as is; make a local byte pointer
        !	index off a global address.
        !-

        IF .ptr<24, 12> EQL 0		! Global address?                 !M555
        THEN
            ptr<lh> = .ptr<lh> OR %O'610000'	! Yes - make OWGBP
        ELSE
            BEGIN

            IF .ptr<30, 6> LEQ %O'44'	! Not one-word global
            THEN
                BEGIN
                ptr<30, 6> = ( SELECT .ptr<24, 6> OF
                               SET
                               [6]: %O'45';
                               [7]: %O'61';
                               [8]: %O'54';
                               [9]: %O'67';
                               [18]:%O'74';
                               [OTHERWISE]: RETURN 0;   ! No can do
                               TES ) + ( %BPVAL / .ptr<24, 6> )
                                     - ( .ptr<30, 6> / .ptr<24, 6> );

                ptr<18, 12> = .BlkSec<18, 12>;
                END;

            END;

        END;

    .ptr                                ! Return pointer as value
    END;                                ! of UAPointer
GLOBAL ROUTINE TGUPointer (aptr: REF $Byte_Pointer, bytesize) =
!++
! FUNCTIONAL DESCRIPTION
!
!   In this routine, we will make a
!   possibly 2-word global byte pointer out of
!    one of four types of pointer that
!    the user could pass us in the FNA field:
!
!	1)  a local byte pointer.  If he gives us a
!	    local byte pointer in section 0,
!	    everything is fine.  If we get a local
!	    byte pointer in a non-zero section, then
!	    Change the bytepointer to 2-word global.
!
!	2)  a halfword address.  A halfword address
!	    will be built into a local byte pointer,
!	    which will then receive the same
!	    treatment as above.
!
!	3)  a global address (if we are in a
!	    non-zero section).  Build a global byte
!	    pointer therefrom by dumping octal 61 in
!	    front of the 30-bit address.
!
!	4)  a global byte pointer (again, if we are
!	    in a non-zero section).  Use as is.
!
! FORMAL PARAMETERS:
!
!   aptr: an address or byte pointer (see above)
!   bytesize: The byte size to use building the byte pointer.
!
! IMPLICIT PARAMETERS:
!
!   BlkSec: Section number RMS blocks are in. (in left half of BlkSec)
!
! RETURNED VALUE:
!
!   None.
!
!--

    BEGIN
    !+
    !   If the address is zero or -1 in the
    !   left half, make it into an appropriate byte pointer.
    !-

    IF .aptr[Ptr$h_lh] EQL 0                ! Whole word pointer?
    OR .aptr[Ptr$h_lh] EQL %O'777777'       ! -1,,ADDR?
        THEN
            BEGIN
            aptr[Ptr$h_LH] = 0;
            aptr[Ptr$v_Byte_Size] = .bytesize;
            aptr[Ptr$v_Byte_Position] = %BPVAL;
            END;

    IF .rmssec NEQ 0			! If non-zero sections
    THEN
        BEGIN
        !+
        !	We have now either a global address, a
        !	global byte pointer, or a local byte
        !	pointer.  Convert a global address into a
        !	global byte pointer; use a global byte
        !	pointer as is; make a local byte pointer
        !	into a global byte pointer.
        !-

        IF .aptr[Ptr$v_Byte_Position] EQL 0               ! Global address?
        THEN
            BEGIN
            aptr[Ptr$a_Global_Address] = .aptr[Ptr$a_Owg_Global_Address];
            ! Put addr in 2nd word
            aptr[Ptr$a_Local_Address] = 0;
            aptr[Ptr$v_Byte_Position] = %BPVAL;
            aptr[Ptr$v_Byte_Size]= .bytesize;
            aptr[Ptr$v_Global_Flag] = 1;
            END
        ELSE
            BEGIN
            IF (.aptr[Ptr$v_Byte_Position] LEQ %O'44')	! Not one-word global
            AND (.aptr[Ptr$v_Global_Flag] EQL 0)    ! or  two-word global
            THEN
                BEGIN
                ! Local address to 2nd word
                aptr[Ptr$a_Section_Address] = .aptr[Ptr$a_Local_Address];

                ! Add section containing block to pointer
                aptr[Ptr$v_Section_Number] = .blksec<LH>;               !m600

                aptr[Ptr$a_Local_Address] = 0;       ! Clear this out 
                aptr[Ptr$v_Global_Flag]=1;  ! This is now a 2-word global
                END;

            END;

        END;
    1                                   ! OK return
    END;                                ! of TGUPointer
GLOBAL ROUTINE UAddr (ptr) =
!++
! FUNCTIONAL DESCRIPTION
!
!   In this routine, we will make a global address
!    from one of two types of pointer that
!    the user could pass us:
!
!	1)  a halfword address.  A halfword address
!           will be turned into a global address
!
!	3)  a global address (if we are in a
!	    non-zero section). Use as is
!
! FORMAL PARAMETERS:
!
!   ptr: an address (see above)
!
! IMPLICIT INPUTS:
!
!   BlkSec: Section number RMS blocks are in. (in left half of BlkSec)
!
! RETURNED VALUE:
!
!   a global address
! 
!--

    BEGIN
    SELECT .ptr OF
    SET
    [%O'20' TO %O'777777']: (.ptr OR .BlkSec); ! Make global address
    [OTHERWISE]: .ptr;                         ! Already global, special, or 0
    TES
    END;                                ! of UAddr
GLOBAL ROUTINE UClass ( UsrFab : REF $Fab_decl ) =
!++
! FUNCTIONAL DESCRIPTION:
!
!    Determine what kind of file this is
!
! FORMAL PARAMETERS:
!
!    UsrFab:  Address of user's FAB;
!             possibly the FAB points to a TYP block
!
! RETURNED VALUE:
!
!    File class value (Typ$k_xxx)
!
!--
BEGIN
BIND uTyp = (IF .UsrFab[Fab$a_Typ] NEQ 0
             THEN UAddr(.UsrFab[Fab$a_Typ])
             ELSE DefTyp) : $Typ_decl;

.uTyp[Typ$h_Class]                      ! Return class field from this
END;
GLOBAL ROUTINE R$Null = 0 ;
! This routine does nothing
END ELUDOM