Trailing-Edge
-
PDP-10 Archives
-
BB-4170G-SM
-
sources/netwrk.mac
There are 6 other files named netwrk.mac in the archive. Click here to see a list.
;<3A.MONITOR>NETWRK.MAC.6, 28-May-78 01:48:11, Edit by BORCHEK
;REMOVE OPENING NET IN 7 BIT MODE
;<3A-MONITOR>NETWRK.MAC.4, 22-Apr-78 20:37:51, Edit by BORCHEK
;SPEED UP NETWORK FTP
;<HACKS>NETWRK.MAC.8, 2-Apr-78 02:27:39, EDIT BY JBORCHEK
;USE AN ADJBP AT DMPBUF
;<3A.MONITOR>NETWRK.MAC.2, 19-Mar-78 13:07:41, Edit by BORCHEK
;GET DIR # FROM JSBSDN IN NETVER
;ONLY 8, 32, 36 BIT CONNECTIONS ALLOWED
;<4.MONITOR>NETWRK.MAC.2, 29-Jan-78 16:59:49, Edit by BORCHEK
;FIX DIR NET:<*> FROM HANGING JOB. CHECK AT NETSET FOR <*>
;<4.MONITOR>NETWRK.MAC.1, 29-Nov-77 12:24:13, EDIT BY CROSSLAND
;PREVENT CLOBBERING OF WAIT ROUTINE ADDRESS ON BOUT.
;<3-MONITOR>NETWRK.MAC.22, 20-Nov-77 19:50:49, EDIT BY CROSSLAND
;<3-MONITOR>NETWRK.MAC.21, 9-Nov-77 09:55:22, EDIT BY KIRSCHEN
;MORE COPYRIGHT UPDATING...
;<3-MONITOR>NETWRK.MAC.20, 19-Oct-77 00:59:37, EDIT BY CROSSLAND
;<3-MONITOR>NETWRK.MAC.19, 12-Oct-77 14:01:52, EDIT BY KIRSCHEN
;UPDATE COPYRIGHT FOR RELEASE 3
;<3-MONITOR>NETWRK.MAC.18, 6-Oct-77 03:18:01, EDIT BY CROSSLAND
;FIX EXPRESSIONS CONTAINING ANBSEC
;<3-MONITOR>NETWRK.MAC.17, 6-Oct-77 00:27:55, EDIT BY CROSSLAND
;<3-MONITOR>NETWRK.MAC.16, 1-Sep-77 11:52:02, EDIT BY CROSSLAND
;<3-MONITOR>NETWRK.MAC.15, 3-Aug-77 23:48:46, EDIT BY CROSSLAND
;MAKE NEW TELNET NVT'S WORK
;<3-MONITOR>NETWRK.MAC.14, 23-Jul-77 22:55:57, EDIT BY CROSSLAND
;MOVE BUFFERS TO ANBSEC SECTION
;<3-MONITOR>NETWRK.MAC.13, 30-Jun-77 20:04:56, EDIT BY CROSSLAND
;<3-MONITOR>NETWRK.MAC.12, 29-Jun-77 04:20:19, EDIT BY CROSSLAND
;FIX MODEL B ADDRESSING PROBLEMS
;<3-MONITOR>NETWRK.MAC.11, 17-Jun-77 05:36:27, EDIT BY CROSSLAND
;MORE CONVERSION FOR MODEL B
;<3-MONITOR>NETWRK.MAC.10, 11-Jun-77 03:29:02, EDIT BY CROSSLAND
;<3-MONITOR>NETWRK.MAC.9, 9-Jun-77 04:28:25, EDIT BY CROSSLAND
;<3-MONITOR>NETWRK.MAC.8, 6-Jun-77 00:48:49, EDIT BY CROSSLAND
;<3-MONITOR>NETWRK.MAC.7, 21-May-77 23:26:44, EDIT BY BOSACK
;ELIMINATE USE MACRO
;<3-MONITOR>NETWRK.MAC.6, 19-May-77 08:01:14, EDIT BY CROSSLAND
;<3-MONITOR>NETWRK.MAC.5, 14-May-77 19:26:51, EDIT BY CROSSLAND
;<3-MONITOR>NETWRK.MAC.4, 8-May-77 18:16:34, EDIT BY CROSSLAND
;<3-MONITOR>NETWRK.MAC.3, 6-May-77 11:56:44, EDIT BY HURLEY
;ADD SET INPUT/OUTPUT AND ATTRIBUTE CHECK ENTRIES IN DISPATCH TABLE
;<3-MONITOR>NETWRK.MAC.2, 27-Apr-77 17:09:26, EDIT BY CROSSLAND
; TCO 1742 MERGE ARPA SOURCES
;<A-MONITOR>NETWRK.MAC.10, 27-Dec-76 14:41:45, EDIT BY CROSSLAND
;CHANGE ERROR CODES ATPX?? TO ATPNX??
;<A-MONITOR>NETWRK.MAC.9, 3-Dec-76 17:10:38, EDIT BY CLEMENTS
; GIVE FLHST AN ITRAP ERROR IF NO CAPS. RANGE CHECK ITS ARG.
;<A-MONITOR>NETWRK.MAC.8, 1-Dec-76 14:40:53, EDIT BY CLEMENTS
;<A-MONITOR>NETWRK.MAC.7, 23-Nov-76 18:36:34, EDIT BY CLEMENTS
;<134-TENEX>NETWRK.MAC;240 4-NOV-75 12:00:04 EDIT BY ALLEN
;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.
SEARCH PROLOG,MACSYM,MONSYM
TTITLE NETWRK
SUBTTL R.S.Tomlinson
; Macros to turn imp on and off
DEFINE NCPON<PUSHJ P,ULKNCP>
DEFINE NCPOFF<PUSHJ P,LCKNCP>
; Local accumulators
DEFAC (UNIT,Q1) ;PSEUDO-UNIT NUMBER
DEFAC (IOS,Q2) ; STATUS FLAGS (FROM NETSTS(UNIT))
DEFAC (STS,P1)
DEFAC (JFN,P2)
DEFAC (DEV,P4)
DEFAC (F1,P5)
;PARAMETERS
NLNKBW==<LLINK+^D35>/^D36 ;LENGTH OF LINK BITTABLE
;FLAGS IN LH OF NETSTS
FLG(BFSND,L,IOS,020000) ;BUFFERED SEND MODE
FLG(ERRB,L,IOS,010000) ;ERROR HAS OCCURRED
FLG(EOTF,L,IOS,004000) ;END OF TRANSMISSION FLAG
FLG(SVCIF,L,IOS,002000) ;SERVICE INTERRUPTION IN PROGRESS
FLG(CLZF,L,IOS,001000) ;CONNECTION IS BEING CLOSED
FLG(DEDF,L,IOS,000400) ;HOST IS DEAD
FLG(PROGF,L,IOS,000200) ;SET IF PROGRAM IS WATCHING THIS CONNECTION
FLG(ALLFF,L,IOS,000100) ;ALLOCATION RESYNC HAS BEEN DONE
EOTF==:EOTF ;MAKE THESE INTERNAL
DEDF==:DEDF ; ..
; Pointers to various fields of a connection
RESCD
PLINK:: POINT 9,NETAWD(UNIT),8 ; Pointer to link number
PFHST:: POINT 9,NETAWD(UNIT),17 ; Pointer to foreign host number
PCLKS: POINT 6,NETAWD(UNIT),23 ; Pointer to time-out counter
PINTCH: POINT 6,NETFRK(UNIT),5 ; Pointer to ins/inr psi channel
PFSMCH: POINT 6,NETFRK(UNIT),17 ; Pointer to psi channel for fsm change
PFSM: POINT 4,NETSTS(UNIT),3 ; Pointer to current state of fsm
PBPBYT: POINT 6,NETSTS(UNIT),17 ; Pointer to net bit stream byte size
PBFSIZ: POINT 18,NETBUF(UNIT),17; Pointer to bytes per buffer
; Bbn socket numbers description
; A socket number is a 32-bit number which in conjunction with
; A host number specifies one end of a connection
; For bbn sockets, the 32 bit field is divided in 3 parts:
; The high 17 bits is used as follows:
; if 0: then this is a system socket
; if <100000 then the number is a bbn user number and the socket is
; is called a user socket
; if >99999 then the number is tss job-number plus 100000, and the
; socket is called a job socket
; A job socket is analogous to a temporary file and is guaranteed to
; Be unique to that job. a user socket is analogous to a regular file
; And is guaranteed to be unique to that user. a system socket is
; For use as agreed upon by members of the network for such purposes
; As inter system communication, memo-distribution etc.
; The next 14 bits are an arbitrary number which may be defaulted
; To the jfn associated with the socket or specified by the name field
; Of the file name string. the low order bit is determined by
; The gender of the socket. a socket opened for for writing
; Will have this bit equal to one. a socket opened for reading will
; Have this bit equal to zero.
; Network dispatch table
SWAPCD
NETDTB::DTBDSP (NETSET) ;DIRECTORY SETUP
DTBDSP (NETNAM) ;NAME LOOKUP
DTBDSP (NETEXT) ;EXTENSION LOOKUP
DTBDSP (NETVER) ;VERSION LOOKUP
DTBBAD (DESX9) ;PROTECTION INSERT
DTBBAD (DESX9) ;ACCOUNT INSERT
DTBBAD (DESX9) ;STATUS INSERT
DTBDSP (NETOPN) ;OPEN
DTBDSP (NETSQI) ;BYTE INPUT
DTBDSP (NETSQO) ;BYTE OUTPUT
DTBDSP (NETCLZ) ;CLOSE
DTBBAD (DESX9) ;RENAME
DTBBAD (DESX9) ;DELETE
DTBBAD (DESX9) ;DUMP
DTBBAD (DESX9)
DTBBAD (DESX9) ;MOUNT
DTBBAD (DESX9) ;DISMOUNT
DTBBAD (DESX9) ;INITIALIZE
DTBDSP (NETMTP) ;MTOPR
DTBDSP (NETGST) ;GET STATUS
DTBDSP (NETSST) ;SET STATUS
DTBSKP ;RECORD OUT
DTBDSP (RFTADN) ;READ TAD
DTBDSP (SFTADN) ;SET TAD
DTBDSP (BIOINP) ;SET JFN FOR INPUT
DTBDSP (BIOOUT) ;SET JFN FOR OUTPUT
DTBBAD (GJFX49) ;CHECK ATTRIBUTE
DTBLEN==:.-NETDTB ;GLOBAL LENGTH OF DISPATCH TABLE
; Network lock and unlock
LCKNCP::AOS NCPLCN ; COUNT CALLS TO THIS ROUTINE
; LOCK NCPLCK,<JRST LCKNC1>,SPQ ;SHOULD BE SPECIAL Q IF SUCCEED
LOCK NCPLCK,<JRST LCKNC1>
LCKNC2: PUSH P,FORKX
POP P,NCPLLK ; SAVE LAST LOCKER
POPJ P,
LCKNC1: AOS NCPLFC ; COUNT FAILURES
PUSH P,1
MOVEI 1,NCPLKT
MDISMS
POP P,1
JRST LCKNC2
RESCD
NCPLKT: AOSE NCPLCK
JRST 0(4)
JRST 1(4)
SWAPCD
ULKNCP::
; UNLOCK NCPLCK,RESIDENT,SPQ
UNLOCK NCPLCK ;SIMPLER LOCK MACRO FOR TOPS20
POPJ P,
; Initialize network stuff
NETINI::SE1CAL ;ENTER SECTION 1 FOR THIS ROUTINE
SETZM NETSTS
MOVE A,[NETSTS,,NETSTS+1]
BLT A,NETSTS+NSKT-1
SETZM NETCNC
SETZM FUNNYC
MOVE A,[ANBSEC,,NTBUFS]
MOVEM A,NETFRE ;INITIAL FREE LIST
MOVEI B,NNTBFS ;SIZE OF BUFFER AREA
MOVEM B,NETFRE+2 ;FREE SPACE LEFT IN BUFFER AREA
MOVEM A,NETFRE+3 ;START OF BUFFER AREA
MOVE A,[ANBSEC,,NTBUFS+NNTBFS-1] ;END OF BUFFER AREA
MOVEM A,NETFRE+4
;INITIALIZE FREE LIST INTO ITEMS OF MAXWPM EACH
IDIVI B,MAXWPM ;COMPUTE NUMBER OF BUFFERS
SKIPE C
BUG (HLT,NETNNI,<NETINI: NNTBFS NOT INTEGRAL MULTIPLE OF MAXWPM>)
MOVE C,[ANBSEC,,NTBUFS] ;SET UP C TO POINT TO NET BUFFERS
NETIN2: MOVE A,C ;COPY C INTO A
ADDI C,MAXWPM ;RH(C) POINTS TO NEXT BUFFER
HRLOM C,0(A) ;STORE THAT IN LEFT HALF IN CURRENT BUFFER
SOJG B,NETIN2 ;DO ANOTHER
HRRZS 0(A) ;LAST ITEM POINTER IS 0
SETOM NETFRE+1 ;NETWORK BUFFER LOCK
SETOM NCPLCK
MOVE A,DBUGSW ;IN SYSTEM DEBUG MODE?
CAIGE A,2 ;IF SO, DON'T TURN ON NET.
SETOM NETON ;NET ON
MOVEI A,MAXWPM ;GET SIZE OF EACH BUFFER
ASH A,3 ;TIMES 8
MOVEM A,ASNTHR ;SETS BUFFER SPACE LOW THRESHOLD
POPJ P,
; Prepare to lookup network names
NETSET: TQNE <STEPF> ;WANT TO STEP?
RETBAD (GJFX17) ;YES. CAN'T DO IT
NOINT ;PREVENT INTS
JRST SK2RET ;AND SAY IT IS SET
; Name lookup routine
NETNAM: JUMPE A,NAMBAD ; *. -- failure
HRLI A,(<POINT 7,0,35>) ; Make lookup pointer into byte pointer
PUSHJ P,NAMDEC ; Decode name
JRST NAMBAD ; Bad syntax
OKRET: TQNE <UNLKF>
JRST SK2RET
OKINT
JRST SK2RET
NAMBAD: MOVEI A,GJFX18
JRST ERRET ; Error return
ERRET: OKINT
POPJ P,
; Extension lookup routine
NETEXT: JUMPE A,NAMBAD ; .* -- failure
HRLI A,(<POINT 7,0,35>) ; Make lookup pointer into byte pointer
PUSHJ P,EXTDEC ; Decode extension to check syntax
JRST EXTBAD ; Bad syntax
JRST OKRET ; Success
EXTBAD: MOVEI A,GJFX19
JRST ERRET
; Version lookup
NETVER: HRRES T1 ; Extend sign
CAIL T1,^D100000 ; If geq 100000
JRST NETVR1 ; Use job related socket
HLLZ T1,JSBSDN ; Get structure
LSH T1,-6
ADD T1,JSBSDN ; Add in directory
ANDI T1,177777 ; Clear junk
NETVR1: TQNE <UNLKF>
JRST RSKP
OKINT
JRST RSKP
; Decode extension string
; Called both at gtjfn and openf to decode extension string into
; Foreign socket number and host number
EXTDEC: PUSH P,A
ILDB D,A
POP P,A
JUMPE D,[SETOB A,B
JRST RSKP]
CAIGE D,"8"
CAIGE D,"0"
JRST EXTDES ; Symbolic
MOVEI C,10
NIN
POPJ P,
CAIL B,0
CAILE B,377
POPJ P,
MOVE D,B
LDB B,A
CAIE B,"-"
POPJ P,
NIN
POPJ P,
MOVE A,D
JRST RSKP
EXTDES: HRLZ D,MHOSTS ;SCAN ALL HOSTS IN NAME TABLES
EXTDE1: PUSH P,A
HRRZ C,HOSTN(D)
ADD C,[POINT 7,HSTNAM]
PUSH P,C
EXTDE2: ILDB B,A
ILDB C,0(P)
JUMPE C,EXTDE3
CAMN C,B
JRST EXTDE2
EXTDE4: ADJSP P,-1
POP P,A
AOBJN D,EXTDE1
POPJ P,
EXTDE3: CAIE B,"-"
JRST EXTDE4 ; Not this one
MOVEI C,10
NIN ; Convert remainder of string to number
JRST EXTDE4 ; Must not be this one
LDB C,A ; Get terminator
JUMPN C,EXTDE4 ; Not this one
ADJSP P,-2 ; This is it, flush stack
LDB A,[POINT 9,HOSTN(D),17]
JRST RSKP
; Decode name string
; Called both at gtjfn and openf to decode name string into
; Local socket number
NAMDEC: MOVEI C,10 ; Perhaps this should be decimal?
NIN ; Convert to a number
JRST NAMDE1 ; Failure: no number there
LDB C,A ; Get terminator
CAIE C,"#" ; If not number sign
JRST NAMDE2 ; Then ordinary
MOVE C,CAPMSK ; Else system socket
TRNN C,SC%WHL!SC%OPR!SC%NAS ;MUST BE WHEEL, OPR, OR
; HAVE ABSOLUTE SOCKET CAPABILITY
POPJ P, ; Else fail
ILDB C,A ; Get next ch
TDZA A,A ; Zero for high 17 bits
NAMDE2: HRRZ A,FILVER(JFN) ; Use filver for high 17 bits
JUMPN C,CPOPJ ; String too long
SKIPE A
ANDI B,77777 ; If not system socket, retain 15 bits
TRZ B,1 ; Clear gender
ROT A,^D15
IOR A,B
JRST RSKP
NAMDE1: LDB C,A
JUMPN C,CPOPJ ; Not number, fail
MOVE B,JFN ; Default to jfn
PUSH P,T3 ;SAVE T3 OVER DIVIDE
IDIVI T2,MLJFN ;GET THE JFN
POP P,T3 ;RESTORE T3
LSH B,1 ; Jfn will end up lsh'ed 1
JRST NAMDE2
; Open network file
NETOPN: TQNE <XCTF,RNDF>
JRST ILLACC ; Illegal to access in append or xct
TQNE <READF>
TQNN <WRTF>
TQNN <READF,WRTF>
JRST ILLACC ; Must be only one of read or write
LDB T1,PBYTSZ
CAIN T1,^D8 ; Check for 8 32 or 36 bit bytes
CAIA
CAIN T1,^D32
CAIA
CAIN T1,^D36
CAIA
JRST [ MOVEI A,SFBSX2
POPJ P,] ; Bad byte size
HLRZ A,FILNEN(JFN)
HRLI A,(<POINT 7,0,35>)
PUSHJ P,NAMDEC ; Decode name
JRST ILLACC ; Can only happen if wheel lost
TQNE <WRTF>
TROA A,1 ; If writing set gender bit for local
TRZ A,1 ; Else clear it
PUSH P,A ; Save for later
HRRZ A,FILNEN(JFN)
HRLI A,(<POINT 7,0,35>)
PUSHJ P,EXTDEC ; Decode extension
BUG(HLT,NETIEF,<NETOPN: EXTDEC FAILURE AFTER PREVIOUS NON-FAILURE.>)
TQNE <READF>
TROA B,1 ; If reading set gender bit for forskt
TRZ B,1 ; Else clear
POP P,C
LDB D,PBYTSZ ; Get file byte size
JUMPL A,OPNLSN ; No foreign socket, do a listen
PUSHJ P,CONNECT ; Connect
POPJ P,
TQZ <WNDF>
NETOP1: HRLM UNIT,FILSKT(JFN) ;REMEMBER UNIT NUMBER
SETZ IOS, ; Clear status bits
LDB A,[POINT 4,STS,35]
CAIE A,5 ; In modes 5
CAIN A,7 ; Or 7
TQO <BFSND> ; DO BUFFERED TRANSMISSION
IORB IOS,NETSTS(UNIT) ; Set it in status word
MOVEI A,^D36
LDB B,PBYTSZ
IDIV A,B ; Get bytes per WORD
XCTBU [ LDB C,[POINT 6,2,17]] ; GET DESIRED SIZE OF BUFFER
IMUL A,C ; DESIRED BYTES
DPB A,PBFSIZ ; Gives bytes per buffer
SETZM FILBYN(JFN) ; About to reference byte 0 of buffer
SETZM FILOFN(JFN) ; NEXT BYTE TO XMIT = 0
TQO <SIZF> ; CANNOT CHANGE BYTE SIZE
TQOE <WNDF> ; NO BUFFER YET. ALSO IF LISTEN
JRST RSKP ; Return immediately
LDB A,[POINT 4,STS,35]
CAIE A,6 ; Also in modes 6
CAIN A,7 ; And 7
JRST RSKP ; Return immediately
LDB A,PFSM ; No. get current state
CAIN A,RFCS ; Will usually be rfcs
PUSHJ P,WATNOT ; If so, wait for it to not be
MOVE IOS,NETSTS(UNIT) ; GET STATE
LDB A,[POINT 4,IOS,3]
TQNN <EOTF> ; IF LEFT OPND
CAIN A,OPND ; OR STILL OPENED
JRST RSKP ; THEN SUCCEED
OPNFAI: MOVX B,PROGF
ANDCAM B,NETSTS(UNIT) ; Program not watching
TQNE <ERRB> ; ERRB REMEMBERS BAD BYTE SIZE
SKIPA A,[OPNX22] ; MAKE THAT THE ERROR CODE
MOVEI A,OPNX21 ; ELSE IT WAS REJECTED
POPJ P, ; And give bad return
OPNLSN: PUSHJ P,LISTEN
POPJ P, ; Can't listen
TQO <WNDF> ; TO REMEMBER THAT THIS WAS A LISTEN
JRST NETOP1 ; First bin/out is accept
ILLACC: MOVEI A,OPNX14
POPJ P,
; Wait for fsm to leave state given in a
WATNOT: HRLI A,NOTTST ; TEST ROUTINE ADDRESS
WATNO1: MOVE B,UNIT ; COMPUTE SCHEDULER TEST ARGUMENT
ROT B,-9
MOVSS A
IOR A,B
SKIPE INSKED
BUG(HLT,NETWNS,<WATNOT: WAS CALLED FROM SCHEDULER LEVEL.>)
MDISMS
POPJ P,
; Wait for fsm to enter a particular state
WATFOR: HRLI A,WATTST
JRST WATNO1
RESCD
NOTTST: LDB B,[POINT 9,A,26] ; EXTRACT UNIT
ANDI A,777 ; AND STATE TO TEST AGAINST
EXCH UNIT,B
LDB C,PFSM ; GET CURRENT STA(E
EXCH UNIT,B
CAME A,C ; IS IT THE SAME
JRST 1(4) ; NO, READY TO GO
JRST WATTS1 ; YES, MAKE OTHER TESTS
; SCHEDULER TEST WAITING FOR CONNECTION TO GET TO A STATE
WATTST: LDB B,[POINT 9,A,26] ; EXTRACT UNIT
ANDI A,777 ; AND STATE
EXCH B,UNIT
LDB C,PFSM ; GET CURRENT STATE
EXCH B,UNIT
CAMN C,A ; SAME?
JRST 1(4) ; YES, READY TO GO
WATTS1: MOVE C,FKINT(7) ; Look for deferred interrupts
TLNN C,(1B1)
JRST 0(4) ; None. return no skip
EXCH B,UNIT ; Deferred interrupt, get back unit
SETZ C,
DPB C,PCLKS ; Set clock to zero to hasten time-out
EXCH B,UNIT
JRST 0(4)
;SCHEDULER TEST FOR BIT ALLOCATION
;CONNECTION NUMBER IN T1
BALTST: EXCH UNIT,T1 ;GET CONNECTION NUMBER IN UNIT
LDB T2,PBPBYT ;GET BIT STREAM BYTE SIZE
LOAD T3,LTIDX,(UNIT) ;GET LINK TABLE INDEX
SKIPE IMPLT4(T3) ;SKIP IF NEITHER MSG ALLOC OR BUFFER
CAMLE T2,NETBAL(UNIT) ;MSG OK, HOW ABOUT BITS?
JRST [ HLL T3,NETSTS(UNIT) ; GET STATUS INFO
TXNE C,DEDF+EOTF ; ALLOC BAD. BUT IF DEAD..STILL OK
JRST BALTS1 ;OK. TAKE SKIP RETURN
JRST BALTS2] ;WAIT SOME MORE
BALTS1: AOS T4 ;TAKE SKIP RETURN
BALTS2: EXCH UNIT,T1 ;RESTORE UNIT
JRST 0(T4) ;RETURN
SWAPCD
; Close network file
NETCLZ: HLRZ UNIT,FILSKT(JFN)
TQNN <WNDF> ; IF NO BUFFER EVER ASSIGNED
TQNN <WRTF> ; OR IF READING
JRST NETCL1 ; Then skip the following
PUSHJ P,DMPBUF ; Dump last buffer
JRST NETCLW ; NOT ALL SENT. GO WAIT.
NETCL1:
REPEAT 0,<
TQNE <ERRF> ; ANY FINAL ERRORS
JRST [ MOVEI A,IOX5
RET] ; DON'T CLOSE IF ANY UN-HANDLED ERRORS
>
HRROS FILSKT(JFN) ; IN CASE JFN RE-OPENED, SET UNIT TO -1
SETOM NETFRK(UNIT)
HRRZ T2,NETBUF(UNIT) ;GET BUFFER ADDRESS
JUMPE T2,NETCL3 ;IS THERE A BUFFER
MOVEI T1,JSBFRE ;THIS IS ALSO THE BLOCK TO FREE
CALL RELFRE ;YES. RELEASE IT
NETCL3: TQNN <WRTF> ; IF NOT SENDING
SKIPA A,[CLZR] ; THEN DO CLZR
MOVEI A,CLZS ; ELSE do clzs
PUSHJ P,DOFSM
UMOVE A,1
TDNN A,[1,,400000]
TLNN A,(1B1)
JRST NETCL2 ; Return immediately if no bit 1
LDB B,PFSM
MOVEI A,FREE
CAIE B,FREE
PUSHJ P,WATFOR
NETCL2: MOVX A,PROGF
ANDCAM A,NETSTS(UNIT) ; No program wants this any more
JRST RSKP
NETCLW: MOVEI B,^D60 ; 5 MINUTES OF TICKS
DPB B,PCLKS
MOVX IOS,CLZF
IORB IOS,NETSTS(UNIT)
MDISMS
JRST NETCLZ ; AND GO TRY AGAIN
; Close nvt
NVTCLZ::MOVE A,LSKT(UNIT)
TRNN A,1
SKIPA A,[CLZR]
MOVEI A,CLZS
PUSHJ P,DOFSM
POPJ P,
; Network mtopr routines
NETMTP: HLRZ UNIT,FILSKT(JFN)
MOVE IOS,NETSTS(UNIT)
CAIG B,26
CAIGE B,20
RETSKP ; ANYTHING ELSE IS A NOP
JRST .+1-20(B)
JRST NETACP
JRST NETDMP
JRST SNDINT
JRST ABTCON
JRST NETINT
JRST NETRDY
JRST NETFAL
NETACP: LDB B,PFSM
MOVEI A,ACPT
CAIN B,RFCR
PUSHJ P,DOFSM
RETSKP
NETDMP: TQNE <BFSND> ;SENDING BY BUFFER?
TQNN <WRTF> ;AND A SEND CONNECTION?
RETSKP ;NO, A NOP
TQNE <WNDF> ;YES. BUFFER SET UP?
RETSKP ;NO, NOTHING TO SEND
PUSHJ P,DMPBUF
JRST WATXXX
RETSKP
SNDINT: LDB A,PFHST
LDB B,PLINK
MOVE D,LSKT(UNIT)
TRNE D,1
SKIPA D,[IFIW!IMPINS]
MOVE D,[IFIW!IMPINR]
NCPOFF
LDB C,PFSM
CAIN C,OPND
PUSHJ P,@D
NCPON
RETSKP
; WAIT FOR READY TO SEND AT LEAST ONE BYTE
ABTCON: MOVE A,CAPENB
TXNN A,SC%NWZ
JRST [ MOVEI A,NTWZX1 ; NOT A NET WIZARD. FAIL.
RET]
CALL SKTDWN
RETSKP
NETRDY: TQNN <WRTF> ; RECEIVE OR SEND?
JRST NETRD1 ; RECEIVE. SEND ALLOCATES OUT
LOAD T1,LTIDX,(UNIT) ;GET LINK TABLE INDEX
PUSHJ P,PKCHK ; GET BYTES THAT CAN BE SENT
JUMPE B,[PUSHJ P,WATBAL ; COMPUTE ACTIVATION TEST
JRST WATXXX] ; AND WAIT
CALL PKULCK
RETSKP
NETRD1: TQNN <WNDF> ;HAS ALLOCATION ALREADY BEEN SENT?
RETSKP
PUSHJ P,FIRSTI ;NO. SEND IT OUT.
RET ;PASS ON DOWN BLOCK
RETSKP
NETINT: UMOVE B,3
HRR B,FORKX ; REMEMBER THIS FORK, AND USER'S
MOVEM B,NETFRK(UNIT) ; REQUESTED PI CHANNELS
RETSKP
NETFAL: TQNE <WNDF,WRTF> ; IF READ AND FIRSTI NOT DONE
RETSKP
CALL FIRSTI ; SET UP BUFFERS AND SEND ALLOCATE
RET ;PASS ON DOWN BLOCK
RETSKP
; HERE WHEN A FORK IS KILLED, TO FORGET THE PSI INFO
NETKFK::PUSH P,UNIT
PUSH P,A
MOVSI UNIT,-NSKT
NETKF1: HRRE A,NETFRK(UNIT)
CAMN A,FORKX
SETOM NETFRK(UNIT)
AOBJN UNIT,NETKF1
POP P,A
POP P,UNIT
POPJ P,
; HERE FROM LOGOUT CODE TO RELEASE JOB-WIDE NET RESOURCES
NETLGO::SETO A,0 ;RELEASE ALL SPECIAL QUEUES
RELSQ
RET ; THAT'S ALL
; SKIP IF NET INPUT BUFFER EMPTY
NTSIBE: HLRZ UNIT,FILSKT(JFN)
LOAD T1,LTIDX,(UNIT) ;GET LINK TABLE INDEX
MOVSI B,777777
TDNN B,IMPLT4(A)
TDNE B,IMPLT3(A)
POPJ P,
JRST RSKP
; Network file sequential byte input
NETSQI: HLRZ UNIT,FILSKT(JFN)
MOVE IOS,NETSTS(UNIT)
TQNN <WNDF>
JRST NTSQI1
PUSHJ P,FIRSTI ; Wait for listen set up buffers etc.
RET ;PASS ON DOWN BLOCK
NTSQI1: SOSL FILCNT(JFN)
JRST NTSQI2
PUSHJ P,LODBUF ; Get another bufferful
RET ;PASS ON DOWN BLOCK
NTSQI2: TQNE <EOFF>
POPJ P,
ILDB A,FILBYT(JFN)
AOS FILBYN(JFN)
POPJ P,
LODBUF: MOVX IOS,ERRB
TDNE IOS,NETSTS(UNIT)
TQO <ERRF>
ANDCAB IOS,NETSTS(UNIT)
MOVE T3,NETBUF(UNIT) ;GET ADDRESS OF BUFFER
HLL T3,FILBYT(JFN) ;GET THE BYTE SIZE
TLZ T3,770000 ;SET AT END OF FIRST WORD
TLNN T3,700 ;36 BIT MODE?
TLO T3,40000 ;NO GET BYTE OFFSET RIGHT
MOVEM T3,FILBYT(JFN) ;SAVE BYTE POINTER
LDB T4,PBFSIZ ;GET BUFFER SIZE
LOAD T1,LTIDX,(UNIT) ;GET LINK TABLE INDEX
CALL UPMSG ;UNPACK MESSAGE(S) INTO BUFFER
JRST [MOVX IOS,EOTF ;GET END OF FILE FLAG
TDNE IOS,NETSTS(UNIT) ;IS IT SET FOR THIS CONNECTION
JRST [ TQO <EOFF> ;YES SET FOR THIS JFN
RETSKP] ;AND RETURN
JRST WATXXX] ;BACK OUT AND WAIT THEN START OVER
LDB T2,PBFSIZ ;GET BUFFER SIZE IN BYTES
SUB T2,T4 ;BYTES LOADED
MOVEM T2,FILCNT(JFN) ;SET BYTES IN BUFFER FOR THIS JFN
ADDM T2,FILLEN(JFN) ;UPDATE NUMBER OF BYTES ON THIS CONN.
LDB T4,PBPBYT ;GET BYTE SIZE
IMUL T4,T2 ;BITS RECEIVED
ADDM T4,NETBTC(UNIT) ;KEEP COUNT OF BITS RECEIVED
MOVN T2,T4 ;GET NEGATIVE OF BITS RECIEVED
ADDM T2,NETBAL(UNIT) ;DEBIT ALLOCATION FOR MESSAGE RECEIVED
CALL NETRAL ;RE-ALLOCATE IF NEEDED
SOSGE FILCNT(JFN) ;DID WE GET ANYTHING?
JRST LODBUF ;NO BYTES GO TRY AGAIN
RETSKP
NETRAL::NCPOFF ; PREVENT CONFUSION
MOVE IOS,NETSTS(UNIT)
TQNE <EOTF,DEDF>
JRST NETRAX ; DON'T BOTHER IF DEAD OR DONE
MOVE D,NETDAL(UNIT) ; GET DESIRED BIT ALLOCATION
MOVE B,D
ASH B,-1 ; HALVE
PUSH P,B ; SAVE
MOVEI C,MSGALL ; DESIRED LEVEL OF MSG ALLOC
MOVE B,C
ASH B,-1 ; HALVE
PUSH P,B ; AND SAVE
LOAD T2,LTIDX,(UNIT) ; GET LINK TABLE INDEX
HRRZ B,IMPLT4(B) ; OUTSTANDING MSG ALLOC
SUB C,B ; NEEDED INCREMENT
SUB D,NETBAL(UNIT) ; NEEDED INCREMENT
LDB B,PLINK
LDB A,PFHST
CAMGE D,-1(P) ; IF GREATER THAN HALF
CAML C,0(P) ; FOR EITHER ONE
PUSHJ P,IMPALL ; THEN SEND AN ALLOCATE
ADJSP P,-2
NETRAX: NCPON
POPJ P,
FIRSTI: PUSHJ P,FRSTIO ; SET UP BUFFER
RET ;PASS ON DOWN BLOCK
JUMPG B,FRSTI1 ; BUFFER SPECIFIED. USE FOR ALLOCATION
PUSH P,A
MOVEI A,MAXBPM ; MAXIMUM BITS IN A MESSAGE
LDB B,PBPBYT ; CONNECTION BYTE SIZE
IDIV A,B ; BYTES
IMULI A,MSGALL ; TIMES MESSAGE ALLOCATION
ADDM A,0(P) ; THAT PLUS FILE BUFFER BYTES
POP P,B ; IS WHAT TO USE
FRSTI1: LDB D,PBPBYT ; GET BYTES SIZE
IMUL D,B ; BITS IN BUFFERS
MOVEM D,NETDAL(UNIT) ; SAVE DESIRED LEVEL
PUSHJ P,NETRAL ; SEND ALLOCATE AS NEEDED
RETSKP
WATLSN: LDB A,PFSM ; Get state of this connection
CAIN A,OPND
RETSKP
CAIN A,RFCR
JRST [ MOVEI A,ACPT
PUSHJ P,DOFSM
RETSKP]
CAIN A,RFCS ; If still waiting for rfc
JRST WATLS1 ; Continue waiting
CAIE A,LSNG
JRST [ MOVX IOS,EOTF
TDNE IOS,NETSTS(UNIT)
RETSKP ; Null file sent
MOVX IOS,ERRB!EOTF ; Connection never actually opened
IORB IOS,NETSTS(UNIT)
RETSKP]
WATLS1: MOVE T2,UNIT ;GET UNIT
ROT T2,-9 ;PUT IN BITS 0-8
HRLI T1,NOTTST ;TEST ROUTINE ADDRESS,,STATE
MOVSS T1 ;STATE TO WAIT FOR,,TEST ROUTINE ADDRESS
IOR T1,T2 ;UNIT/STATE,,TEST ROUTINE
TQO <BLKF> ;BLOCK FOR STATE CHANGE
RET
WATXXX: TQO <BLKF> ;TELL LOWER LEVEL TO BLOCK
RET
; Network file sequential byte output
NETSQO: HLRZ UNIT,FILSKT(JFN)
MOVE IOS,NETSTS(UNIT)
TQNE <DEDF,ERRB>
TQO <ERRF>
TQNE <DEDF,EOTF>
POPJ P,
PUSH P,A
TQNN <WNDF>
JRST NTSQO4
CALL FIRSTO
JRST [POP P,0(P) ;CLEAN UP STACK
RET] ;PASS ON DOWN BLOCK
NTSQO4: TQNE <BFSND> ; IMMEDIATE SEND?
JRST NTSQO1 ; No
LOAD T1,LTIDX,(UNIT) ;GET LINK TABLE INDEX
PUSHJ P,PKCHK ; HOW MANY BYTES CAN WE SEND?
POP P,C
JUMPE B,NTSQO3 ; NOT ENOUGH
PUSHJ P,PKBYT
JFCL
LDB A,PBPBYT
ADDM A,NETBTC(UNIT)
MOVNS A
ADDM A,NETBAL(UNIT)
MOVEI A,^D24
DPB A,PCLKS ; RESET CLOCK TO TWO MINUTES
POPJ P,
NTSQO1: SOSL FILCNT(JFN)
JRST NTSQO2
PUSHJ P,DMPBUF
JRST [POP P,C ;CLEAN UP STACK
JRST WATXXX] ; Can't dump now, wait
NTSQO2: AOS FILBYN(JFN)
POP P,A
IDPB A,FILBYT(JFN)
POPJ P,
NTSQO3: PUSHJ P,WATBAL ;WAIT FOR BITS AND A MSG TO BE ALLOCATED
JRST WATXXX ; ..
DMPBUF: MOVX IOS,ERRB ;GET ERROR HAS OCCURED FLAG
TDNE IOS,NETSTS(UNIT) ;HAS ERROR OCCURED?
TQO <ERRF> ;YES. INDICATE IT FOR THE JFN
ANDCAB IOS,NETSTS(UNIT) ;CLEAR ERROR FLAG FOR CONNECTION
MOVE T4,FILOFN(JFN) ;GET CURRENT OUTPUT POINT
CAML T4,FILBYN(JFN) ;DONE?
JRST DMPDUN ;YES
TQNE <EOTF,DEDF> ;END OF FILE OR DEAD HOST
JRST [ TQO <ERRF> ;YES. SET ERROR FOR JFN
SETZM FILBYT(JFN) ;ZERO BYTE POINTER
SETZM FILBYN(JFN) ;BYTE COUNT
SETZM FILOFN(JFN) ;AND CURRENT POSITION IN FILE
HRLOI T1,377777 ;AND SET NUMBER OF BYTES TO INFINITY
MOVEM T1,FILCNT(JFN)
RETSKP]
LOAD T1,LTIDX,(UNIT) ;GET LINK TABLE INDEX
CALL PKCHK ;HOW MANY BYTES CAN WE SEND?
JUMPE T2,WATBAL ;NONE, WAIT
MOVE T4,FILBYN(JFN) ;GET BYTE COUNT
SUB T4,FILOFN(JFN) ;GET NUMBER OF BYTES IN BUFFER
CAML T4,T2
MOVE T4,T2 ;TAKE MIN OF THE TWO
MOVE T2,NETBUF(UNIT) ;GET BUFFER ADR
HLL T2,FILBYT(JFN) ;GET BYTE SIZE
TLZ T2,770000 ;END OF FIRST WORD
TLNN T2,700 ;36 BIT MODE?
TLO T2,40000 ;NO GET BYTE OFFSET RIGHT
MOVE T3,FILOFN(JFN) ;GET BYTE OFFSET
ADJBP T3,T2 ;GET OFFSET POINTER
LOAD T1,LTIDX,(UNIT) ;GET LINK TABLE INDEX
PUSH P,T4 ;SAVE COUNT WE ARE ASKING FOR
CALL PKMSG ;GO PACK MESSAGE AND SEND IT
POP P,T4 ;GET BYTE COUNT BACK
ADDM T4,FILOFN(JFN) ;UPDATE BYTE COUNT OF BUFFER
LDB T3,PBPBYT ;GET BYTE SIZE
IMUL T4,T3 ;GIVES BITS JUST SENT
ADDM T4,NETBTC(UNIT) ;KEEP COUNT OF BITS SENT
MOVNS T4 ;GET NEGATIVE OF BITS SENT
ADDM T4,NETBAL(UNIT) ;UPDATE BIT ALLOCATION
; HRRM T2,NETSTS(UNIT) ;NEED TO HAVE MESSAGES GENERATED
MOVEI T1,^D24
DPB T1,PCLKS ;RESET CLOCK FOR THIS CONNECTION
JRST DMPBUF ;GO CHECK FOR ERRORS
DMPDUN: SETZM FILBYN(JFN) ;ZERO BYTE COUNT FOR BUFFER
SETZM FILOFN(JFN) ;ZERO CURRENT OUTPUT POINT
MOVE T1,NETBUF(UNIT) ;GET ADDRESS OF BUFFER
HLL T1,FILBYT(JFN) ;GET THE BYTE SIZE
TLZ T1,770000 ;SET AT END OF FIRST WORD
TLNN T1,700 ;36 BIT MODE?
TLO T1,40000 ;NO GET BYTE OFFSET RIGHT
MOVEM T1,FILBYT(JFN) ;SAVE BYTE POINTER
LDB T1,PBFSIZ ;GET BUFFER SIZE
SUBI T1,1 ;DECREMENT IT BY ONE
MOVEM T1,FILCNT(JFN) ;AND SAVE IT AS BYTES IN BUFFER
RETSKP
WATBAL: LOAD T1,LTIDX,(UNIT) ;GET LINK TABLE INDEX
CALL PKULCK ;UNLOCK CONNECTION TOO
MOVEI T1,BALTST ;GET ADDRESS OF TEST ROUTINE
HRL T1,UNIT ;AND UNIT TO WAIT ON
RET
FIRSTO: TQNN <BFSND> ; BUFFERED?
JRST [ PUSHJ P,WATLSN ; NO, WAIT FOR CONNECTION TO OPEN
RET ;PASS ON DOWN BLOCK
TQZ <WNDF>
RETSKP]
PUSHJ P,FRSTIO ; YES, SET UP BUFFER ETC
RET ;PASS ON DOWN BLOCK
RETSKP
;FRSTIO - SET UP BUFFER N JSB FREE SPACE
;ACCEPTS UNIT/ NETWORK PSEUDO UNIT NUMBER
;RETURNS +1 FAILURE
; +2 SUCCESS
; RH NETBUF(UNIT) HAS BUFFER ADDRESS
FRSTIO: CALL WATLSN ;WAIT FOR CONNECTION COMPLETE
RET ;PASS ON DOWN BLOCK
STKVAR <FRSTBY,FRSTBF>
LDB T2,PBYTSZ ;GET BYTE SIZE FROM JFN BLOCK
MOVEI T1,^D36 ;GET WORD SIZE
IDIVM T1,T2 ;CALCULATE BYTES PER WORD
MOVEM T2,FRSTBY ;SAVE BYTES PER WORD
LDB T3,PBPBYT ;GET NET CONNECTION BIT PER BYTE
IDIV T1,T3 ;GET BYTES PER WORD
IMUL T3,T1 ;CALCULATE BITS USED PER WORD
MOVEI T1,MAXBPM ;GET MAXIMUM BITS PER MESSAGE
IDIVM T1,T3 ;CALCULATE MAX WORDS FOR MESSAGE
LDB T1,PBFSIZ ;GET DESIRED BYTES IN BUFFER
MOVE T2,FRSTBY ;GET BYTES PER WORD
IDIVM T1,T2 ;CALCULATE NUMBER OF WORDS/ BUFFER
SKIPE T2 ;ZERO WORDS REQUESTED
CAML T2,T3 ;OR GREATER THAN MAX
MOVE T2,T3 ;YES. USE MAX WORDS/ BUFFER
MOVEM T2,FRSTBF ;SAVE WORDS/ BUFFER
AOS T2 ;NEED 1 WORD FOR FREE SPACE HEADER
CALL ASGJFR ;ASSIGN A PAGE IN JOB AREA
JRST [TQO <ERRF> ;INDICATE AN ERROR
RETBAD] ;RETURN
HRRM T1,NETBUF(UNIT) ;SAVE BUFFER ADDRESS
MOVE T3,FRSTBF ;GET SIZE AVAILABLE FOR BUFFER
MOVE T1,FRSTBY ;GET BYTES/WORD BACK
IMUL T1,T3 ;CALCULATE BYTES BUFFER WILL HOLD
LDB T2,PBFSIZ ;RETURN AS VALUE
DPB T1,PBFSIZ ;REAL BYTES PER BUFFER
TQZ <WNDF>
RETSKP
; Attach sockets to pty
; Call: 1 ; Receive jfn of opened network connection
; 2 ; Send jfn of opened network connection
; ATNVT
; Returns
; +1 ; Cannot attach
; +2 ; Ok. the jfns are released, ac 1 has line number of
; ; Attached pty.
.ATNVT::MCENT
STKVAR <ATUNTS,ATRCJF,ATNDAD>
UMOVE JFN,1
HRRZS JFN
PUSHJ P,CHKJFN ; Check jfn of receive connection
JRST ATPER0 ; Only real jfns are legal
JRST ATPER0
JRST ATPER0
MOVEI A,ATNX2 ; Error code if test skips
TQNE <READF> ; MUST BE OPENED FOR READING
PUSHJ P,CHKATP ; Check for dev=net, open, no buffer
JRST ATPER1 ; Failed one of the above
HLRZ UNIT,FILSKT(JFN)
MOVEM UNIT,ATUNTS ;SAVE DEV AND JFN
MOVEM JFN,ATRCJF
ATNVT1: UMOVE JFN,2 ; Get send jfn
PUSHJ P,CHKJFN ; Check it
JRST ATPER2 ; Must also be a real jfn
JRST ATPER2
JRST ATPER2
MOVEI A,ATNX2 ; Becomes atNx8 at atper3
TQNE <WRTF> ; THIS ONE MUST BE FOR WRITING
PUSHJ P,CHKATP ; And dev=net, open, no buffer
JRST ATPER3 ; Failed above tests
HLRZ UNIT,FILSKT(JFN)
LDB A,PFSM
CAIN A,RFCS
PUSHJ P,WATNOT ; Wait for response from foreign host
MOVEI A,ATNX12 ; Error code for refused send
LDB B,PFSM ; Now get state
CAIE B,OPND ; If not opnd
JRST ATPER4 ; Then fail
HRLM UNIT,ATUNTS ;SAVE SEND JFN IN LEFT HALF
HRRZ UNIT,ATUNTS ;SWITCH TO RECEIVE CONNECTION
LDB A,PFSM ; Get its state
CAIN A,RFCS
PUSHJ P,WATNOT ; Wait for response from foreign host
MOVEI A,ATNX6 ; Error code for refused receive
LDB B,PFSM
CAIE B,OPND ; If not opnd
JRST ATPER4 ; Then fail
ATNVT2: NCPOFF
LDB A,PFSM
CAIE A,OPND
JRST [ MOVEI A,ATNX6
JRST ATPERZ]
HLRZ UNIT,ATUNTS ;GET SEND UNIT
LDB A,PFSM
CAIE A,OPND
JRST [ MOVEI A,ATNX12
JRST ATPERZ]
UMOVE 1,1 ; GET OPTION FLAGS
HRR T1,ATUNTS ;SET UP ARGS, RECEIVE UNIT IN 1
HLRZ T2,ATUNTS ;SEND UNIT IN 2
PUSHJ P,ASNNVT ; Assign NVT to these units
JRST [ MOVEI A,ATNX13 ; Can't, no pty's
JRST ATPERZ]
MOVEM T2,ATNDAD ;SAVE ADDRESS OF DYNAMIC DATA
HRRZ UNIT,ATUNTS ;RECIEVE UNIT
MOVX T3,PROGF
ANDCAM T3,NETSTS(UNIT) ; PROGRAM NO LONGER LOOKING
HRRM T1,NETBUF(UNIT) ; Store pty number here
HLRZ UNIT,ATUNTS ;SEND UNIT
ANDCAM T3,NETSTS(UNIT) ; NOT HERE EITHER
HRRM T1,NETBUF(UNIT) ; Put pty here also
NCPON
IORI A,400000 ; Convert pty to tty designator
UMOVEM A,1 ; Return to user
PUSHJ P,RELJFN ; Release send jfn
MOVE JFN,ATRCJF
PUSHJ P,RELJFN ; And receive jfn
HRRZ UNIT,ATUNTS ;GET RECIEVE UNIT
MOVE T2,ATNDAD ;GET ADDRESS OF DYNAMIC DATA
CALL NVTRAL ;GO REALLOCATE
MOVE T2,ATNDAD ;GET ADDRESS OF DYNAMIC DATA
CALL ULKTTY ;UNLOCK DATA BASE
SMRETN ;RETURN SKIPPING
; Check validity of jfn for atpty
CHKATP: MOVEI A,ATNX3 ; Receive not open
TQNN <OPNF> ; IS IT OPEN?
POPJ P, ; NO
HRRZ B,DEV
MOVEI A,ATNX4
CAIE B,NETDTB
POPJ P,
MOVEI A,ATNX5
TQNN <WNDF>
POPJ P,
JRST RSKP
ATPERZ: NCPON
JRST ATPER4
ATPER2: MOVEI A,ATNX7 ; Bad send jfn
JRST ATPER5
ATPER3: ADDI A,ATNX7-ATNX1 ; Convert receive errors to send errors
ATPER4: PUSHJ P,UNLCKF
ATPER5: MOVE JFN,ATRCJF ;GET RECIEV JFN
MOVE STS,FILSTS(JFN)
ATPER1: PUSHJ P,UNLCKF
JRST MRETNE ; Save error return in ac1
ATPER0: MOVEI A,ATNX1 ; Bad receive jfn
JRST MRETNE
; Convert jfn to absolute network socket number
; Call: 1 ; Jfn
; CVSKT
; Returns
; +1 ; Error
; +2 ; Ok, in 2 the absolute socket number
.CVSKT::MCENT
MOVE JFN,1
PUSHJ P,CHKJFN
JRST CVSER0
JRST CVSER0
JRST CVSER0
HLRZ A,FILNEN(JFN)
HRLI A,(<POINT 7,0,35>)
PUSHJ P,NAMDEC
JRST CVSER1
TRZ A,1
PUSHJ P,UNLCKF
UMOVEM A,2
JRST SKMRTN
CVSER1: PUSHJ P,UNLCKF
SKIPA A,[CVSKX2]
CVSER0: MOVEI A,CVSKX1
JRST MRETNE
; Flush host
.FLHST::MCENT
MOVEI B,SC%WHL!SC%OPR
TDNN B,CAPENB
ITERR (WHELX1)
ANDI A,377 ;MAXIMUM HOST NUMBER ALLOWED IS 8 BITS
PUSHJ P,HSTDED
PUSHJ P,IMSRST
JRST MRETN
; Convert host number to string
.CVHST::MCENT
HRLZ D,MHOSTS ;SCAN ALL HOSTS IN NAME TABLES
LDB C,[POINT 9,HOSTN(D),17]
CAME C,B
AOBJN D,.-2
JUMPGE D,[EMRETN <CVHST1>] ;GET ERROR CODE AND RETURN TO USER
HRRZ A,HOSTN(D)
ADDI A,HSTNAM-1
PUSHJ P,JFNSS
JRST SKMRTN
; Get net status
NETGST: HLRZ UNIT,FILSKT(JFN)
MOVE A,NETSTS(UNIT)
LDB B,PFHST
UMOVEM B,3
MOVE B,FSKT(UNIT)
UMOVEM B,4
POPJ P,
; Set net status
NETSST: POPJ P,
; ASSIGN BUFFERS IN NETWORK AREA
RESCD
ASNTBF:: MOVE A,FORKX ; IS THIS THE NCP FORK?
CAMN A,NCPFRK
JRST ASNTB3 ; YES, GIVE HIM BUFFER IF WE CAN
MOVE A,NETFRE+2 ; NO, GIVE BUFFER ONLY IF ABOVE ASNTHR
CAMG A,ASNTHR
RET ; REFUSE REQUEST -- NOT ENOUGH SPACE
ASNTB3: CAILE B,MAXWPM ; BE SURE REQUEST NOT LARGER THAN WHAT WE HAVE
BUG (HLT,NETRBL,<ASNTBF: REQUEST FOR BUFFER LARGER THAN MAXWPM>)
AOS ASNTBC ; COUNT CALLS
LOCK NETFRE+1 ;LOCK NETWORK BUFFER FREE LIST
MOVE A,NETFRE ;GET POINTER TO CURRENT BUFFER
JUMPE A,ASNTB2 ;THERE ISN'T ONE
HRL B,0(A) ;GET CURRENT SIZE FIELD
HRRM B,0(A) ;STASH REQUESTED SIZE
HLRZS B ;MOVE OLD SIZE FIELD TO RH, CLEARING LH
CAIG B,MAXWPM ;MAKE SURE ITS NOT IN USE
BUG (HLT,NETBAU,<ASNTBF: ATTEMPT TO ASSIGN A BUFFER ALREADY IN USE>)
HLRZ B,0(A) ;GET POINTER TO NEXT ONE IN LIST
HRLI B,ANBSEC ;PUT ON SECTION ADDRESS
MOVEM B,NETFRE ;THAT BECOMES FIRST ONE
AOS 0(P) ;INDICATE SUCCESS
HRROI B,-MAXWPM ;MAINTAIN TOTAL SPACE AS A MATTER
;OF INTEREST
ADDM B,NETFRE+2
ASNTB2: UNLOCK NETFRE+1 ;UNLOCK FREE LIST
RET
; RELEASE NETWORK BUFFERS
RLNTBF::MOVE A,NETFRE+3 ;GET LOWER BUFFER AREA BOUNDARIES
CAMGE B,A ;RETURNED BUFFER .GE. LOWER BOUND?
JRST RLNTER ;NO, CRASH
MOVE A,NETFRE+4 ;GET UPPER BOUND
CAML B,A ;.LT. UPPER BOUND?
RLNTER: BUG (HLT,NETRBG,<RLNTBF: ATTEMPT TO RELEASE BUFFER AT GARBAGE LOCATION>)
LOCK NETFRE+1 ;LOCK FREE LIST
HRRZ A,0(B) ;GET COUNT FIELD
CAILE A,MAXWPM ;MAKE SURE NOT ALREADY ON FREELIST
BUG (HLT,NETBAF,<RLNTBF: ATTEMPT TO RELEASE BUFFER ALREADY ON FREE LIST>)
MOVE A,0(P) ;GET PC OF CALLER
HRL A,NETFRE ;GET POINTER TO CURRENT FIRST BUFFER
MOVEM B,NETFRE ;RETURNED ONE IS NOW FIRST
MOVEM A,0(B) ;AND POINTS TO OLD FIRST ONE
;SIZE FIELD IS PC OF CALLER
MOVEI A,MAXWPM ;MAINTAIN TOTAL SPACE COUNT
ADDM A,NETFRE+2
UNLOCK NETFRE+1 ;UNLOCK FREE LIST
RET
SWAPCD
; The following code and tables PROVIDE a finite state machine
; Implementation of the transitions and actions produced by various
; Events associated with a connection
; Assumed are that unit indexes the proper local socket
; Events are numbered as follows
RRFC==0 ; Received an rfc
CLSR==1 ; Cls for a receive socket
CLSS==2 ; Cls for a send socket
CLZR==3 ; Close done on a receive socket
CLZS==4 ; Close done on a send socket
ACPT==5 ; Program issued an accept
CONN==6 ; Program issued a connect
LISN==7 ; Program issued a listen
RRFN==10 ; Received a rfnm with no more data outstanding
HUNG==11 ; Time out event (happens 2 minutes after last dofsm)
RRFB==12 ; RECEIVED RFC WITH NON-MATCHING BYTE SIZE
; Actions are numbered as follows
ANOP==0 ; No operation
AFNY==1 ; No operation (unexpected event)
ACLS==2 ; Send cls
ARFC==3 ; Send rfc
AOPB==4 ; Send rfc and open link
AOPL==5 ; Open link
ACLL==6 ; Close link
ACLO==7 ; Close link and send cls
AEOR==10 ; END OF RECEIVE
AEOS==11 ; END OF SEND
AES1==12 ; END OF SEND WHEN ABORTED BY FOREIGN HOST
AABT==13 ; CONNECTION ABORTED BY FAR END
ACKA==14 ; CHECK ALLOCATION
; States are numbered as follows
DEAD==0 ; Never used
CLZD==1 ; Closed
PNDG==2 ; Pending. rfc received while closed
LSNG==3 ; Listening. listen issued while closed
RFCR==4 ; Rfc received while listening
CLW1==5 ; Close wait alternate. clzr from opnd
RFCS==6 ; Rfc sent
OPND==7 ; Opened
CLSW==10 ; Waiting for a cls
DATW==11 ; Waiting for all data to be sent
RFN1==12 ; Waiting for last rfnm
CLZW==13 ; Waiting for program close
RFN2==14 ; Waiting for rfnm after clss
NUSE==15 ; THIS STATE NO LONGER USED
FREE==16 ; Not in use
; The following table of byte pointers is used to get to the next state
; Given the current state and the event
; This table is indexed by event, the table addressed by this table
; Is indexed by old state
RADIX ^D10
QQ==3
CBPFSM: REPEAT 9,<
POINT 4,NXTSTT(B),QQ
QQ==QQ+4>
QQ==3
REPEAT 9,<
POINT 4,NXTSTT+1(B),QQ
QQ==QQ+4>
; Following table of pointers is used to get the action to be taken
; Given the current state and the event
; This table is indexed by event, the table addressed by this table
; Is indexed by old state
QQ==3
CBAFSM: REPEAT 9,<
POINT 4,ACTION(B),QQ
QQ==QQ+4>
QQ==3
REPEAT 9,<
POINT 4,ACTION+1(B),QQ
QQ==QQ+4
>
; This is the transition table
; Each word contains the new state for a given old state
; Successive bytes are used for different events
; Event rrfc clsr clss clzr clzs acpt conn lisn rrfe hung old state
NXTSTT:
BYTE (4)DEAD,DEAD,DEAD,DEAD,DEAD,DEAD,DEAD,DEAD,DEAD,DEAD,DEAD ; Dead
BYTE (4)PNDG,CLZD,CLZD,CLZD,CLZD,CLZD,RFCS,LSNG,CLZD,CLZD,CLZD ; Clzd
BYTE (4)PNDG,FREE,FREE,PNDG,PNDG,PNDG,OPND,RFCR,PNDG,CLSW,PNDG ; Pndg
BYTE (4)RFCR,LSNG,LSNG,FREE,FREE,LSNG,LSNG,LSNG,LSNG,LSNG,CLSW ; Lsng
BYTE (4)RFCR,FREE,FREE,CLSW,CLSW,OPND,RFCR,RFCR,RFCR,RFCR,RFCR ; Rfcr
BYTE (4)CLW1,FREE,FREE,CLW1,CLW1,CLW1,CLW1,CLW1,CLW1,FREE,CLW1 ; Clw1
BYTE (4)OPND,FREE,FREE,CLSW,CLSW,RFCS,RFCS,RFCS,RFCS,CLSW,CLSW ; Rfcs
BYTE (4)OPND,CLZW,RFN2,CLW1,DATW,OPND,OPND,OPND,OPND,OPND,OPND ; Opnd
BYTE (4)CLSW,FREE,FREE,CLSW,CLSW,CLSW,CLSW,CLSW,CLSW,FREE,CLSW ; Clsw
BYTE (4)DATW,DATW,RFN1,DATW,DATW,DATW,DATW,DATW,CLW1,CLW1,DATW ; Datw
BYTE (4)RFN1,RFN1,RFN1,RFN1,RFN1,RFN1,RFN1,RFN1,FREE,FREE,RFN1 ; Rfn1
BYTE (4)CLZW,CLZW,CLZW,FREE,FREE,CLZW,CLZW,CLZW,CLZW,CLZW,CLZW ; CLZW
BYTE (4)RFN2,RFN2,RFN2,RFN1,RFN1,RFN2,RFN2,RFN2,CLZW,CLZW,RFN2 ; Rfn2
BYTE (4)NUSE,NUSE,NUSE,NUSE,NUSE,NUSE,NUSE,NUSE,NUSE,NUSE,NUSE ; NUSE
BYTE (4)FREE,FREE,FREE,FREE,FREE,FREE,FREE,FREE,FREE,FREE,FREE ; Free
; This is the action table
; It is referenced the same as the transition table
; Event rrfc clsr clss clzr clzs acpt conn lisn rrfe hung old state
ACTION:
BYTE (4)AFNY,AFNY,AFNY,AFNY,AFNY,ANOP,AFNY,AFNY,AFNY,ANOP,AFNY ; Dead
BYTE (4)ANOP,AFNY,AFNY,AFNY,AFNY,ANOP,ARFC,ANOP,AFNY,ANOP,AFNY ; Clzd
BYTE (4)AFNY,ACLS,ACLS,AFNY,AFNY,ANOP,AOPB,ANOP,AFNY,ACLS,AFNY ; Pndg
BYTE (4)ANOP,AFNY,AFNY,ANOP,ANOP,ANOP,AFNY,AFNY,AFNY,ANOP,ACLS ; Lsng
BYTE (4)AFNY,ACLS,ACLS,ACLS,ACLS,AOPB,AFNY,AFNY,AFNY,ANOP,AFNY ; Rfcr
BYTE (4)AFNY,ACLL,ACLL,AFNY,AFNY,ANOP,AFNY,AFNY,AFNY,ACLL,AFNY ; Clw1
BYTE (4)AOPL,ACLS,ACLS,ACLS,ACLS,ANOP,AFNY,AFNY,AFNY,ACLS,ACLS ; Rfcs
BYTE (4)AFNY,AEOR,AES1,ACLS,AEOS,ANOP,AFNY,AFNY,AFNY,ACKA,AFNY ; Opnd
BYTE (4)ANOP,ANOP,ANOP,ANOP,ANOP,ANOP,AFNY,AFNY,AFNY,ANOP,AFNY ; Clsw
BYTE (4)AFNY,AFNY,AES1,AFNY,AFNY,ANOP,AFNY,AFNY,ACLS,ACLS,AFNY ; Datw
BYTE (4)AFNY,AFNY,AFNY,AFNY,AFNY,ANOP,AFNY,AFNY,ACLO,ACLO,AFNY ; Rfn1
BYTE (4)AFNY,AFNY,AFNY,ACLL,ANOP,ANOP,AFNY,AFNY,AFNY,ANOP,AFNY ; CLZW
BYTE (4)AFNY,AFNY,AFNY,ANOP,ANOP,ANOP,AFNY,AFNY,ACLO,ACLO,AFNY ; Rfn2
BYTE (4)AFNY,AFNY,AFNY,AFNY,AFNY,AFNY,AFNY,AFNY,AFNY,AFNY,AFNY ; NUSE
BYTE (4)AFNY,AFNY,AFNY,ANOP,ANOP,AABT,AFNY,AFNY,AFNY,ANOP,AFNY ; Free
;DISPATCH TABLE FOR ACTIONS
;ROUTINES ARE CALLED EFFECTIVELY BY PUSHJ P,@ACTAB(ACTION#)
ACTAB: IFIW!CPOPJ ;NOP
IFIW!FUNNY ;UNEXPECTED EVENT
IFIW!SNDCLS ;SEND CLS
IFIW!SNDRFC ;SEND STR OR RTS
IFIW!NETOPB ;SNED RFC AND OPEN LINK
IFIW!NETOPL ;OPEN LINK
IFIW!NETCLL ;CLOSE LINK
IFIW!NETCLB ;CLOSE LINK AND SEND CLS
IFIW!DOEOR ;FINISH UP INPUT
IFIW!DOEOS ;FINISH UP OUTPUT
IFIW!DOES1 ;END OF SEND IF TRANSMISSION ABORTED
IFIW!DOABT ;ACCEPT ON ABORTED CONNECTION
IFIW!CKALL ;ALLOCATIN CHECK FOR OPENED CONN
RADIX 8
;UNEXPECTED EVENT
; T1/ EVENT
; UNIT/ UNIT INDEX
FUNNY: HLL T1,NETSTS(UNIT) ;GET STATUS
LDB T2,PFHST ;GET FOREIGN HOST
BUG(INF,NCPFUN,<NCP FSM RECIEVED FUNNY INPUT>,<T1,T2,UNIT>)
AOS FUNNYC ;COUNT THEM
JRST NCPERR ;AND SEND TYPE 0 ERR
; ACCEPTED AN ABORTED REQUEST
DOABT: MOVX IOS,EOTF ; SET FLAG TO CAUSE ERROR
IORB IOS,NETSTS(UNIT) ; IN STATUS WORD
POPJ P,
; CHECK ALLOCATION
CKALL: MOVE A,LSKT(UNIT)
TRNN A,1 ; SEND SOCKET?
RET ; NO. DO NOTHING
TQNE <ALLFF> ; Allocation failure??
TQNN <CLZF> ; BEING CLOSED?
JRST CKALL1 ; NO, IGNORE
TQO <ERRB,EOTF> ; SIGNAL ERROR, AND STOP TRANSMISSION
MOVEM IOS,NETSTS(UNIT)
RET
CKALL1: LOAD T1,LTIDX,(UNIT) ;GET LINK TABLE INDEX
LDB B,PBPBYT
CAMG B,NETBAL(UNIT) ; SUFFICIENT BIT ALLOCATION?
SKIPN IMPLT4(A) ; AND MESSAGE SPACE?
JRST CKALL2 ; NO
TQZ <ALLFF>
MOVEM IOS,NETSTS(UNIT)
RET
CKALL2: LOAD T1,LTIDX,(UNIT) ;GET LINK TABLE INDEX
CALL IMPSYN ; RESYNC ALLOCATION
MOVX IOS,ALLFF
IORB IOS,NETSTS(UNIT) ; REMEMBER WE DID THIS ONCE
RET
; END OF SEND
DOES1: PUSHJ P,DOEOS
PUSHJ P,IMPABL ; FLUSH QUEUED MESSAGES
POPJ P,
DOEOS: MOVX IOS,EOTF
IORB IOS,NETSTS(UNIT)
LOAD T1,LTIDX,(UNIT) ;GET LINK TABLE INDEX
PUSHJ P,IMPSDB ; SET DONE BIT IN LINK TABLE
POPJ P,
; End of receive
DOEOR: PUSHJ P,SNDCLS
HRRZ B,NETBUF(UNIT)
JUMPE B,DOEOS
CAIL B,1000
JRST DOEOS
EORNVT: PUSHJ P,DOEOS ; DO SAME AS END OF SEND
NCPON ; NCP BACK ON SO NVTDET CAN USE IT
EORNV0: HRRZ B,NETBUF(UNIT) ; PICK UP LINE NUMBER
JUMPE B,EORNV1 ;ALREADY GONE
PUSH P,UNIT
CALL LCKDVL ;LOCK DEVICE LOCK, GO NOINT
CALL NVTDET
JRST EORNV2 ;FAILURE
EORNV3: UNLOCK DEVLCK ;UNLOCK THE DEVICE LOCK
OKINT ;DEVLCK WENT NOINT
POP P,UNIT
EORNV1: NCPOFF ; BACK OFF SO CALLER IS NOT CONFUSED
POPJ P,
EORNV2: TXZN T1,1B0 ;WAIT OR ERROR?
JRST [ BUG (CHK,NETDET,<NVTDET: COULD NOT CLOSE NVT>,<T1>)
JRST EORNV3] ;GO CLEAN UP
UNLOCK DEVLCK ;UNLOCK THE DEVICE LOCK
OKINT ;DEVLCK WENT NOINT
POP P,UNIT
HRL T1,NETBUF(UNIT) ;GET TTY NUMBER
MDISMS ;WAIT UNTIL DEALLOCATE IS POSSIBLE
JRST EORNV0 ;GO TRY AGAIN
; Close link
NETCLL: LOAD T1,LTIDX,(UNIT) ;GET LINK TABLE INDEX
PUSHJ P,IMPCLL
POPJ P,
NETCLB: PUSHJ P,NETCLL
SNDCLS: LDB A,PFHST ; Get foreign host
MOVE C,FSKT(UNIT) ; And foreign socket
MOVE B,LSKT(UNIT) ; And local socket
TQNN <DEDF>
PUSHJ P,IMPCLS ; Send the control message
POPJ P,
; OPEN LINK
NETOPL: LDB A,PFHST
MOVE B,LSKT(UNIT)
TRNE B,1 ; Send socket?
IORI A,1000 ; Mak as such
LDB B,PLINK ; Get link
LDB C,PBPBYT
PUSHJ P,IMPOPL
STOR T1,LTIDX,(UNIT) ;SAVE LINK TABLE INDEX
POPJ P,
; Send rfc and open link
NETOPB: PUSHJ P,NETOPL
JRST SNDRFC
; Send rfc
SNDRFC: TQNE <DEDF>
POPJ P,
LDB A,PFHST ; Get foreign host
MOVE B,LSKT(UNIT) ; And local socket
MOVE C,FSKT(UNIT)
LDB D,PBPBYT ; Byte size
TRNE B,1
JRST IMPSTR
LDB D,PLINK
JRST IMPRTS ; Send control message
; This here is the main fsm routine
DOFSM: MOVE IOS,NETSTS(UNIT)
TQNN <DEDF>
JRST DOFSMA
PUSHJ P,DOFSMA
LDB A,PFSM
DOFSMB: PUSH P,A
MOVEI A,HUNG
PUSHJ P,DOFSMA
LDB A,PFSM
POP P,B
CAME A,B
JRST DOFSMB
POPJ P,
DOFSMA: NCPOFF ; Allow no control messages while here
PUSH P,A ; Save event for footprints
MOVEI B,^D24 ; Time out in 2 minutes
DPB B,PCLKS
LDB B,PFSM ; Get old state
PUSH P,B
LSH B,1 ; Two words per old state
LDB C,CBPFSM(A) ; Get new state
LDB B,CBAFSM(A) ; Get action
DPB C,PFSM
PUSH P,B ; Save action
MOVE B,-1(P) ; Get old state
CAME C,B ; State changed?
PUSHJ P,STCPSI ; GENERATE STATE CHANGE PSI
DOFSM2: POP P,B ; GET ACTION
ADJSP P,-1 ; FLUSH OLD STATE
POP P,A ; Restore event
PUSHJ P,@ACTAB(B) ; Call action routine
NCPON
POPJ P,
; Generate state change PSI
STCPSI: HRRE A,NETFRK(UNIT)
JUMPL A,CPOPJ ; No fork for interrupts
LDB B,PFSMCH ; Get psi channel
CAIL B,^D36
POPJ P,
EXCH A,B
PUSHJ P,PSIRQ
POPJ P,
; Make a socket or find existing one
GETSKT: TDZA D,D
MAKSKT: SETO D,
PUSH P,D
PUSH P,A ; Save foreign host
PUSH P,B ; Save foreign socket
PUSH P,C ; Save local socket
MOVE UNIT,C
XOR UNIT,B
TRNN UNIT,1 ; Homosexual?
JRST MAKSKX ; Yes. error
ROT C,-4
MOVS UNIT,C
IMULI C,123431
XOR UNIT,C ; Randomize from local socket
LSH UNIT,-1
MULI UNIT,NSKT ; Initial probe
MOVEI D,NSKT
SETO C,
NCPOFF
MAKSKL: LDB A,PFSM ; Get state of this socket
CAIE A,FREE
CAIN A,DEAD
JRST MAKSK1
CAIN A,CLZW ; WAITING FOR USER TO CLOSE?
JRST MAKSKN ; YES. DON'T PICK THIS ONE
MOVE B,LSKT(UNIT) ; What local socket is this for?
CAME B,(P)
JRST MAKSKN ; Not the one we're after, try next
MAKSK3: SKIPGE -2(P)
JRST MAKSK6
LDB B,PFHST
MOVE A,FSKT(UNIT)
CAIN B,777
JRST [ SKIPN -3(P) ; Was getskt called?
JRST MAKSKN ; Yes, getskt called
POP P,C ; Makskt...suceed
JRST MAKSKF]
CAMN B,-2(P)
CAME A,-1(P)
JRST MAKSKN ; Foreign host or socket doesn't match
AOS -4(P) ; EVERYTHING MATCHES. SKIP RETURN
SETZ A,
JRST MAKSKV ; NCPON, POP STACK
MAKSK6: POP P,C
ADJSP P,-3
MOVE B,FSKT(UNIT)
LDB A,PFHST
NCPON
JRST RSKP
MAKSKN: SOJLE D,MAKSKE ; Full, error
SOJGE UNIT,MAKSKL ; Loop back for next slot
MOVEI UNIT,NSKT-1
JRST MAKSKL
MAKSK1: MOVX B,PROGF
TDNE B,NETSTS(UNIT)
JRST MAKSKN ; Ignore those assigned to programs
SKIPGE C
MOVE C,UNIT ; Save where it's at
CAIE A,DEAD
JRST MAKSKN ; Space keeper, test next
MAKSK5: SKIPN -3(P)
JRST MAKSKR
MOVE UNIT,C
SETZM NETSTS(UNIT)
SETZM NETBUF(UNIT)
SETZM NETAWD(UNIT)
SETZM NETBAL(UNIT)
SETZM NETBTC(UNIT)
SETOM NETFRK(UNIT)
MOVEI A,CLZD
DPB A,PFSM ; Set its state to be closed
POP P,C
MOVEM C,LSKT(UNIT)
MAKSKF: MOVE A,-1(P) ; Foreign host
MOVE B,LSKT(UNIT)
TRNE B,1 ; Receive?
JRST MAKSKQ
PUSHJ P,ASNLNK ; Assign link for that host
JRST [ LDB A,PFSM
MOVEI B,FREE
CAIN A,CLZD ; Just created?
DPB B,PFSM ; Yes, delete it
PUSH P,LSKT(UNIT)
JRST MAKSKR] ; And fail
MAKSKQ: POP P,B ; Common for old and new
MOVEM B,FSKT(UNIT)
POP P,A
DPB A,PFHST
ADJSP P,-1
NCPON
JRST RSKP
MAKSKE: JUMPGE C,MAKSK5
MAKSKW: SKIPA A,[0] ; FULL
MAKSKR: MOVEI A,4 ; NON-EXISTENT
MAKSKV: NCPON
SKIPA A,A
MAKSKX: MOVEI A,3 ; BAD PARAMETERS
HRLM A,-2(P) ; STORE ERROR CODE
POP P,C
POP P,B
POP P,A
ADJSP P,-1
POPJ P,
; Assign link number for this connection
ASNLNK: PUSH P,B
PUSH P,C
PUSH P,D
MOVEI D,1(P) ; Where bits will be
PUSH P,[<1B<FLINK>-1>_1+1]
REPEAT NLNKBW-2,<PUSH P,[-1]>
PUSH P,[-<1B<LLINK-<^D36*<NLNKBW-1>>-1>>]
PUSH P,UNIT ; Preserve unit
PUSH P,A
MOVSI UNIT,-NSKT
ASNLNL: LDB A,PFSM
CAIE A,FREE
CAIN A,DEAD
JRST ASNLNN
LDB A,PFHST
CAME A,0(P) ; Check all connection to this host
JRST ASNLNN ; Get next
MOVE A,LSKT(UNIT)
TRNE A,1 ; Only receive connections
JRST ASNLNN
LDB A,PLINK ; Get link assigned
IDIVI A,^D36 ; Separate word and bit
MOVE B,BITS(B) ; Get the bit
ADD A,D
ANDCAM B,0(A) ; Clear bits for links in use
ASNLNN: AOBJN UNIT,ASNLNL ; Loop thru all connections
HRLI D,-NLNKBW ; Prepare to look at all bits
SETZ C,
ASNLNC: MOVE A,0(D)
JFFO A,ASNLNF
ADDI C,^D36
AOBJN D,ASNLNC
JRST ASNLN1 ; Failed
ASNLNF: ADD B,C
ASNLN0: POP P,A
POP P,UNIT
DPB B,PLINK
ADJSP P,-NLNKBW
AOS -3(P)
ASNLN1: POP P,D
POP P,C
POP P,B
POPJ P,
; Do a listen (openf for file with no foreign host/socket)
LISTEN: PUSHJ P,HSTCHK
POPJ P,
PUSH P,D ; Save byte size
PUSHJ P,MAKSKT ; Make a socket
JRST [ POP P,D
MOVEI A,OPNX10
POPJ P,] ; No room
MOVEI A,LISN
JRST CONNE1
; Do a connect (openf for file with foreign host/socket specified)
CONNEC: PUSHJ P,HSTCHK
POPJ P,
PUSH P,D ; Save byte size
PUSHJ P,MAKSKT ; Make a socket or find existing one
JRST [ POP P,D
MOVEI A,OPNX10
POPJ P,] ; No room
MOVEI A,CONN
CONNE1: NCPOFF
LDB B,PFSM
CAIN B,CLZD ; Received any rfc here?
JRST CONNE2 ; No
CAIN B,PNDG ; Same question
JRST CONNE3 ; Yes
MOVEI A,OPNX9 ; Already in use
POP P,D
NCPON
POPJ P,
CONNE2: MOVX D,PROGF
IORM D,NETSTS(UNIT) ; Mark as attached to program
NCPON
POP P,D ; My choice of byte size
DPB D,PBPBYT ; Set byte size
PUSHJ P,DOFSM ; Send rfc etc
JRST RSKP
CONNE3: TRNE C,1 ; Are we sender?
JRST CONNE2 ; Also our choice
LDB D,PBPBYT ; Get his byte size
CAMN D,0(P) ; Does byte size agree?
JRST CONNE2 ; Yes, same as if my choice
NCPON
MOVEI A,HUNG ; Flush his connection attempt
PUSHJ P,DOFSM
POP P,D
MOVEI A,OPNX22 ; Bad byte size error
POPJ P,
; Check if host is available
HSTCHK: SKIPL IMPRDY
JRST [ MOVEI A,OPNX19
POPJ P,]
JUMPL 1,RSKP ; ALWAYS OK IF LISTEN
PUSH P,B
PUSH P,A
IDIVI A,^D36
MOVE B,BITS(B)
TDNE B,IMPBHT(A)
JRST [ MOVEI A,OPNX20
JRST HSTCHF]
TDNE B,IMPHRT(A)
JRST HSTCHO
MOVE A,0(P)
PUSH P,3
PUSH P,4
PUSH P,5
PUSHJ P,IMSRST ; RESET HIM
POP P,5
POP P,4
POP P,3
MOVE A,TODCLK ; GET NOW
ANDI A,377777
ADDI A,^D5000 ; PLUS 5 SECONDS
ANDI A,777777-377 ; LEAVE ROOM FOR HOST
IOR A,0(P)
HRLI A,HUPTST ; TEST ADDRESS
MOVSS A
MDISMS
MOVE A,0(P)
IDIVI A,^D36
MOVE B,BITS(B)
TDNN B,IMPHRT(A)
JRST [ MOVEI A,OPNX20
JRST HSTCHF]
HSTCHO: POP P,A
AOSA -1(P)
HSTCHF: ADJSP P,-1
POP P,B
POPJ P,
RESCD
HUPTST: MOVE 2,1
ANDI 2,377
IDIVI 2,^D36
MOVE 3,BITS(3)
TDNE 3,IMPHRT(2)
JRST 1(4)
ANDCMI 1,377
JRST BLOCKW ; CHECK TIME RUN OUT
SWAPCD
; Routines to call when control messages are received
; Receive cls
; Reccls(fhost,fskt,lskt)--nil
RECCLS::PUSHJ P,GETSKT ; Get the socket entry
JRST NCPERR
RECCL1: MOVE B,LSKT(UNIT)
TRNN B,1
SKIPA A,[CLSR]
MOVEI A,CLSS
PUSHJ P,DOFSM
POPJ P,
; RECEIVED INCORRECT MESSAGE
; REPLY WITH ERR
NCPERR: PUSH P,1 ; SAVE AC'S
PUSH P,2
PUSH P,3
PUSH P,4
PUSH P,5
MOVE 5,[I8CAL,,3] ; COMPLAIN ABOUT LAST CONTROL MESSAGE
BLT 5,5
HLRZ 2,1 ; SUBCODE TYPE FOR "ERR" MSG
HRRZS 1 ; AND HOST TO COMPLAIN TO.
PUSHJ P,IMPERR
POP P,5
POP P,4
POP P,3
POP P,2
POP P,1
HRRZS 1
POPJ P,
; Receive str
; Recstr(fhost,fskt,lskt)--nil
RECSTR::PUSH P,D ; Save byte size
RCSTR0: PUSHJ P,MAKSKT
JRST [ POP P,D
JRST NCPERR]
MOVE D,0(P)
PUSHJ P,CHKSKT ; MAKE SURE THIS SOCKET NOT IN USE
JRST RCSTR0 ; IT WAS. DELETED. NOW TRY AGAIN.
LDB A,PFSM ; What is state of this connection
CAIE A,CLZD ; If not clzd
JRST [ LDB D,PBPBYT ; Then get user's byte size
CAMN D,0(P) ; If not the same
JRST .+1
MOVEI A,RRFB ; RECEIVED BAD BYTE SIZE
PUSHJ P,DOFSM
MOVX A,ERRB
IORM A,NETSTS(UNIT)
POP P,D
POPJ P,]
POP P,D
DPB D,PBPBYT
MOVEI A,RRFC
PUSHJ P,DOFSM
MOVE A,UNIT
LDB B,PLINK
POPJ P,
CHKSKT: PUSH P,A
PUSH P,B
PUSH P,C
PUSH P,D
LDB A,PFSM ; GET STATE
CAIE A,RFCS ; STATES WHERE RFC IS EXPECTED
CAIN A,CLZD
JRST SKTCK1
CAIN A,LSNG
SKTCK1: AOSA -4(P) ; OK, SKIP RETURN
PUSHJ P,SK2DWN ; ELSE KILL THE OLD ONE
POP P,D
POP P,C
POP P,B
POP P,A
POPJ P,
CHKLNK: PUSH P,A
PUSH P,B
PUSH P,C
PUSH P,D
MOVSI UNIT,-NSKT
CHKLK1: LDB B,PLINK ; GET THE LINK
LDB C,PFHST ; AND HOST
CAMN B,0(P)
CAME C,-3(P)
JRST CHKLK2
MOVE B,LSKT(UNIT)
TRNN B,1
JRST CHKLK2 ; SKIP SEND CONNECTIONS
LDB B,PFSM ; LINK-HOST MATCHES. GET STATE
CAIE B,DEAD
CAIN B,FREE
JRST CHKLK2
CAIE B,CLZD
CAIN B,RFCS
JRST CHKLK2
CAIE B,LSNG
CAIN B,CLZW
JRST CHKLK2
PUSHJ P,SK2DWN
CHKLK2: AOBJN UNIT,CHKLK1
POP P,D
POP P,C
POP P,B
POP P,A
POPJ P,
; Receive rts
; Recrts(fhost,fskt,lskt,link)
RECRTS::PUSHJ P,CHKLNK ; CHECK AND DELETE ANY MATCHING LINKS
PUSH P,D ; SAVE LINK
PUSHJ P,MAKSKT ; MAKE SOCKET TABLE ENTRY
JRST [ POP P,D ; FAILED, SEND ERR
JRST NCPERR]
POP P,D ; RESTORE LINK
PUSHJ P,CHKSKT ; MAKE SURE NO DUPLICATES
JRST RECRTS ; PREVIOUS CONNECTION CLOSED. TRY AGAIN
DPB D,PLINK
MOVEI A,RRFC
PUSHJ P,DOFSM
POPJ P,
; Receive rfnm
RCFRFN::MOVEI A,RRFN
PUSHJ P,DOFSM
POPJ P,
; Receive ins/inr
RECINR::
RECINS::LDB B,PINTCH
LDB A,PFSM
CAIGE B,^D36 ; RETURN IF CHANNEL IS 77 OCTAL
CAIE A,OPND
POPJ P,
HRRZ A,NETBUF(UNIT)
SKIPE A
CAIL A,1000
CAIA
POPJ P,
HRRE A,NETFRK(UNIT)
JUMPL A,CPOPJ
EXCH A,B
PUSHJ P,PSIRQ
POPJ P,
; INITIATE SERVICE INTERRUPTION (HOST DEAD)
SVCINT::MOVX IOS,SVCIF
IORB IOS,NETSTS(UNIT)
PUSHJ P,STCPSI ; GENERATE STATE CHANGE PSI
POPJ P,
; TERMINATE SERVICE INTERRUPTION
SVCRST::MOVX IOS,SVCIF
ANDCAB IOS,NETSTS(UNIT)
PUSHJ P,STCPSI
POPJ P,
; Receive reset message
RECRST::PUSHJ P,NETHDN
JRST IMPRRP
; BITS AND FIELD VALUES FOR B0-8 OF HOSTN TABLE
SERVER==400000
USER==200000
NICKNAME==100000
TENEX==1000
ITS==2000
DEC==3000
TIP==4000
MTIP==5000
ELF==6000
ANTS==7000
MULTICS==10000
OPST20==11000
HSTINI::PUSH P,7
PUSH P,6
PUSH P,5
MOVEI 1,400000
RCM ; GET CHANNELS THAT ARE ON
PUSH P,1 ; REMEMBER THEM
MOVEI 1,400000
MOVSI 2,(1B10)
DIC ; TURN OFF EOF CHANNEL
MOVSI 1,(1B2+1B17)
HRROI 2,[ASCIZ \<SYSTEM>HSTNAM.TXT\]
GTJFN
JRST HSTINF ; FAIL
PUSH P,1
MOVE 2,[7B5+1B19]
OPENF
JRST [ POP P,1
RLJFN
JFCL
JRST HSTINF] ; FAIL
SETZM HSTNAM ; CLEAR OLD STUFF IN TABLE
MOVSI 4,HSTNAM ; (TELNET FAILS IF THIS ISN'T DONE
HRRI 4,HSTNAM+1 ; AND IT LOOKS NEATER TO HAVE WHOLE
BLT 4,HSTNAM+NHSTN-1 ; WORD OF NULL AFTER EACH NAME)
SETZM NWPBT ; ALSO CLEAR NEW PROTOCOL BIT TABLE
MOVSI 4,NWPBT
HRRI 4,NWPBT+1
BLT 4,NWPBT+^D<<256+35>/36>-1
MOVEI 4,HOSTN
MOVEI 5,HSTNAM
LUP0: PUSHJ P,GCH
JRST DONE
MOVEM 3,7 ; SAVE IN CASE THIS IS ALINE
CAIN 2,12
JRST LUP0
CAIGE 4,HOSTN+NHOSTS
CAIL 5,HSTNAM+NHSTN
JRST FULL
BKJFN
JFCL
RFPTR
JFCL
PUSH P,2
MOVEI 3,10
NIN
JRST [ HRLI 6,[ASCIZ /BAD NUMBER/]
POP P,3
JRST SYNERR]
POP P,3
CAILE 2,0
CAILE 2,377
JRST [ HRLI 6,[ASCIZ /HOST NUMBER OUT OF RANGE/]
JRST SYNERR]
HRLZM 2,0(4) ; STORE HOST NUMBER
BKJFN
JFCL
LUP4: PUSHJ P,GCH
JRST PEOF
CAIE 2,","
JRST [ HRLI 6,[ASCIZ /MISSING COMMA AFTER HOST NUMBER/]
JRST SYNERR]
MOVE 6,5 ; TEMP FOR BYTE POINTER
SUBI 6,HSTNAM ; MAKE RELATIVE POINTER
HRRM 6,0(4) ; STORE IN RH OF HOSTN
MOVE 6,5 ; TEMP POINTER AGAIN
HRLI 6,440700 ; 7 BIT LEFT JUSTIFIED
LUP1: PUSHJ P,GCH ; READ NEXT CHARACTER
JRST PEOF
CAIE 2,12 ; TERMINATE ON END OF LINE
CAIN 2,","
SETZ 2, ; OR COMMA
IBP 6
HRRZ 1,6 ; WHERE ARE WE GOING TO PUT THIS?
CAIL 1,HSTNAM+NHSTN ; OFF END OF TABLE?
JRST FULL ; YES, SAY FULL
DPB 2,6 ; STORE THE BYTE
JUMPN 2,LUP1 ; LOOP IF NOT THE END
MOVE 1,0(P)
BKJFN ; GET THE TERMINATOR AGAIN
JFCL
LUP2: PUSHJ P,GCH
JRST PEOF
LUP2A: CAIN 2,12
JRST LUP2X ; DONE IF END OF LINE
CAIE 2,"," ; SCAN UNTIL COMMA FOUND
JRST LUP2
LUP3: PUSHJ P,GCH ; GET FIRST LETTER OF WORD
JRST PEOF
CAIN 2,","
JRST LUP2A ; JUMP IF NULL WORD
CAIN 2,12
JRST LUP2X ; DONE IF END OF LINE
GWORD: SETZ 1, ; PUT VALUE OF WORD HERE
CAIN 2,"A"
MOVSI 1,ANTS
CAIN 2,"D"
MOVSI 1,DEC
CAIN 2,"E"
MOVSI 1,ELF
CAIN 2,"I"
MOVSI 1,ITS
CAIN 2,"M"
JRST [ PUSHJ P,GCH
JRST PEOF
CAIN 2,"U"
MOVSI 1,MULTICS
CAIN 2,"T"
MOVSI 1,MTIP
JRST ELUP3]
CAIN 2,"N"
JRST [ PUSHJ P,GCH
JRST PEOF
CAIN 2,"E"
JRST SETNWP
CAIN 2,"I"
MOVSI 1,NICKNAME
JRST ELUP3]
CAIN 2,"S"
MOVSI 1,SERVER
CAIN 2,"T"
JRST [ PUSHJ P,GCH
JRST PEOF
CAIN 2,"E"
MOVSI 1,TENEX
CAIN 2,"I"
MOVSI 1,TIP
JRST ELUP3]
CAIN 2,"U"
MOVSI 1,USER
ELUP3: HRLI 6,[ASCIZ /UNRECOGNIZED FLAG NAME/]
JUMPE 1,SYNERR ; JUMP IF NO MATCH FOUND
MOVSI 2,(17B8)
HRLI 6,[ASCIZ /MULTIPLE SYSTEM TYPE SPECIFICATION/]
TDNE 2,0(4) ; ALREADY HAVE A SYSTEM TYPE?
TDNN 2,1 ; YES AND IS THIS TRYING TO SET IT?
SKIPA
JRST SYNERR ; YES. ERROR
IORM 1,0(4) ; ACCUMULATE BITS
JRST LUP2 ; AND SKIP TO COMMA/EOL
LUP2X: MOVEI 5,1(6) ; START NEXT STRING IN NEXT WORD
AOJA 4,LUP0 ; STEP TO NEXT HOSTN SLOT AND LOOP
SETNWP: LDB 1,[POINT 8,0(4),17] ; GET HOST NUMBER
IDIVI 1,^D36
MOVE 2,BITS(2)
IORM 2,NWPBT(1)
JRST LUP2
PEOF: MOVE 1,0(P)
RFPTR
JFCL
MOVE 3,2
HRLI 6,[ASCIZ /PREMATURE END OF FILE/]
SYNERR: HLRO 1,6
PSOUT
HRROI 1,[ASCIZ / IN HOST DESCRIPTOR FILE
/]
PSOUT
MOVE 2,7
MOVE 1,0(P)
SFPTR ; SET BACK TO BEGINNING OF LINE
JFCL
SETO 7,
PERLP: MOVE 1,0(P)
RFPTR
JFCL
CAME 2,3
JRST PERLP1
MOVEI 1,101
RFPOS
HRRZ 7,2
PERLP1: MOVE 1,0(P)
PUSHJ P,GCH1
MOVEI 2,12
CAIN 2,12
JRST PERLPX
MOVE 1,2
PBOUT
JRST PERLP
PERLPX: HRROI 1,[ASCIZ /
/]
PSOUT
JUMPLE 7,PMRK
MOVEI 1,40
PBOUT
SOJG 7,.-1
PMRK: MOVEI 1,"^"
PBOUT
HRROI 1,[ASCIZ /
/]
PSOUT
JRST LUP0
FULL: HRROI 1,[ASCIZ /HOST TABLES FULL BEFORE END OF FILE
/]
PSOUT
JRST DONE
DONE: PUSH P,5
MOVE 2,4
SUBI 2,HOSTN
MOVNM 2,MHOSTS ; SAVE FOR CVHST, ...
MOVEI 1,GTTAB+.HOSTN
CALL SETGTB
POP P,2
SUBI 2,HSTNAM
MOVEI 1,GTTAB+.HSTNA
CALL SETGTB
POP P,1
CLOSF
JFCL
AOS -4(P) ; SUCCESS RETURN
HSTINF: POP P,2 ; GET CHANNELS THAT WERE ON BEFORE
MOVEI 1,400000
AIC ; TURN THEM BACK ON
POP P,5
POP P,6
POP P,7
POPJ P,
SETGTB: PUSH P,2
PUSH P,1
CALL FPTA
PUSH P,1
CALL MRPACS
HRLZ 2,1
PUSH P,2
TLO 2,40000
MOVE 1,-1(P)
CALL MSPACS
push p,3
MOVE 2,-4(P)
move 3,-3(P)
HRLM 2,(3)
pop p,3
POP P,2
POP P,1
CALL MSPACS
POP P,1
POP P,2
POPJ P,
GCH: MOVE 1,-1(P)
RFPTR
JFCL
MOVEM 2,3
GCH2: PUSHJ P,GCH1
POPJ P,
CAIN 2,";"
JRST GCHSMC
CAIE 2,11
CAIN 2,40
JRST GCH2
GCHX: CAIN 2,37
MOVEI 2,12
AOS 0(P)
POPJ P,
GCH1: BIN
CAIE 2,15
CAIN 2,14
JRST GCH1
JUMPN 2,RSKP
GCHNUL: GTSTS
TLNE 2,1000
POPJ P,
JRST GCH1
GCHSMC: BIN
CAIE 2,37
CAIN 2,12
JRST GCHX
JUMPN 2,GCHSMC
GTSTS
TLNN 2,1000
JRST GCHSMC
POPJ P,
; Kill all connection -- net is down
NETDWN::MOVSI UNIT,-NSKT
PUSHJ P,SKTDWN
AOBJN UNIT,.-1
; Periodic check of all connections for time-out
NETCHK::MOVSI UNIT,-NSKT
NETCKL: LDB A,PFSM
CAIE A,DEAD
CAIN A,FREE
JRST NETCKN
MOVX A,DEDF
TDNN A,NETSTS(UNIT)
SKIPL IMPRDY
JRST NETCK1
LDB B,PCLKS
SOS B
DPB B,PCLKS
JUMPG B,NETCKN
NETCK1: MOVEI A,HUNG
PUSHJ P,DOFSM
NETCKN: AOBJN UNIT,NETCKL
MOVEI A,^D5000
SKIPL IMPRDY
MOVEI A,^D500
ADD A,TODCLK
MOVEM A,NETTIM
POPJ P,
; Host has died
NETHDN::MOVSI UNIT,-NSKT
PUSH P,A
NETHDL: LDB A,PFSM
CAIE A,FREE
CAIN A,DEAD
JRST NETHDX
LDB A,PFHST
CAMN A,(P)
PUSHJ P,SKTDWN
NETHDX: AOBJN UNIT,NETHDL
POP P,A
POPJ P,
SK2DWN::HRRZ B,NETBUF(UNIT)
CALL NVTCHK ; AN NVT?
JRST SKTDWN ; NO, TREAT NORMALLY
PUSH P,UNIT
PUSH P,B
PUSHJ P,SKTDWN
MOVE B,0(P)
CALL NVTIPU ;GET INPUT UNIT
SKIPA ;NO UNITS FOR THIS LINE
PUSHJ P,SKTDWN ; CLOSE THE OTHER HALF
POP P,B ;GET ADDRESS OF DYNAMIC DATA FOR TTY
CALL ULKTTY ;UNLOCK DATA BASE
POP P,UNIT
POPJ P,
SKTDWN: LDB A,PFSM ; GET STATE
CAIN A,LSNG ; IF LSNG
POPJ P, ; IGNORE
MOVX B,ERRB!DEDF
IORM B,NETSTS(UNIT)
CAIE A,CLSW ; IF WAITING FOR CLOSE,
CAIN A,CLW1
PUSHJ P,SKTDW2 ; PRETEND ONE HAPPENED.
CAIE A,RFCR
CAIN A,OPND ; If opnd
SKTDW2: PUSHJ P,RECCL1 ; Simulate receipt of cls
MOVEI A,HUNG
PUSHJ P,DOFSM
POPJ P,
TNXEND
END