Trailing-Edge
-
PDP-10 Archives
-
BB-H138A-BM
-
3a-sources/please.mac
There are 31 other files named please.mac in the archive. Click here to see a list.
;<3-UTILITIES>PLEASE.MAC.6, 8-Nov-77 10:49:27, EDIT BY KIRSCHEN
;MORE COPYRIGHT UPDATING...
;<3-UTILITIES>PLEASE.MAC.5, 26-Oct-77 11:14:24, EDIT BY KIRSCHEN
;UPDATE COPYRIGHT FOR RELEASE 3
;<3-UTILITIES>PLEASE.MAC.4, 3-Oct-77 11:22:44, EDIT BY DBELL
;TELL USER IF THE OPERATOR IS NOT IN ATTENDANCE. TCO 1870.
;<3-UTILITIES>PLEASE.MAC.3, 30-Sep-77 23:03:12, EDIT BY BORCHEK
; FIX ONE WAY PLEASE GIVING WRONG TIME
;<3-UTILITIES>PLEASE.MAC.2, 25-Aug-77 10:50:57, EDIT BY KIRSCHEN
;FIX VERSION NUMBERS FOR RELEASE 3
;<2-UTILITIES>PLEASE.MAC.5, 27-Dec-76 17:07:26, EDIT BY HURLEY
;<2-UTILITIES>PLEASE.MAC.4, 22-Dec-76 13:41:09, EDIT BY HURLEY
;<2-UTILITIES>PLEASE.MAC.3, 21-Oct-76 14:32:03, Edit by MACK
;TCO 1613 - FIX GTXT AND WAKEUP TO HANDLE ESC AND CTRL/Z PROPERLY.
;<2-UTILITIES>PLEASE.MAC.2, 14-Sep-76 21:44:30, EDIT BY OSMAN
; TCO 1527 - REMOVE IPCF SYMBOL DEFS AND SEARCH COMSYM INSTEAD
;<1B-UTILITIES>PLEASE.MAC.12, 10-JUN-76 18:47:46, Edit by KOHN
;<1B-UTILITIES>PLEASE.MAC.11, 10-JUN-76 18:44:21, Edit by KOHN
;TCO #1399-FIX PROBLEM OF USING SAME BUFFER FOR RDTTY AND SNDTXT--TAH
;<KOHN>PLEASE.MAC.7, 10-JUN-76 18:27:05, Edit by KOHN
;<1B-UTILITIES>PLEASE.MAC.6, 21-MAY-76 12:11:55, Edit by HESS
;<EXEC>PLEASE.MAC.5, 22-APR-76 12:17:51, Edit by HESS
; ADD .DIRECT XTABM
;<EXEC>PLEASE.MAC.4, 25-MAR-76 15:38:00, Edit by HESS
;<V-SOURCES>PLEASE.MAC.3, 23-DEC-75 12:23:59, EDIT BY LEWINE
;<UTILITIES-MACK>PLEASE.MAC.3, 18-NOV-75 11:17:05, EDIT BY HURLEY
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (C) 1976, 1977, 1978 BY DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.
TITLE PLEASE
;THIS PROGRAM IS THE USER HALF OF THE PLEASE/OPLEASE PAIR OF PROGRAMS. EACH
;USER WHO WANTS TO TALK TO AN OPERATOR RUNS PLEASE, SPECIFYING THE DESIRED
;OPERATOR. THAT OPERATOR RUNS OPLEASE, AND THE TWO PROGRAMS TALK VIA IPCF
;MESSAGES.
;THE PDB'S FOR THE MESSAGES ARE SET UP IN THE USUAL WAY; I.E.,
;.IPCFL: FLAG WORD
;.IPCFS: SENDER'S PID
;.IPCFR: RECEIVER'S PID
;.IFCFP: 1000,,PAGE NUMBER
;ALL MESSAGES ARE SENT IN PAGE MODE.
;THE FIRST WORD OF EACH MESSAGE CONTAINS A CODE IN THE RIGHT HALF INDICATING
;THE MESSAGE TYPE. IN A 'TEXT" MESSAGE THE LEFT HALF CONTAINS THE NUMBER
;OF TEXT MESSAGES SENT. IN A 'BYE' MESSAGE THE LEFT HALF CONTAINS THE NUMBER
;THAT WAS IN THE FIRST WORD OF THE LAST TEXT MESSAGE RECEIVED. ALL OTHER
;MESSAGES HAVE ZERO IN THE LEFT HALF OF THE FIRST WORD.
;THE CONTENTS OF THE REMAINING WORDS OF A MESSAGE VARY WITH THE MESSAGE TYPE.
SUBTTL DATA DEFINITION
SEARCH MONSYM,MACSYM,COMSYM ;HAS JSYS DEFINITIONS, BITS, ETC.
.REQUIRE SYS:MACREL.REL ;HAS JSERR
SALL
IFNDEF .PSECT,<
.DIRECT .XTABM>
;MACRO TO RESET, HALT, RESTART IF USER CONTINUES
;RESET PREVENTS INTERRUPT ON MESSAGES SENT TO OLD PID BEFORE
;RESET AT START IS EXECUTED
DEFINE QUIT1
<JRST [ RESET
HALTF
JRST START2]>
;REGISTER USAGE
;PRIMARY USAGE - CARRIED OVER SUBROUTINE CALLS
;P1/ ADDRESS OF RECEIVE PDB
;P2/ ADDRESS OF SEND PDB
;P3/ ADDRESS OF SEND MESSAGE
;P4/ SIZE OF SEND MESSAGE
;Q1/ FLAG WORD RECEIVED
;Q2/ SENDER'S PID
;Q3/TRANSFER ADDRESS
;TEMPORARY USAGE
;P5/ASSORTED SEMI-PERMANENT VALUES
;P6/DITTO
;REGISTERS FROM ABOVE USED AS LOCAL TEMPORARY VALUES
;T1-T4 USED FOR TEMPORARY VALUES
;AC DEFINITIONS
F=0
T1=1
T2=2
T3=3
T4=4
Q1=5
Q2=6
Q3=7
P1=10
P2=11
P3=12
P4=13
P5=14
P6=15
P=17
;DEBUG SWITCH - 1 IF WANT EXTRA PRINTING. ALL DEBUG PRINTING PRECEDED BY 'D:'
DEBUG: 0
; MASKS FOR FLAG WORD RECEIVED (FIRST WORD IN PDB)
MSKSTR(ERROR,,IP%CFE) ;ERROR FIELD IN FLAG WORD
MSKSTR (SYSTEM,,IP%CFC) ;SYSTEM SEND FIELD IN FLAG WORD
;STACK
STKSIZ=10
STK: BLOCK STKSIZ
;REGISTER SAVE AREA. REGISTERS ARE STORED IN ORDER IN INTERRUPT ROUTINES
REGSAV: BLOCK 20
;ENTRY VECTOR
PRGVER==3 ;VERSION NUMBER
PRGEDT==10 ;EDIT NUMBER
PRGMIN==0 ;MINOR VERSION
PRGCST==0 ;CUSTOMER ID
ENTVEC: JRST START ;START ADDRESS
JRST START2 ;REENTER ADDRESS
PRGCST_^D33+PRGVER_^D24+PRGMIN_^D18+PRGEDT
;TRANSFER VECTOR BASED ON CODE RECEIVED
DEFINE TX(ADDRES,CODE)
<
IFG CODE-%%MAX,<%%MAX==CODE>
RELOC GOTAB+CODE
ADDRES
RELOC GOTAB+%%MAX+1
>
%%MAX==0 ;FINAL VALUE IS ONE LESS THAN LENGTH OF TABLE
GOTAB: TX BYE,PLBYE ;PLBYE HAS BEEN RECEIVED
TX TEXT,PLTXT ;PLTXT HAS BEEN RECEIVED
TX OK,PLOK ;PLOK HAS BEEN RECEIVED
TX CONFUS,PLCON ;PLCON HAS BEEN RECEIVED
TX PWAIT,PLWAIT ;PLWAIT HAS BEEN RECEIVED
TX ANSWER,PLANS ;PLANS HAS BEEN RECEIVED
TABSIZ=.-GOTAB
;BUFFER THAT HOLDS TEXT SENT BY OPERATOR
LOC 10000
TXTBUF: BLOCK 1000
BUFEND:
RELOC
BUFNXT: XWD -1,TXTBUF ;NEXT LOCATION TO WRITE INTO
;MESSAGE AREA FOR RECEIVE
;PDB
RMSGSZ= 1000
RPDB: IP%CFB!IP%TTL!IP%CFV ;DON'T BLOCK;TRUNCATE;PAGE MODE
block 1 ;sender's pid
BLOCK 1 ;receiver's pid
XWD RMSGSZ,RPAGE ;message length,,page number
BLOCK 2 ;DIRECTORIES AND PRIVILEGES
RPDBSZ=.-RPDB
;MESSAGE
LOC 11000
RMSG: BLOCK RMSGSZ ;MESSAGE AREA
RELOC
RPAGE=RMSG/1000 ;PAGE NUMBER FOR MESSAGE
;MESSAGE AREA FOR SEND at interrupt level
;PDB
SMSGSZ=1000
SPDB: IP%CFV ;PAGE MODE
block 1 ;SENDER'S PID
BLOCK 1 ;RECEIVER'S PID
XWD SMSGSZ,SPAGE ;MESSAGE LENGTH,,PAGE NUMBER
SPDBSZ=.-SPDB
;MESSAGE
LOC 12000
SMSG: BLOCK SMSGSZ ;MESSAGE AREA
RELOC
SPAGE=SMSG/1000 ;PAGE NUMBER FOR MESSAGE
;message area for send at NON-INTerrupt level
;PDB
OMSGSZ=1000
OPDB: IP%CFV ;PAGE MODE
block 1 ;SENDER'S PID
block 1 ;RECEIVER'S PID
XWD OMSGSZ,OPAGE ;MESSAGE LENGTH,,page NUMBER
OPDBSZ=.-OPDB
;MESSAGE
LOC 13000
OMSG: BLOCK OMSGSZ ;MESSAGE AREA
RELOC
OPAGE=OMSG/1000 ;PAGE NUMBER FOR MESSAGE
;THIS AREA CONTAINS TEXT TO BE SENT TO OPLEAS. INITIALLY IT CONTAINS
;<OPERATOR>OPLEASE FOLLOWED BY THE OPERATOR ID FOLLOWED IMMEDIATELY
;BY THE FIRST LINE OF TEXT.
;THE STRING '<OPERATOR>OPLEASE' CONCATENATED WITH THE ID IS SENT TO
;INFO TO GET THE PID FOR THE OPERATOR. THE FIRST LINE OF TEXT FOLLOWS
;THE ID IMMEDIATELY. WHEN THE USER TYPES, THE TEXT IS ADDED TO THE END OF
;PREVIOUS LINES OF TEXT. WHEN THE TEXT IS SENT TO OPLEAS, THE POINTER
;IS RESET TO THE BYTE IMMEDIATELY AFTER THE ID AND THE NEXT READ BEGINS
;THERE. 'TEXT" AND 'ONEWAY' MESSAGES ARE SENT BY SOUTING TO THE APPROPRIATE
;MESSAGE AREA FROM THIS PAGE.
linesz=775 ;words AVAILABLE AFTER NAME BEFORE ID ADDED
namlen=21 ;LENGTH OF NAME BEFORE ID ADDED
NAMSIZ: block 1 ;SIZE OF NAME TO SEND TO INFO
;INCLUDES ID TYPED BY USER
;keep OPRNAM AND INITXT together
LOC 14000
OPRNAM: ASCIZ /<OPERATOR>OPLEASE/
INITXT=.-1
block linesz-1 ;SPACE FOR REST OF ID AND TEXT
RELOC
;THE FOLLOWING VALUE IS FIXED.
INISIZ=<LINESZ*5>-5 ;BYTES AVAILABLE FOR TEXT BEFORE ID ADDED
;THE FOLLOWING ARE UPDATED AFTER THE ID IS READ.
inibeg: block 1 ;pointer to FIRST BYTE AFTER ID
; (START OF TEXT)
TXTSIZ: BLOCK 1 ;NUMBER OF BYTES AFTER ID (SPACE
; FOR TEXT)
;THE FOLLOWING ARE UPDATED AFTER EACH TTY READ AND RESET TO THE PRECEDING
;VALUES AFTER THE TEXT IS SENT
RDNXT: BLOCK 1 ;NEXT AVAILABLE BYTE IN BUFFER
RDLIM: BLOCK 1 ;NUMBER OF BYTES AVAILABLE IN BUFFER
;TEMPORARY BUFFER USED FOR RDTTY CALL
TBUFSZ==^D120
TBUF: BLOCK TBUFSZ
;VARIABLES USED WHILE READING FIRST LINE
IDFLG: 0 ;SET WHEN OPERATOR ID FOUND
MSGFLG: 0 ;TEXT FOUND
CHCNT: 0 ;NUMBER OF NON-PUNCTUATION CHARS PROCESSED
BYTCNT: 0 ;NUMBER OF BYTES PROCESSED
initer: BLOCK 1 ;last character typed IN FIRST LINE OF TEXT
JOBNAM: ASCIZ/PLEASE/ ;OUR PROGRAM NAME
;PIDS
MYPID: 0 ;THIS USER'S PID
OPRPID: 0 ;PID OF OPERATOR TALKING TO
;MAXIMUM MESSAGE SIZE FOR THIS INSTALLATION
MAXMSG: BLOCK 1 ;DETERMINED DURING INITIALIZATION WITH MUTIL
;ASSOCIATED VARIABLE FOR NEXT MESSAGE IN IPCF QUEUE
NXTMSG: 0 ;0 IF THERE WAS NO MESSAGE WAITING
;AFTER THE LAST RECEIVE
; ARGUMENT BLOCK FOR MUTIL
MUTILD: BLOCK 10
;FLAGS TO INDICATE STATE
INTFLG: 0 ;SET WHEN INTERRUPT PROCESSED
WTFLG: 0 ;SET WHEN WAITING FOR AN INTERRUPT
;FLAGS SET BASED ON MESSAGES RECEIVED
ACTFLG: 0 ;SET WHEN RECEIVE OK FROM OPLEAS
; AND TWO WAY CONVERSATION HAS BEGUN
BYEFLG: 0 ;SOMEONE WANTS TO SAY GOODBYE
; BIT 0 SET IF USER SAYS GOODBYE
;BIT 1 SET IF OPERATOR SAYS GOODBYE
TXTFLG: 0 ;TEXT FROM OPERATOR WAITING IN BUFFER
;COUNT OF TEXT MESSAGES SENT AND RECEIVED
SNDCNT: 0 ;NUMBER OF MESSAGES SENT BY PLEASE
RCVCNT: 0 ;NUMBER OF LAST MESSAGE RECEIVED BY PLEASE
TXTCNT: 0 ;NUMBER OF LAST MESSAGE RECEIVED BY OPLEAS
NOW: 0 ;CURRENT TIME
;INTERRUPT SYSTEM
; [LEVEL,,INTERRUPT ADDRESS]
CHNTAB: XWD 1,IPCINT ;IPCF ON CHANNEL 0
XWD 1,TINT ;^T ON CHANNEL 1
XWD 1,CINT ;^C ON CHANNEL 2
XWD 1,TYPINT ;INPUT BUFFER NON-EMPTY ON 3
BLOCK ^D32 ;REST OF TABLE
; [LOCATION WHERE PC STORED BY LEVEL]
LEVTAB: PCSAV1 ;LEVEL 1 PC STORAGE
PCSAV2 ;LEVEL 2 PC STORAGE
PCSAV3 ;LEVEL 3 PC STORAGE
;PC'S SAVED HERE
PCSAV1: BLOCK 1 ;PC FOR LEVEL 1 INTERRUPTS
PCSAV2: BLOCK 1 ;PC FOR LEVEL 2 INTERRUPTS (NOT USED)
PCSAV3: BLOCK 1 ;PC FOR LEVEL 3 INTERRUPTS (NOT USED)
;KLUDGE TO KEEP THE SYMBOL TABLE OUT OF MY DATA
LOC 16000 ;kludge to keep the symbol table
-1 ; out of my data
RELOC
SUBTTL INITIALIZATION
;HERE IF RESTARTING AFTER ERROR. INPUT WILL COME FROM ANSWERS TO QUESTIONS
;AND NOT FROM THE EXEC VIA RSCAN.
START2: TMSG <
[Restarting]
>
movei t1,.priin ;t1/primary input
cfibf ;clear input buffer (discard erroneous text)
HRROI T1,T2 ;POINT TO INTERNAL AREA
SETZ T2, ;CLEAR IT
RSCAN ;PUT NULL IN RESCAN BUFFER SO
; RSCAN WILL RETURN NO CHARACTERS
;HERE FOR NORMAL START
START: RESET ;GET RID OF PIDS, CLEAR INTERRUPTS, ETC.
MOVE P,[IOWD STKSIZ,STK] ;SET UP THE STACK
;CLEAR VARIOUS LOCATIONS (SEE DATA DEFINITION FOR EXPLANATIONS)
SETZM MYPID
SETZM OPRPID
SETZM WTFLG
SETZM INTFLG
SETZM TXTFLG
SETZM ACTFLG
SETZM BYEFLG
SETZM NXTMSG
SETZM PCSAV1
SETZM IDFLG
SETZM MSGFLG
SETZM INITER
SETZM CHCNT
SETZM BYTCNT
SETZM SNDCNT
SETZM RCVCNT
SETZM TXTCNT
CALL CLRTXT ;CLEAR BUFFER AREA FOR RECEIVED TEXT
;SET UP BUFFER FOR OPERATOR ID AND TEXT. INITIALIZE TO ASSUME
;BLANK ID.
MOVE T1,[ASCII /SE/] ;RESTORE NULLS TO BYTES AFTER 'OPLEAS'
MOVEM T1,INITXT
move t1,[INITXT+1,,INITXT+2] ;CLEAR REMAINING WORDS
setzm initxt+1
BLT T1,INITXT+LINESZ-1
move t1,[point 7,initxt,13] ;point to LAST BYTE OF
movem t1,inibeg ;NAme to send to info
MOVEM T1,RDNXT
MOVEI T1,INISIZ ;NUMBER OF BYTES AVAILABLE AFTER
MOVEM T1,TXTSIZ ; NAME TO SEND TO INFO
MOVEM T1,RDLIM
MOVEI T1,namlen ;SIZE OF NAME SENT TO INFO
MOVEM T1,NAMSIZ ;INITIALIZE TO ASSUME NULL ID
;FIND OUT MAXIMUM MESSAGE SIZE - USED WHEN RECEIVING IN NON-PAGE MODE
MOVEI T1,26 ;CODE: GET MAX MESSAGE
MOVEM T1,MUTILD ;SAVE IN MUTIL AREA
MOVEI T1,2 ;T1/SIZE OF MUTIL BLOCK
MOVEI T2,MUTILD ;T2/LOCATION OF MUTIL BLOCK
MUTIL ;GET SIZE LIMIT
JSERR ;ERROR
MOVE T1,MUTILD+1 ;SAVE LIMIT
MOVEM T1,MAXMSG
;..
SUBTTL FIRST - READS FIRST INPUT LINE
;THIS CODE READS THE LINE TYPED TO THE EXEC. THIS MAY BE OF THE FORM
;@PLEASE ID:TEXT
;@PLEASE ID:
;@PLEASE TEXT
;@PLEASE
;@R PLEASE
;@START
;ETC. IT SEARCHES FOR THE ID AND TEXT AND STORES THEM IN THE INITXT AREA.
;IT SETS IDFLG ON FINDING AN ID, MSGFLG ON FINDING TEXT.
;READ THE LINE TYPED TO THE EXEC
;..
MOVEI P4,INISIZ ;SPACE AVAILABLE FOR TEXT AFTER NAME
SETZ T1, ;MOVE THE LINE TYPED TO THE EXEC INTO
RSCAN ; THE INPUT BUFFER
JRST [ JSERR ;FAILED
JRST START2] ;START OVER
MOVEM T1,P6 ;SAVE BYTE COUNT
JUMPE P6,GTINFO ;IF NO CHARACTERS, STARTED WITH DDT.
; OR RESTARTED FROM WITHIN
;THERE IS AT LEAST ONE CHARACTER. SEE IF IT STARTED WITH JOB NAME.
;IF SO, MAY CONTAIN ID AND TEXT. IF NOT, GO ASK FOR THEM.
MOVE P5,[440700,,JOBNAM] ;POINT TO JOB NAME
FIRST1: ILDB T2,P5 ;GET NEXT CHARACTER IN NAME
JUMPE T2,FIRST2 ;IF ZERO, MATCHED WHOLE NAME
PBIN ;YES. GET A CHARACTER
SOS P6 ;DECREMENT COUNT OF REMAINING CHARS
JUMPE P6,GTINFO ;LAST CHARACTER? MUST BE BREAK
CAMN T1,T2 ;DO THEY MATCH?
JRST FIRST1 ;YES. GO LOOK AT NEXT PAIR
JRST FIRST6 ;NO. DIDN'T START WITH JOBNAME
;STARTED WITH JOB NAME. LOOK FOR FIRST SPACE OR TAB
;JOB NAME MAY BE FOLLOWED BY RECOGNIZED FILE NAME, ETC.
FIRST2: PBIN ;READ NEXT CHARACTER
SOS P6 ;DECREMENT REMAINING COUNT
JUMPE P6,GTINFO ;LAST CHARACTER? MUST BE BREAK
CAIN T1,40 ;IS IT A BLANK?
JRST FIRST3 ;YES. ON TO ID AND TEXT
CAIE T1,.CHTAB ;NO. IS IT TAB?
JRST FIRST2 ;NO. GO TO NEXT CHARACTER
;FOUND SPACE OR TAB AFTER JOBNAME. LOOK FOR FIRST NON-SPACE,
;NON-TAB TO BEGIN ID OR TEXT.
FIRST3: PBIN ;YES. READ ONE
SOS P6 ;DECREMENT COUNT OF REMAINING CHARS
JUMPE P6,GTINFO ;LAST CHARACTER? MUST BE BREAK
CAIN T1,40 ;SPACE?
JRST FIRST3 ;YES. KEEP LOOKING
CAIN T1,.CHTAB ;NO.TAB?
JRST FIRST3 ;YES. KEEP LOOKING
CAIE T1,.CHCRT ;NO. CARRIAGE RETURN?
JRST FIRST7 ;NO.
;QUIT BEFORE READING ENTIRE BUFFER. READ AND DISCARD
FIRST6: JUMPE P6,GTINFO ;IF ZERO, HAVE READ ALL
PBIN ;READ A CHARACTER
SOS P6 ;DECREMENT COUNT
JRST FIRST6
;HAVE FOUND 'JOBNAME...CHARACTER'. THE CHARACTER IS NON-BLANK.
;READ IT AND REMAINING CHARACTERS INTO INITXT AREA STARTING AT BYTE
;POINTED TO BY INIBEG
FIRST7: MOVEI T1,.PRIIN ;BACK UP POINTER SO READ WILL INCLUDE
BKJFN ; CHARACTER ALREADY READ
JRST [ JSERR ;FAILED
JRST START2] ;START OVER
aos p6 ;add back re-read character to count
MOVE T1,INIBEG ;DEST:BYTE AFTER 'OPLEASE' IN OPRNAM
MOVX T2,RD%BRK!RD%BEL ;STANDARD BREAK PLUS EOL
HRRI T2,INISIZ ;T2/SPACE AVAILABLE IN BUFFER
HRR T4,T2 ;SAVE SPACE AVAILABLE BEFORE READ
SETZ T3, ;NO CTRL/R BUFFER
RDTTY ;READ INPUT LINE FROM RESCAN BUFFER
jrst [ jserr ;read failed
jrst start2] ;start over
HRRM T2,RDLIM ;SAVE SPACE AFTER FIRST LINE OF TEXT
MOVEM T1,RDNXT ;SAVE NEXT LOCATION FOR TEXT
txnn t2,rd%btm ;did we read A BREAK CHARACTER?
JRST [ TMSG <
?Input too long. It has been rejected.
> ;NO. RAN OUT OF BUFFER SPACE
JRST START2]
MOVE T3,T4 ;SPACE ORIGINALLY AVAILABLE
movem t1,T4 ;save pointer to last byte
SUBI T3,(T2) ;COMPUTE BYTES READ FROM BYTES REMAINING
SUB P6,T3 ;NUMBER BYTES STILL IN RESCAN BUFFER
FIRST9: SKIPE P6 ;ANY MORE CHARACTERS TO BE READ?
JRST [ PBIN ;YES. READ ONE AND DISCARD
SOS P6 ;DECREMENT THE COUNT
JRST FIRST9] ;REPEAT UNTIL ALL READ
MOVE P6,T4 ;P6/POINTER TO LAST BYTE
ldb p5,p6 ;save last byte (WILL BE CHECKED FOR
MOVEM P5,INITER ; CNTL/Z OR ESCAPE)
SETZM CHCNT ;CLEAR COUNT OF NON-BLANK CHARACTERS
SETZM BYTCNT ;CLEAR COUNT OF BYTES
MOVE T1,INIBEG ;POINT TO BEGINNING
;LOOK THROUGH CHARACTERS LOOKING FOR ID AND TEXT
FIRST4: ILDB P5,T1 ;LOOK AT NEXT BYTE
AOS BYTCNT ;INCREMENT BYTE COUNT
CAMN T1,P6 ;IS IT THE LAST?
JRST FIRST8 ;YES
CAIN P5,.CHCRT ;CARRIAGE RETURN?
;CARRIAGE RETURN OR LAST CHARACTER. IF ANY CHARACTERS READ,
;THEY MUST BE TEXT SINCE DIDN'T END WITH COLON (LAST CHARACTER
;MUST BE BREAK).
FIRST8: JRST [ SKIPN CHCNT ;READ ANY CHARACTERS?
JRST GTINFO ;NO.
SETOM IDFLG ;YES. WE HAVE AN ID
SETOM MSGFLG ;WE HAVE A MESSAGE
JRST GTINFO]
;NOT CARRIAGE RETURN. BLANK OR TAB?
CAIN P5,40 ;BLANK?
JRST FIRST5 ;YES.
CAIN P5,.CHTAB ;NO.TAB?
;SPACE OR TAB. IF THERE HAVE BEEN CHARACTERS THIS IS DELIMITER
;IN TEXT.
FIRST5: JRST [ SKIPN CHCNT ;SPACE OR TAB. DID NON-BLANK PRECEDE?
JRST FIRST4 ;NO. KEEP LOOKING
SETOM MSGFLG ;YES. WE HAVE A MESSAGE
SETOM IDFLG ;WE HAVE AN ID
JRST GTINFO]
;NOT SPACE OR TAB
CAIE P5,72 ;COLON?
JRST [ AOS CHCNT ;NOT A COLON. INCREMENT CHAR COUNT
SKIPN IDFLG ;DO WE ALREADY HAVE AN ID?
JRST FIRST4 ;NO. THIS IS PART OF IT
SETOM MSGFLG ;YES. THIS IS START OF TEXT
JRST GTINFO]
;COLON. THIS IS END OF ID.
SUB P4,CHCNT ;SPACE LEFT FOR TEXT AFTER NAME
MOVEM P4,TXTSIZ ;SPACE FOR TEXT AFTER ID
SETOM IDFLG ;COLON. THIS IS END OF ID.
SETZM CHCNT ;RESET NON-BLANK COUNT
MOVEM T1,INIBEG ;SAVE POINTER TO BEGINNING OF TEXT
MOVE T2,NAMSIZ ;ADD LENGTH OF ID TO LENGTH OF NAME
ADD T2,BYTCNT
SOS T2 ;DON'T COUNT THE COLON
MOVEM T2,NAMSIZ
JRST FIRST4
SUBTTL GTINFO - GETS INFO NOT ENTERED IN CALL
;HERE AFTER PROCESSING THE LINE TYPED TO THE EXEC. IDFLG IS SET
;IF AN OPERATOR ID WAS FOUND; MSGFLG IS SET IF TEXT WAS FOUND.
;IF EITHER IS MISSING, THIS CODE PROMPTS FOR THEM AND STORES THE
;ANSWERS IN THE INITXT AREA.
;REACHED VIA JRST
GTINFO: MOVEI T1,.SFOPR ;SET TO READ MONITOR FLAG
TMON ;TO SEE IF OPERATORS ARE AROUND
JUMPN T2,GTINF0 ;IN ATTENDANCE, SKIP MESSAGE
TMSG <
% Warning: Operator is not in attendance.
> ;NOT AROUND, SAY SO
GTINF0: SKIPE IDFLG ;DO WE HAVE AN OPERATOR ID?
JRST GTINF4 ;YES. DON'T ASK FOR IT
TMSG <
What is the operator's ID? > ;NO. ASK FOR IT
MOVE T1,INIBEG ;READ ID INTO END OF NAME
MOVX T2,RD%BRK!RD%BEL ;STANDARD BREAK PLUS BEL
HRRI T2,INISIZ ;SPACE AVAILABLE FOR NAME AND TEXT
SETZ T3, ;NO CONTROL/R BUFFER
RDTTY ;READ THE OPERATOR ID
jrst [ jserr ;error in reading
jrst start2] ;start over
txnn t2,rd%btm ;did we get all that was typed?
jrst [ tmsg<
?INPUT TOO LONG. IT HAS BEEN REJECTED.
> ;no. tell the user
jrst start2] ;start over
MOVEM T1,RDNXT ;NEXT LOCATION TO READ TEXT INTO
MOVEI T3,INISIZ ;ORIGINAL BYTES AVAILABLE
SUBI T3,(T2) ;COMPUTE BYTES READ FROM BYTES REMAINING
MOVEM T3,P6 ;P6/ NUMBER OF BYTES READ
;USER TYPED ID OR CR. BACK UP TO LAST CHARACTER NOT A BREAK
GTINF1: LDB P5,T1 ;LOOK AT LAST BYTE
CAIN P5,.CHLFD ;IS IT A LINE FEED?
JRST GTINF2 ;YES.
CAIN P5,72 ;COLON?
JRST GTINF2 ;YES.
CAIN P5,.CHCUN ;END OF LINE?
JRST GTINF2 ;YES
CAIE P5,.CHCRT ;CARRIAGE RETURN?
JRST GTINF3
;LF, COLON, EOL, OR CARRIAGE RETURN - KEEP BACKING UP
GTINF2: SOS P6
JUMPE P6,GTINF4 ;ANY MORE CHARACTERS?
BKJFN ;YES. BACK UP
JSERR
JRST GTINF1
;NOT A BREAK CHARACTER
GTINF3: MOVEM T1,INIBEG ;LAST CHAR IN ID. SAVE POINTER TO
; TO BEGINNING OF TEXT
MOVE T2,NAMSIZ ;INCREASE NAME SIZE BY LENGTH
ADD T2,P6 ; OF ID
MOVEM T2,NAMSIZ
SUB P4,P6 ;BYTES AVAILABLE FOR TEXT AFTER NAME
MOVEM P4,TXTSIZ ;SPACE LEFT FOR TEXT AFTER ID
;GET MESSAGE IF NOT PREVIOUSLY TYPED
GTINF4: SKIPE MSGFLG ;IS THERE TEXT?
JRST GTINF5 ;YES.
TMSG <
Enter text: > ;NO. ASK FOR IT
MOVE T1,INIBEG ;T1/STORE AFTER ID
MOVX T2,RD%BRK!RD%BEL ;T2/[STANDARD BREAK PLUS END OF LINE,,
hrr T2,p4 ; number of bytes available]
SETZ T3, ;T3/NO CNTL/R BUFFER
RDTTY ;read the text
jrst [ jserr ;read fails
jrst start2] ;start over
txnn t2,rd%btm ;did we get all that was typed?
JRST [ TMSG<
?Input too long. It has been rejected.
> ;NO. TELL THE USER
JRST START2] ;YES. START OVER
MOVEM T1,RDNXT ;NEXT LOCATION AFTER FIRST TEXT
HRRM T2,RDLIM ;NUMBER BYTES AFTER FIRST TEXT
LDB P5,T1 ;SAVE LAST CHARACTER (WILL BE CHECKED
MOVEM P5,INITER ; FOR CNTL/Z OR ESCAPE)
GTINF5: JFCL
;AT THIS POINT THE FOLLOWING SHOULD BE DEFINED
;INIBEG: FIRST LOCATION FOR TEXT (FIRST AFTER ID)
;TXTSIZ: NUMBER BYTES FOR TEXT (AFTER NAME)
;RDNXT: LOCATION AFTER FIRST LINE OF TEXT
;RDLIM: NUMBER BYTES AFTER FIRST LINE OF TEXT
;..
SUBTTL GET A PID
;THIS CODE GETS A PID FOR THIS USER USING MUTIL. IT SAVES THE
;PID IN MYPID AND IN THE APPROPRIATE WORD OF THE 3 PDB'S.
;..
MOVEI T1,.MUCRE ;CREATE A PID
MOVEM T1,MUTILD ;FUNCTION CODE
MOVE T1,[0,,.FHSLF] ;MY FORK
MOVEM T1,MUTILD+1 ;TO MUTIL AREA
MOVEI T1,3 ;T1/LENGTH
MOVEI T2,MUTILD ;T2/LOCATION
MUTIL ;GET A PID
JRST [ JSERR ;FAILED
QUIT1] ;QUIT
MOVE T1,MUTILD+2 ;RETRIEVE THE PID FROM MUTIL AREA
MOVEM T1,MYPID ; AND SAVE
MOVEI T2,RPDB ;SAVE MY PID IN RECEIVER FIELD FOR
MOVEM T1,.IPCFR(T2) ; RECEIVES
MOVEI T2,SPDB ;SAVE IN SENDER FIELD FOR INTERRUPT
MOVEM T1,.IPCFS(T2) ; LEVEL SENDS
MOVEI T2,OPDB ;SAVE IN SENDER FIELD FOR NON-INTERRUPT
MOVEM T1,.IPCFS(T2) ; LEVEL SENDS
SKIPE DEBUG ;DEBUGGING?
JRST [ TMSG <
D:User's PID is > ;YES. PRINT USER'S PID
MOVEI T1,.PRIOU ;T1/PRIMARY OUTPUT
MOVE T2,MYPID ;T2/USER'S PID
MOVX T3,1B0+10B35 ;MAGNITUDE,OCTAL
NOUT ;PRINT THE PID
JSERR
TMSG <
>
JRST .+1]
;..
SUBTTL ASK INFO
;THIS CODE SENDS A MESSAGE TO INFO CONTAINING <OPERATOR>OPLEASE FOLLOWED
;BY THE OPERATOR'S ID. IT ASKS FOR THE PID ASSOCIATED WITH THAT
;NAME AND WAITS FOR THE ANSWER FROM INFO. IF SAVES THE ANSWER
;IN OPRPID
;..
ASKINF: MOVEI P2,OPDB ;P2/ADDRESS OF SEND PDB
MOVEI P3,OMSG ;P3/ADDRESS OF SEND MESSAGE
SETZM .IPCFR(P2) ;RECEIVER'S PID (0 FOR INFO)
MOVE T1,[1,,.IPCIW] ;CODE,,FIND PID
MOVEM T1,.IPCI0(P3) ; INTO MESSAGE
SETZM .IPCI1(P3) ;NO DUPLICATE REPLY
HRROI T1,.IPCI2(P3) ;TRANSFER NAME TO MESSAGE
HRROI T2,OPRNAM ; FROM OPRNAM
MOVN T3,NAMSIZ ;T3/NEGATIVE BYTE COUNT
SOUT ;TRANSFER, UPDATING POINTERS
MOVEI P4,OPDBSZ ;P4/SIZE OF SEND PDB
CALL SNDMSG ;SEND THE MESSAGE
JRST [ CALL NOINFO ;SEND FAILED. PRINT MESSAGE
JRST START2] ;START OVER
;READ ALL MAIL UNTIL GET ANSWER FROM INFO.
ASKIN1: MOVEI P1,RPDB ;P1/LOCATION OF RECEIVE PDB
MOVX T1,IP%TTL ;BLOCK, TRUNCATE, no page mode
MOVEM T1,.IPCFL(P1) ;FLAG WORD
MOVE T1,[RMSGSZ,,RMSG] ;MAX MESSAGE SIZE,,LOCATION
MOVEM T1,.IPCFP(P1) ;TO PDB
MOVEI T1,RPDBSZ ;T1/LENGTH OF PDB
MOVEI T2,RPDB ;T2/LOCATION OF PDB
MRECV ;WAIT FOR MESSAGE AND RECEIVE
JRST ASKIN5 ;RECEIVE FAILED
;RECEIVE SUCCEEDED. SEE WHO SENT IT.
MOVE Q1,.IPCFL(P1) ;FLAG BITS
JXE Q1,IP%CFC,ASKIN1 ;SENT BY SYSTEM? IF NO, IGNORE
LOAD T2,SYSTEM,Q1 ;YES. FIND OUT WHO SENT IT
CAME T2,.IPCCF ;FROM INFO?
JRST ASKIN1 ;NO. IGNORE IT.
JXE Q1,IP%CFE,ASKIN3 ;FROM INFO. ERROR?
LOAD T2,ERROR,Q1 ;YES. GET ERROR CODE
CAIN T2,.IPCNN ;NAME UNKNOWN?
JRST [ TMSG<
?operator job to service please requests is not running.
[Waiting.]
> ;YES.
MOVEI T1,^D60000 ;TIME TO WAIT: ONE MINUTE
DISMS ;WAIT A WHILE
JRST ASKINF] ;GO TRY AGAIN
;ERROR FROM INFO BUT NOT NAME UNKNOWN
SKIPE DEBUG ;DEBUGGING?
JRST [ TMSG <
D:Error from INFO: > ;YES
MOVEI T1,.PRIOU ;T1/PRIMARY OUTPUT
MOVX T3,10B35 ;OCTAL
NOUT ;PRINT THE ERROR CODE
JSERR ;FAILED
TMSG <
>
JRST .+1]
JRST ASKIN1 ;GO READ NEXT MESSAGE
;FROM INFO WITH NO ERROR CODE. TEST FOR UNDELIVERED MAIL
ASKIN3: JXE Q1,IP%CFM,ASKIN4 ;NO ERROR.UNDELIVERED?
TMSG <
?System jobs not running.
> ;YES. PRINT MESSAGE
JRST START2 ;START OVER
;MAIL IS FROM INFO WITH NO ERRORS. SHOULD CONTAIN OPERATOR'S PID
ASKIN4: MOVE T1,[1,,.IPCIW] ;GET CODE
CAME T1,RMSG ;SAME CODE,,FUNCTION?
JRST ASKIN1 ;NO. IGNORE.
MOVE T1,RMSG+1 ;YES. GET ANSWER
MOVEM T1,OPRPID ;SAVE OPERATOR'S PID
JRST INTERR
;RECEIVE FAILED. IF PAGE MODE, READ AND DISCARD
ASKIN5: CAIE T1,IPCF16 ;DATA MODE PROBLEM?
JRST ASKIN6 ;NO. SOME OTHER ERROR
MOVX T2,IP%CFB!IP%TTL!IP%CFV ;PAGE MODE, TRUNCATE, DON'T BLOCK
MOVEM T2,.IPCFL(P1) ;TO PDB
HRRZI T1,RPAGE ;ZERO LENGTH,,USUAL PAGE
MOVEM T1,.IPCFP(P1) ;TO PDB
MOVEI T1,RPDBSZ ;T1/SIZE OF PDB
MOVEI T2,RPDB ;T2/LOCATION OF PDB
MRECV ;RECEIVE IT
JRST ASKIN6 ;DIDN'T SOLVE THE PROBLEM
JRST ASKIN1 ;GO GET NEXT MESSAGE
;NOT A PAGE PROBLEM
ASKIN6: JSERR ;SOME OTHER ERROR. PRINT MESSAGE.
JRST ASKIN1 ;GO GET NEXT MESSAGE
SUBTTL SET UP INTERRUPTS
;THIS CODE SETS UP FOR INTERRUPTS ON THE FOLLOWING CHANNELS:
;0-IPCF MESSAGE RECEIVED
;1-CTRL/T
;2-CTRL/C
;3-INPUT BUFFER GOES FROM EMPTY TO NON-EMPTY
;IT ACTIVATES CHANNEL 0 BUT DOESN'T ENABLE ANY CHANNELS. THUS AN
;IPCF INTERRUPT IS DELAYED UNTIL THE INTERRUPTS ARE ENABLED.
;REACHED VIA JRST
INTERR: CIS ;CLEAR THE INTERRUPT SYSTEM
MOVEI T1,.MUPIC ;ASSOCIATE PID WITH CHANNEL
MOVEM T1,MUTILD ;FUNCTION CODE
MOVE T1,MYPID ;PID FOR OPLEASE
MOVEM T1,MUTILD+1 ;PID TO ASSOCIATE WITH CHANNEL
SETZM MUTILD+2 ;CHANNEL 0
MOVEI T1,3 ;T1/LENGTH OF ARGUMENT BLOCK
MOVEI T2,MUTILD ;T2/LOCATION OF ARGUMENT BLOCK
MUTIL ;ASSOCIATE CHANNEL WITH PID
JRST [ JSERR ;CAN'T SET UP CHANNEL. QUIT
SKIPN DEBUG ;DEBUGGING?
QUIT1 ;NO. GIVE UP
TMSG <
D:Trying to associate PID > ;YES. PRINT PID
MOVEI T1,.PRIOU ;T1/PRIMARY OUTPUT
MOVE T2,MYPID ;T2/PID USED IN MUTIL
MOVX T3,1B0+10B35 ;T3/MAGNITUDE, OCTAL
NOUT ;PRINT THE PID
JSERR
TMSG < with channel 0
>
QUIT1] ;GIVE UP
MOVE T1,[.TICCT,,1] ;CTRL/T ON CHANNEL 1
ATI ;ASSIGN CTRL/T TO CHANNEL 1
MOVX T1,.FHSLF ;T1/MY FORK
RPCAP ;GET PRESENT CAPABILITIES
txnn t2,sc%ctc ;can we enable ctrl/c?
JRST [ TMSG<
% CTRL/C NOT ENABLED. ABORTING WITH CTRL/C WILL NOT WARN OPERATOR>
jrst chan] ;no. don't try
TXO T3,SC%CTC ;ALLOW CTRL/C INTERRUPTS
EPCAP ;ENABLE THIS PLUS EXISTING
MOVE T1,[.TICCC,,2] ;CTRL/C ON CHANNEL 2
ATI ;ASSIGN CTRL/C TO CHANNEL 2
chan: mOVE T1,[.TICTI,,3] ;INPUT BUFFER NON-EMPTY
ATI ;ASSIGN BUFFER NON-EMPTY TO 3
MOVX T1,.FHSLF ;T1/ MY FORK
MOVE T2,[LEVTAB,,CHNTAB] ;T2/ ADDRESSES OF TABLES
SIR ;SET UP INTERRUPT TABLES
MOVX T1,.FHSLF ;T1/MY FORK
MOVX T2,1B0 ;T2/CHANNel TO ACTIVATE
aic ;activate ipcf channel
;..
SUBTTL SEND FIRST MESSAGE
;THIS CODE SENDS 'ONEWAY' TO OPLEAS IF TEXT ENDED WITH
;ESCAPE OR CTRL/Z. OTHERWISE, IT SENDS 'HELLO'
;..
MOVE T1,INITER ;GET TERMINATOR
CAIE T1,.CHCNZ ;CTRL/Z?
CAIN T1,.CHESC ;NO. ESCAPE?
;MESSAGE ENDED WITH CTRL/Z OR ESCAPE. SEND ONEWAY TO OPLEAS
JRST [ CALL SNDONE ;SEND ONEWAY AND TYPE MESSAGE
JRST START2 ;FAILED. START OVER
QUIT1] ;QUIT
; SEND 'HELLO' TO OPLEAS
MOVEI P2,OPDB ;P2/LOCATION OF PDB
MOVE T1,OPRPID
MOVEM T1,.IPCFR(P2) ;RECEIVER IS OPLEAS
MOVEI T1,PLHEL ;CODE IS 'HELLO'
MOVEM T1,OMSG
MOVEI P4,OPDBSZ ;P4/ SIZE OF PDB
CALL SNDMSG ;SEND THE MESSAGE
JRST [ CALL ERR1 ;RETRY IF POSSIBLE
JRST START2 ;RETRY FAILED OR COULDN'T RETRY
JRST .+1]
;ACTIVATE CTRL/C,CTRL/T, AND INPUT BUFFER CHANNELS.
;ENABLE INTERRUPT SYSTEM
movei t1,.fhslf ;t1/my fork
movx T2,1b1!1b2!1b3 ;t2/channels to activate
aic ;activate ctrl/t,ctrl/c,input buffer
MOVEI T1,.FHSLF ;T1/MY FORK
EIR ;ENABLE INTERRUPTS
;CAUSE AN INTERRUPT ON THE IPCF CHANNEL IN CASE THERE WAS A MESSAGE
;IN THE QUEUE WHEN THE CHANNEL WAS ACTIVATED. INTERRUPT ROUTINE
;WILL IGNORE THE INTERRUPT IF THE MRECV FAILS.
MOVEI T1,.FHSLF ;T1/MY FORK
MOVX T2,1B0 ;CHANNEL 0 (IPCF)
IIC ;CAUSE INTERRUPT
;..
SUBTTL WAKEUP
;THIS IS THE MAIN NON-INTERRUPT LEVEL ROUTINE. IT IS STARTED FOR THE
;FIRST TIME AFTER THE FORCED IPCF INTERRUPT. IT CLEARS INTFLG
;WHEN IT STARTS. WHEN IT HAS NOTHING TO DO, IT CHECKS INTFLG.
;IF IT IS SET, AN INTERRUPT HAS OCCURRED SINCE WAKEUP BEGAN, SO IT
;STARTS OVER. OTHERWISE, IT SETS WTFLG AND SLEEPS.
;EACH INTERRUPT ROUTINE DECIDES WHERE TO RETURN BASED ON WTFLG. IF
;IT IS SET, THE ROUTINE RETURNS TO WAKEUP. OTHERWISE, IT RETURNS TO
;THE NEXT LOCATION TO BE EXECUTED WHEN THE INTERRUPT
;OCCURRED.
;REACHED VIA DEBRK
;..
WAKEUP:
SETZM INTFLG ;CLEAR INTERRUPT FLAG
SETZM WTFLG ;CLEAR WAIT FLAG
;IF TEXT HAS COME IN FROM OPLEASE, IT IS STORED IN TXTBUF. PRINT IT.
;THE MESSAGES ARE CONCATENATED. A NULL FOLLOWS THE LAST MESSAGE.
MOVEI T1,.FHSLF ;T1/MY FORK
DIR ;NO INTERRUPTS WHILE READING BUFFER
SKIPE TXTFLG ;ANY MESSAGES WAITING TO BE TYPED?
CALL PRNTXT ;YES. PRINT THE TEXT
MOVEI T1,.FHSLF ;T1/MY FORK
EIR
;IF THE USER HAS TYPED ON THE TERMINAL, READ IT
MOVEI T1,.PRIIN ;T1/PRIMARY INPUT
SIBE ;HAS USER TYPED ANYTHING?
JRST WAKE1 ;YES.
;USER IS NOT TYPING BUT TEXT MAY BE IN BUFFER TO BE SENT.
;IF TEXT IS THERE AND OK HAS BEEN RECEIVED, SEND IT
SKIPN ACTFLG ;ARE WE IN TWO-WAY CONVERSATION?
JRST WAKE3 ;NO. DON'T SEND TEXT
MOVE T1,INIBEG ;POINT TO START OF BUFFER
CAME T1,RDNXT ;IS NEXT FREE LOCATION AT START OF BUFFER?
JRST [ CALL SNDTXT ;NO. SEND TEXT IN BUFFER
JRST START2 ;FAILED
JRST .+1] ;SUCCEEDED
JRST WAKE3
;USER HAS TYPED, READ IT
WAKE1: CALL GTXT ;GET TEXT
JRST WAKE11
;READ ENDED ON BUFFER FULL. USER WANTS TO SEND MORE. IF ACTIVE,
;SEND THIS MUCH AND GO READ THE REST. IF NOT, SEND AS ONEWAY.
MOVEI T4,.CHCRT ;ADD A CARRIAGE RETURN
IDPB T4,T1
MOVEI T4,.CHLFD ;ADD LINE FEED
IDPB T4,T1
SETZ T4, ;ADD NULL
IDPB T4,T1
SKIPN ACTFLG ;ARE WE IN TWO-WAY CONVERSATION
JRST [ TMSG <
%Text exceeds maximum for one message. Message sent as one-way.
> ;NO. OK NOT RECEIVED
CALL SNDONE ;SEND A ONEWAY
JRST START2 ;FAILED
QUIT1] ;GO QUIT
TMSG <
%Text exceeds maximum for one message. Message being sent.
> ;YES. SEND AS MUCH AS WE READ
CALL SNDTXT ;SEND TEXT
JRST START2 ;FAILED
JRST WAKE1 ;SUCCEEDED. GO READ REST
;entire message read. check terminator for goodbye
WAKE11: MOVE P5,INITER ;P5/ LAST BYTE READ
CAIE P5,.CHCNZ ;TERMINATED ON CTRL/Z?
CAIN P5,.CHESC ;no. ESCAPE?
JRST WAKE2 ;CNTL/Z OR ESCAPE
;DIDN'T END WITH CTRL/Z OR ESCAPE. SEND TEXT IF TWO-WAY, STORE
;OTHERWISE.
SKIPN ACTFLG ;NO. ARE WE IN TWO-WAY?
JRST WAKEUP ;NO. GO SEE IF THERE'S MORE TO READ
CALL SNDTXT ;YES. SEND TEXT
JRST START2 ;FAILED
JRST WAKEUP ;GO SEE IF THERE IS MORE TO READ
;ENDED WITH CTRL/Z OR ESCAPE. SEND ONEWAY IF NOT ACTIVE, TEXT AND
;BYE IF ACTIVE
WAKE2: SKIPN ACTFLG ;TWOWAY?
JRST [ CALL SNDONE ;NO. SEND ONE-WAY AND PRINT MESSAGE
JRST START2 ;FAILED. START OVER
QUIT1] ;SUCCEEDED. QUIT
CALL SNDTXT ;YES. SEND TEXT
JRST START2 ;FAILED
MOVX T2,1B0 ;SET BYEFLG SAYING USER QUIT
IORM T2,BYEFLG
;SEE IF ANYONE HAS SAID GOODBYE
WAKE3: SKIPN P6,BYEFLG ;HAS ANYONE SAID GOODBYE? LOAD P6
JRST WAKE5 ;NO.
;SOMEONE HAS SAID GOODBYE. IF TEXT HAS BEEN RECEIVED AND NOT
;PRINTED, DUMP THE BUFFER
MOVEI T1,.FHSLF ;T1/MY FORK
DIR ;DISABLE INTERRUPTS
MOVE P5,RCVCNT ;SAVE NUMBER OF LAST MESSAGE RECEIVED
SKIPE TXTFLG ;ANY MESSAGES WAITING TO BE TYPED?
CALL PRNTXT ;YES. PRINT THEM
MOVEI T1,.FHSLF ;T1/MY FORK
EIR ;ENABLE INTERRUPTS
;SEE WHO SAID GOODBYE
TXNE P6,1B1 ;WAS IT THE OPR?
JRST WAKE10 ;YES.
TXNN P6,1B0 ;NO. WAS IT USER?
JRST WAKE5 ;NO.
;USER HAS SAID GOODBYE AND OPERATOR HAS NOT. SEND 'GOODBYE'.
MOVEI P2,OPDB ;P2/ADDRESS OF SEND PDB
MOVE T1,OPRPID ;SEND TO OPLEASE'S PID
MOVEM T1,.IPCFR(P2)
MOVEI T1,PLBYE ;CODE IS GOODBYE
MOVEM T1,OMSG ;SAVE IN FIRST WORD OF MESSAGE
HRLM P5,OMSG ;SEND NUMBER OF LAST MESSAGE RECEIVED
MOVEI P4,OPDBSZ ;P4/LENGTH OF PDB
CALL SNDMSG ;SEND GOODBYE TO OPLEASE
JRST [ CAIE T1,IPCFX7 ;RECEIVER OVER QUOTA?
JRST .+1 ;NO. IGNORE
MOVEI T1,^D1000 ;TIME TO WAIT
DISMS ;WAIT A WHILE
CALL SNDMSG ;RESEND
JFCL ;FAILED AGAIN. GIVE UP
JRST .+1] ;SUCCEEDED SECOND TIME
JRST WAKE4 ;GO PRINT MESSAGE
;OPERATOR SAID GOODBYE. SEE IF ALL THE MESSAGES WE SENT GOT THERE
WAKE10: MOVE T1,TXTCNT ;T1/NUMBER OF LAST MESSAGE RECEIVED BY OPLEAS
CAMN T1,SNDCNT ;SAME AS NUMBER SENT?
JRST WAKE4 ;YES. GOOD
TMSG <
%Part of your message was not transmitted.
> ;NO. PRINT MESSAGE
SKIPN DEBUG ;DEBUGGING?
JRST WAKE4 ;NO. DON'T PRINT NUMBERS
TMSG <
D:Number of messages sent: > ;YES. PRINT NUMBERS COMPARED
MOVEI T1,.PRIOU ;T1/PRIMARY OUTPUT
MOVE T2,SNDCNT ;T2/NUMBER SENT
MOVX T3,12B35 ;T3/DECIMAL RADIX
NOUT ;PRINT THE NUMBER SENT
JSERR
TMSG <
D:Number of messages received: >
MOVEI T1,.PRIOU ;T1/PRIMARY OUTPUT
MOVE T2,TXTCNT ;T2/NUMBER OF MESSAGES RECEIVED BY UPLEASE
MOVX T3,12B35 ;T3/DECIMAL RADIX
NOUT ;PRINT THE NUMBER RECEIVED
JSERR
;PRINT MESSAGE INDICATING CONVERSATION IS FINISHED
WAKE4: TMSG <
[Finished at >
MOVX T1,.PRIOU ;T1/PRIMARY OUTPUT
SETOM T2 ;T2/PRINT CURRENT TIME
MOVX T3,1B0+1B17 ;T3/TIME ONLY, NO COLUMNATION
ODTIM ;PRINT THE TIME
TMSG < ]
>
QUIT1
;IF INTERRUPTS HAVE COME IN, REPEAT WAKEUP CODE. IF NOT, WAIT FOR
;ANOTHER INTERRUPT
WAKE5: SETOM WTFLG ;SET FLAG INDICATING WAITING
SKIPE INTFLG ;HAS AN INTERRUPT BEEN PROCESSED?
JRST WAKEUP ;YES. SEE WHAT NEEDS TO BE DONE
WAIT ;NO. WAIT FOR SOMETHING TO HAPPEN
;SHOULDN'T BE HERE. PRINT MESSAGE IF DEBUGGING. IGNORE OTHERWISE.
SKIPN DEBUG ;DEBUGGING?
JRST WAKEUP ;NO. IGNORE THE PROBLEM
TMSG <
D:At HALT after WAIT.
>
JRST WAKEUP
SUBTTL SNDONE - SEND ONEWAY MESSAGE
;USER HAS TYPED CTRL/Z OR ESCAPE. SEND TEXT STORED IN INITXT AREA
;AS A ONEWAY MESSAGE. SINCE PID WILL GO AWAY, OPLEASE WON'T BE
;ABLE TO IDENTIFY JOB, SO SEND IDENTIFYING INFORMATION
;REACHED VIA CALL SNDONE FROM NON-INTERRUPT LEVEL ROUTINE
;RETURNS +1:SEND SUCCEEDED
; +2:SEND FAILED
SNDONE:
MOVEI T1,PLONE ;CODE IS ONEWAY
MOVEM T1,OMSG ;TO FIRST WORD OF MESSAGE
GTAD ;GET CURRENT TIME
MOVEM T1,OMSG+1 ;TO SECOND WORD OF MESSAGE
MOVEM T1,NOW ;ALSO SAVE IT HERE
GJINF ;GET JOB INFORMATION
MOVEM T1,OMSG+2 ;LOGGED IN DIRECTORY TO 3RD WORD
MOVEM T4,OMSG+3 ;LINE NUMBER TO 4TH WORD
HRROI T1,OMSG+4 ;DESTINATION:5TH WORD AND FOLLOWING
MOVE T2,INIBEG ;SOURCE:TEXT BUFFER AREA
MOVEI T3,<OMSGSZ-4>*5 ;NUMBER OF BYTES AVAILABLE
SETZ T4, ;STOP ON NULL
SOUT ;TRANSFER MESSAGE TO MESSAGE AREA
MOVEI P2,OPDB ;P2/ADDRESS OF PDB
MOVE T1,OPRPID ;OPERATOR'S PID
MOVEM T1,.IPCFR(P2) ;TO RECEIVER FIELD
MOVEI P4,OPDBSZ ;P4/PDB SIZE
CALL SNDMSG ;SEND ONEWAY
JRST [ CALL ERR1 ;SEND FAILED. RETRY IF POSSIBLE
RET ;RETRY FAILED OR COULDN'T RETRY
JRST .+1] ;RETRY SUCCEEDED
MOVEI T1,.FHSLF ;DISABLE INTERRUPTS TO PREVENT [NOTIFIED]
DIR ; FROM COMING OUT IN MIDDLE OF THIS MESSAGE
TMSG <
[One-way sent at >
MOVEI T1,.PRIOU ;T1/PRIMARY OUTPUT
MOVE T2,NOW ;TIME SENT WITH MESSAGE
MOVX T3,1B0!1B17 ;T3/TIME ONLY, NO COLUMNATION
ODTIM ;PRINT THE TIME SENT WITH MESSAGE
TMSG <]
>
MOVEI T1,.FHSLF ;RESTORE INTERRUPTS
EIR
RETSKP ;SUCCESSFUL RETURN
SUBTTL SNDTXT - SEND TEXT MESSAGE
;USER IS IN TWO-WAY CONVERSATION WITH THE OPERATOR AND HAS TYPED
;TEXT. SEND TEXT, STORED IN INITXT AREA, AS A TEXT MESSAGE.
;REACHED VIA CALL SNDTXT FROM NON-INTERRUPT LEVEL ROUTINE
;RETURNS: +1 SEND SUCCEEDED
; +2 SEND FAILED
SNDTXT: MOVEI P2,OPDB ;P2/LOCATION OF SEND PDB
MOVE T1,OPRPID ;OPLEASE'S PID
MOVEM T1,.IPCFR(P2) ;SEND TO OPERATOR'S PID
MOVEI T1,PLTXT ;MESSAGE IS 'TEXT'
MOVEM T1,OMSG ;TO FIRST WORD OF MESSAGE
AOS T1,SNDCNT ;INCREMENT COUNT OF TEXT MESSAGES SENT
HRLM T1,OMSG ;SEND WITH MESSAGE
HRROI T1,OMSG+1 ;DESTINATION:2ND WORD OF MESSAGE
MOVE T2,INIBEG ;SOURCE:TEXT BUFFER AREA
MOVEI T3,<OMSGSZ-1>*5 ;T3/NUMBER BYTES AVAILABLE
SETZ T4, ;T4/STOP ON NULL
SOUT ;COPY TEXT TO MESSAGE AREA
MOVEI P4,OPDBSZ ;P4/LENGTH OF SEND PDB
CALL SNDMSG ;SEND THE TEXT
JRST [ CALL ERR1 ;SEND FAILED. RETRY IF POSSIBLE
RET ;RETRY FAILED OR COULDN'T RETRY
JRST .+1] ;RETRY SUCCEEDED
MOVE T1,INIBEG ;RESTORE POINTER TO BEGINNING OF BUFFER
MOVEM T1,RDNXT ; FOR NEXT READ
MOVE T1,TXTSIZ ;RESET BYTE LIMIT FOR NEXT READ
MOVEM T1,RDLIM
RETSKP ;SUCCESSFUL RETURN
SUBTTL SNDMSG
;SEND A MESSAGE WHOSE PDB AND MESSAGE AREA HAVE BEEN SET UP.
;ACCEPTS
;P2/ ADDRESS OF SEND PDB
;P4/ SIZE OF SEND PDB
;REACHED VIA CALL SNDMSG FROM ROUTINE AT EITHER INTERRUPT OR NON-
;NON-INTERRUPT LEVEL
;RETURNS: +1 SEND FAILED
; +2 SEND SUCCEEDED
SNDMSG: MOVE T1,P4 ;T1/ SIZE OF SEND PDB
MOVE T2,P2 ;T2/ LOCATION OF SEND PDB
MSEND
JRST SNDMS1 ;FAILED
RETSKP ;SUCCEEDED
;FAILED. PRINT INFO IF DEBUGGING.
SNDMS1: SKIPN DEBUG ;DEBUGGING?
RET ;NO. NO MESSAGES.
TMSG <
D:Failed on send to PID >
MOVX T1,.PRIOU ;T1/PRIMARY OUTPUT
MOVE T2,.IPCFR(P2) ;T2/RECEIVER
MOVE T3,[1B0+10B35] ;T3/MAGNITUDE,OCTAL
NOUT ;PRINT PID SENT TO
JSERR
TMSG <
D:First word of message: >
MOVX T1,.PRIOU
MOVE T2,SMSG ;T2/FIRST WORD OF MESSAGE
NOUT ;PRINT IT
JSERR ; FAILED
TMSG <
>
RET
SUBTTL PRNTXT
;PRINT TEXT THAT HAS COME IN AND IS WAITING IN THE BUFFER
;INTERRUPTS ARE DISABLED BY CALLING ROUTINE
;REACHED VIA CALL PRNTXT BY NON-INTERRUPT LEVEL ROUTINE
;RETURNS +1 ALWAYS
PRNTXT: SETZM TXTFLG ;CLEAR TEXT FLAG
HRROI T1,TXTBUF ;POINT TO BEGINNING OF BUFFER
PSOUT ;PRINT TEXT
call clrtxt ;clear text area and reset bufnxt
RET
subttl clrtxt
;clears txtbuf area - contains text that has been received but not
;typed out. called at initialization and after all characters have
;been typed. clears the area and resets bufnxt to point to start
;INTERRUPTS HAVE BEEN DISABLED BY CALLING ROUTINE
;REACHED VIA CALL PRNTXT BY NON-INTERRUPT LEVEL ROUTINE
;RETURNS +1 ALWAYS
clrtxt: setzm txtbuf
move t1,[txtbuf,,txtbuf+1]
blt t1,bufend-1
hrroi t1,txtbuf
movem t1,bufnxt
RET
SUBTTL IPCF INTERRUPT PROCESSING
;THIS IS THE MAIN ROUTINE FOR PROCESSING IPCF INTERRUPTS. IT IS INVOKED
;WHENEVER THE NUMBER OF MESSAGES WAITING TO BE RECEIVED GOES FROM
;ZERO TO NON-ZERO.
;IT RECEIVES A MESSAGE AND JUMPS TO THE CODE TO PROCESS THE MESSAGE.
;WHEN THERE ARE NO MORE MESSAGES WAITING, IT RETURNS.
;REACHED VIA INTERRUPT ON CHANNEL 0.
IPCINT: SETOM INTFLG ;SET INTERRUPT FLAG
MOVEM 17,REGSAV+17 ;SAVE REGISTER 17
MOVEI 17,REGSAV ;SET UP FOR BLT OF 0 TO REGSAV
BLT 17,REGSAV+16 ;MOVE 0-16 TO REGSAV
MOVE 17,REGSAV+17
;SET UP FOR RECEIVE
IPCIN1: MOVEI T4,RPDB ;T4/ADDRESS OF RECEIVE PDB
MOVX T1,IP%CFB!IP%TTL!IP%CFV ;DON'T BLOCK,TRUNCATE,PAGE MODE
MOVEM T1,.IPCFL(T4) ;FLAG WORD
MOVE T1,[RMSGSZ,,RPAGE] ;PAGE SIZE, PAGE NUMBER
MOVEM T1,.IPCFP(T4) ;STORE IN PDB
MOVEI T1,RPDBSZ ;T1/LENGTH OF PDB
MOVEI T2,RPDB ;T2/LOCATION OF PDB
MRECV ;RECEIVE NEXT MESSAGE
JRST IPCIN2 ;FAILED
JRST IPCIN5 ;SUCCEEDED
;RECEIVE FAILED. IF PROBLEM IS THAT MESSAGE IS NOT IN PAGE MODE
;TRY RECEIVING WITHOUT PAGE MODE BIT SET. RECEIVE INTO THE SAME PAGE
;AS IN PAGE MODE.
IPCIN2: CAIE T1,IPCF16 ;DATA MODE PROBLEM?
JRST IPCIN3 ;NO.
MOVX T2,IP%CFB!IP%TTL ;NO PAGE MODE
MOVEM T2,.IPCFL(T4) ;TO PDB
MOVE T1,[MAXMSG,,RMSG] ;MESSAGE SIZE,LOCATION
MOVEM T1,.IPCFP(T4) ;TO PDB (size already set)
MOVEI T1,RPDBSZ ;T1/SIZE OF PDB
MOVEI T2,RPDB ;T2/LOCATION OF PDB
MRECV ;READ MESSAGE AND DISCARD
JRST IPCIN3 ;STILL FAILS
JRST IPCIN5 ;SUCCEEDS. GO PROCESS IT
;NOT A PAGE PROBLEM. IF THERE WAS NO MESSAGE, IGNORE THE INTERRUPT.
;OTHERWISE, PRINT THE ERROR AND RETRY.
IPCIN3: CAIE T1,IPCFX2 ;NO MESSAGE?
JRST IPCIN4 ;NO.
SETZM NXTMSG ;YES. CLEAR ASSOCIATED VARIABLE
JRST ENDINT ;IGNORE THE INTERRUPT
IPCIN4: JSERR ;UNKNOWN ERROR
JRST IPCIN1 ;SEE IF THERE ARE ANY MORE
;RECEIVE SUCCEEDED. CHECK FOR UNDELIVERED MAIL AND ERRORS.
;IGNORE ALL OTHER MESSAGES EXCEPT THOSE FROM OPLEASE
IPCIN5: MOVEM T1,NXTMSG
MOVEI P1,RPDB ;P1/LOCATION OF RECEIVE PDB
MOVE Q2,.IPCFS(P1) ;Q2/SENDER'S PID
MOVE Q1,.IPCFL(P1) ;Q1/FLAG WORD RECEIVED
JXN Q1,IP%CFM,UNDEL ;UNDELIVERED MAIL?
JXN Q1,IP%CFE,RCVERR ;NO. ERROR?
JXN Q1,IP%CFC,ENDINT ;FROM SYSTEM? IGNORE
CAME Q2,OPRPID ;FROM OPERATOR?
JRST ENDINT ;NO. IGNORE
;FROM OPLEASE. TRANSFER ACCORDING TO CODE SENT
HRRZ P6,RMSG ;P6/CODE SENT IN MESSAGE
MOVEI P2,SPDB ;P2/LOCATION OF SEND PDB
CAIGE P6,TABSIZ ;LEGAL CODE?
JRST @GOTAB(P6) ;YES. GO PROCESS
; RECEIVED BAD CODE FROM OPLEASE
SKIPN DEBUG ;DEBUGGING?
JRST ENDINT ;NO. IGNORE.
TMSG <
D:Received code >
MOVEI T1,.PRIOU ;T1/PRIMARY OUTPUT
MOVE T2,P6 ;T2/FIRST WORD OF MESSAGE
MOVX T3,1B0+10B35 ;T3/MAGNITUDE,,OCTAL
NOUT ;PRINT THE CODE
JSERR
TMSG < from PID >
MOVEI T1,.PRIOU ;T1/PRIMARY OUTPUT
MOVE T2,Q2 ;T2/SENDING PID
NOUT ;PRINT THE PID
JSERR
TMSG <
>
;..
;MESSAGE HAS BEEN PROCESSED. IF THERE WAS ANOTHER MESSAGE WAITING
;WHEN THIS ONE WAS RECEIVED, NXTMSG IS NON-ZERO. GO RECEIVE THE NEXT
;ONE. IF NXTMSG IS ZERO, ANY MESSAGE THAT HAS COME IN SINCE THE
;LAST RECEIVE WILL CAUSE A NEW INTERRUPT.
;..
ENDINT: SKIPE NXTMSG ;ANY MORE MESSAGES IN QUEUE?
JRST IPCIN1 ;GO RECEIVE THE NEXT MESSAGE
;NO MORE TO RECEIVE. IF CAME FROM WAIT, WAKE UP. IF NOT,
;RETURN TO WHERE WE WERE BEFORE THE INTERRUPT.
HRLZI 17,REGSAV ;RESTORE REGISTERS
BLT 17,17
SKIPN WTFLG ;CAME FROM A WAIT?
DEBRK ;NO. RETURN TO WHERE WE WERE
MOVEI T1,WAKEUP ;YES. START WAKE-UP PROCEDURE
MOVEM T1,PCSAV1
MOVE T1,REGSAV+1 ;RESTORE T1
DEBRK
;SOMETHING FAILED. START OVER.
RESTRT: MOVEI T1,START2 ;DEBRK TO RESTART LOCATION
MOVEM T1,PCSAV1
DEBRK
SUBTTL OK
;'OK' RECEIVED. OPLEASE IS READY TO TALK. SEND THE PREVIOUSLY TYPED TEXT
;ACCEPTS:
;P2/ ADDRESS OF SEND PDB
;Q2/ PID OF SENDER
;REACHED VIA JRST FROM IPCINT
;JRSTS TO ENDINT ON SUCCESSFUL SEND OF TEXT
; RESTRT ON FAILURE OF SEND
OK: SETOM ACTFLG ;SET INDICATOR THAT OK WAS RECEIVED.
TMSG <
[Operator has been notified]
> ;TELL THE USER
;send text as read from tty.
MOVEI P4,SPDBSZ ;P4/SIZE OF SEND PDB
MOVE T1,OPRPID ;RECEIVER IS OPLEASE
MOVEM T1,.IPCFR(P2)
MOVEI T1,PLTXT ;CODE IS 'TEXT'
MOVEM T1,SMSG
hrroi t1,smsg+1 ;destination: send message area
move t2,inibeg ;source: first line typed
movei t3,<smsgsz-1>*5 ;maximum bytes available
SETZ T4, ;STOP ON NULL
sout ;transfer text to smsg area
CALL SNDMSG ;SEND THE TEXT
JRST [ CALL ERR1 ;FAILED. RETRY IF POSSIBLE
JRST RESTRT ;RETRY FAILED OR COULDN'T RETRY
JRST .+1]
MOVE T1,INIBEG ;RESTORE POINTER TO BEGINNING OF BUFFER
MOVEM T1,RDNXT ; FOR NEXT READ
MOVE T1,TXTSIZ ;RESET BYTE LIMIT FOR NEXT READ
MOVEM T1,RDLIM
;if first line ended with ^z or escape, set up for goodbye
move t4,initer ;terminating character
caIE t4,.chcnz ;ctrl/Z?
CAIN T4,.CHESC ;NO. ESCAPE?
JRST SETBYE ;CNTL/Z OR ESCAPE. SET FLAG
JRST ENDINT ;NO.
setbye: movx t3,1b0 ;^z or esc. set flag indicating
IOrm t3,byeflg ; user said goodbye
JRST ENDINT
SUBTTL TEXT
;'TEXT' RECIEVED. STORE TEXT IN TXTBUF AREA. APPEND TO PREVIOUS
;TEXT IF THERE IS ANY. SET FLAG TO INDICATE TEXT IS WAITING TO BE PRINTED.
;ACCEPTS:
;Q2/ PID OF SENDER
;P1/ ADDRESS OF RECEIVE PDB
;P2/ ADDRESS OF SEND PDB
;REACHED VIA JRST FROM IPCINT
;JRSTS TO ENDINT ALWAYS
TEXT:
HLRZ T1,RMSG ;SAVE NUMBER OF THIS MESSAGE
MOVEM T1,RCVCNT ; TO SEND BACK WITH 'BYE'
HRROI T2,RMSG+1 ;POINT TO FIRST WORD OF TEXT
MOVE T1,BUFNXT ;POINT TO NEXT AVAILABLE LOCATION
; IN BUFFER
MOVEI T3,BUFEND ;END OF BUFFER
HRRZ T4,BUFNXT ;NEXT AVAILABLE LOCATION
SUB T3,T4 ;MAX WORDS REMAINING
JUMPLE T3,TEXT1 ;ERROR IF NO ROOM
SOS T3 ;ROUND DOWN
IMULI T3,5 ;MAXIMUM BYTES
SETZ T4, ;STOP ON NULL BYTE
SOUT ;TRANSFER TEXT TO OUTPUT AREA
BKJFN ;BACKUP THE POINTER TO OVERWRITE THE
JFCL ; NULL NEXT TIME (T1 CONTAINS POINTER)
MOVEM T1,BUFNXT ;SAVE UPDATED POINTER
SETOM TXTFLG ;SET FLAG TO INDICATE BUFFER NON-EMPTY
JUMPE T3,TEXT1 ;END OF BUFFER?
JRST ENDINT ;NO.
TEXT1: TMSG<
%Text deleted from incoming message.
> ;YES. TELL USER
JRST ENDINT
SUBTTL BYE
;'BYE' RECEIVED. SET BYEFLG TO INDICATE OPERATOR QUIT.
;SAVE NUMBER OF LAST TEXT MESSAGE RECEIVED BY OPLEASE.
;REACHED VIA JRST FROM IPCINT
;JRSTS TO ENDINT ALWAYS
BYE: MOVX T1,1B1 ;BIT 1 FOR OPERATOR QUIT
IORM T1,BYEFLG
HLRZ T1,RMSG ;LAST MESSAGE RECEIVED BY OPLEASE
MOVEM T1,TXTCNT ;SAVE TO CHECK AGAINST OUR COUNT
JRST ENDINT
;HERE TO READ FROM TERMIN