From:	CSBVAX::MRGATE!RELAY-INFO-VAX@CRVAX.SRI.COM@SMTP 20-OCT-1988 22:26
To:	ARISIA::EVERHART
Subj:	Broadcast Trapping without SMG$


Received: From KL.SRI.COM by CRVAX.SRI.COM with TCP; Thu, 20 OCT 88 18:32:57 PDT
Received: from ucbvax.Berkeley.EDU by KL.SRI.COM with TCP; Thu, 20 Oct 88 18:12:58 PDT
Received: by ucbvax.Berkeley.EDU (5.59/1.31)
	id AA00246; Thu, 20 Oct 88 14:27:34 PDT
Received: from USENET by ucbvax.Berkeley.EDU with netnews
	for info-vax@kl.sri.com (info-vax@kl.sri.com)
	(contact usenet@ucbvax.Berkeley.EDU if you have questions)
Date: 18 Oct 88 22:01:41 GMT
From: bsu-cs!cfchiesa@iuvax.cs.indiana.edu  (Christopher Chiesa)
Organization: CS Dept, Ball St U, Muncie, Indiana
Subject: Broadcast Trapping without SMG$
Message-Id: <4396@bsu-cs.UUCP>
Sender: info-vax-request@kl.sri.com
To: info-vax@kl.sri.com

Finally, I've gotten around to commenting my code (perhaps overly so; forgive
me if so, and feel free to strip 'em out if you desire) and transferring it
from our VMS to UNIX system to access the Net.

I posted a LO-O-O-ONG time ago that I had these things available, but it's
taken me quite a while to get around to posting it.  Sorry.

The latter part of this message contains TWO files: the "set up broadcast 
trapping" routine, and a "test program" that gives you an environment for
testing the former.  Both are in Macro, and both were written (and assembled
and executed) under VMS v4.7 .  Enjoy, modify, and critique to your hearts'
delight!

   Chris Chiesa

;========================================================================
;=== CUT HERE ===  File MAILBOX2.MAR ==== 187 LINES ==== CUT HERE =======


; This file is a simple procedure that performs the equivalent of the SMG$ 
; function SMG$SET_BROADCAST_TRAPPING, without the overhead of creating a
; pasteboard, virtual display, and all that.  The steps involved are:
;
;   1.) Create a mailbox (using the $CREMBX system service).
;
;   2.) Assign a channel to the current terminal, with an "associated mailbox,"
;       namely, the one created in step 1.
;
;   3.) Set a Write-Attention AST on the mailbox, specifying the address of 
;       the AST routine to be executed when the mailbox is written into.
;
; This procedure accepts one argument, namely, the address of a "client" AST
; routine to be invoked on arrival of broadcast messages.  The "client" AST
; routine is invoked somewhat "indirectly," however: since events other than
; broadcast-message arrival can write to the mailbox and trigger the AST,
; this routine examines the "message type" field of the mailbox message buffer,
; and compares it against known "valid" broadcast-message-identifier types.
; I guess you can think of it as a two-level scheme, with an "immediate" AST
; taking some of the "load off" the "deferred" one.
; 
; I must admit, this looks like a real "hack" from my vantage point of months
; later; today I would use labels instead of using the constant 390 in several
; places in the code, and would probably do bit-examinations of the message-
; type value rather than just compare it against values obtained by trial-
; and-error!  Ah well, this is what I have to offer, and what the heck, lots
; of people around me here can't do it at ALL.
;
			ESC = 27
			LF  = 10

ACTION_VECTOR:		.BLKL			; store address of "client" AST
						; routine

MAILBOX_NAME:		.ASCID	/BROAD_TRAP/	; mailbox identifier, required
MBXCHAN:		.BLKW			; mailbox has its own Channel

TT_NAME:		.ASCID	/SYS$OUTPUT/	; This will break if SYS$OUTPUT
TT_CHAN:		.BLKW			; is DEFINEd to something other
						; than a terminal!  Needs work!
;
; Message used for debugging in "immediate" AST routine
;
ANNOUNCE:		.ASCID	/Got to the AST routine, at least!/

;
;========================================================================
;
;
MSGBUF:						; VMS standard mailbox-message
						; format block	

MSGTYPE:		.BLKW	1
UNITNUM:		.BLKW	1
CSTRING:		.BLKB	1
CONTROLLER:		.BLKB	15
BROAD_LEN:		.BLKW	1
MSG:			.BLKB	390		; actual useful text here

MESSAGE:		.LONG	390		; descriptor for text above
			.ADDRESS -
				MSG

MODE_BUFFER:					; terminal characteristics
						; buffer; this may prove
						; useful in other applications

DEVCLASS:		.BLKB			; device: terminal, disk, etc.
DEVTYPE:		.BLKB			; TYPE of terminal or other...
PG_WIDTH:		.BLKW			; as shown on SHOW TERM
BASIC_CHAR:		.BLKB	3
PG_LEN:			.BLKW
EXT_CHAR:		.BLKL


;
;  At long last, the actual program...
;
			.ENTRY	SETUP_MBOX,^M<>

			$CREMBX_S -			; create mailbox...
				CHAN=MBXCHAN,-
				LOGNAM=MAILBOX_NAME,-
				MAXMSG=#390
			BLBS	R0,ASN_TT_CHAN
			BRW	QUIT


ASN_TT_CHAN:		$ASSIGN_S -			; associate mailbox
				CHAN=TT_CHAN,-		; with terminal
				DEVNAM=TT_NAME,-
				MBXNAM=MAILBOX_NAME

			BLBS	R0,SET_WRT_AST
			BRW	QUIT

SET_WRT_AST:		$QIOW_S	CHAN=MBXCHAN,-		; set up Write-Attn AST
				FUNC=#<IO$_SETMODE!IO$M_WRTATTN>,-
				P1=AST_ROUTINE,-	
				P3=#3
			BLBS	R0,SNS_TT_MODE
			BRW	QUIT

;
; To ensure that the mailbox, rather than the terminal, receives broadcasts,
; the terminal's "BRDCSTMBX" characteristic must be set.   This is done by
; obtaining the existing characteristics, setting the appropriate bit, and
; setting the modified characteristics.
;

SNS_TT_MODE:		$QIOW_S	CHAN=TT_CHAN,-		; get existing char...
				FUNC=#<IO$_SENSEMODE>,-
				P1=MODE_BUFFER,-
				P2=#12
			BLBS	R0,SET_TT_MODE
			BRW	QUIT

SET_TT_MODE:		BISL	#TT2$M_BRDCSTMBX,EXT_CHAR	; Set the 
							; appropriate bit for
							; the characteristic
							; you want... 

			$QIOW_S	CHAN=TT_CHAN,-		; set new characteris- 
				FUNC=#<IO$_SETMODE>,-	; tics...
				P1=MODE_BUFFER,-
				P2=#12
			BLBC	R0,QUIT
;
;  The key step is that of pointing to the external "deferred" AST routine
;  supplied by the calling program.  If the calling routine passes a parameter
;  of 0, this is in turn passed on to the "immediate" AST, and thence to the
;  $QIOW service, cancelling any further AST activity.  (This should really
;  have been done in a different order, but I TOLD you this was a hack...)
; 
			MOVAL	@4(AP),ACTION_VECTOR
			RET				; here on success...

QUIT:			$EXIT_S	R0			; here on any error.

;========================================================================
;  The preceding is the "setup" routine, and is invoked ONCE to prepare the
; terminal environment for subsequent receipt of broadcasts.  The following
; routine is invoked on any WRITE operation to the terminal mailbox; it de-
; termines whether the message is associated with a broadcast message (as
; opposed to a typeahead-character-available or other message), and if it
; IS a broadcast, invokes the user-supplied routine mentioned earlier.

MBX_RD_AST:		.ENTRY	AST_ROUTINE,^M<>

;			PUSHAQ	ANNOUNCE		; for debugging only
;			CALLS	#1,G^LIB$PUT_OUTPUT
;			BLBC	R0,AST_QUIT

			$QIOW_S	CHAN=MBXCHAN,-		; get mailbox message
				FUNC=#IO$_READVBLK,-	; (standard block fmt)
				P1=MSGBUF,-
				P2=#390
			BLBC	R0,AST_QUIT

			CMPW	MSGTYPE,#83		; These aren't the 
			BEQL	DOIT			; 'standard' codes;
			CMPW	MSGTYPE,#8		; but rather "what 
			BEQL	DOIT			; works."  Ugh.
			BRB	NOPE

; 
; And at long last, the externally-supplied routine is invoked!
; 

DOIT:			CALLS	#0,@ACTION_VECTOR	; You could pass pa-
							; rameters, of course,
							; but I didn't.
;
;  The Write-Attention AST must be reset after each 'firing' of the AST...
;

NOPE:			$QIOW_S	CHAN=MBXCHAN,-
				FUNC=#<IO$_SETMODE!IO$M_WRTATTN>,-
				P1=MBX_RD_AST,-
				P3=#3
			BLBC	R0,QUIT

			RET				; successful completion

AST_QUIT:		$EXIT_S	R0			; error completion

			.END

;========================================================================
;==== CUT HERE ==== File TESTMBOX.MAR ==== 93 LINES ==== CUT HERE =======

; This is a simple "dummy" program to TEST the "SETUP_MBOX" routine that sets
; up broadcast-trapping.  
;
; This program provides its own AST routine (at the bottom of this file), passes
; the address of that routine to SETUP_MBOX, then innocently loops in a "read a
; string, write it out" operation just to have something to "actually do" while
; waiting for the AST routine to occur.  The program might just as well use 
; $HIBER to "do nothing" and conserve CPU time, but THIS way you can exit from
; it by entering a string of "control Z".
;
; The effect of this program is best observed if you do a SET TERM/NOBROADCAST
; before invoking it; that way, no actual broadcasts appear on the terminal,
; proving that THIS program is in total control of the situation! :-)
;
; Enjoy!
;
;========================================================================
;
; *** ALL *** storage definitions in this program are for the sake of the 
; dummy input-echo loop, with the exception of ANNOUNCE_MSG which is the 
; notification message displayed by the (very simple) example AST routine.
;

			CR = 13
			LF = 10

ANNOUNCE_MSG:		.ASCID	<CR><LF>/Broadcast message arrived!/<CR><LF>
PROMPT:			.ASCID	/Enter a string: /

DUMMY:			.LONG	80
			.ADDRESS DUMBUF
DUMBUF:			.BLKB	80

ECHOFMT:		.ASCID	/Your string: !AS/
ECHODESC:		.LONG	95
			.ADDRESS ECHOBUF
ECHOBUF:		.BLKB	95

;
;========================================================================
;

MAIN:			.ENTRY	Test_Mailbox,^M<>	; test the Broadcast-
							; trapping setup

			PUSHAQ	NOTIFY			; Address of AST routine
			CALLS	#1,SETUP_MBOX		; Invoke setup routine
			BLBC	R0,QUIT			; Exit on error!

LOOP:			PUSHAW	DUMMY			; All of this can be 
			PUSHAQ	PROMPT			; replaced with whatever
			PUSHAQ	DUMMY			; your actual program 
			CALLS	#2,G^LIB$GET_INPUT	; wants to do while 
			BLBC	R0,QUIT			; waiting for broadcast
							; messages...
			MOVAL	DUMMY,R2
			$FAO_S	CTRSTR=ECHOFMT,-
				OUTLEN=ECHODESC,-
				OUTBUF=ECHODESC,-
				P1=R2
			BLBC	R0,QUIT

			PUSHAQ	ECHODESC
			CALLS	#1,G^LIB$PUT_OUTPUT
			BLBC	R0,QUIT
			MOVL	#80,DUMMY
			BRB	LOOP

QUIT:			PUSHL	#0			; Cancel the AST by
			CALLS	#1,SETUP_MBOX		; calling with value 0
			$EXIT_S	R0

;========================================================================
;  The AST routine used in this example is as "totally trivial" as the 
;  above loop!  It is here only to prove that it is in fact invoked when
;  broadcast messages arrive.  It simply TELLS you that "a broadcast mes-
;  sage arrived".
;
			.ENTRY	Notify,^M<>		; Pass this mask's ad-
							; dress to SETUP_MBOX,
							; and this routine will
							; be invoked when a 
							; broadcast message ar-
							; rives.

			PUSHAQ	ANNOUNCE_MSG
			CALLS	#1,G^LIB$PUT_OUTPUT
			BLBC	R0,10$
			RET

10$:			$EXIT_S	R0

			.END	Test_Mailbox

;========================================================================
;====  CUT HERE ====  Get rid of signature.. ============================
-- 
UUCP: <backbones>!{iuvax,pur-ee,uunet}!bsu-cs!cfchiesa 
cfchiesa@bsu-cs.UUCP                                           

