;
;       NAME:  BCAST.SBR
;
;       FUNCTION:  This program is used to "broadcast" a message to every
;       terminal on the system.  The restraints is uses in terminal
;       selection are:  1) the terminal must be attached to a job, and
;       2) it must not be a PSEUDO terminal.  The actual sending is done
;       by opening the terminal as a file using the TRM: driver.
;
;       NOTE!!!  --  TRM.DVR MUST be loaded into system memory for this to work!!
;
;
;       AUTHOR:  Tom Dahlquist
;
;       HISTORY:
;         DATE   WHO SUBSTANCE
;       09/19/83 TAD Written.
;       07/16/84 TAD Was moving a blank into low memory, causing random
;                       failures.
;       06/85   John Baima
;               Eisenbrauns
;               PO Box 275
;               Winona Lake, IN 46590
;               Don't send messages to jobs running LPTSPL--they are printers.
;
;       05/05/86  Dale A. Eichbauer  Convert into a Basic callable subroutine.
;
;

       SEARCH  SYS
       SEARCH  SYSSYM
       SEARCH  TRM

       AUTOEXTERN

       OBJNAM  BCAST.SBR

ASECT
=0
;
;       Workarea and Constants
;
DDB:    BLKB    D.DDB
DBUF:   BLKB    512.
JOB:    BLKB    8.
=0

       VMAJOR=1.
       VMINOR=0.
       VSUB=0.
       VEDIT=100.
       VWHO=1.

=0
PSECT
       PHDR    -1,PV$RPD,PH$REE!PH$REU


BCAST:  SAVE    A0-A6
       CMMW    @A3,#1                  ; CHECK FOR ONE ARGUMENT
       JNE     EXIT
       CMMW    2(A3),#2                ; MUST BE STRING TYPE ARGUMENT
       JNE     EXIT
       TST     10(A3)                  ; SIZE MUST BE GREATER THAN ZERO
       JEQ     EXIT
       MOV     4(A3),A2                ; POINT TO STRING
       LIN                             ; anything to send?
       JEQ     EXIT                    ; leave if not...

       LEA     A3,DDB(A4)              ; let A3 -> to DDB throughout...
                                       ; BECAUSE WE CANNOT DO AN INIT WHILE
                                       ; RUNNING UNDER BASIC, WE SET UP THE
                                       ; DDB MANUALLY, WITH OUR OWN BUFFER
       CLEAR   @A3,D.DDB               ; FIRST CLEAR IT
       MOVW    #[TRM],D.DEV(A3)        ; NEXT INSERT DEVICE NAME
       LEA     A1,DBUF(A4)             ; GET ADDRESS FOR BUFFER
       MOV     A1,D.BUF(A3)            ; AND PUT IT INTO DDB BUFFER ADDRESS
       MOVW    #41400,@A3              ; SET DDB FLAGS
       MOV     #1000,D.SIZ(A3)         ; SET THE RECORD SIZE TO 512

       JOBIDX  A0                      ; A0 -> out JCB...
       LEA     A1,JOBNAM(A0)           ; A1 -> job name field...
       PUSH    A2                      ; save A2...
       LEA     A2,JOB(A4)              ; A2 -> job name work area...
       UNPACK                          ; unpack name into work area...
       UNPACK
       MOVB    #' ,@A2
       POP     A2

       MOV     JOBTBL,A0               ; -> first JCB pointer...
LOOP:   MOV     (A0)+,D7                ; -> JCB...
       BEQ     LOOP                    ; if not allocated...
       CMP     D7,#-1                  ; test for end of table...
       JEQ     EXIT                    ; leave if so...
       MOV     D7,A1
       CMM     JOBPRG(A1),#[LPT]_16.+[SPL]     ; JKB-Running Spooler
       BEQ     LOOP                    ; br if this is a printer
       MOV     JOBTRM(A1),D7           ; D7 -> TCB...
       BEQ     LOOP                    ; br if no terminal...
       MOV     D7,A5                   ; A5 -> TCB...
       MOV     2(A5),A5                ; A5 -> interface driver...
       SUB     #4,A5                   ; A5 -> I.D. name...
       CMM     @A5,#[PSE]_16.+[UDO]    ; PSEUDO?
       BEQ     LOOP                    ; br if so...
       CMM     @A5,#[FLP]_16.+[IDV]    ; ALSO IGNORE FLIP TRMDEFS IN ALPHABASE
       BEQ     LOOP
       MOV     JOBTRM(A1),A5           ; A5 -> TCB...AGAIN
       MOV     -4(A5),D.FIL(A3)        ; move in terminal name...
       OPENO   @A3                     ; open for output
       MOVB    #';,D1                  ; make it look like SEND...
       FILOTB  @A3

       LEA     A1,JOB(A4)              ; A1 -> job name work area...
NLOOP:  MOVB    (A1)+,D1
       FILOTB  @A3
       CMPB    D1,#'
       BNE     NLOOP
       MOVB    #'-,D1
       FILOTB  @A3
       MOVB    #' ,D1
       FILOTB  @A3

       PUSH    A2                      ; save -> text line...
OLOOP:  MOVB    (A2)+,D1                ; get next byte of text and
       FILOTB  @A3                     ; output...
       LIN                             ; end of input line?
       BNE     OLOOP                   ; br if not, else
       POP     A2                      ; restore A2 and
       MOVB    #7,D1
       FILOTB  @A3                     ; give him a BELL and
       MOVB    #15,D1                  ; a CR and a LF.
       FILOTB  @A3
       MOVB    #12,D1
       FILOTB  @A3
       CLOSE   @A3                     ; close output file.
       JMP     LOOP                    ; and back.

EXIT:   REST    A0-A6
       RTN                             ; BACK TO BASIC

       END