.title inform_oper Send/Wait-for-Reply messages via OPCOM .ident /V01-003/ ; KOB 2nd May 1986 ; KOB 8th-April-1987 Added OPCOM receive selection parameter ; KOB 12th-November-1986 Put file into standard format ; KOB 11th-November-1986 Add declare macro ; Entry points are as follows :- ;;HELP_START;; ;2 Inform_oper ; Inform_oper, allows the user to send requests to the operator, ; and optionally request a reply. ; ; Routine inform_oper :- 1 args min 6 args max ; Inform_oper (msg,rpy,rst,rmg,len,omk) ; Send/Request Operator messages ;Rq/Opt R/W Type Name Description ;------------------------------------------------------------------------- ;Rq R Descriptor msg - String to transmit ;Op R Logical*1 rpy - Zero if no reply wanted ; If reply is wanted but text not, then reply wait is ; issued but the text is ignored ;Op W Integer*4 rst - Reply status received ;Op W Descriptor rmg - Reply string received ;Op W Integer*4 len - Reply string length received ; Maximum reply buffer is 255, but routine will only ; return up to length of string supplied by user, ; i.e. Length given in "RMG" descriptor ;Op R Integer*4 omk - LW bit mask to receive OPCOM's ; Default will be OPC$M_NM_TAPES!OPC$M_NM_CENTRL ; I*4 function. Any errors returned to user. ;;HELP_END;; .enable suppression .library /sys$library:lib.mlb/ .library /pfm_root:[000000]macrolib.mlb/ $opcdef ; Opcom Buffer layout defs $opcmsg ; Reply message type defs $dscdef ; String defs $iodef ; Io defs .psect rw_data, noexe, rd, wrt, long, pic, noshr ;Read/Write data ; Request message buffer descriptor reqmsgd: .long 0 ; Request message buffer length reqmsga: .address reqmsg ; Request message buffer address reqmsg: .blkb 264 ; max message + 8 .quad 0 ; after buffer space jusdt in case mistakes reqcnt: .long 0 ; user request number reply: .byte 0 ; clear is no reply requested ; Reply message buffer descriptor maxsiz = 282 ; max message + 8 + 2 + 16 maxquo = maxsiz * 5 ; 5 messages. Should be only one at a time repmsgd: .long 0 ; Reply message buffer length repmsga: .address repmsg ; Reply message buffer address repmsg: .blkb maxsiz ; Mailbox for reply devnamd: .long devnamx - devnama .address devnama devnama: .ascii /oper_temp_mbx/ ; process local logical name for mbx devnamx: maxmsg: .long maxsiz ; max mailbox message size bufquo: .long maxquo ; number of msg bytes devchn: .word 0 ; device channel from $assign mbxchn: .long 0 ; mailbox channel from $crembx repchn: .long 0 ; reply channel iosb: .quad 1 ; iosb ;; .psect rd_data, noexe, rd, nowrt, long, pic, shr ;Read Only data .psect prog_code, rd, nowrt, exe, pic, shr, long .sbttl inform_oper (msg,rpy,rst,rmg,len,omk) declare inform_oper ; .entry inform_oper ^m .CALL_ENTRY MAX_ARGS=6, HOME_ARGS=TRUE,- INPUT=,- PRESERVE=,- LABEL=INFORM_OPER chkread (ap), 4 ; Branch if arglist not readable chk_params (ap), #msgprm ; Check for required params chk_zero msgoff, msgoff ; Check AP's Rqd params not 0's moval reqmsg, r2 clrl repchn ; clear reply channel before call clrb reply ; Def : No reply requested movb #opc$_rq_rqst, opc$b_ms_type(r2) ; no reply wanted cmpl (ap),#2 ; is a reply wanted blss 50$ ; no reply wanted tstl rpyoff(ap) ; was reply requested beql 50$ ; not specified tstb @rpyoff(ap) ; was reply requested beql 50$ ; not wanted incb reply ; reply wanted ; Create mailbox if not already present movl mbxchn, repchn ; Set reply channel before call tstl mbxchn ; is mailbox channel clear bneq 50$ ; already set up $crembx_s chan = mbxchn, - ; returned by $crembx maxmsg = maxmsg, - ; size of mbx messages bufquo = bufquo, - ; size of mailbox lognam = devnamd ; device name bsbw error_chk ; Check success ; Now send request to oper movl mbxchn, repchn ; Set reply channel before call 50$: tstparam omk, 52$, 52$ ; Check param present & specified tstl @omkoff(ap) ; Any bits set beql 52$ ; Zero contents insv @omkoff(ap), #0, #24, - ; Use Users setting opc$b_ms_target(r2) ; Send to central & tape operators brw 54$ ; Skip default setting 52$: insv #, - #0, #24, - opc$b_ms_target(r2) ; Send to central & tape operators 54$: incl reqcnt ; increment user request number movl reqcnt, opc$l_ms_rqstid(r2) ;Set request id movl msgoff(ap), r4 ; get msg desc adr in r4 pushr #^m ; save regs from movc5 movc5 dsc$w_length(r4), - ; # Chars to move @dsc$a_pointer(r4),- ; Source address #0, #255,- ; Fill with 0's until #255 opc$l_ms_text(r2) ; Dest address popr #^m ; save regs from movc5 moval reqmsgd, r6 ; get opcom msg buffer descr addw3 #opc$l_ms_text,- ; opcom pre msg info dsc$w_length(r4),- ; Users msg length dsc$w_length(r6) ; Fill in msg request length $sndopr_s msgbuf = reqmsgd,- ; request buffer descriptor chan = repchn ; returned by $crembx bsbw error_chk ; Check success tstb reply ; wait for reply ? bneq 55$ ; Yes brw 100$ ; Nop ; Read and wait for mailbox opcom reply 55$: $qiow_s chan = mbxchn, - ; mailbox channel func = #io$_readvblk, - ; read and wait iosb = iosb, - ; for result p1 = repmsg, - ; reply buffer p2 = #maxsiz ; num of bytes bsbw error_chk ; Check success movzwl iosb, r0 bsbw error_chk ; Check success movzwl iosb+2, repmsgd ; Get length of reply message moval repmsg, r2 ; Get reply buffer address moval repmsgd, r6 ; Get reply buffer desc address ; pass user reply status cmpl (ap),#3 ; is a reply status wanted blss 100$ ; not wanted tstl rstoff(ap) ; was reply sts requested beql 60$ ; not specified movl rstoff(ap), r8 ; return reply status movw #opc$_facility, 2(r8) ; put in opc facility movw opc$w_ms_status(r2), (r8) ; return reply status ; pass user reply message if requested 60$: cmpl (ap),#4 ; is a reply msg wanted blss 100$ ; no reply msg wanted tstl rmgoff(ap) ; was reply msg requested beql 100$ ; not specified movl rmgoff(ap), r4 ; get msg desc adr in r4 tstw (r4) ; is string length 0 - bad length beql 100$ ; not specified subw3 #opc$l_ms_text, - ; calc length of reply text dsc$w_length(r6), r5 ; opcom pre msg info cmpw r5, dsc$w_length(r4) ; Users msg length bleq 70$ ; Pass full message back movw dsc$w_length(r4), r5 ; Move Users length back 70$: pushr #^m ; save regs from movc5 movc5 r5, - ; # Chars to move opc$l_ms_text(r2),- ; Source address #^a/ /, dsc$w_length(r4),- ; Fill user buf with spaces @dsc$a_pointer(r4) ; Dest address popr #^m ; save regs from movc5 cmpl (ap),#5 ; is reply length wanted blss 100$ ; not wanted tstl lenoff(ap) ; was reply msg requested beql 100$ ; not specified movzwl dsc$w_length(r6), @lenoff(ap) ; pass length back 100$: movzwl #ss$_normal, r0 ; return good status ret ;------------------------------------------------------------------------------ ; Error checking subroutine error_chk: .JSB_ENTRY INPUT=,- OUTPUT= blbs r0,10$ ; Branch if O.K. ret 10$: rsb ; Return ; Alternative error handling error_hdlr: blbs r0,10$ ; Branch if O.K. ; some kind of error handling ; and a return as necessary 10$: rsb ; Return ; ; Subroutine to upcase a string ; r2 = Address of string descriptor ; r0 & r1 used upcase_string: movq (r2),r0 ; Get descriptor 10$: cmpb (r1)+,#^a'a' ; Check if lower case blssu 20$ ; branch if not addb #^a'A'-^a'a',-1(r1) ; Convert to upper case 20$: sobgtr r0,10$ ; loop until done rsb .end