Trailing-Edge
-
PDP-10 Archives
-
BB-JF18A-BM
-
sources/rms/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