Trailing-Edge
-
PDP-10 Archives
-
BB-FP64A-SB_1986
-
10,7/who/whosrv.mac
There are 4 other files named whosrv.mac in the archive. Click here to see a list.
TITLE WHOSRV - SRVF INTERFACE FOR WHOSRV
SEARCH WHOMAC
$SETUP (WHOSRV)
; Dummy definitions if loading without the server
IFE FTSERV,<
SRVPUT::! ;COMMAND BUFFER PUTTER
SRVTAK::! ;COMMAND BUFFER TAKER
SRVTYO::! ;OUTPUT TO SOME TASK
SRVXIT::!POPJ P, ;EXIT ROUTINE
> ;END IFE FTSERV
IFN FTSERV,<
SUBTTL Table of Contents
; TABLE OF CONTENTS FOR WHOSRV
;
;
; SECTION PAGE
; 1. Table of Contents......................................... 2
; 2. System server
; 2.1 CHKSRV - Check FRCLIN startup..................... 3
; 2.2 SRVSYS - Start up server.......................... 4
; 2.3 LGNJOB - Login a job.............................. 5
; 3. User server
; 3.1 SRVUSR - Initiate server connects................. 6
; 4. Server loop
; 4.1 WHOSRV - Top level................................ 7
; 4.2 TINI - INIT TYPE IN AND STORAGE................... 8
; 5. SCAN interface
; 5.1 .ISCAN block...................................... 9
; 5.2 SRVCHR - Character typeout........................ 10
; 5.3 TYPIN - Character typein.......................... 11
; 6. Server loop
; 6.1 GMSG - Get an IPCF message........................ 12
; 6.2 SMSG - Send an IPCF message....................... 13
; 7. Buffer control
; 7.1 Definitions....................................... 14
; 7.2 SRVCMD/SRVTYP - Initialize character storage...... 15
; 7.3 ADVBUF - Advance buffers.......................... 16
; 7.4 SRVPUT/TYPPUT - Character putters................. 17
; 7.5 CMDTAK/TYPTAK - Character takers.................. 18
; 8. Task I/O
; 8.1 Dispatch vectors.................................. 19
; 8.2 Initialization.................................... 20
; 8.3 IPCF.............................................. 22
; 8.4 ANF10............................................. 24
; 8.5 DECnet............................................ 26
; 9. Storage................................................... 27
SUBTTL System server -- CHKSRV - Check FRCLIN startup
CHKSRV::MOVNI T1,1 ;-1 MEANS US
PUSHJ P,UTRMNO## ;GET OUR LINE NUMBER
PJRST SRVCMD ;DETACHED--INIT COMMAND BUFFER
MOVE T2,T1 ;COPY IT
ANDX T2,UX.UNT ;KEEP JUST THE UNIT NUMBER
MOVX T1,%CNFLN ;GETTAB TO RETURN FRCLIN TTY NUMBER
PUSHJ P,GTAB## ;GET IT
CAME T1,T2 ;ARE WE RUNNING ON FRCLIN ?
PJRST SRVCMD ;NO--INIT COMMAND BUFFER
HRLZS T2 ;SETUP LINE#,,0 FOR DETACH
ATTACH T2, ;DETACH FROM FRCLIN
JFCL ;OH WELL...
MOVSI T1,.STWTC ;GET FUNCTION CODE TO SET WATCH
SETUUO T1, ;SET WATCH NONE
JFCL ;HOPE NOTHING TYPES OUT
PUSHJ P,SRVSYS ;SET UP SYSTEM SERVERS
PJRST SRVLOP ;AND START DOING THE WORK
SUBTTL System server -- SRVSYS - Start up server
SRVSYS::TLO F,(FL.WHOSRV) ;FLAG THE WHOSRVER
PUSHJ P,LGNJOB ;MAKE SURE WE'RE LOGGED IN
PUSHJ P,SETME## ;SET UP OUR PRIV AND JOB FLAGS
MOVE T1,[LN$IBLK##,,ISBLK##] ;POINT TO .ISCAN BLOCK
PUSHJ P,.ISCAN## ;INIT SCAN
PUSHJ P,OUTDEF## ;SET UP THE LOG FILE SPEC
PUSHJ P,OPNLST## ;OPEN THE LOG FILE
PUSHJ P,LOGHDR ;PUT A HEADER OUT
PUSHJ P,.SAVE2## ;SAVE P1 AND P2
MOVSI P1,-.TSNUM+1 ;AOBJN POINTER
SRVS.1: MOVE P2,TSKTAB(P1) ;GET TASK DISPATCH VECTOR
TDNN F,.TSFET(P2) ;HAVE THE NECESSARY MONITOR FEATURES?
JRST SRVS.2 ;NO
SETZ T1, ;PASSIVE TASK
MOVE T2,.TSTIM(P2) ;GET TIMEOUT VALUE
STORE T2,T1,TS.TIM ;SAVE IT
MOVE T2,.TSTYP(P2) ;GET TASK TYPE
STORE T2,T1,TS.TYP ;SAVE IT
MOVEI T2,0 ;0 TO ACCEPT CONNECTS FROM ALL NODES
PUSHJ P,OPNTSK ;OPEN A TASK
SKIPA T1,[LOGSTE] ;FAILED
MOVEI T1,LOGSTA ;STARTED WITHOUT ERRORS
PUSHJ P,(T1) ;LOG THE START OR FAILURE
SRVS.2: AOBJN P1,SRVS.1 ;LOOP
MOVE T1,F ;COPY FLAGS
AND T1,[FL.SRVFLG+FR.OPEN] ;KEEP ONLY SPECIAL SERVER JOB FLAGS
MOVEM T1,SRVFLG ;SAVE FOR LATER
PUSHJ P,CLSLST## ;CLOSE SERVER LOG
POPJ P, ;RETURN
SUBTTL System server -- LGNJOB - Login a job
LGNJOB: TLNE F,(FL.LOGIN) ;ALREADY LOGGED IN?
POPJ P, ;YES
MOVE T1,OPRPPN## ;GET OPERATOR PPN
MOVEM T1,LOGDAT+0 ;SAVE IT
SETOM LOGDAT+1 ;WANT ALL DEC AND CUSTOMER PRIVS
MOVE T1,['WHO-SE'] ;USER NAME
MOVEM T1,LOGDAT+2 ; (WORD 1)
MOVE T1,['RVER '] ;USER NAME
MOVEM T1,LOGDAT+3 ; (WORD 2)
SETZM LOGDAT+4 ;NO CHARGE NUMBER
MOVE T1,[-5,,LOGDAT] ;POINT TO ARGS
LOGIN T1, ;TURN ON JLOG, TOO BAD IT CLEARS JACCT
POPJ P, ;BET YOU THOUGHT LOGIN UUO SKIPPED!
SUBTTL System server -- SRVDEF - Set up log file
SRVDEF::SETOM PRVFLG## ;TELL WHOIO TO USE FILOP PRIVS
MOVE T1,[O.SPEC##,,O.SPEC##+1] ;SET UP BLT
SETZM O.SPEC## ;CLEAR FIRST WORD
BLT T1,O.SPEC+.FZLEN##-1 ;CLEAR ENTIRE SCAN BLOCK
MOVEI T1,O.SPEC## ;POINT TO OUTPUT SCAN BLOCK
MOVSI T2,'SSL' ;DEVICE
MOVEM T2,.FXDEV(T1) ;SET IT
MOVE T2,[SIXBIT/WHO/] ;FILE NAME
MOVEM T2,.FXNAM(T1) ;SET IT
SETOM .FXNMM(T1) ;NOT WILD
HRLOI T2,'LOG' ;EXTENSION AND MASK
MOVEM T2,.FXEXT(T1) ;SET IT
MOVE T2,QUEPPN## ;GET PPN
MOVEM T2,.FXDIR(T1) ;SET IT
SETOM .FXDIM(T1) ;NOT WILD
MOVE T2,.JBVER ;GET OUR VERSION
MOVEM T2,.FXVER(T1) ;SET IT
SETOM .FXEST(T1) ;NO ESTIMATED LENGTH
MOVX T2,FX.DIR+FX.PHY ;DIRECTORY SPECIFIED, /PHYSICAL
MOVE T3,SPLPRT## ;GET SPOOLED FILE PROTECTION CODE
LSH T3,-<ALIGN.(RB.PRV)> ;RIGHT JUSTIFY
DPB T3,[POINTR (T2,FX.PRO)] ;STORE PROTECTION CODE
MOVEM T2,.FXMOD(T1) ;SET BITS
TXO T2,FX.PRO ;TELL SCAN A PROTECTION WAS SPECIFIED
MOVEM T2,.FXMOM(T1) ;SET THE MODIFIER MASK
MOVE T1,[.FZLEN##,,O.SPEC##] ;POINT TO OUTPUT SPEC
MOVEI T2,O.OPEN## ;POINT TO OPEN BLOCK
MOVE T3,[LN$LEN,,O.ENTER##] ;POINT TO ENTER BLOCK
MOVEI T4,O.PATH## ;POINT TO OUTPUT PATH. BLOCK
PUSHJ P,.STOPB## ;CONVERT SCAN BLOCKS
JFCL ;CANNOT FAIL
MOVSI T1,'WHO' ;GET PROGRAM NAME
MOVEM T1,O.ENTER##+.RBSPL ;STORE AS SPOOLED NAME
MOVEI T1,1 ;GET "YES"
MOVEM T1,S.APPEND## ;TURN ON /APPEND
POPJ P, ;AND RETURN
SUBTTL System server - LOGHDR - Write a log file header
LOGHDR: AOS T1,HDRFLG ;GET HEADER FLAG
SOJN T1,.POPJ## ;RETURN IF ALREADY HAVE DONE THIS
MOVEI T1,CHRFIL ;WANT LOG FILE ONLY OUTPUT
PUSHJ P,.TYOCH## ;TELL SCAN
PUSH P,T1 ;SAVE OLD TYPER
MOVEI T1,NEWPAG ;POINT TO NEW PAGE TEXT
PUSHJ P,.TSTRG## ;TYPE IT
MOVEI T1,STARS ;POINT TO A STRING OF STARS
PUSHJ P,.TSTRG## ;TYPE IT
MOVEI T1,[ASCIZ | WHO server log file |]
PUSHJ P,.TSTRG## ;TYPE INTRODUCTION
PUSHJ P,.GTNOW## ;GET UDT
PUSHJ P,.TDTTM## ;AND TYPE THE CURRENT DATE AND TIME
PUSHJ P,.TCRLF## ;CRLF
PUSHJ P,.TCRLF## ;ONE MORE
MOVEI T1,[ASCIZ |Server: |]
PUSHJ P,.TSTRG## ;TYPE INTRO
PUSHJ P,WRTUSR ;WRITE OUT USER INFO
MOVEI T1,[ASCIZ | running |]
PUSHJ P,.TSTRG## ;TYPE SEPARATOR
PUSHJ P,WRTPGM ;WRITE OUT OUR NAME AND VERSION
PUSHJ P,.TCRLF## ;CRLF
MOVEI T1,[ASCIZ |System: |]
PUSHJ P,.TSTRG## ;TYPE INTRO
PUSHJ P,WRTSYS ;WRITE OUT OUR SYSTEM NAME
PUSHJ P,.TCRLF## ;CRLF
MOVEI T1,[ASCIZ |File: |]
PUSHJ P,.TSTRG## ;TYPE INTRO
MOVEI T1,O.FILOP## ;POINT TO FILOP BLOCK
PUSHJ P,.TFLPB## ;TYPE FILESPEC
PUSHJ P,.TCRLF## ;CRLF
MOVEI T1,STARS ;POINT TO A STRING OF STARS
PUSHJ P,.TSTRG## ;TERMINATE HEADER
POP P,T1 ;GET OLD TYPER
PJRST .TYOCH## ;RESET SCAN AND RETURN
; Start of page text
NEWPAG: BYTE(7) .CHCRT,.CHFFD,0 ;<CR><FF>
; Stars for log file header
STARS: ASCIZ |
**********************************************************************
|
SUBTTL System server -- LOGBEG/LOGEND - begin and end log file I/O
LOGBEG: PUSH P,T1 ;SAVE KEYWORD STAMP
MOVEI T1,CHRFIL## ;WANT FILE OUTPUT ONLY
PUSHJ P,.TYOCH## ;TELL SCAN
MOVEM T1,LOGTYO ;SAVE TYPER
PUSHJ P,.TTIMN## ;PUT OUT TIME STAMP
PUSHJ P,.TSPAC## ;SPACE OVER
POP P,T1 ;GET KEYWORD STAMP
PUSHJ P,.TSIXN## ;TYPE IT
PJRST .TTABC## ;TAB OVER AND RETURN
LOGEND: MOVE T1,LOGTYO ;GET OLD TYPER
PJRST .TYOCH## ;TYPE IT AND RETURN
SUBTTL System server -- LOGSTA/LOGSTE - Log starting message
LOGSTA: MOVE T1,[SIXBIT /START/] ;STAMP
PUSHJ P,LOGBEG ;SET UP FOR LOG FILE OUTPUT
MOVEI T1,[ASCIZ |Starting |]
JRST LOGSTX ;ENTER COMMON CODE
LOGSTE: MOVE T1,[SIXBIT /ERROR/] ;STAMP
PUSHJ P,LOGBEG ;SET UP FOR LOG FILE OUTPUT
MOVEI T1,[ASCIZ |Failed to start|]
LOGSTX: PUSHJ P,.TSTRG## ;TYPE TEXT
MOVE T1,T.DISP ;GET DISPATCH
MOVE T1,.TSNAM(T1) ;GET TASK NAME
PUSHJ P,.TSTRG## ;TYPE IT
MOVEI T1,[ASCIZ | server|]
PUSHJ P,.TSTRG## ;TYPE TEXT
PUSHJ P,.TCRLF## ;CRLF
PJRST LOGEND ;END LOG FILE I/O
SUBTTL System server -- LOGCON - Log CONNECT
LOGCON: MOVE T1,[SIXBIT /CONNEC/] ;STAMP
PUSHJ P,LOGBEG ;START BEGIN LOG FILE I/O
MOVE T1,T.DISP ;GET DISPATCH
MOVE T1,.TSNAM(T1) ;GET TASK NAME
PUSHJ P,.TSTRG## ;TYPE IT
MOVEI T1,[ASCIZ | running in sequence #|]
PUSHJ P,.TSTRG## ;TYPE TEXT
MOVE T1,T.SEQN ;GET SEQUENCE NUMBER
PUSHJ P,.TDECW## ;TYPE IT
PUSHJ P,.TCRLF## ;CRLF
PJRST LOGEND ;END LOG FILE I/O
SUBTTL System server -- LOGDSC - Log DISCONNECT
LOGDSC: MOVE T1,[SIXBIT /DISCON/] ;STAMP
PUSHJ P,LOGBEG ;BEGIN LOG FILE I/O
MOVE T1,T.DISP ;GET DISPATCH
MOVE T1,.TSNAM(T1) ;GET TASK NAME
PUSHJ P,.TSTRG## ;TYPE IT
PUSHJ P,.TCRLF## ;CRLF
PJRST LOGEND ;END LOG FILE I/O
SUBTTL System server -- LOGRMT - Log REMOTE
LOGREM: MOVE T1,[SIXBIT /REMOTE/] ;STAMP
PUSHJ P,LOGBEG ;BEGIN LOG FILE I/O
MOVEI T1,[ASCIZ |Remote data|]
PUSHJ P,.TSTRG## ;TYPE INTRO
PUSHJ P,.TCRLF## ;CRLF
PUSHJ P,.SAVE1## ;SAVE P1
MOVE P1,[-DATLEN,,DATTAB] ;AOBJN POINTER TO TABLE
LOGRE1: HRRZ T1,.DTFLG(P1) ;POINT TO DATA STORAGE
SKIPN (T1) ;HAVE SOMETHING THERE?
JRST LOGRE2 ;NO
PUSHJ P,.TTABC## ;TAB
PUSHJ P,.TTABC## ;ONE MORE
HLLZ T1,.DTNAM(P1) ;GET DATA ITEM NAME
PUSHJ P,.TSIXN## ;TYPE IT
PUSHJ P,.TSPAC## ;SPACE
HRRZ T1,.DTFLG(P1) ;GET STORAGE ADDRESS
PUSHJ P,.TSTRG## ;TYPE DATA
PUSHJ P,.TCRLF## ;CRLF
LOGRE2: ADD P1,[.DTMAX-1,,.DTMAX-1] ;ACCOUNT FOR MULTIPLE WORD ENTRIES
AOBJN P1,LOGRE1 ;LOOP
PJRST LOGEND ;END LOG FILE I/O
SUBTTL System server -- LOGCMD - Log COMMAND
LOGCMD: MOVE T1,[SIXBIT /COMMAN/] ;STAMP
PUSHJ P,LOGBEG ;BEGIN LOG FILE I/O
PUSHJ P,SRVSET ;RESET BYTE POINTER
LOGCM1: PUSHJ P,SRVTAK ;GET A CHARACTER
SKIPN T1,C ;COPY IT
JRST LOGCM2 ;DONE
PUSHJ P,.TCHAR## ;LOG IT
JRST LOGCM1 ;LOOP BACK FOR MORE
LOGCM2: PUSHJ P,.TCRLF## ;CRLF
PJRST LOGEND ;END LOG FILE I/O
SUBTTL User server -- SRVUSR - Initiate server connects
SRVUSR::SKIPL T1,S.SERVER##+.SVFLG ;WAS /SERVER TYPED?
TLNE F,(FL.WHOSRV) ;OR ARE WE A SERVER?
JRST .POPJ1## ;JUST A NORMAL COMMAND
SETOM S.DPY## ;NEVER LOOP IN DPY MODE
SETOM S.REPEAT## ;NEVER LOOP IN REPEAT MODE
MOVE T1,S.SERVER##+.SVNOD ;GET NODE
CAMN T1,[EXP -1] ;OUR GOT ONE?
MOVE T1,CENSTA## ;NO--DEFAULT TO CENTRAL STATION
PUSHJ P,NODINF## ;SEE WHAT TYPE IT IS
$FATAL (NSN,<No such node ">,E.NSN)
MOVEM T1,S.SERVER##+.SVNOD ;UPDATE NODE NAME
TXNN T3,NT.ONL ;IS IT REALLY ONLINE (DECNET)?
$FATAL (NNO,<Node not online ">,E.NSN)
MOVE T3,TSKNET(T3) ;TRANSLATE NETWORK TYPE TO TASK TYPE
SKIPGE T4,S.SERVER##+.SVTYP ;GET CONNECT TYPE
MOVE T4,T3 ;DEFAULT TASK TYPE TO MATCH NODE TYPE
TLNN F,(FL.NETWORKS) ;HAVE NETWORK SUPPORT?
MOVEI T4,.TSIPC ;NO--THEN WE CAN ONLY DO IPCF
CAIN T4,.TSIPC ;IPCF CONNECT?
MOVE T3,T4 ;YES
CAME T3,T4 ;MATCH?
$FATAL (NCM,<Network node type and connect type mismatch>)
MOVEM T4,S.SERVER##+.SVTYP ;SAVE FOR LATER
MOVX T1,TS.ACT ;ACTIVE TASK
STORE T4,T1,TS.TYP ;STORE CONNECT TYPE
MOVE T4,TSKTAB(T4) ;GET DISPATCH VECTOR FOR THIS TASK
SKIPG T2,S.SERVER##+.SVTIM ;GET TIMEOUT IN SECONDS
MOVE T2,.TSTIM(T4) ;DEFAULT IT
STORE T2,T1,TS.TIM ;STORE IT
MOVE T2,S.SERVER##+.SVNOD ;GET TARGET NODE
PUSHJ P,OPNTSK ;OPEN A TASK
$FATAL (TOF,<Task open failed>)
$INFO (CTS,<Connecting to server, >,CONMSG)
PUSHJ P,XMTDAT ;TRANSMIT LOCAL DATA TO REMOTE
JRST SRVU.E ;TASK ERROR
PUSHJ P,SRVSET ;RESET COMMAND BYTE POINTER
SRVU.1: PUSHJ P,SRVTAK ;GET A CHARACTER
MOVE T1,C ;COPY IT
PUSHJ P,TSKTYO ;PUT A CHARACTER
SRVU.E: $FATAL (SOE,<Output error to server>,SRVU.4)
JUMPN T1,SRVU.1 ;LOOP
PUSHJ P,OUTTSK ;FORCE BUFFERS OUT
JRST SRVU.E ;CAN'T
PUSHJ P,RCVDAT ;RECEIVE AND PROCESS REMOTE DATA
SKIPA T1,DATERR ;GET DATA ERROR TYPE
JRST SRVU.2 ;PROTOCOL OK
MOVE T1,DATETB-1(T1) ;POINT TO ASSOCIATED TEXT
$FATAL (TPE,<Task protocol error; >,.TSTRG##)
SRVU.2: PUSHJ P,TYPDAT ;TYPE REMOTE DATA
SRVU.3: PUSHJ P,TSKTYI ;GET A CHARACTER
$FATAL (SIE,<Input error from server>,CLSTSK)
JUMPE T1,SRVU.4 ;DONE?
PUSHJ P,.TCHAR## ;TYPE IT
JRST SRVU.3 ;LOOP
SRVU.4: PUSHJ P,CLSTSK ;CLOSE THE TASK
JFCL ;IGNORE ERRORS
POPJ P, ;RETURN
E.NSN: MOVE T1,S.SERVER##+.SVNOD ;GET NODE NAME
PUSHJ P,.TSIXN## ;TYPE IT
MOVEI T1,"""" ;CLOSING QUOTE
PJRST .TCHAR## ;TYPE IT AND RETURN
SUBTTL Server loop -- SRVLOP - Top level
SRVLOP: MOVE P,[IOWD LN$PDL,PDL##] ;RESET STACK
MOVX T1,HB.IPC!HB.RIO ;WAKE UP BITS
SKIPN T.ATTN ;ANYTHING TO DO?
HIBER T1, ;ZZZZZZ
JFCL ;ERROR?
SRVL.1: MOVE P,[IOWD LN$PDL,PDL##] ;RESET STACK
SKIPN T.ATTN ;ANY ACTIVITY?
JRST SRVLOP ;NO--SPURRIOUS WAKEUP
MOVEI T1,0 ;DON'T KNOW THAT TYPE OF TASK YET
SKIPE DCNATN ;DECNET?
MOVEI T1,DCNTSK ;YES
SKIPE ANFATN ;ANF10?
MOVEI T1,ANFTSK ;YES
SKIPE IPCATN ;IPCF?
MOVEI T1,IPCTSK ;YES
JUMPE T1,SRVL.4 ;HAVE SOMETHING?
MOVEM T1,T.DISP ;SET UP DISPATCH
PUSHJ P,SRVCMD ;SET UP COMMAND BUFFERS
AOS T.SEQN ;BUMP SEQUENCE NUMBER
PUSHJ P,LOGCON ;LOG THE CONNECT
TLZ F,(FL.SRVJOB) ;CLEAR OUT ALL PRIV AND JOB FLAGS
PUSHJ P,PRVTSK ;SET ONLY THOSE WHICH APPLY THIS TASK
PUSHJ P,RCVDAT ;RECEIVE LOCAL DATA FROM REMOTE
JRST SRVL.3 ;TASK ERROR
PUSHJ P,LOGREM ;LOG REMOTE DATA
SRVL.2: PUSHJ P,TSKTYI ;GET A CHARACTER
JRST SRVL.3 ;INPUT ERROR
MOVE C,T1 ;COPY
PUSHJ P,SRVPUT ;PUT A CHARACTER
JUMPN C,SRVL.2 ;LOOP READING FROM REMOTE
PUSHJ P,LOGCMD ;LOG THE COMMAND
PUSHJ P,XMTDAT ;TRANSMIT LOCAL DATA TO REMOTE
JRST SRVL.3 ;TASK ERROR
PUSHJ P,SRVSET ;RESET THE POINTERS
MOVE T1,[LN$IBLK##,,ISBLK##] ;POINT TO .ISCAN BLOCK
PUSHJ P,.ISCAN## ;INITIALIZE COMMAND SCANNER
MOVEI T1,CHRLST## ;POINT TO SCAN'S CHARACTER LISTER
MOVEM T1,.TOUTZ## ;STORE
PUSHJ P,CMDLOP## ;PROCESS A COMMAND
JFCL ;SHOULDN'T HAPPEN
SRVXIT::!
SRVL.3: SKIPN T.DISP ;TASK ACTIVE?
JRST SRVL.4 ;NO
PUSHJ P,OUTTSK ;FORCE OUTPUT
JFCL ;IGNORE ERRORS
PUSHJ P,LOGDSC ;LOG THE DISCONNECT
PUSHJ P,CLSLST## ;CLOSE THE LOG FILE
PUSH P,T.DISP ;SAVE OLD DISPATCH
PUSHJ P,CLSTSK ;CLOSE TASK
JFCL ;IGNORE ERRORS
POP P,T.DISP ;RESTORE DISPATCH
DMOVE T1,T.OARG ;GET SAVED OPEN ARGUMENTS
PUSHJ P,OPNTSK ;RE-OPEN THE TASK
HALT .
SRVL.4: SOS T.ATTN ;COUNT DOWN
JRST SRVL.1 ;LOOP BACK FOR MORE
SUBTTL Server loop -- GMSG - Get an IPCF message
GMSG: SETZM PDB+.IPCFL ;FLAGS
SETZM PDB+.IPCFS ;SENDER
SETZM PDB+.IPCFR ;RECEIVER
MOVE T1,[12,,BUFFER] ;BUFFER
MOVEM T1,PDB+.IPCFP ;STORE
MOVE T1,[6,,PDB] ;POINT TO PDB
IPCFR. T1, ;GET SOMETHING
JRST GMSG.1 ;NOPE
MOVE T1,PDB+.IPCFS ;GET SENDER
MOVEM T1,SPID ;SAVE FOR LATER
LOAD T1,PDB+.IPCFC,IP.SJN ;GET SENDERS JOB
MOVEM T1,MYJOB## ;AND AS MYJOB
MOVE T1,[POINT 7,BUFFER+2] ;POINT TO DATA
POPJ P, ;AND RETURN
; The IPCF receive shouldn't have failed. Since it's ugly to
; HALT, we'll sleep a little and try it again. If we're in a
; loop, this will give others a chance to run.
GMSG.1: MOVEI T1,^D10 ;10 SECONDS
SLEEP T1, ;ZZZZZZ
JRST GMSG ;TRY AGAIN
SUBTTL Server loop -- SMSG - Send an IPCF message
SMSG: MOVEI T1,0 ;TERMINATE
IDPB T1,TXTPTR ;STORE
MOVX T1,IP.CFV ;WE SEND PAGES
MOVEM T1,PDB+.IPCFL ;SET FLAGS
MOVE T1,SPID ;GET SENDERS PID
MOVEM T1,PDB+.IPCFR ;NOW HE WILL RECEIVE IT
SETZM PDB+.IPCFS ;ZERO SENDER
MOVE T1,TXTPAG ;GET THE PAGE
HRLI T1,1000 ;ITS LENGTH
MOVEM T1,PDB+.IPCFP ;STORE
MOVE T1,[4,,PDB] ;POINT TO PDB
IPCFS. T1, ;SEND IT
JFCL
POPJ P, ;AND RETURN
SUBTTL Buffer control -- SRVCMD/SRVSET - Initialize character storage
; Init command buffer after call to .ISCAN in WHO
SRVINI::LDB T1,CMDPTR ;GET LAST SCANNED CHARACTER
PUSH P,T1 ;SAVE IT
PUSHJ P,SRVCMD ;RESET COMMAND BUFFER
POP P,T1 ;RESTORE CHARACTER
JUMPLE T1,.POPJ## ;RETURN ON EOL OR EOF
CAIE T1,.CHESC ;ESCAPE?
CAIN T1,.CHLFD ;LINE-FEED?
POPJ P, ;YES
CAIN T1,"(" ;OR MAYBE .R WHO(FOO)?
POPJ P, ;YES TO EITHER
MOVE C,T1 ;COPY CHARACTER
PJRST SRVPUT ;STORE IT AND RETURN
; Set up command buffer
SRVCMD::MOVE T1,[CMDTAB,,CMDTAB+1] ;SET UP BLT
SETZM CMDTAB ;CLEAR FIRST WORD
BLT T1,CMDTAB+LN$SBT-1 ;CLEAR BUFFER TABLE
MOVE T1,[CMDBUF,,CMDBUF+1] ;SET UP BLT
SETZM CMDBUF ;CLEAR FIRST WORD
BLT T1,CMDBUF+LN$SCB-1 ;CLEAR OUT INTERNAL COMMAND BUFFER
; Here to just reset the pointers
SRVSET::SETOM CMDIDX ;SET BUFFER TABLE INDEX
MOVEI T1,CMDBUF ;POINT TO INTERNAL BUFFER
MOVEM T1,CMDTAB ;MAKE IT THE FIRST BUFFER TO USE
HRLI T1,(POINT 7,) ;BYTE POINTER TO BUFFER
MOVEM T1,CMDPTR ;SAVE IT
MOVEI T1,<LN$SCB*5>-1 ;GET LENGTH OF BUFFER IN CHARACTERS
MOVEM T1,CMDCTR ;SAVE COUNT
POPJ P, ;RETURN
; Output a character
SRVTYO::PUSHJ P,TSKTYO ;OUTPUT TO TASK
JFCL ;CATCH ERRORS ELSEWHERE??
POPJ P, ;RETURN
SUBTTL Buffer control -- ADVBUF - Advance buffers
; Call: PUSHJ P,ADVBUF
; <NON-SKIP> ;OVERFLOW
; <SKIP> ;BUFFERS ADVANCED
;
ADVBUF: PUSHJ P,.SAVE1## ;SAVE P1
PUSH P,T1 ;SAVE T1 AND SCAN FROM DESTRUCTION
AOS P1,CMDIDX ;GET TABLE INDEX
CAIL P1,LN$SBT ;HAVE ROOM FOR ANOTHER BUFFER?
JRST ADVBU2 ;NO--ERROR
ADDI P1,CMDTAB ;INDEX INTO THE TABLE
SKIPE T1,(P1) ;GET PAGE ADDRESS (IF ANY)
JRST ADVBU1 ;THERE ISN'T ONE
PUSHJ P,M$GPAG## ;GET A PAGE
JRST ADVBU2 ;LOSE
MOVEM T1,(P1) ;SAVE PAGE ADDRESS
ADVBU1: HRLI T1,(POINT 7,) ;MAKE A BYTE POINTER
MOVEM T1,CMDPTR ;SAVE IT
MOVEI T1,<1000*5>-1 ;BYTE COUNT
MOVEM T1,CMDCTR ;SAVE IT
AOS -1(P) ;SKIP
ADVBU2: POP P,T1 ;RESTORE T1
POPJ P, ;RETURN
SUBTTL Buffer control -- SRVPUT/SRVTAK - Character putter & taker
; Put a character in the command buffer
SRVPUT::SOSGE CMDCTR ;COUNT CHARACTERS
JRST SRVPU1 ;BUFFER FULL
IDPB C,CMDPTR ;STORE CHARACTER
POPJ P, ;RETURN
SRVPU1: PUSHJ P,ADVBUF ;ADVANCE BUFFER
$FATAL (SCO,<Server command buffer overflow>)
JRST SRVPUT ;GO BACK AND STORE CHARACTER
; Take a character from the command buffer
SRVTAK::SOSGE CMDCTR ;COUNT CHRACTERS
JRST SRVTA1 ;BUFFER EMPTY
ILDB C,CMDPTR ;GET A CHARACTER
POPJ P, ;RETURN
SRVTA1: PUSHJ P,ADVBUF ;ADVANCE BUFFERS
$STOP (NNB,<No next server buffer>)
JRST SRVTAK ;GO BACK AND GET A CHARACTER
SUBTTL Task service -- Dispatch vectors
; Table of dispatch vector addresses (indexed by task type)
TSKTAB: EXP IPCTSK, ANFTSK, DCNTSK
; Network to task type translation table (indexed by network type)
TSKNET: EXP .TSIPC, .TSANF, .TSDCN
; Dispatch vectors
; Name Prefix Type Network Timeout Feature
TASK IPCF, IPC, .TSIPC, .NTNON, 15, -1
TASK ANF10, ANF, .TSANF, .NTANF, 30, FL.ANF10
TASK DECnet, DCN, .TSDCN, .NTDCN, 60, FL.DECNET
SUBTTL Task service -- I/O operations
OPNTSK: PUSHJ P,.SAVE2## ;SAVE P1 AND P2
DMOVE P1,T1 ;COPY FLAGS AND NODE NAME
DMOVEM P1,T.OARG ;SAVE FOR POSTERITY
LOAD T1,P1,TS.TIM ;GET TIMEOUT
MOVEM T1,T.TIME ;SAVE IT
LOAD T1,P1,TS.TYP ;GET TYPE OF TASK
HRRZ T2,TSKTAB(T1) ;GET DISPATCH TABLE
MOVEM T2,T.DISP ;SAVE IT
SKIPA T1,[.TSOPN] ;OPEN OFFSET
CLSTSK: MOVEI T1,.TSCLS ;CLOSE OFFSET
PJRST TSKIO ;ENTER COMMON CODE
INPTSK: SKIPA T1,[.TSINP] ;OFFSET TO INPUT
OUTTSK: MOVEI T1,.TSOUT ;OFFSET TO OUTPUT
JRST TSKIO ;ENTER COMMON CODE
PRVTSK: MOVEI T1,.TSPRV ;OFFSET TO PRIV CODE
TSKIO: PUSH P,T.TIME ;GET COUNT DOWN TIMER
POP P,T.WAIT ;SET IT UP
ADD T1,T.DISP ;INDEX INTO TABLE
PUSHJ P,@(T1) ;DO I/O
POPJ P, ;PROPAGATE ERROR BACK
JRST .POPJ1## ;RETURN
SUBTTL Task service -- Common routines
; Set up PSI vector
; Call: MOVE T1, vector offset
; MOVE T2, interrupt address
; PUSHJ P,TSKVEC
;
TSKVEC: ADDI T1,VECTOR## ;OFFSET INTO VECTOR BLOCKS
MOVEM T2,.PSVNP(T1) ;SAVE NEW PC
SETZM .PSVOP(T1) ;CLEAR OLD PC
MOVX T2,PS.VPO ;DISABLE ALL INTERRUPTS
MOVEM T2,.PSVFL(T1) ;SAVE FLAGS
SETZM .PSVIS(T1) ;CLEAR INTERRUPT STATUS
POPJ P, ;RETURN
; Turn on or off interrupts
TSKPSI: PISYS. T1, ;
$STOP (PSI,<Can't turn on/off PSI; PISYS. error >,.TOCTW##)
POPJ P, ;RETURN
; Dismiss interrupts
TSKJEN: DEBRK. ;DISMISS AND RE-ENABLE PSI
JFCL ;UUO NOT INPLEMENTED??
POPJ P, ;HOPE WE GOT HERE VIA A PUSHJ
; Task wait
TSKWAI: SOSGE T.WAIT ;WAIT TIME EXPIRED?
POPJ P, ;YES
MOVEI T1,1 ;ONE SECOND
SLEEP T1, ;ZZZZZZ
JRST .POPJ1## ;RETURN
SUBTTL Task service -- TSKTYI - Character input
; Input a character
TSKTYI: MOVE T1,T.DISP ;GET DISPATCH
MOVE T1,.TSIBR(T1) ;POINT TO INPUT BUFFER RING HEADER
SOSGE .BFCTR(T1) ;COUNT CHARACTERS
JRST TSKTI1 ;BUFFER EMPTY
ILDB T1,.BFPTR(T1) ;GET A CHARACTER
JRST .POPJ1## ;RETURN
TSKTI1: PUSHJ P,INPTSK ;INPUT A BUFFER
SKIPA T1,T.IOST ;INPUT ERROR--GET I/O STATUS
JRST TSKTYI ;GO BACK AND GET A CHARACTER
TXNN T1,IO.EOF ;EOF?
POPJ P, ;NO--A REAL ERROR
MOVEI T1,.CHNUL ;GET A NUL TO TERMINATE I/O
JRST .POPJ1## ;AND RETURN
SUBTTL Task service -- TSKTYO - Character output
; Output a character
TSKTYO::MOVEM T1,T.CHAR ;SAVE CHARACTER
TSKTO1: MOVE T1,T.DISP ;GET DISPATCH
MOVE T1,.TSOBR(T1) ;POINT TO OUTPUT BUFFER RING HEADER
SOSGE .BFCTR(T1) ;COUNT CHARACTERS
JRST TSKTO2 ;BUFFER FULL
MOVEI T1,.BFPTR(T1) ;GET BYTE POINTER ADDRESS
EXCH T1,T.CHAR ;SWAP WITH SAVED CHARACTER
IDPB T1,@T.CHAR ;PUT A CHARACTER
JRST .POPJ1## ;RETURN
TSKTO2: PUSHJ P,OUTTSK ;OUTPUT A BUFFER
POPJ P, ;OUTPUT ERROR
JRST TSKTO1 ;GO BACK AND STORE CHARACTER
SUBTTL Task service -- IPCF
; Turn interrupts on or off
IPCON: SKIPA T1,[PS.FON!PS.FAC+IPCPSI] ;TURN ON
IPCOFF: MOVE T1,[PS.FOF!PS.FRC+IPCPSI] ;TURN OFF
JRST TSKPSI ;GO TURN ON OR OFF CONDITION
IPCPSI: EXP .PCIPC ;IPCF
XWD .IVIPC,0 ;OFFSET,,REASONS
XWD 0,0 ;PRIORITY 0,,RESERVED
; Here on an interrupt
IPCINT::HALT .
JRST TSKJEN ;DISMISS INTERRUPT
; Open an IPCF task. This routine will become [SYSTEM]WHOSRV
; if passive requested. If active requested, then the PID of
; [SYSTEM]WHOSRV will be found.
;
IPCOPN: MOVE T1,[I.SRV,,I.SRV+1] ;SET UP BLT
SETZM I.SRV ;CLEAR FIRST WORD
BLT T1,I.SRV+11 ;CLEAR OUT BLOCK
TXNE P1,TS.ACT ;WHAT MODE?
SKIPA T1,['WHO',,.IPCIW] ;ACTIVE
MOVE T1,['WHO',,.IPCII] ;PASSIVE
MOVEM T1,I.SRV+0 ;SAVE IT
SETZM I.SRV+1 ;NO PID FOR COPY
IPCOP1: MOVEI T1,[IDPB T1,I.PTR
POPJ P,] ;CHARACTER TYPER
PUSHJ P,.TYOCH## ;TELL SCAN
PUSH P,T1 ;SAVE OLD TYPER
MOVE T1,[POINT 7,I.SRV+2] ;WHERE TO PUT THE NAME
MOVEM T1,I.PTR ;SAVE IT
MOVE T1,.MYPPN## ;GET OUR PPN
TXNE P1,TS.ACT ;ACTIVE?
JRST IPCOP2 ;YES--SKIP AROUND LISTENER STUFF
CAMN T1,OPRPPN## ;YES--ARE WE THE OPERATOR?
MOVE T1,['SYSTEM'] ;THEN MAKE IT [SYSTEM]WHOSRV
IPCOP2: PUSHJ P,.TPPNW## ;TYPE PPN WORD
MOVE T1,['WHOSRV'] ;GET SERVER NAME
PUSHJ P,.TSIXN## ;TYPE IT
POP P,T1 ;RESTORE TYPER
PUSHJ P,.TYOCH## ;TELL SCAN
SETZM I.PDB+.IPCFL ;NO FLAGS
SETZM I.PDB+.IPCFS ;TO SYSINF
SETZM I.PDB+.IPCFR ;NO RECIEVER
MOVE T1,[12,,I.SRV] ;LENGTH,,PACKET ADDRESS
MOVEM T1,I.PDB+.IPCFP ;STORE
IPCOP3: MOVE T1,[4,,I.PDB] ;POINT TO MESSAGE
IPCFS. T1, ;SEND IT
$FATAL (STS,<Send to [SYSTEM]INFO failed>)
MOVE T1,[12,,I.PKT] ;POINT TO BUFFER
PUSHJ P,IPCRCV ;RECEIVE A PACKET
$FATAL (RFS,<Receive from [SYSTEM]INFO failed>)
HLRZ T1,I.PKT ;GET ACK CODE
CAIE T1,'WHO' ;OURS?
JRST IPCOP3 ;NO--TRY AGAIN
MOVE T1,I.PKT+1 ;GET RETURNED PID
MOVEM T1,I.PID ;SAVE IT
AOS IPCFLG ;TASK INITIALIZED
JRST .POPJ1## ;RETURN
; Close an IPCF task
IPCCLS: SETZM IPCFLG ;TASK DONE
SETZM T.DISP ;CLEAR DISPATCH
JRST .POPJ1## ;RETURN
; Input from an IPCF task (IPCF receive)
IPCINP: HALT .
; Output to an IPCF task (IPCF send)
IPCOUT: HALT .
; Send an IPCF packet
; Call: MOVE T1,[LEN,,ADDR]
; PUSHJ P,IPCSND
; <ERROR>
; <NORMAL>
;
IPCSND: PUSHJ P,.SAVE1## ;SAVE P1
SKIPA P1,T1 ;SAVE USERS ADDRESS INCASE OF ERROR
IPCSE1: MOVE T1,P1 ;GET USERS ADDRESS
IPCFS. T1, ;SEND IT
SKIPA ;FAILED
JRST .POPJ1## ;RETURN
CAIE T1,IPCRS% ;SENDERS QUOTA EXCEEDED?
CAIN T1,IPCRR% ;OR RECIEVERS?
JRST IPCSE2 ;YES--TRY TO RESEND
CAIE T1,IPCRY% ;FREE SPACE EXHAUSTED?
POPJ P, ;NO--RETURN ERROR TO USER
IPCSE2: PUSHJ P,TSKWAI ;ZZZZZZ
POPJ P, ;TIMED OUT
JRST IPCSE1 ;AND TRY AGAIN
; Receive an IPCF packet
; Call: MOVE T1,[length,,address]
; PUSHJ P,IPCRCV
; <ERROR>
; <NORMAL>
;
IPCRCV: PUSHJ P,.SAVE1## ;SAVE P1
MOVE P1,T1 ;COPY POINTER
MOVEM T1,I.PDB+.IPCFP ;SAVE LENGTH AND ADDRESS
HLRZS T1 ;GET LENGTH
CAIE T1,1000 ;A PAGE?
TDZA T1,T1 ;NO
MOVX T1,IP.CFV ;ASSUME PAGE
MOVEM T1,I.PDB+.IPCFL ;SAVE
SETZM I.PDB+.IPCFS ;CLEAR PIDS
SETZM I.PDB+.IPCFR ;..
SETZM I.PDB+.IPCFU ;CLEAR PPN
SETZM I.PDB+.IPCFC ;CLEAR CAPABILITY WORD
MOVE T1,[4,,I.PDB] ;POINT TO PDB
IPCFR. T1, ;RECEIVE
POPJ P, ;FAILED
MOVE T1,P1 ;RESTORE POINTER
JRST .POPJ1## ;RETURN
; Set/clear privs and job information
IPCPRV: IOR F,SRVFLG ;RESET OUR JOB'S FLAGS
POPJ P, ;RETURN
SUBTTL Task service -- ANF10
; Turn interrupts on or off
ANFON: SKIPA T1,[PS.FON!PS.FAC+ANFPSI] ;TURN ON
ANFOFF: MOVE T1,[PS.FOF!PS.FRC+ANFPSI] ;TURN OFF
JRST TSKPSI ;GO TURN ON OR OFF CONDITION
ANFPSI: EXP TSK ;ANF10 I/O CHANNEL
XWD .IVANF,PS.RID!PS.ROD ;OFFSET,,REASONS
XWD 0,0 ;PRIORITY 0,,RESERVED
; Here on an interrupt
ANFINT::AOS ANFATN ;REMEMBER THE INTERRUPT
AOS T.ATTN ;HERE TOO
JRST TSKJEN ;DISMISS INTERRUPT
; Open an ANF10 task channel
ANFOPN: TLNN F,(FL.ANF10) ;HAVE ANF10 SUPPORT?
POPJ P, ;NO
MOVE T1,[UU.PHS!UU.AIO+.IOASC] ;PHYSICAL ASYNC I/O IN ASCII MODE
MOVEM T1,ANFOBK+.OPMOD ;SAVE MODE WORD
MOVSI T1,'TSK' ;DEVICE
MOVEM T1,ANFOBK+.OPDEV ;SAVE IT
MOVE T1,[ANFOBR,,ANFIBR] ;BUFFER RING HEADERS
MOVEM T1,ANFOBK+.OPBUF ;SAVE ADDRESSES
SKIPN T1,P2 ;GET NODE NAME
JRST ANFOP1 ;THERE ISN'T ONE
PUSHJ P,ANODE## ;TRANSLATE TO NODE NUMBER
POPJ P, ;NO SUCH NODE
TRNN T1,777700 ;MUST
LSH T1,3 ; LEFT
TRNN T1,777700 ; JUSTIFY
LSH T1,3 ; IN RH WORD
PUSHJ P,OCTSIX## ;CONVERT OCTAL TO SIXBIT
MOVE T1,P2 ;HMMM. MUSTA BEEN OCTAL
HRRM T1,ANFOBK+.OPDEV ;STORE RH OF DEVICE NAME
ANFOP1: OPEN TSK,ANFOBK ;OPEN A TSK CHANNEL
POPJ P, ;CAN'T
SKIPE T1,ANFBFS ;ALREADY HAVE BUFFERS ALLOCATED?
JRST ANFOP2 ;YES
MOVEI T1,ANFOBK ;POINT TO OPEN BLOCK
DEVSIZ T1, ;FIND DEVICE SIZE
MOVE T1,[2,,103] ;ASSUME 2 TSK BUFFERS
HLRZ T2,T1 ;GET NUMBER OF BUFFERS
IMULI T1,(T2) ;COMPUTE SIZE
PUSHJ P,M$ALLOC## ;ALLOCATE CORE
MOVEM T1,ANFBFS ;SAVE ADDRESS OF BUFFERS
ANFOP2: EXCH T1,.JBFF ;SAVE .JBFF, POINT MONITOR AT BUFFERS
OUTBUF TSK,1 ;BUILD OUTPUT BUFFERS
INBUF TSK,1 ;BUILD INPUT BUFFERS
MOVEM T1,.JBFF ;RESTORE .JBFF
ANFOP3: MOVE T1,['WHOSRV'] ;TASK NAME
MOVEM T1,ANFLEB+0 ;SAVE IT
SETZM ANFLEB+1 ;NO EXTENSION
SETZM ANFLEB+2 ;CLEAR JUNK HERE
SETZB T1,ANFLEB+3 ;ASSUME ACTIVE (WE'LL TALK TO ANYONE)
TXNE P1,TS.ACT ;ACTIVE?
JRST ANFOP4 ;YES--SKIP AROUND LISTENER STUFF
MOVE T1,.MYPPN## ;GET OUR PPN
CAMN T1,OPRPPN## ;ARE WE THE OPERATOR?
MOVNI T1,1 ;ACCEPT CONNECTS FROM [*,*]
ANFOP4: MOVEM T1,ANFLEB+3 ;SET PPN WORD
TXNE P1,TS.ACT ;WHAT MODE?
SKIPA T1,[ENTER TSK,ANFLEB] ;ACTIVE
MOVE T1,[LOOKUP TSK,ANFLEB] ;PASSIVE
XCT T1 ;DO ENTER OR LOOKUP
POPJ P, ;CAN'T
TXNE P1,TS.ACT ;ACTIVE?
JRST ANFOP5 ;YES--FINISH UP
MOVEI T1,.IVANF ;ANF10 VECTOR OFFSET
MOVEI T2,ANFINT ;ANF10 INTERRUPT ADDRESS
PUSHJ P,TSKVEC ;SET UP VECTOR
PUSHJ P,ANFON ;PASSIVE NEEDS PSI TURNED ON
PUSHJ P,ANFINP ;PRIME THE PUMP
JFCL ;NOT REALLY A FAILURE
ANFOP5: AOS ANFFLG ;TASK INITIALIZED
JRST .POPJ1## ;RETURN
; Close an ANF10 task channel
ANFCLS: PUSHJ P,ANFOFF ;TURN OFF PSI
CLOSE TSK, ;CLOSE
RELEAS TSK, ;RELEASE CHANNEL
SETZM ANFATN ;CLEAR ATTENTION FLAG
SETZM ANFFLG ;TASK DONE
SETZM T.DISP ;CLEAR DISPATCH ADDRESS
JRST .POPJ1## ;RETURN
; Input from an ANF10 task
ANFINP: IN TSK, ;READ A BUFFER
JRST .POPJ1## ;RETURN SUCESSFUL
GETSTS TSK,T1 ;GET CHANNEL STATUS
MOVEM T1,T.IOST ;UPDATE I/O STATUS
TXNN T1,IO.ERR!IO.EOF ;ANY ERRORS OR EOF?
PUSHJ P,TSKWAI ;NO--WAIT A SECOND
POPJ P, ;INPUT ERRORS OR TIMED OUT
JRST ANFINP ;TRY THE READ AGAIN
; Output to an ANF10 task
ANFOUT: OUT TSK, ;WRITE A BUFFER
JRST .POPJ1## ;RETURN SUCESSFUL
GETSTS TSK,T1 ;GET CHANNEL STATUS
TXNN T1,IO.ERR ;ANY ERRORS?
PUSHJ P,TSKWAI ;NO--WAIT A SECOND
POPJ P, ;OUTPUT ERRORS OR TIMED OUT
JRST ANFOUT ;TRY THE READ AGAIN
; Set/clear privs and job information
ANFPRV: MOVSI T1,(FL.SPY) ;GET PRIVS
HRR T1,SRVFLG ;GET RANDOM INTERNAL BITS
AND T1,SRVFLG ;BUT ONLY IF WE HAVE THEM TO BEGIN WITH
TDO F,T1 ;SET FLAGS
POPJ P, ;RETURN
SUBTTL Task service -- DECnet
; Turn interrupts on or off
DCNON: SKIPA T1,[PS.FON!PS.FAC+DCNPSI] ;TURN ON
DCNOFF: MOVE T1,[PS.FOF!PS.FRC+DCNPSI] ;TURN OFF
JRST TSKPSI ;GO TURN ON OR OFF CONDITION
DCNPSI: EXP .PCNSP ;DECNET I/O
XWD .IVDCN,0 ;OFFSET,,REASONS
XWD 0,0 ;PRIORITY 0,,RESERVED
; Here on an interrupt
DCNINT::HALT .
JRST TSKJEN ;DISMISS INTERRUPT
; Open a DECnet task
DCNOPN: TLNN F,(FL.DECNET) ;HAVE DECNET?
POPJ P, ;NO
AOS DCNFLG ;TASK INITIALIZED
HALT .
; Close a DECnet task
DCNCLS: SETZM DCNFLG ;TASK DONE
JRST .POPJ1## ;RETURN
DCNINP: HALT .
DCNOUT: HALT .
; Set/clear privs and job information
DCNPRV: IOR F,SRVFLG ;RESET OUR JOB'S FLAGS
POPJ P, ;RETURN
SUBTTL Message generation -- Connect
CONMSG: MOVEI T1,[ASCIZ |Type:|] ;FIRST THE TYPE
PUSHJ P,.TSTRG## ;TYPE TEXT
MOVE T1,T.DISP ;GET DISPATCH ADDRESS
MOVE T1,.TSNAM(T1) ;POINT TO TASK NAME
PUSHJ P,.TSTRG## ;TYPE IT
MOVEI T1,[ASCIZ | Node:|] ;NEXT THE NODE NAME
PUSHJ P,.TSTRG## ;TYPE TEXT
MOVE T1,T.OARG+1 ;GET NODE NAME
PUSHJ P,.TSIXN## ;TYPE IT
MOVEI T1,[ASCIZ | Timeout:|] ;FINALLY THE TIMEOUT
PUSHJ P,.TSTRG## ;TYPE TEXT
MOVE T1,T.TIME ;GET TIMEOUT VALUE
PJRST .TDECW## ;TYPE SECONDS AND RETURN
CONTYP: ASCIZ |WHO server connect|
CONLEN==.-CONTYP ;LENGTH OF CONNECT "TYPE" TEXT
SUBTTL Message generation -- Error
ERRMSG: POPJ P,
ERRTYP: ASCIZ |WHO server error|
ERRLEN==.-ERRTYP ;LENGTH OF ERROR "TYPE" TEXT
SUBTTL Message generation -- Disconnect
DISMSG: POPJ P,
DISTYP: ASCIZ |WHO server disconnect|
DISLEN==.-DISTYP ;LENGTH OF DISCONNECT "TYPE" TEXT
SUBTTL Message generation -- Miscellaneous routines
; Init buffer
MSGINI: MOVEI T1,<LN$SMB*5>-1 ;GET CHARACTER COUNT
MOVEM T1,MSGCTR ;SAVE IT
MOVE T1,[POINT 7,MSGBUF] ;GET BYTE POINTER
MOVEM T1,MSGPTR ;SAVE IT
MOVE T1,[MSGBUF,,MSGBUF+1] ;SET UP BLT
SETZM MSGBUF ;CLEAR FIRST WORD
BLT T1,MSGBUF+LN$SMB-1 ;CLEAR ENTIRE BUFFER
MOVEI T1,MSGTYO ;GET CHARACTER TYPER
PUSHJ P,.TYOCH## ;TELL SCAN
MOVEM T1,MSGTYP ;SAVE OLD TYPER
POPJ P, ;RETURN
; Character typer
MSGTYO: SOSLE MSGCTR ;COUNT DOWN
IDPB T1,MSGPTR ;STORE CHARACTER
POPJ P, ;RETURN
; Exit
MSGXIT: MOVE T1,MSGTYP ;GET OLD TYPER
PUSHJ P,.TYOCH## ;RESET SCAN
POPJ P, ;RETURN
SUBTTL Protocol -- Data definitions
; Data table (DATTAB) entry offsets
.DTNAM==0 ;SIXBIT NAME,,ASCIZ TEXT
.DTFLG==1 ;LENGTH AND STORAGE ADDRESS
DT.CRL==1B0 ;CRLF PREFIXES TEXT
DT.NTY==1B1 ;DATA ITEM NOT TYPED OUT
DT.FLG==777B8 ;MASK OF ALL FLAGS
DT.LEN==777B17 ;MASK OF BUFFER LENGTH IN CHARACTERS
.DTIOS==2 ;READ,,WRITE I/O SUBROUTINES
.DTMAX==3 ;LENGTH OF ENTRY
DEFINE $DATA,<
X (DTM,025,<Packet transmitted at >,<DT.CRL>)
X (USR,039,<User >,<DT.CRL>)
X (PGM,048,< running >,<0>)
X (SEQ,006,< in sequence >,<0>)
X (SYS,073,<System is >,<DT.CRL>)
X (IPC,044,<IPCF process-ID >,<DT.CRL>)
X (ANF,034,<ANF10 node/task >,<DT.CRL>)
X (DCN,015,<DECnet node/task >,<DT.CRL>)
X (MOD,006,<Mode>,<DT.NTY>)
X (END,050,<Comment>,<0>)
> ;END $DATA MACRO
DEFINE X (NAM,LEN,TXT,FLG),<
XWD ''NAM'',[ASCIZ |TXT|]
EXP FLG+<XWD ^D<LEN>,NAM'BUF>
XWD RED'NAM,WRT'NAM
>
DATTAB: $DATA
DATLEN==.-DATTAB
DATETB: [ASCIZ |I/O error|]
[ASCIZ |Format error|]
; Write DTM
WRTDTM: PUSHJ P,XB$UDT## ;GET DATE/TIME
PJRST .TDTTM## ;TYPE IT AND RETURN
; Read DTM
REDDTM: POPJ P,
; Write PGM
WRTPGM: HRROI T1,.GTPRG ;WANT OUR PROGRAM NAME
PUSHJ P,GTAB## ;GET IT
PUSHJ P,.TSIXN## ;SEND IT OUT
MOVEI T1,[ASCIZ | %|] ;TYPE
PUSHJ P,.TSTRG## ; SEPARATOR
MOVE T1,.JBVER ;GET OUR VERSION
PUSHJ P,.TVERW## ;TYPE IT
SKIPN .JBCST ;HAVE A CUSTOMER VERSION?
POPJ P, ;NO
MOVEI T1,"/" ;GET A SLASH
PUSHJ P,.TCHAR## ;TYPE IT
MOVE T1,.JBCST ;GET CUSTOMER VERSION
PJRST .TVERW## ;TYPE IT AND RETURN
; Read PGM
REDPGM: POPJ P,
; Write USR
WRTUSR: HRROI T1,.GTNM1 ;USER NAME (WORD 1)
PUSHJ P,GTAB## ;GET IT
PUSH P,T1 ;SAVE FOR LATER
HRROI T1,.GTNM2 ;USER NAME (WORD 2)
PUSHJ P,GTAB## ;GET IT
JUMPE T1,WRTUS1 ;2 WORD?
EXCH T1,(P) ;YES--SWAP
MOVEI T3,6 ;SIX CHARACTERS
PUSHJ P,.TSIXJ## ;TYPE IT
WRTUS1: POP P,T1 ;GET NAME
PUSHJ P,.TSIXN ;OUTPUT
PUSHJ P,.TSPAC## ;SPACE OVER
MOVE T1,.MYPPN## ;GET OUR PPN
PJRST .TPPNW## ;TYPE IT AND RETURN
; Read USR
REDUSR: POPJ P,
; Write IPC
WRTIPC: POPJ P,
; Read IPC
REDIPC: POPJ P,
; Write ANF
WRTANF: TLNN F,(FL.ANF10) ;HAVE ANF10 SUPPORT?
POPJ P, ;NO
MOVE T1,CENSTA## ;GET OUR NODE NUMBER
PUSHJ P,ANODE## ;CONVERT TO NODE NAME
MOVE T1,[SIXBIT/??????/] ;HMMM
PUSHJ P,.TSIXN## ;TYPE IT
PUSHJ P,.TLPRN## ;TYPE "("
MOVE T1,CENSTA## ;GET NODE NUMBER AGAIN
PUSHJ P,.TOCTW## ;TYPE IT
PUSHJ P,.TRPRN## ;TYPE ")"
PUSHJ P,.TSPAC## ;SPACE
MOVE T1,['WHOSRV'] ;TASK NAME
PUSHJ P,.TSIXN## ;TYPE IT
MOVE T1,.MYPPN## ;GET PPN
PJRST .TPPNW## ;TYPE IT AND RETURN
; Read ANF
REDANF: POPJ P,
; Write DCN
WRTDCN: POPJ P,
; Read DCN
REDDCN: POPJ P,
; Write SYS
WRTSYS: MOVEI T1,[ASCIZ |TOPS-10 %|] ;TYPE
PUSHJ P,.TSTRG## ; INTRODUCTION
PUSHJ P,XB$DVN## ;GET DEC VERSION NUMBER
PUSHJ P,.TVERW## ;TYPE IT
PUSHJ P,XB$CVN## ;GET CUSTOMER VERSION
JUMPE T1,WRTSY1 ;HAVE ONE?
PUSH P,T1 ;YES--SAVE IT
MOVEI T1,"/" ;GET SLASH
PUSHJ P,.TCHAR## ;TYPE IT
POP P,T1 ;GET BACK CUSTOMER VERSION
PUSHJ P,.TVERW## ;TYPE IT
WRTSY1: MOVEI T1,[ASCIZ |, |] ;TYPE
PUSHJ P,.TSTRG## ; SEPARATOR
PUSHJ P,XB$NAM## ;GET MONITOR NAME
PJRST .TSTRG## ;TYPE IT AND RETURN
; Read SYS
REDSYS: POPJ P,
; Write SEQ
WRTSEQ: MOVE T1,T.SEQN ;GET SEQUENCE NUMBER
PJRST .TDECW## ;TYPE IT AND RETURN
; Read SEQ
REDSEQ: POPJ P,
; Write MOD
WRTMOD: MOVE T1,MON.T##(M) ;GET THE MODE NAME
PJRST .TSIXN## ;TYPE IT AND RETURN
; Read MOD
REDMOD: SETZ T1, ;CLEAR DESTINATION
MOVE T3,[POINT 7,MODBUF] ;POINT TO MOD STORAGE
MOVE T4,[POINT 6,T1] ;POINT TO MOD CONVERSION STORAGE
REDMO1: ILDB T2,T3 ;GET A CARACTER
JUMPE T2,REDMO2 ;DONE?
SUBI T2,40 ;CONVERT TO SIXBIT
TRNN T1,77 ;WORD FULL?
IDPB T2,T4 ;STORE CHARACTER
JRST REDMO1 ;LOOP
REDMO2: MOVE N,T1 ;GET MODE KEYWORD
MOVE T1,[IOWD MON.L##,MON.T##] ;POINT TO COMMAND TABLE
PUSHJ P,.NAME## ;LOOKUP NAME
TDZA T1,T1 ;DON'T KNOW THIS ONE
SUBI T1,MON.T## ;INDEX INTO TABLE
ANDI T1,-1 ;NO JUNK
PJRST SETMOD## ;SET UP AC 'M' WITH MODE INDEX
; Write END
WRTEND: POPJ P, ;NO "END" COMMENTS
; Read END
REDEND: POPJ P,
SUBTTL Protocol -- XMTDAT - Transmit local data to remote
XMTDAT: PUSHJ P,.SAVE1## ;SAVE P1
TRO F,FR.TASK ;FLAG TASK I/O
MOVEI T1,CHRLST## ;POINT TO CHARACTER TYPER
PUSHJ P,.TYOCH## ;TELL SCAN
PUSH P,T1 ;SAVE OLD TYPER
MOVE P1,[-DATLEN,,DATTAB] ;AOBJN POINTER TO TABLE
XMTD.1: PUSHJ P,.TDOT## ;SEND OUT A PERIOD TO START LINE
HLLZ T1,.DTNAM(P1) ;GET DATA ITEM NAME
PUSHJ P,.TSIXN## ;SEND TO REMOTE
PUSHJ P,.TSPAC## ;FOLLOW BY A SPACE
HRRZ T1,.DTIOS(P1) ;GET ROUTINE TO WRITE
PUSHJ P,(T1) ;PUT DATA INTO THE BUFFER
PUSHJ P,.TCRLF## ;END LINE WITH A CRLF
ADD P1,[.DTMAX-1,,.DTMAX-1] ;ACCOUNT FOR MULTIPLE WORD ENTRIES
AOBJN P1,XMTD.1 ;LOOP
POP P,T1 ;GET OLD TYPER BACK
PUSHJ P,.TYOCH## ;RESET SCAN
TRZ F,FR.TASK ;CELAR TASK I/O FLAG
JRST .POPJ1## ;RETURN
SUBTTL Protocol -- RCVDAT - Receive local data from remote
RCVDAT: PUSHJ P,.SAVE1## ;SAVE P1
SETZM DATBFS ;CLEAR A WORD
MOVE T1,[DATBFS,,DATBFS+1] ;SET UP BLT
BLT T1,DATBFE-1 ;CLEAR DATA BUFFERS
RCVD.1: MOVE T3,[POINT 6,T4] ;BYTE POINTER
SETZ T4, ;CLEAR DESTINATION
PUSHJ P,TSKTYI ;GET A CHARACTER
PJRST RCVIOE ;I/O ERROR
CAIE T1,"." ;MUST BEGIN WITH A PERIOD
PJRST RCVPFE ;PROTOCOL FORMAT ERROR
RCVD.2: PUSHJ P,TSKTYI ;GET A CHARACTER
PJRST RCVIOE ;I/O ERROR
CAIE T1,.CHNUL ;EOF?
CAIN T1," " ;END OF NAMED DATA ITEM?
JRST RCVD.3 ;YES
SUBI T1," " ;CONVERT ASCII TO SIXBIT
TRNN T4,777777 ;OVERFLOW? (POSSIBLE JUNK)
IDPB T1,T3 ;STORE CHARACTER
JRST RCVD.2 ;LOOP BACK FOR MORE
RCVD.3: MOVE P1,[-DATLEN,,DATTAB] ;AOBJN POINTER TO TABLE
RCVD.4: HLLZ T1,.DTNAM(P1) ;GET A NAME
CAME T1,T4 ;MATCH?
AOBJN P1,RCVD.4 ;NO--LOOP
JUMPGE P1,RCVD.6 ;PROTOCOL FORMAT ERROR
MOVE T1,.DTFLG(P1) ;POINT TO LENGTH AND ADDRESS
TLZ T1,(DT.FLG) ;CLEAR OUT TYPEOUT FLAGS
PUSHJ P,CHRSET## ;SET UP BYTE COUNT AND POINTER
RCVD.5: PUSHJ P,TSKTYI ;GET A CHARACTER
PJRST RCVIOE ;I/O ERROR
CAIN T1,.CHCRT ;CARRIAGE RETURN?
JRST RCVD.5 ;YES--IGNORE IT
CAIN T1,.CHLFD ;LINE FEED?
JRST RCVD.7 ;YES
PUSHJ P,CHRPUT## ;STORE IT AWAY
JRST RCVD.5 ;LOOP BACK FOR MORE
RCVD.6: PUSHJ P,TSKTYI ;GET A CHARACTER
PJRST RCVIOE ;I/O ERROR
JUMPE T1,RCVPFE ;PROTOCOL FORMAT ERROR
CAIE T1,.CHLFD ;EOL?
JRST RCVD.6 ;LOOP BACK AND EAT MORE CHARACTERS
JRST RCVD.1 ;FINALLY DONE WITH THIS ONE
RCVD.7: PUSHJ P,CHRNUL## ;FORCE A NUL INTO THE BUFFER
HLRZ T1,.DTIOS(P1) ;GET ROUTINE TO READ
PUSHJ P,(T1) ;READ DATA FROM BUFFER
HLRZ T1,.DTNAM(P1) ;GET ITEM NAME
CAIE T1,'END' ;LAST ONE?
JRST RCVD.1 ;NO--GO BACK FOR ANOTHER DATA ITEM
SETZM DATERR ;CLEAR ERROR FLAG
JRST .POPJ1## ;AND RETURN
RCVIOE: SKIPA T1,[EXP 1] ;DATA I/O ERROR
RCVPFE: MOVEI T1,2 ;PROTOCOL FORMAT ERROR
MOVEM T1,DATERR ;SET ERROR FLAG
POPJ P, ;AND RETURN
SUBTTL Protocol -- TYPDAT - Type local data from remote
TYPDAT: PUSHJ P,.SAVE2## ;SAVE P1 AND P2
MOVE P1,[-DATLEN,,DATTAB] ;AOBJN POINTER TO TABLE
TYPD.1: HRRZ T1,.DTFLG(P1) ;POINT TO STORAGE ADDRESS
SKIPN (T1) ;HAVE THIS ONE?
JRST TYPD.2 ;NO
MOVE P2,.DTFLG(P1) ;GET FLAGS
TLNE P2,(DT.NTY) ;NEVER TYPE THIS ONE?
JRST TYPD.2 ;THATS RIGHT
TLNE P2,(DT.CRL) ;PREFIX WITH A CRLF?
PUSHJ P,.TCRLF## ;YES
HRRZ T1,.DTNAM(P1) ;GET ITEM NAME
PUSHJ P,.TSTRG## ;TYPE IT
HRRZ T1,.DTFLG(P1) ;POINT TO DATA STORAGE
PUSHJ P,.TSTRG## ;TYPE IT
TYPD.2: ADD P1,[.DTMAX-1,,.DTMAX-1] ;ACCOUNT FOR MULTIPLE WORD ENTRIES
AOBJN P1,TYPD.1 ;LOOP
PUSHJ P,.TCRLF## ;CRLF
PJRST .TCRLF## ;ONE MORE AND RETURN
SUBTTL Storage
SRVLGO::BLOCK 1 ;NON-ZERO IF OK TO USE /SERVE LOGGED OUT
$LOW
HDRFLG: BLOCK 1 ;NON-ZERO IF HAVE OUTPUT LOG HEADER
; Command buffer data
CMDIDX: BLOCK 1 ;TABLE INDEX
CMDTAB: BLOCK LN$SBT ;TABLE
CMDCTR: BLOCK 1 ;BYTE COUNT
CMDPTR: BLOCK 1 ;BYTE POINTER
CMDBUF: BLOCK LN$SCB ;BUFFER
; Message buffer data
MSGCTR: BLOCK 1 ;BYTE COUNT
MSGPTR: BLOCK 1 ;BYTE POINTER
MSGBUF: BLOCK LN$SMB ;BUFFER
MSGTYP: BLOCK 1 ;OLD CHARACTER TYPER
LOGDAT: BLOCK 5 ;LOGIN ARGUMENT BLOCK
LOGTYO: BLOCK 1 ;OLD TYPER USED BY LOG FILE I/O ROUTINES
SAVCHR: BLOCK 1 ;SAVED CHARACTER
SRVFLG: BLOCK 1 ;SPECIAL SERVER JOB FLAGS
TXTPTR: BLOCK 1
TXTCNT: BLOCK 1
TXTPAG: BLOCK 1
SPID: BLOCK 1
PDB: BLOCK 6
BUFFER: BLOCK 12
DEFINE X (NAM,LEN,TXT,FLG),<
NAM'BUF: BLOCK <^D<LEN>/5>+1
>
DATERR: BLOCK 1 ;DATA ERROR ON RECEIVE
DATBFS:!$DATA ;BUILD DATA BUFFERS
DATBFE:! ;END OF DATA BUFFERS
; Task independant data
T.OARG: BLOCK 2 ;SAVED OPEN ARGUMENTS
T.SEQN: BLOCK 1 ;SEQUENCE NUMBER
T.ATTN: BLOCK 1 ;TOTAL INTERRUPT(S) NEEDING ATTENTION
T.TIME: BLOCK 1 ;TIMEOUT IN SECONDS
T.WAIT: BLOCK 1 ;WORKING COPY OF COUNTDOWN TIMER
T.DISP: BLOCK 1 ;DISPATCH ADDRESS
T.CHAR: BLOCK 1 ;TEMPORARY CHARACTER STORAGE
T.IOST: BLOCK 1 ;SAVED I/O STATUS AFTER AN ERROR
; IPCF data
I.PDB: BLOCK 6 ;PACKET DESCRIPTOR BLOCK
I.PKT: BLOCK 12 ;PACKET
I.PTR: BLOCK 1 ;BYTE POINTER TO NAME
I.SRV: BLOCK 12 ;PID/NAME PACKET
I.PID: BLOCK 1 ;PID
IPCATN: BLOCK 1 ;INTERRUPT(S) NEEDING ATTENTION
IPCFLG: BLOCK 1 ;TASK INITIALIZED FLAG
IPCNAM: BLOCK <^D29/5>+1 ;PID NAME
IPCOBR: BLOCK 3 ;OUTPUT BUFFER RING HEADER
IPCIBR: BLOCK 3 ;INPUT BUFFER RING HEADER
; ANF10 data
ANFATN: BLOCK 1 ;INTERRUPT(S) NEEDING ATTENTION
ANFFLG: BLOCK 1 ;TASK INITIALIZED FLAG
ANFOBK: BLOCK 3 ;OPEN BLOCK
ANFOBR: BLOCK 3 ;OUTPUT BUFFER RING HEADER
ANFIBR: BLOCK 3 ;INPUT BUFFER RING HEADER
ANFLEB: BLOCK 4 ;LOOKUP/ENTER BLOCK
ANFBFS: BLOCK 1 ;ADDRESS OF BUFFERS
; DECnet data
DCNATN: BLOCK 1 ;INTERRUPT(S) NEEDING ATTENTION
DCNFLG: BLOCK 1 ;TASK INITIALIZED FLAG
DCNOBR: BLOCK 3 ;OUTPUT BUFFER RING HEADER
DCNIBR: BLOCK 3 ;INPUT BUFFER RING HEADER
> ;END IFN FTSERV FROM WAY BACK
END