	.TITLE STLO
	.IDENT /23OC87/

;	Version: 3.0
;	File:[22,310]STLO.MAC
;	Author: Philip Hannay
;	Last Edit: 23-OCT-1987 15:49:25 
;	History:
;
;         23-Oct-87.  Philip Hannay.  Created.

.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.

*END*}

{*TECH*

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.

*END*} 

|
;
; Assemble with PASMAC.MAC as prefix file.
;
; NOTE: Since Gentyp2.Pas defines a f0 (null EFN), the resulting
;       type Event_Flag_set contains 97 members, despite being a
;       subrange f1..f97. To overcome this, STLO must first shift the
;	flag set supplied one bit right, and overwrite b0 (f0).
;	This will leave us with a flag set of 6 words, where each
;	flag group is word aligned.  Note that we use three PARAM 
;	macros to allocate the 13 bytes taken by FLAGS value parameter.

	.MCALL STLO$S
	
	PROC STLO
	PARAM DUMMY1, SCALAR
	PARAM DUMMY2, DOUBLE
	PARAM FLAGS, REAL
	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 13 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

