; INFSND - Sends message to all Infinity users
; Modified from a distant version of an AMUS donated utility BRDCST
; by Dave Greene
;
; Edit History:
;
; 11/26/90 Created DJG
;
SEARCH SYS
SEARCH SYSSYM
SEARCH TRM
; Allow lower case input
JOBIDX
MOV JOBTRM(A6),A6
ORW #T$ILC,@A6
; Check what user wants to send
BYP
LIN ; anything to send?
BNE 0$
TYPE <Message: >
KBD EXIT
BYP
LIN
JEQ EXIT ; leave if not...
; Setup output device info
0$:
MOVW #[TRM],DDB+D.DEV(A4) ; move in device name,
INIT DDB(A4) ; and initialize.
; Clear flags
CLRW SHOW(A4) ; show senders name
CLRW SILENT(A4) ; output bell
JOBIDX A0 ; A0 -> out JCB...
; This is the start of the program. Check for valid switches.
1$:
CMPB @A2,#'/ ; switch marker?
BNE 10$ ; no - done checking for switches
MOVB 1(A2),D1 ; yes - D1 = switch character
UCS ; fold
CMPB D1,#'T ; suppress sending senders jobname?
BNE 5$ ; no - check other switches
SETW SHOW(A4) ; yes - flag it
ADD #2,A2 ; bump past this switch
BYP ; skip spaces
BR 1$ ; continue check
5$:
CMPB D1,#'S ; silent mode?
BNE 10$ ; no - done with switches
SETW SILENT(A4) ; yes - flag it
ADD #2,A2 ; bump past this switch
BYP ; and spaces
BR 1$ ; and continue check
; save sending jobs jobname to display with message
10$:
TSTW SHOW(A4) ; are we sending this info
BNE BEGIN ; no - skip this
PUSH A2 ; save A2...
LEA A1,JOBNAM(A0) ; A1 -> job name field...
LEA A2,JOB(A4) ; A2 -> job name work area...
UNPACK ; unpack name into work area...
UNPACK
MOVB #32.,@A2
POP A2
;***********
;* BEGIN *
;***********
; This is the main loop. Scan through all entries in the job table, and
; check for jobs that look like they are running Infinity. Rule out
; task manager jobs and the like.
BEGIN:
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 ; A1 -> current job entry
; Test to see if this job is me
JOBIDX A6 ; get my job
CMP A6,A1 ; same?
BEQ LOOP ; yes - skip me
; Test to see if this job is running an Infinity Module
CMMW JOBPRG(A1),#[INF] ; program starts with "INF"
BNE LOOP ; no - forget
; Test for task managr job just in case it's not using PSEUDO tdv
CMM JOBNAM(A1),#[TAS]_16.+[K ] ; is job a TASK MANAGR?
BEQ LOOP ; branch if so
; Test for job spawned by MULTI. Send to base job
MOV JOBATT(A1),D7 ; get attached job
BEQ 10$ ; if none then proceed
MOV D7,A1 ; now use base job
; Ignore spooler jobs and slaves to TASK MANAGR
10$:
MOVW JOBTYP(A1),D7 ; get job type
ANDW #<J.LPT!J.TSK>,D7 ; mask off spooler and task bits
JNE LOOP ; loop if either set
; Now check to see if the terminal qualifies for the message
MSGSND:
MOV JOBTRM(A1),D7 ; D7 -> TCB...
JEQ LOOP ; br if no terminal...
MOV D7,A5 ; A5 -> TCB...
MOV 2(A5),A3 ; A3 -> interface driver...
SUB #4,A3 ; A3 -> I.D. name...
CMM @A3,PSEUDO ; PSEUDO?
JEQ LOOP ; skip if so...
; Terminal OK. Prepare to output message
MOV -4(A5),D.FIL(A4) ; move in terminal name...
OPENO DDB(A4) ; open for output
; Prepare to output bell
TSTW SILENT(A4) ; suppressing bell?
BNE FNDTRM ; yes - forget it
SEND #7 ; ring the chime
;************
;* FNDTRM *
;************
;
; This section of code, uses a table which contains information on
; how to activate the unshifted status line in REVERSE mode. If a terminal
; does not have info in this table, this program will output it much the
; same way as send does.
;
; Table consists of entries of names of terminal drivers, and then the
; offset to the routine that contains the appropriate escape codes.
;
FNDTRM:
PUSH A1 ; save work register
LEA A3,VALIDT ; A3 -> table
MOV 16(A5),A1 ; A1 -> terminal driver
20$:
TST @A3 ; end of table?
BEQ 90$ ; yes - didn't find it
CMM (A3)+,-4(A1) ; found a match?
BEQ 30$ ; yes - cool
ADD #4,A3 ; no - goto next entry in table
BR 20$ ;
30$:
ADD @A3,A3 ; add offset to current location
; A3 -> status line activation string null terminated
40$:
TSTB @A3 ; are we at end?
BEQ 90$ ; yes - good
SEND (A3)+ ; no - send next character in string
BR 40$ ; and continue
90$:
POP A1 ; restore A1
; Now we are almost ready to send message. First, we need to check to
; see if we will be sending the Senders jobname.
TSTW SHOW(A4) ; sending jobname?
BNE START ; no - forget it
CLR D2 ; D2 keeps track of characters sent
LEA A1,JOB(A4) ; A1 -> job name work area...
SEND #'( ; parens are nicer
INC D2
NLOOP:
MOVB (A1)+,D1 ; get next character of jobname
CMPB D1,#' ; a space?
BNE SENDIT ; yes - done with this
BR ENDPAR ;
SENDIT:
FILOTB DDB(A4) ; send character
INC D2 ; and incrment "sent" count
BR NLOOP ; and continue
ENDPAR:
SEND #') ; done - close parens
INC D2 ;
START:
MOVB #32.,D1 ; need a space seperator
FILOTB DDB(A4) ; output
PUSH A2 ; save -> text line...
;***********
;* OLOOP *
;***********
; Main loop to output message. We either send characters until end of line
; is reached, or 77 characters have been sent; which ever comes first.
;
OLOOP:
MOVB (A2)+,D1 ; get next byte of text and
FILOTB DDB(A4) ; output...
INC D2 ; increment count
CMP D2,#77. ; 77 yet?
BHIS ESEND ; yes - done
LIN ; end of input line?
BNE OLOOP ; br if not, else
POP A2 ; restore A2 and
NEG D2 ; D2 will equal number of spaces
ADD #78.-1.,D2 ; .. to fill out line
TST D2 ; (in case there is already stuff
BMI ESEND ; on the status line)
BEQ ESEND
10$: ; output filler spaces
SEND #32. ;
SOB D2,10$
; Done sending message.
ESEND:
SEND #127. ; terminate status line activity
CLOSE DDB(A4) ; close output file.
; Show this user, so we can tell who was/is effected.
MOV -4(A0),A1 ; Get last job entry
MOVW #-1_8.+11.,D1 ; dim
TCRT
TYPE <User > ; display user name of person
MOVW #-1_8.+12.,D1 ; logged in at this job
TCRT
TTYL JOBUSN(A1)
CLR D1
MOVW #-1_8.+11.,D1
TCRT
TYPE < notified (> ; and then the job they are logged
MOVW #-1_8.+12.,D1 ; in at
TCRT
PUSH A2 ; save A2...
LEA A1,JOBNAM(A1) ; A1 -> job name field...
LEA A2,PBUF(A4) ; A2 -> job name work area...
UNPACK ; unpack name into work area...
UNPACK
CLRB @A2
POP A2
TTYL PBUF(A4)
MOVW #-1_8.+11.,D1
TCRT
TYPECR <)>
MOVW #-1_8.+12.,D1
TCRT
JMP LOOP ; do next job
EXIT:
CRLF ; done
EXIT