Google
 

Trailing-Edge - PDP-10 Archives - cuspbinsrc_1of2_bb-x128c-sb - 10,7/galaxy/please/please.mac
There are 31 other files named please.mac in the archive. Click here to see a list.
TITLE	PLEASE - Galaxy CUSP for Operator/User Commumications
SUBTTL	D.P.Mastrovito /DPM/PJT/PGW/NT/LWS	12-SEP-85

;
;
;	COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION 1979,1980,1981,1982,1983,
;	1984,1986,1987.  ALL RIGHTS RESERVED.
;
;     THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY  BE  USED
;     AND COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE
;     AND WITH THE INCLUSION OF THE ABOVE COPYRIGHT NOTICE.   THIS
;     SOFTWARE  OR ANY OTHER COPIES THEREOF MAY NOT BE PROVIDED OR
;     OTHERWISE MADE AVAILABLE TO ANY OTHER PERSON.  NO  TITLE  TO
;     AND OWNERSHIP OF THE SOFTWARE IS HEREBY TRANSFERRED.
;
;     THE INFORMATION  IN  THIS  SOFTWARE  IS  SUBJECT  TO  CHANGE
;     WITHOUT  NOTICE  AND SHOULD NOT BE CONSTRUED AS A COMMITMENT
;     BY DIGITAL EQUIPMENT CORPORATION.
;
;     DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY
;     OF  ITS  SOFTWARE  ON  EQUIPMENT  WHICH  IS  NOT SUPPLIED BY
;     DIGITAL.


	SEARCH	GLXMAC			;Galaxy symbols
	SEARCH	ORNMAC			;ORION symbols

	PROLOG	(PLEASE)		;Set up

	PLSVER==104			;Major version
	PLSMIN==0			;Minor version
	PLSWHO==0			;Who last patched
	PLSEDT==115			;Edit level

	TWOSEG				;MAKE US SHARABLE
	RELOC	400000

TOPS10	<IF2,<PRINTX [Assembling Galaxy-10 PLEASE]>>
TOPS20	<IF2,<PRINTX [Assembling Galaxy-20 PLEASE]>>

	LOC	<.JBVER==:137>		;Set up JOBDAT
	EXP	<%%.PLS==<VRSN.(PLS)>>	;Assemble version number

	RELOC	0

COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION 1971,1987. ALL RIGHTS RESERVED.
\;END COPYRIGHT MACRO


SUBTTL	Table of contents


;               TABLE OF CONTENTS FOR PLEASE
;
;
;                        SECTION                                   PAGE
;    1. Table of contents.........................................   2
;    2. Edit history..............................................   3
;    3. Assembly parameters and local storage.....................   4
;    4. Galaxy interface..........................................   5
;    5. Macros....................................................   6
;    6. PLEASE command parse tables...............................   7
;    7. Dialogue mode parse tables................................   8
;    8. Program intialization and command parsing.................   9
;    9. Command mode processor....................................  10
;   10. Dialogue loop.............................................  11
;   11. Switch processors.........................................  12
;   12. Command line RESCANing....................................  13
;   13. Command parsing...........................................  14
;   14. IPCF message processing...................................  15
;   15. Check for operator on duty................................  16
;   16. Exit routines.............................................  17
;   17. Message handler...........................................  18
;   18. Messages..................................................  19
SUBTTL	Edit history


COMMENT	\

Edit	Explanation
----	-----------

100	Rewrite entire program in an attempt to solve some major problems.

101	Fix $HELP prompt text for /NODE: specification

102	Increase PDL size from 120 to 150 words to accomodate P$HELP.

103	Weed out control characters in text message sent to the operator.
	The only exceptions are bell, line-feed and carriage-return.

104	Clean up control-Z in dialogue command table.

105	Make PLEASE a single high segment linked with GLXLIB.

106	Use job number for a PID so SYSINF isn't required to run PLEASE.

107	Fix up low seg zeroing BLT to correct off by one problem.
	Fixed SCAN to work right.

110	Major edit to fix:
		1) Dialog mode to so that it would accept "?"
		the message without a ^V quote.
		2) Two prompts now apply to dialog mode. The first
		explains the functions of the delimiters, the second
		just prompts for the next message.
		3) Made ^Z delimiter work consistently. (i.e. it will
		no longer get you out if the message is null, but
		rather, just prompts you for the next message without
		sending the null to the OPR.)

111	Make sure the delimiter character doesn't get sent to the
	operator.
112	Part 3 of EDIT 110 didn't quite work. Fix it.
	SPR 10-33632 1-Nov-83 /LWS

113	When in DIALOG mode don't display messages that may have been
	from a previous PLEASE (WTOR) command. Build an ACK code from
	job number and UDT. Check for this ACK code on a RESPONSE from
	operator. If ACKs don't match, pitch message and wait.
	SPR 10-34007 3-Nov-83 /LWS

114	Update copyright statements. 12-SEP-85 /LEO

115	Change $STOP to STOPCD.
	GCO 10466  21-Nov-86  /BAH

\

SUBTTL	Assembly parameters and local storage


; Assembly parameters
;
	ND	PDLSIZ,150		;Stack size
	ND	BUFSIZ,<^D400/5>+1	;S%CMND buffer size in characters
	ND	ATMSZ,<^D400/5>+1	;ATOM buffer size in characters
	SYSPRM	MC.CON,JW.WCN,<1B9>	;/MESSAGE:CONTINUATION
	SYSPRM	MC.FIR,JW.WFL,<1B10>	;/MESSAGE:FIRST
	SYSPRM	MC.PFX,JW.WPR,<1B11>	;/MESSAGE:PREFIX


	RELOC	0

; Local storage
;
ZBEG:!					;Start of block to clear on start up

PDL:	BLOCK	PDLSIZ			;Stack
PIBBLK:	BLOCK	PB.MNS			;PIB
MSGBLK:	BLOCK	5			;Message block
	ACK.JB==777000,,0		;[113] Mask for job # in ACK code
	ACK.UT==777,,777777		;[113] Mask for UDT part of ACK code
USRACK:	BLOCK	1			;[113] User ACK code
OPRNOD:	BLOCK	1			;Operator node number/name
BUFFER:	BLOCK	BUFSIZ			;S%CMND buffer
ATMBUF:	BLOCK	ATMSZ			;ATOM buffer
CMDMOD:	BLOCK	1			;Command mode flag
PARBLK:	BLOCK	PAR.SZ			;Parser block
PARFLG:	BLOCK	1			;Parse flags
CMDBLK:	BLOCK	PAGSIZ			;Command block
CSB:	BLOCK	1			;Command state block address (S%CMND)
TCSB:	BLOCK	1			;Command state block address (K%TXTI)
GTJBLK:	BLOCK	16			;GTJFN block for S%CMND
SWTWRD:	BLOCK	1			;Set if switches have been specified
SCNFLG:	BLOCK	1			;Light on a RESCAN 
ZEND:!					;End of block to clear on start up

	RELOC	400000
	SUBTTL	Galaxy interface

; GLXLIB initialization block
;
IB:	$BUILD	(IB.SZ)			;Size of block
	  $SET	(IB.PRG,,%%.MOD)	;Program name
	  $SET	(IB.OUT,,T%TTY)		;TTY output
	  $SET	(IB.FLG,IT.OCT,1)	;Require command terminal
	  $SET	(IB.FLG,IB.DPM,1)	;Use job number for a PID
	  $SET	(IB.PIB,,PIBBLK)	;PID block pointer
	$EOB				;End of block


; Template for Command State Block for S%CMND
;
CSBTMP:	$BUILD	.CMGJB+1
	$SET	.CMIOJ,LHMASK,.PRIIN	;Primary input
	$SET	.CMIOJ,RHMASK,.PRIOU	;Primary output
	$SET	.CMBFP,,<POINT 7,BUFFER> ;Pointer to input buffer
	$SET	.CMPTR,,<POINT 7,BUFFER> ;Start the parse at the beginning
	$SET	.CMCNT,,BUFSIZ*5-1	;Size of buffer
	$SET	.CMABP,,<POINT 7,ATMBUF> ;Pointer to start of atom buffer
	$SET	.CMABC,,ATMSZ*5-1	;Size of atom buffer
	$SET	.CMGJB,,GTJBLK		;GTJFN block
	$EOB

; Template for Command State Block for K%TXTI
;
TXTTMP:	$BUILD	.RDBKL+1
	$SET	.RDCWB,,.RDBKL		;Primary input
	$SET	.RDFLG,,<RD%BRK!RD%JFN>	;Primary output
	$SET	.RDIOJ,LHMASK,.PRIIN	;Input device is TTY
	$SET	.RDIOJ,RHMASK,.PRIOU	;Output device is TTY
	$SET	.RDDBP,,<POINT 7,ATMBUF> ;Pointer to input buffer
	$SET	.RDDBC,,ATMSZ*5-1	;Size of buffer
	$SET	.RDBFP,,<POINT 7,ATMBUF> ;Pointer to start of atom buffer
	$SET	.RDRTY,,0		; Place to store our prompts
	$SET	.RDBRK,,0		; No break set
	$SET	.RDBKL,,<POINT 7,ATMBUF> ; Backup limit
	$EOB



; File open block (FOB) for help file
;
HLPFOB:	EXP	HELPFD			;File Descriptor
	EXP	7			;Bytesize

; File descriptor (FD) for help file
;
TOPS10	<				;TOPS-10 spec
HELPFD:	$BUILD	(FDMSIZ)		;Size of block
	  $SET	(.FDLEN,FD.LEN,FDMSIZ)	;Length of FD
	  $SET	(.FDLEN,FD.TYP,.FDNAT)	;File spec type (native)
	  $SET	(.FDSTR,,<'HLP   '>)	;Ersatz device HLP:
	  $SET	(.FDNAM,,<'PLEASE'>)	;File name
	  $SET	(.FDEXT,,<'HLP   '>)	;Extension
	$EOB				;End of block
>					;End of TOPS-10 conditional

TOPS20	<				;TOPS-20 spec
HELPFD:	XWD	FDSIZ,.FDNAT		;Native FD with size FDSIZ
	ASCIZ |HLP:PLEASE.HLP|		;Write the file name
FDSIZ==.-HELPFD				;Define the size
>					;End of TOPS-20 conditional
SUBTTL	Macros


;; Macros for building FDB's

; Macro to generate function data block -- caller supplies help text

    DEFINE FLDDB. (TYP,FLGS,DATA,HLPM,DEFM,LST) <
	XLIST
	..XX==<FLD(TYP,CM%FNC)>+FLGS+<Z LST>
	IFNB <HLPM>,<..XX==CM%HPP!..XX>
	IFNB <DEFM>,<..XX==CM%DPP!..XX>
	    ..XX
	IFNB <DATA>,<DATA>
	IFB <DATA>,<0>
	IFNB <HLPM>,<POINT 7,[ASCIZ \HLPM\]>
	IFB <HLPM>,<IFNB <DEFM>,<0>>
	IFNB <DEFM>,<POINT 7,[ASCIZ \DEFM\]>
	LIST
    >


;Macro to generate function descriptor block with break mask supplied

DEFINE FLDBK. (TYP,FLGS,DATA,HLPM,DEFM,BRKADR,LST)<
	..XX==<FLD(TYP,CM%FNC)>+FLGS+<Z LST>
   IFNB <HLPM>,<..XX=CM%HPP!..XX>
   IFNB <DEFM>,<..XX=CM%DPP!..XX>
   IFNB <BRKADR>,<..XX=CM%BRK!..XX>
	..XX
   IFNB <DATA>,<DATA>
   IFB <DATA>,<0>
   IFNB <HLPM>,<POINT 7,[ASCIZ HLPM]>
   IFB <HLPM>,<IFNB <DEFM'BRKADR>,<0>>
   IFB <DEFM>,<IFNB <BRKADR>,<0>>
   IFNB <DEFM>,<POINT 7,[ASCIZ \DEFM\]>
   IFNB <BRKADR>,<BRKADR>
   >

; Macro to generate a message
;
DEFINE	$MSG	(PFX,ADDR),<
	PUSHJ	P,MSG			;;Call the message processor
	CAI	[EXP	M..'PFX		;;Text block address
		 EXP	ADDR]		;;Return address
>					;;End of $MSG macro


; Macro to generate the message text
;
DEFINE	$MSGT	(CHR,PFX,FIRST,CONT),<
M..'PFX:EXP	"CHR"			;;Character
	SIXBIT	|PLS'PFX|		;;Prefix
	[ITEXT	(< 'FIRST>)]		;;First line
	[ITEXT	(<CONT>)]		;;Continuation line
>					;;End of $MSGT macro
SUBTTL	PLEASE command parse tables


PLS010:	FLDDB.(.CMINI)			;INIT FDB 

PLS020:	FLDDB.(.CMKEY,,PLS030)		;KEYWORD FDB

PLS030:	$STAB				;Keyword table for PLS020
	KEYTAB	(DIALOG,<Continue>,CM%INV)
	KEYTAB	(PLSCMD,<Please>)
	KEYTAB	(DIALOG,<Run>,CM%INV)
	KEYTAB	(DIALOG,<Start>,CM%INV)
	$ETAB

PLS040:	FLDDB.	(.CMSWI,,PLS050,Single line message
or Confirm for Multiple-line message
or)					;SWITCH FDB

PLS050:	$STAB				;Switch table for PLS040
	KEYTAB	(.SWHLP,<Help>)
	KEYTAB	(.SWNNM,<Node:>)
	$ETAB

PLS060:	FLDDB.	(.CMNOD,CM%SDH,,Operator node to send to)

PLS080:	FLDDB.	(.CMCFM,CM%SDH,,Confirm for multi-line message,,PLS090)

PLS090:	FLDBK.	(.CMFLD,CM%SDH,,Single line message,,CMDBRK)

PLS100:	FLDDB.	(.CMCFM)

; Break character mask for command mode input
;
TOPS10<
CMDBRK:	000340,,001400			;Break on <LF><VT><FF><CTRLZ><ESCAPE>
	000000,,000000			;Allow
	000000,,000000			; all other
	000000,,000000			;  characters
	> ;End TOPS-10 Conditional

TOPS20<
CMDBRK:	000240,,000000			;Break on <LF><FF>
	000000,,000000			;Allow
	000000,,000000			; all other
	000000,,000000			;  characters
	> ;End TOPS-20 Conditional

; Please command mode prompt
;
PLSPMT:	ASCIZ	|PLEASE>|

SUBTTL	Dialogue mode parse tables


DIA020:	FLDDB.	(.CMKEY,,DIA030,,,DIA040)

DIA030:	$STAB
	KEYTAB	(,\"32)
	$ETAB

DIA040:	FLDBK.	(.CMFLD,,,,,DIABRK)

; Break character mask for dialogue mode input
;
DIABRK:	000000,,001400			;Break on <CTRLZ> or <ESCAPE>
	000000,,000000			;Allow
	000000,,000000			; all other
	000000,,000000			;  characters


; Dialog mode prompt
;
BDIAPT:	ASCIZ	|Enter text, terminate with CTRL/Z to wait for response,
or ESCape to send message and exit
|

DIAPMT:	ASCIZ	|Enter new text (Same terminators)
|
SUBTTL	Program intialization and command parsing


PLEASE:	JFCL				;No CCL
	RESET				;Stop I/O
	MOVE	P,[IOWD	PDLSIZ,PDL]	;Set up stack
	MOVE	S1,[ZBEG,,ZBEG+1]	;Set up BLT
	SETZM	ZBEG			;Clear the first word
	BLT	S1,ZEND-1		;Clear low segment
	MOVX	S1,PB.MNS		;Minimum size block
	STORE	S1,PIBBLK+PB.HDR,PB.LEN	;Store it
	MOVX	S1,IB.SZ		;Size of block
	MOVEI	S2,IB			;Address of block
	PUSHJ	P,I%INIT##		;Initialize GLXLIB
	SETO	S1,			;-1 means us
	MOVX	S2,JI.JNO		;Function code
	$CALL	I%JINF			;Get our job number
	STORE	S2,USRACK,ACK.JB	;[113] Store it	in ACK code
	SETO	S1,			;-1 our job
	MOVX	S2,JI.LOC		;Function code
	$CALL	I%JINF			;Get our node number
	MOVEM	S2,OPRNOD		;Incase /NODE omitted
	PUSHJ	P,SCAN			;Rescan the command line
					;Fall into command mode processor
SUBTTL	Command mode processor


COMMAND:MOVE	P,[IOWD	PDLSIZ,PDL]	;Reset the PDL
	SETOM	CMDMOD			;Indicate in command mode
	SKIPN	S1,CSB			;Get address of CSB
	PUSHJ	P,GETCSB		;Get storage for CSB
	HRLI	S1,CSBTMP		;Make a BLT pointer
	MOVEI	S2,(S1)			;Get dest address in S2
	BLT	S1,.CMGJB(S2)		;Fill in the block
COMM.1:	MOVE	S1,CSB			;Get address of CSB
	MOVE	S2,[POINT 7,PLSPMT]	;Get the PLEASE> prompt
	MOVEM	S2,.CMRTY(S1)		;Put in CSB
TOPS10<
	MOVE	S2,[XWD .PRIIN,.PRIOU]	;Get the JFN's incase we had a RESCAN
	MOVEM	S2,.CMIOJ(S1)		;And stick them in the CSB
	> ;End TOPS-10 Conditional
	MOVEI	S2,REPARS		;Get reparse address
	HRRM	S2,.CMFLG(S1)		;Put in CSB
	SKIPN	SCNFLG			;Have we found anything when scanning
	JRST	COMM.3			;No, go on
	SETZM	SCNFLG			;Yes, turn off the flag
	MOVE	S2,[POINT 7,[0]]	;Yes, get a dummy prompt
	MOVEM	S2,.CMRTY(S1)		;And make it current
TOPS10<
	MOVEI	S2,.NULIO		;Get null output
	STORE	S2,.CMIOJ(S1),RHMASK	;We don't want to echo
	> ;End TOPS-10 Conditional

COMM.3:	MOVEI	S2,PLS010		;Key address of INIT FDB
	PUSHJ	P,S%CMND		;Init the PARSER
COMM.2:	SETZM	SWTWRD			;No switches used yet
	MOVE	S1,CSB			;Get CSB
	MOVEI	S2,PLS020		;Get FDB
	PUSHJ	P,CMDPRS		;Parse a command
	  JUMPF	CMDERR			;Can't, issue error
	MOVE	S1,CR.RES(S2)		;Get the keyword address
	HRRZ	S1,(S1)			;Get the code for the keyword
	PJRST	(S1)			;Dispatch and never return

GETCSB:	MOVEI	S1,.CMGJB+1		;Get a CSB of length .CMGJB+1
	$CALL	M%GMEM			;Get the memory
	MOVEM	S2,CSB			;Store it away
	MOVE	S1,S2			;Get the address in S1
	POPJ	P,			;And return

; Here on a PLEASE command
;
PLSCMD:	PUSHJ	P,CHKOPR		;Check for an operator on duty
	MOVE	S1,CSB			;Get CSB
	MOVEI	S2,PLS040		;Get SWITCH FDB
	PUSHJ	P,CMDPRS		;Parse the command
	 JUMPF	PLSC.1			;If it wasn't a switch, go on
	MOVE	S1,CR.RES(S2)		;Get the keyword address
	HRRZ	S1,(S1)			;Get the code
	JRST	(S1)			;And go process the switch
PLSC.1:	MOVE	S1,CSB			;Get the CSB
	MOVEI	S2,1			;Get a lit bit
	STORE	S2,.CMFLG(S1),CM%WKF	;Light the wakeup on end-of-field bit
	MOVEI	S2,PLS080		;Get CONFIRM/FIELD switch
	PUSHJ	P,CMDPRS		;Parse it
	 JUMPF	[STOPCD	(IPE,HALT,,<Internal parser error>)]
	HRRZ	S1,CR.PDB(S2)		;Find out which FDB was used
	CAIN	S1,PLS080		;Was it the CONFIRM
	JRST	DIALOG			;Yes, do dialog stuff
	LDB	S1,[POINT 7,ATMBUF,6]	;Look at first byte of field
	CAIN	S1,"/"			;Was he trying to do a switch
	 $MSG	(SSE,CHKXIT)		;? Switch syntax error
	HRRZ	S1,CR.PDB(S2)		;Get address of used FDB
	LOAD	S1,.CMFNP(S1),CM%FNC	;Get function code
	CAIN	S1,.CMKEY		;Was it keyword?
	 JRST	MONRET			;Must have a control-Z
	CAIE	S1,.CMFLD		;Then it better have been field
	 JRST	[$MSG (EPM,CHKXIT)]	;? Error parsing message
	JRST	DIAL.1			; Go process the message
SUBTTL	Dialogue loop

DIALOG:	MOVE	P,[IOWD	PDLSIZ,PDL]	;Reset the PDL
	SETZM	CMDMOD			;Indicate dialogue mode
	SKIPE	TCSB			;Get address of CSB
	 JRST	D.1			; Don't get any memory now
	MOVEI	S1,.RDRTY		; Get the lenght of the block
	$CALL	M%GMEM			; Get a chunk of memory
	MOVEM	S2,TCSB			; Store the address away
	SKIPA	T1,[POINT 7,BDIAPT]	;Get the pre-dialog prompt

D.1:	MOVE	T1,[POINT 7,DIAPMT]	; Get the regular dialog prompt
	MOVE	S2,TCSB			; Get the address of the arg block
	HRLI	S1,TXTTMP		;Make a BLT pointer
	HRR	S1,S2			; Put destination in S1
	MOVEI	S2,(S1)			; S2 also
	BLT	S1,.RDRTY-1(S2)		;Fill in the block
	MOVE	S1,TCSB			;Get address of CSB
	MOVEM	T1,.RDRTY(S1)		; Store the prompt
	$TEXT	(,<^T/(T1)/^A>)		; Prompt him
	$CALL	K%TXTI			;Parse the command
	 JUMPF	[STOPCD	(TBI,HALT,,<K%TXTI block incorrect>)] ; Shouldn't happen

DIAL.1:	MOVE	T2,[POINT 7,ATMBUF]	; Point to the message
DIAL.2:	ILDB	T3,T2			;GET A CHARACTER
	JUMPE	T3,DIAL.4		;[112] Done ?
	MOVEI	T1,(T3)			; Save the character
	CAIE	T3,.CHCNZ		; Message terminator?
	 CAIN	T3,.CHESC		;  .  .  .
	  JRST	DIAL.4			; Yes, go finish up
	CAIL	T3," "			;A CONTROL CHARACTER ?
	JRST	DIAL.2			;NO - IGNORE IT
	CAXN	T3,.CHBEL		;ALLOW <BELL>
	JRST	DIAL.3			;STORE IT
	CAIE	T3,.CHLFD		;ALLOW <LF>
	CAXN	T3,.CHCRT		;ALLOW <CR>
	SKIPA				;DON'T CHANGE IT
	MOVEI	T3," "			;CONVERT TO A SPACE

DIAL.3:	DPB	T3,T2			;STORE CHARACTER
	JRST	DIAL.2			;LOOP BACK FOR MORE

DIAL.4:	SKIPE	CMDMOD			;[112] Are we in dialog mode?
	 JRST	DIAL.5			; No, handle the command
	MOVE	S1,TCSB			; Get the address of arguement block
	MOVE	S1,.RDFLG(S1)		; Get the flags from there
	TXNN	S1,RD%BTM		; Did he type a break character
	 $MSG	(MTL,.+1)		; Message too long
	LDB	S1,[POINT 7,ATMBUF,6]	; Get the first character
	CAIN	S1,.CHESC		; Is it an ESCAPE?
	 JRST	MONRET			; Yes, just go out
	CAIN	S1,.CHCNZ		; Is it a ^Z
	 JRST	D.1			; Yes, don't send null message
	SETZ	S1,			; Make a null character
	DPB	S1,T2			; Store it into the break character
	CAIN	T1,.CHCNZ		; Was the break character a ^Z?
	 JRST	WTOR			; Yes, wait for response
	JRST	WTO			; No, must have been ESCape

DIAL.5:	SETZ	S1,			;[112] Make a null
	DPB	S1,T2			;[112] Overwrite the terminator
	MOVE	S1,CR.FLG(S2)		;Get command flags
	TXNE	S1,CM%ESC		;Was escape typed ?
	JRST	WTO			;Yes - don't wait

; Here to Write To OPR (and wait for a response)
;
WTOR:	$CALL	I%NOW			;[113] Get UDT for ACK code
	STORE	S1,USRACK,ACK.UT	;[113] Store it
	$WTOR	(,<^T/ATMBUF/>,,USRACK,<$WTNOD(OPRNOD),$WTFLG(WT.NFY)>) ;[113]
	$MSG	(OPN,.+1)		;[Operator has been notified]
	PUSHJ	P,IPCSER		;Process IPCF messages
	SKIPE	CMDMOD			; Are we in command mode?
	 JRST	DIALOG			; Yes, Go start up a dialog now
	JRST	D.1			; Otherwise go for more dialogue

; Here to Write To OPR (don't wait for a response)
;
WTO:	$WTO	(,<^T/ATMBUF/>,,<$WTNOD(OPRNOD)>)
	$MSG	(OPN,MONRET)		;[Operator has been notified]
SUBTTL	Switch processors


; /Help
;
.SWHLP:	SKIPE	S1,SWTWRD		;Have any switches been specified	
	JRST	[$MSG(BHR,CHKXIT)]	;Yes, bad help request
	MOVE	S1,CSB			;Get CSB address
	MOVEI	S2,PLS100		;Get confirm FDB
	PUSHJ	P,CMDPRS
	JUMPF	[$MSG(BHR,CHKXIT)]	;Bad help request, no confirmed
	MOVEI	S1,2			;Length of help FOB
	MOVEI	S2,HLPFOB		;Address of help FOB
	$CALL	F%IOPN			;Open the file
	JUMPF	[$MSG(NHA,CHKXIT)]	;No help, sorry Charlie
	MOVEI	T1,(S1)			;Get the IFN for calls
RDHLP:	MOVEI	S1,(T1)			;Get the IFN for call
	$CALL	F%IBUF			;Get a buffer
	JUMPF	CLSHLP			;Assume EOF
	EXCH	S1,S2			;Switch count and BP
	$CALL	K%BUFF			;Put it out to TTY
	JRST	RDHLP			;Get the next buffer
CLSHLP:	$CALL	K%FLSH			;If not assume EOF and flush buffer.
	MOVEI	S1,(T1)			;Get the IFN
	$CALL	F%REL			;And close the file
	JRST	CHKXIT			;We're done





; /Node: xxx
;
.SWNNM:	SKIPE	SWTWRD			;Is this the first switch
	JRST	[$MSG(SUT,CHKXIT)]	;No, switch used twice, no no
	SETOM	SWTWRD			;Say that we have a switch
	MOVE	S1,CSB			;Get the CSB
	MOVEI	S2,PLS060		;Get the NODE FDB
	PUSHJ	P,CMDPRS		;Parse it
	 JUMPF	[$MSG(NIN,CHKXIT)]	;Die on error

TOPS10<
	MOVE	S1,CR.RES(S2)		;Get name or number
	> ;End TOPS-10 Conditional

TOPS20<
	HRROI	S1,ATMBUF		;Pointer to node name
	$CALL	S%SIXB			;Convert to sixbit
	MOVE	S1,S2			;Get in S1
	> ;End TOPS-20 Conditional

	MOVEM	S1,OPRNOD		;Store it
	JRST	PLSCMD			;Get rest of command

; Here on a Reparse

REPARS:	MOVE	P,[IOWD PDLSIZ,PDL]	;Reset the stack
	JRST	COMM.2			;Go to retry the parse

REPAR1:	MOVE	P,[IOWD PDLSIZ,PDL]	;Reset the stack
	JRST	D.1			;Go to retry the parse




SUBTTL	Command line RESCANing


; Macro to build a break character mask
;
DEFINE	$BRK	(CHR),<
	...BRK==0
	IRP	CHR,<...BRK==...BRK!1B35_CHR>
	EXP	...BRK
	PURGE	...BRK
>


SCAN:
TOPS20<
	MOVEI	S1,.RSINI		;Make data available 
	RSCAN				;Check for command
	 JRST GO2			;None
	JUMPE	S1,GO2			;If char count zero, no cmd
	> ;End TOPS-20 Conditional
TOPS10<
	RESCAN	1			;See if anything there
	 SKIPA				;Could be...
	  JRST	GO2			;Nothing, skip all this
	> ;End TOPS-10 Conditional

	SETOM	SCNFLG			;Light the flag
	POPJ	P,			;Return

GO2:
TOPS20<
	HRROI	S1,[0]			;Clear rescan
	RSCAN
	 JFCL
	> ;End TOPS-20 Conditional
	POPJ	P,


SUBTTL	Command parsing


; Parse a command
; Call:		S1/	Address of CSB
;		S2/	Address of FDB
;
; Returns TRUE	if no parsing error with CMDBLK ready to digest
; Returns FALSE parsing error
;
CMDPRS:	$CALL	S%CMND			; Do the Call
	$RETIF				; Pass along a false return
	MOVE	S1,CR.FLG(S2)		; Get flag word of reply block
	TXNE	S1,CM%NOP		; Was no-parse set
	$RETF				; Yes, return false
	$RETT				; No, return true



; Here on command errors
;
CMDERR:	HRROI	T1,[ASCIZ |Illegal Keyword|] ;Get pointer to error text
	$MSG	(CME,CHKXIT)		;? Command syntax error
SUBTTL	IPCF message processing


IPCSER:	$CALL	C%BRCV			;Wait for an IPCF message
	LOAD	P1,MDB.MS(S1),MD.ADR	;Get message address
	LOAD	S1,.MSCOD(P1)		;[113] Get the ACK code
	CAMN	S1,USRACK		;[113] Is it the one we're waiting for?
	  JRST	IPCS.0			;[113] Yes,,continue
	$CALL	C%REL			;[113] No,,release msg and
	JRST	IPCSER			;[113]  go wait for one we're expecting

IPCS.0:	MOVEI	P3,.OHDRS(P1)		;[113] Point to the blocks
	LOAD	S1,PFD.HD(P3),PF.TYP	;Get the type field
	CAIE	S1,.CMTXT		;Is it text?
	JUMPF	IPCERR			;It's an error, otherwise
	MOVEI	T1,ARG.DA(P3)		;Address of the text
	LOAD	S2,PFD.HD(P3),PF.LEN	;Get the length in S2
	ADD	P3,S2			;Add to the current location
	LOAD	S2,.MSTYP(P1),MS.TYP	;Get the message type
	CAXE	S2,MT.TXT		;Is it a text message
	JRST	IPCS.1			;No -  process as a response
	MOVEI	P2,.OHDRS+ARG.DA(P1)	;Get the address
	$MSG	(EFO,.+1)		;? Error from ORION
	$CALL	C%REL			;Release the IPCF page
	PJRST	CHKXIT			;Done


; Here with a normal response from the operator
;
IPCS.1:	MOVE	S2,P3			;Get the current address
	LOAD	S1,PFD.HD(S2),PF.TYP	;And the type field
	LOAD	TF,PFD.HD(S2),PF.LEN	;Get the length
	ADD	P3,TF			;So we can bump the pointer
	CAXE	S1,.ACKID		;Check for ACK ID block
	  JRST	IPCERR			;Generate an error
	MOVE	T2,ARG.DA+1(S2)		;Get the value
	MOVEI	T3,[ITEXT(<^N/T2/>)]	;Node name
	TLNN	T2,770000		;Sixbit node name ?
	MOVEI	T3,[ITEXT(<Terminal ^O/T2/>)] ;No - must be terminal number
	$TEXT	(,<
^C/[-1]/ From Operator ^I/(T3)/:
	=^7/[76]/^T/(T1)/>)		;Dump the response
	$CALL	C%REL			;Release IPCF page
	$RETT				;Return


; Here when we detect a bad message type
;
IPCERR:	$MSG	(UMO,.+1)		;? Unrecognized message from ORION
	$CALL	C%REL			;Release the IPCF page
	JRST	CHKXIT			;Done
SUBTTL	Check for operator on duty


; Check for operator on duty
; Outputs a warning message if monitor beleives there is no
; operator in attendance
;
CHKOPR:
TOPS10	<				;TOPS-10 only
	MOVX	S1,%CNSTS		;Get the STATES word
	GETTAB	S1,
	  SETZ	S1,			;Can't
	TXNE	S1,ST%NOP		;Check for no operator
>					;End of TOPS-10 conditional

TOPS20	<				;TOPS-20 only
	MOVX	S1,.SFOPR		;Get operator in attendance function
	SETZ	S2,			;Clear result
	TMON				;Check
	SKIPN	S2			;No operator check
>					;End of TOPS-20 conditional

	$MSG	(NOP,.+1)		;% No operator in attendance
	$RETT				;Operator on duty
SUBTTL	Exit routines



; Check if PLEASE should exit after an error
;
CHKXIT:
TOPS10<
	CLRBFI				;Clear input buffer of type ahead
	> ;End TOPS-10 Conditional
TOPS20<
	MOVEI	S1,.PRIIN
	CFIBF
	> ;End TOPS-20 Conditional
	SKIPN	CMDMOD			;Called from command mode ?
	JRST	DIALOG			;No - return to dialogue mode
	SKIPN	DEBUGW			;Are we debugging
	JRST	MONRET			;No - then stop the job
	JRST	COMM.1			;Yes - go prompt user


; Return to the monitor
;
MONRET:	$HALT				;Stop the job
	JRST	PLEASE			;Do it again
SUBTTL	Message handler


MSG:	MOVE	S1,@(P)			;Get pointer to argument block
	MOVE	S2,1(S1)		;Get return address
	HRRM	S2,(P)			;Store it
	MOVE	S1,(S1)			;Get address of block
	MOVSI	S2,(S1)			;Get message block address
	HRRI	S2,MSGBLK		;Point to storage address
	BLT	S2,MSGBLK+3		;Copy data
	MOVE	S1,MSGBLK+0		;Get first character
	CAIE	S1,"["			;A comment ?
	TDZA	S1,S1			;No - load a <NUL>
	MOVEI	S1,"]"			;Yes - finish it
	MOVEM	S1,MSGBLK+4		;Store it

TOPS10	<				;TOPS-10 only
	HRROI	S1,.GTWCH		;Get the job's watch bits
	GETTAB	S1,			;From the monitor
	  SETZ	S1,			;Can't
	TXNN	S1,MC.PFX!MC.FIR	;Prefix or first line set ?
>					;End of TOPS-10 conditional
	MOVX	S1,MC.PFX!MC.FIR	;No - load defaults
	MOVX	S2,[ITEXT (<>)]		;Null text
	TXNN	S1,MC.PFX		;Wants a prefix ?
	SETZM	MSGBLK+1		;No
	TXNN	S1,MC.FIR		;Wants a first line ?
	MOVEM	S2,MSGBLK+2		;No
	TXNN	S1,MC.CON		;Wants a continuation message ?
	MOVEM	S2,MSGBLK+3		;No
	$TEXT	(,<^M^J^7/MSGBLK+0/^W/MSGBLK+1/^I/@MSGBLK+2/^I/@MSGBLK+3/^7/MSGBLK+4/>)
	$RET				;Return
SUBTTL	Messages


$MSGT	?,CME,<Command error - ^T/(T1)/>,<
	An incorrect command has been entered.>

$MSGT	?,EFO,<Error from ORION - ^T/(P2)/>,<
	ORION has detected an error.>

$MSGT	?,EPM,<Error while parsing message>,<
	The only legal terminators are ESCape and
	carriage return.>

$MSGT	%,NHA,<No help available>,<
	HLP:PLEASE.HLP cannot be found.>

$MSGT	%,NOP,<No operator in attendance>,<
	The system is unattended. You message will be
	sent however.>

$MSGT	<[>,OPN,<Operator at ^N/OPRNOD/ has been notified at ^C/[-1]/>,<
	Your message has been sent the the operator.>

$MSGT	?,SSE,<Switch syntax error>,<
	The command contained either an illegal switch,
	or a switch delimiter (a slash) with no switch
	name following it.>

$MSGT	?,UMO,<Unrecognized message from ORION>,<
	An unknown message type was received from
	ORION instead of the expected operator
	response message. There could be a version
	skew between PLEASE and ORION.>

$MSGT	?,NIN,<Node ^T/ATMBUF/ is not in the network or was specified
	without trailing double colon>,<The value of the /NODE: switch does
	not correspond to a network node.>

$MSGT	?,SUT,<Switch used twice - ^T/ATMBUF/>,<A switch can
	only be used once in a given command.>

$MSGT	?,BHR,<Bad help request, use PLEASE /HELP>,<An attempt
	was made to use the /HELP switch with other text.>

$MSGT	%,MTL,<Message too long - Will be truncated and sent>,<Your
	message exceeded the maximum numbers of characters allowed.
	It will be sent incomplete.>
	SUBTTL	The end

	END	PLEASE