	.TITLE STLO
	.IDENT /23OC87/

;	Version: 3.0
;	File:[22,310]STLO.MAC
;	Author: Philip Hannay
;	Last Edit: 9-MAY-1989 18:30:29 
;	History:
;
;         23-Oct-87.  Philip Hannay.  Created.
;         09-May-89.  Philip Hannay.  Modified to use new EVENT_FLAG_SET
;                       in GENERAL.TYP - from 13 bytes to 16 bytes.
.REM |	


Procedure STLO( Flags:Event_Flag_set
		);External;

{*USER*
 Pascal-3 procedure to execute a stop for logical OR of event flags.
The STLO directive allows us to stop program execution waiting for
a combination of 1 to 16 flags to be set.  If any flag is that 
combination is set, the program execution resumes.  

Due to the
structure of the RSX directive, the specified flags must ALL reside
in the same "group".  There are six groups (f1 thru f16, f17 thru f32,
f33 thru f48, f49 thru f64, f65 thru f80, and f81 thru f96).  You CANNOT
use flags that reside in two different groups.

The routine is called using the set FLAGS that contains the flags that
you wish to stop for.   Directive status is available in $DSW on
return.  If you specify a set of flags that do not all reside in the
same group, the $DSW directive status will be set to IE.IEF - invalid
event flag specified error.

}

{*WIZARD*

The group number to be used in the directive (0 thru 5) is determined
by examining the event flag set supplied by the caller.

Due to a restriction in the STLO$S macro, we cannot use it and still
dynamically specify the group number.  Rather than generate 6 separate
STLO$S calls, we will just do the macro expansion ourselves.  If the
macro expansion of STLO$S changes, this routine may no longer work.

Before calling the directive, we verify that the caller has supplied an
event flag set in FLAGS that specifies flags in one and only one group.
If this is not so, we make no assumptions, and return a IE.IEF error
in $DSW.

This routine uses the stack for all data structures, so it can reside
in a memory resident library and is also compatible with I/D space tasks.

The EVENT_FLAG_SET is a subrange from f1 thru f96.  However, its parent
type VMS$EVENT_FLAG has 128 elements from f0 thru f127.  Thus the set
is 16 bytes (128 bits).  And so we need to accomodate the 16 byte value
parameter even though we use only a subrange of it.

To top it off, f0 is a null event flag, which is present even though
the subrange begins at f1.  To allow us to word align the event flag
groups for ease of use, we will need to shift all the event flag set
one bit right.

} 

|
;
; Assemble with PASMAC.MAC as prefix file.
;

	.MCALL STLO$S
; set value parameter mapped to FLAGS is 16 bytes - allocate space by specifying
; two DOUBLE (8byte) real value parameters - note that we roll right only
; the RSX subrange f1 thru f96.

	
	PROC STLO
	PARAM DUMMY, DOUBLE
	PARAM FLAGS, DOUBLE
	SAVE <R0, R1, R2 >
	BEGIN
	MOV SP,R0		; SET UP POINTER TO FLAGS SET VALUE PARAM
	ADD #FLAGS,R0		; R0 NOW POINTS TO FLAGS SET
	ADD #12.,R0		; POINT TO BYTE 16 BYTE OF SET
	MOV #12., R1		; LOOP COUNTER IN R1
	RORB (R0)		; ROTATE RIGHT LAST BYTE - F96 LOW BIT TO C BIT
1$:	RORB -(R0)		; ROTATE RIGHT REST OF BYTES
	SOB R1, 1$		; WHEN DONE, F1 - F96 IN FIRST 12 BYTES, R1 CLR
	MOV #1,R2		; R2 IS GROUP COUNTER, STARTS AT 1 (GROUP 0)
4$:	TST (R0)+		; SEE IF WORD (GROUP) NONZERO
	BEQ 2$			; BRANCH IF ZERO
	TST R1			; SEE IF ANOTHER WORD (GROUP) WAS ALREADY ZERO
	BNE 3$			; BRANCH IF SO - ERROR
	MOV R2,R1		; SAVE GROUP NUMBER IN R1
2$:	INC R2			; R2 IS NOW NEXT GROUP NUMBER
	CMP R2,#7		; SEE IF WE HAVE LOOKED AT ALL GROUPS (0-5)
	BNE 4$			; BRANCH IF WE HAVE NOT
	TST R1			; SEE IF WE FOUND A NON-ZERO GROUP
	BEQ 3$			; BRANCH IF WE DID NOT FIND ONE - ERROR
	DEC R1			; ADJUST R1 SO GROUP NUMBER IS 0 THRU 5
	MOV R1,R2		; COMPUTE BYTE OFFSET FOR GROUP
	ADD R1,R2		; R2 IS NOW GROUP * 2
	ADD #FLAGS,R2		; ADD OFFSET TO FLAGS FROM SP
	ADD SP,R2		; R2 NOW POINTS TO GROUP (MASK WORD)
	BR 5$			; GO DO THE STOP LOGICAL OR
3$:	MOV #IE.IEF,$DSW	; INVALID FLAG SET (ALL ZERO OR BAD GROUPS)
	BR 6$			; RETURN TO CALLER WITH NO STOP DONE
5$:	;stlo$s R1,(R2)		; DO THE STLO CALL EQUIVALENT
	MOV (R2),-(SP)		; PUT MASK WORD ON STACK
	MOV R1,-(SP)		; PUT GROUP NUMBER ON STACK
	MOV (PC)+,-(SP)		; PUT DIC AND MACRO SIZE ON STACK
	.BYTE 137.,3		; STLO DIC, 3 WORDS ON STACK
	EMT ^O<377>		; TRAP TO EXEC
6$:				; RETURN TO CALLER, STATUS IN $DSW
	ENDPR
	.END

