Trailing-Edge
-
PDP-10 Archives
-
BB-4170G-SM
-
sources/impdv.mac
There are 16 other files named impdv.mac in the archive. Click here to see a list.
;<3A-MONITOR>IMPDV.MAC.3, 22-Apr-78 20:38:25, Edit by BORCHEK
;SPEED UP NETWORK CODE
;REMOVE USELESS INSTRUCTION IN BYTE LOOPS
;<3A.MONITOR>IMPDV.MAC.2, 19-Mar-78 13:15:57, Edit by BORCHEK
;SPREAD OUT STARTUP RST'S SO BUFFER SPACE IS NOT DEPLETED
;<4.MONITOR>IMPDV.MAC.1, 6-Dec-77 17:12:18, EDIT BY CROSSLAND
;FIX ASNSQ TO USE RIGHT REGISTER IN CONSTRUCTING DIFFERENCE.
;<3-MONITOR>IMPDV.MAC.18, 7-Nov-77 13:02:31, EDIT BY KIRSCHEN
;MORE COPYRIGHT UPDATING...
;<3-MONITOR>IMPDV.MAC.17, 25-Oct-77 01:27:23, EDIT BY CROSSLAND
;CLEAR RFNM COUNT, RETRANSMISSION FLAG AND BUFFER BEFORE UNLOCKING
;BUFFERS ON INTERFACE RESET TO PREVENT IMPMSO BUGINF'S
;<3-MONITOR>IMPDV.MAC.16, 19-Oct-77 00:57:51, EDIT BY CROSSLAND
;REPLACE JFCL'S IN LOGGING ROUTINE WITH ERJMP'S
;<3-MONITOR>IMPDV.MAC.15, 12-Oct-77 13:51:00, EDIT BY KIRSCHEN
;UPDATE COPYRIGHT FOR RELEASE 3
;<3-MONITOR>IMPDV.MAC.14, 7-Oct-77 02:46:23, EDIT BY CROSSLAND
;MOVE REQUEST FOR RESCANNING OF NVT LINE IF OUTSTANDING TTMSG.
;<3-MONITOR>IMPDV.MAC.13, 28-Sep-77 04:30:00, EDIT BY CROSSLAND
;<3-MONITOR>IMPDV.MAC.12, 24-Sep-77 23:56:20, EDIT BY CROSSLAND
;FLUSH TTMSG'S TO NVT'S ON EXPIRATION OF TIMER
;<3-MONITOR>IMPDV.MAC.11, 23-Jul-77 22:54:02, EDIT BY CROSSLAND
;MOVE BUFFERS TO ANBSEC SECTION
;<3-MONITOR>IMPDV.MAC.10, 29-Jun-77 04:20:07, EDIT BY CROSSLAND
;FIX MODEL B ADDRESSING PROBLEMS
;<3-MONITOR>IMPDV.MAC.9, 17-Jun-77 05:36:10, EDIT BY CROSSLAND
;<3-MONITOR>IMPDV.MAC.8, 9-Jun-77 04:25:26, EDIT BY CROSSLAND
;<3-MONITOR>IMPDV.MAC.7, 6-Jun-77 00:45:43, EDIT BY CROSSLAND
;<3-MONITOR>IMPDV.MAC.6, 21-May-77 19:28:58, EDIT BY CROSSLAND
;<3-MONITOR>IMPDV.MAC.5, 14-May-77 19:25:42, EDIT BY CROSSLAND
;<3-MONITOR>IMPDV.MAC.4, 8-May-77 18:29:58, EDIT BY CROSSLAND
;<3-MONITOR>IMPDV.MAC.3, 5-May-77 10:39:47, EDIT BY CROSSLAND
;<3-MONITOR>IMPDV.MAC.2, 27-Apr-77 15:28:18, EDIT BY CROSSLAND
;TCO 1742 MERGE ARPANET SOURCES
;<101B-MONITOR>IMPDV.MAC.3, 3-Apr-77 14:04:51, EDIT BY CROSSLAND
; REPAIR RACE IN HANDLING OF JOBBIT IN ULKIDV -- ALSO CAUSE NCP FORK
; TO RUN ON Q1 ALWAYS
;<101B-MONITOR>IMPDV.MAC.2, 29-Mar-77 10:32:09, EDIT BY CROSSLAND
;TCO 1764 - REPAIR JOBBIT DIDDDLING IN IMP LOCK/UNLOCK CODE
;<CLEMENTS>IMPDV.MAC.17, 5-Aug-76 15:41:19, EDIT BY CLEMENTS
; REMOVE NVT HANDLING INTO "NVT.MAC"
; REMOVE PHYSICAL IMP HANDLER TO IMPPHY
; CHANGE THE HALFWORD DEFS OF =<Z XX-NVTLO> FORM
;ADD TEMPORARY-PARAMETERS AT ***TEMP-PARAMS***
;LS BECOMES RS
;ADJUST BUGXXX STATEMENTS
;<CLEMENTS>IMPDV.MAC.1, 15-Jul-76 16:49:08, EDIT BY CLEMENTS
; ADJUST TITLE, END AND SEARCH STATEMENTS
;<134-TENEX>IMPDV.MAC;361 2-DEC-75 10:31:23 EDIT BY TOMLINSON
;<134-TENEX>IMPDV.MAC;360 2-DEC-75 10:22:37 EDIT BY TOMLINSON
;<134-TENEX>IMPDV.MAC;359 10-NOV-75 13:44:21 EDIT BY ALLEN
; INCREASE IMPNLK TO ^D200
;<134-TENEX>IMPDV.MAC;358 26-OCT-75 11:48:06 EDIT BY TOMLINSON
;<134-TENEX>IMPDV.MAC;357 21-OCT-75 12:38:48 EDIT BY TOMLINSON
; MORE RCTE FIXUPS
;<134-TENEX>IMPDV.MAC;355 9-OCT-75 13:15:48 EDIT BY ALLEN
; MAKE SURE IMIB NOT ON FREELIST IN IMPEIN
;<134-TENEX>IMPDV.MAC;353 24-SEP-75 09:46:23 EDIT BY TOMLINSON
; DEFER OKINT IN NVTCOB 'TIL AFTER SENDING DATA MARK
;<134-TENEX>IMPDV.MAC;352 22-SEP-75 11:46:31 EDIT BY CLEMENTS
; On startup, (IMPRC1), only send RST's to hosts in name table.
;<134-TENEX>IMPDV.MAC;351 19-SEP-75 12:28:44 EDIT BY TOMLINSON
; MORE RCTE BUG FIXES
;<134-TENEX>IMPDV.MAC;350 17-SEP-75 14:55:18 EDIT BY TOMLINSON
;<134-TENEX>IMPDV.MAC;348 17-SEP-75 14:41:56 EDIT BY TOMLINSON
; RCTE BUG FIXES
;<134-TENEX>IMPDV.MAC;344 15-SEP-75 17:12:18 EDIT BY ALLEN
;<134-TENEX>IMPDV.MAC;343 15-SEP-75 16:39:45 EDIT BY ALLEN
; TEMPORARILY NOP'ED NVTCIB
;<134-TENEX>IMPDV.MAC;342 12-SEP-75 15:31:45 EDIT BY ALLEN
; ADD CHECKS TO BE SURE THAT WE NEVER LOCK OR UNLOCK A BUFFER ON THE
; FREELIST
;<TOMLINSON>IMPDV.MAC;1 10-SEP-75 08:34:36 EDIT BY TOMLINSON
; RCTE FIXES
;<134-TENEX>IMPDV.MAC;336 5-SEP-75 15:48:23 EDIT BY ALLEN
; RESTORE ORIGINAL ACTIVATION CRITERIA
;<134-TENEX>IMPDV.MAC;335 5-SEP-75 15:38:54 EDIT BY ALLEN
;<134-TENEX>IMPDV.MAC;334 3-SEP-75 22:01:33 EDIT BY ALLEN
; NEW ACTIVATION LOGIC AND FIX INPUT BUFFER FETCH LOGIC
;<134-TENEX>IMPDV.MAC;333 28-AUG-75 16:32:26 EDIT BY ALLEN
; SLIGHT MOD DUE TO CHANGE IN LOCK-UNLOCK MACROS
;<134-TENEX>IMPDV.MAC;332 19-AUG-75 15:40:48 EDIT BY ALLEN
; REPAIR TO PKQOB TO STORE ACTUAL WORDS IN USE IN HEADER SO
; OUTPUT ROUTINES DON'T TRY TO SEND THE WHOLE BUFFER
;<134-TENEX>IMPDV.MAC;331 14-AUG-75 15:18:49 EDIT BY ALLEN
; ELIMINATE LOCKUP DUE TO RUNNING OUT OF BUFFERS
;<134-TENEX>IMPDV.MAC;330 12-AUG-75 17:07:12 EDIT BY ALLEN
; FIX AT PKMS5 TO KEEP PKMSG FROM GOING NUTS WHEN ASNTBF FAILS
;<134-TENEX>DCAIMP.MAC;9 6-AUG-75 11:19:35 EDIT BY ALLEN
; END INPUT ROUTINE RECORDS ACTUAL COUNT IN BUFFER HEADER
;<134-TENEX>DCAIMP.MAC;8 5-AUG-75 13:57:29 EDIT BY ALLEN
; Various bug fixes to new buffer management
;<134-TENEX>DCAIMP.MAC;7 4-AUG-75 10:46:05 EDIT BY ALLEN
; VARIOUS CHANGES FOR NEW BUFFER MANAGEMENT
;<134-TENEX>IMPDV.MAC;328 11-JUL-75 17:17:33 EDIT BY ALLEN
; MINOR FIX
;<134-TENEX>IMPDV.MAC;327 11-JUL-75 16:12:43 EDIT BY ALLEN
; DELETE CALL IMPKO1 AT PKMSD 4
;<134-TENEX>DCAIMP.MAC;3 11-JUL-75 09:59:54 EDIT BY ALLEN
; PKMSG USES REMAINING SPACE IN CURRENT OUTPUT BUFFER UNLESS
; THIS WOULD CAUSE A CONTROL MESSAGE TO CROSS A NET MESSAGE BOUNDARY.
; PKMSG1 ADDED -- SAME AS PKMSG BUT DOESN'T ATTEMPT TO SEND THE
; CURRENT MESSAGE. CALLED BY NETTCS SO THAT SIZE OF NET MESSAGE
; IS NOW LIMITED ONLY BY AVAILABLE CHARACTERS IN TTY BUFFERS,
; BY ALLOCATION, OR BY SIZE OF OUTPUT BUFFER, NOT BY SIZE
; OF NETTCS' STACK BUFFER.
;<134-TENEX>IMPDV.MAC;326 15-MAY-75 07:51:23 EDIT BY TOMLINSON
; CHANGE REFERENCES TO NLINES TO NVTHI
;<134-TENEX>IMPDV.MAC;325 21-APR-75 11:34:59 EDIT BY TOMLINSON
; Limit special queues on message basis rather than buffer space
;<134-TENEX>IMPDV.MAC;324 14-APR-75 17:08:59 EDIT BY OPERATOR
; CORRECT INITIALIZATION OF IDVLCK
;<134-TENEX>IMPDV.MAC;323 14-APR-75 15:37:09 EDIT BY ALLEN
; AVOID SMASHING AC1 IN PIE-SLICE VERSION OF LCKID1
;<134-TENEX>IMPDV.MAC;322 11-APR-75 17:08:19 EDIT BY ALLEN
; REPAIRS TO NEW LOCKING STUFF
;<134-TENEX>IMPDV.MAC;319 10-APR-75 22:18:40 EDIT BY ALLEN
; MAKE USE OF NEW SCHEDULING FOR LCKERS
;<134-TENEX>IMPDV.MAC;318 4-APR-75 18:00:19 EDIT BY CLEMENTS
; FIX TO PREVENT UNKNOWN LINK IMPBUGS IF REMOTE CLOSES A
; SEND SOCKET WHICH HAS AN OUTSTANDING RFNM
;<134-TENEX>IMPDV.MAC;317 12-MAR-75 14:08:45 EDIT BY PLUMMER
; CHANGE SIQCHK TO FLUSH ENTIRE Q IF NOT ACTIVE
;<134-TENEX>IMPDV.MAC;316 27-FEB-75 15:50:47 EDIT BY CLEMENTS
; INCREASE NUMBER OF CHARACTERS PROCESSED IN NETTCS FROM 32 TO 64
; INCREASE SIZE OF PI-LEVEL STACK, DUE TO DEBUG ROUTINES
;<134-TENEX>IMPDV.MAC;315 10-JAN-75 10:32:56 EDIT BY ALLEN
; REPLENISH INPUT BUFFERS IF IMPNFI .LT. 8
;<133-TENEX>IMPDV.MAC;314 24-DEC-74 08:32:56 EDIT BY TOMLINSON
; DISABLE RCTE UNTIL DEBUGGED THOROUGHLY
;<133-TENEX>IMPDV.MAC;313 18-DEC-74 15:40:48 EDIT BY TOMLINSON
;<133-TENEX>IMPDV.MAC;312 17-DEC-74 16:17:00 EDIT BY TOMLINSON
; CAUSE INITIAL SB STRING FOR RCTE
;MISC BUG FIXES TO RCTE
;<133-TENEX>IMPDV.MAC;311 16-DEC-74 15:50:14 EDIT BY TOMLINSON
; TAKE OUT CODE TO TURN ON RCTE IN ASNNVT. CAN'T DO IT BECAUSE NCPLCK IS SET.
;<133-TENEX>IMPDV.MAC;309 13-DEC-74 12:41:16 EDIT BY TOMLINSON
; INITITATE TURN ON OF RCTE AND SUPPRESS GA
;<133-TENEX>IMPDV.MAC;308 13-DEC-74 12:32:18 EDIT BY TOMLINSON
; BUG FIXES TO RCTE
; PKBY1: MOVE SOS IMPLT4 TO AFTER ASNTBF CALL
; UPBRB: CHANGE BUG MSG
; IM8RAS: ACCOUNT FOR BUFFERS IN CONNECTION QUEUE WHEN RESETTING ALLOC
;<133-TENEX>IMPDV.MAC;306 8-DEC-74 18:28:13 EDIT BY CLEMENTS
; FIX MISSING EXTERN ON SKPRET
;<133-TENEX>IMPDV.MAC;303 3-DEC-74 10:25:14 EDIT BY TOMLINSON
; Added RCTE code
;<133-TENEX>IMPDV.MAC;300 29-OCT-74 08:22:03 EDIT BY TOMLINSON
;<133-TENEX>IMPDV.MAC;299 1-OCT-74 13:16:36 EDIT BY TOMLINSON
; REMOVE SUPERFLUOUS INSTRINCTION AT IMPRAP+2
;<133-TENEX>IMPDV.MAC;298 25-SEP-74 12:47:56 EDIT BY TOMLINSON
; (1) MARK HOST USING NEW PROTOCOL AS UNDERSTANDING SAME.
; (2) RELEASE BOTH HALVES OF AN NVT WHEN RECEIVING NXS/R
; (3) FIX BUGIMH ARG IN BADLKS/R
; (4) BUGCHK IF IMPLT4 IS OVERDECREMENTED IN UPBRB
;<133-TENEX>IMPDV.MAC;297 22-AUG-74 16:28:54 EDIT BY CLEMENTS
;<TENEX-132>IMPDV.MAC;296 22-JUN-74 13:07:40 EDIT BY TOMLINSON
; NOP IMPCHK IF IMPRDY = 0
;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 IMPDV
;***TEMP-PARAMS***
PIESLC==0
;***TEMP-PARAMS
;ACCUMULATORS
DEFAC (IMPUN,Q1) ;SAME AS "UNIT" ELSEWHERE
;PARAMETERS
SIQMAX==6 ;MAXIMUM MESSAGES ALLOWED ON SIQ
RFNTMO==^D20000 ;RFNM TIME-OUT INTERVAL (THREE OF THESE)
UPROBI==^D300000 ;INTERVAL AT WHICH TO PROBE EVERY UP HOST
UPROBT==^D60000 ;TIME TO SPEND PROBING EVERY DOWN HOST
SIQTM0==^D120000 ;SPECIAL QUEUE TIME-OUT INTERVAL
NINBFS==10 ;NUMBER OF IMP INPUT BUFFERS TO KEEP READY
;MACROS
;LOCK IMP DEVICE LOCK
DEFINE ILOCK (A)
< CALL LCKIDV
IFB <A>,<0>
IFNB<A>,<A>
>
;UNLOCK IMP DEVICE LOCK
DEFINE IUNLK
< CALL ULKIDV>
;CALL CLOCK SWITCH CODE
DEFINE IMSCLK(CLOCK)<
MOVE T1,[IFIW!CLOCK]
CALL IMUCLK>
;CALLED BY PERIODIC CHECK ROUTINE
SWAPCD
CHKNET::
IFDEF POLLF,< ;DO THIS PRINTOUT ONLY IF POLLF IS DFND
;THIS POLLING LOGIC IS USELESS ON THE ARPANET THESE DAYS, BECAUSE
; THERE ARE JUST TOO MANY HOSTS. BUT ON A SMALL PRIVATE NET, IT WOULD
; PROBABLY BE USEFUL AND POLLF SHOULD BE DEFINED AS 1.
MOVSI IMPUN,-IMPLBT ;SETUP TO SCAN HOST BIT TABLES
CHKN2: MOVE T3,IMPHL1(IMPUN) ;BIT SET IF HOST HAS GONE DOWN SINCE LAST
JFFO T3,[MOVE T3,BITS(T4) ;FOUND ONE
ANDCAM T3,IMPHL1(IMPUN) ;RESET BITS
ANDCAM T3,IMPHL2(IMPUN)
HRROI T1,[ASCIZ /HOST /]
PSOUT ;REPORT DOWNAGE
MOVEI T1,.PRIOU
MOVEI T2,0(IMPUN) ;COMPUTE HOST NUMBER
IMULI T2,^D36 ;MULTIPLY BY 36
ADDI T2,0(T4) ;ADD IN BIT POSITION
MOVEI T3,^D8 ;OCTAL FOR NOUT
CVHST ;TYPE HOST NAME IF ANY,
NOUT ;BUT IF THAT FAILS, TYPE NUMBER
ERJMP .+1
HRROI T1,[ASCIZ / DOWN
/]
PSOUT
JRST CHKN2]
MOVE T3,IMPHL2(IMPUN) ;STATE OF HOSTS AS REPORTED
XOR T3,IMPHRT(IMPUN) ;COMPARE WITH STATE FROM NCP
JFFO T3,[MOVE T3,BITS(T4) ;FOUND A DIFFERENCE
XORM T3,IMPHL2(IMPUN) ;UPDATE LOGGED TABLE
HRROI T1,[ASCIZ /HOST /]
PSOUT ;REPORT CHANGE ON LOG TTY
MOVEI T1,.PRIOU
MOVEI T2,0(IMPUN) ;COMPUTE HOST NUMBER
IMULI T2,^D36
ADDI T2,0(T4)
MOVEI T3,^D8 ;OCTAL FOR NOUT
CVHST ;TYPE HOST NAME
NOUT ;OR HOST NUMBER
ERJMP .+1
MOVE T3,BITS(T4)
HRROI T1,[ASCIZ / UP
/]
TDNN T3,IMPHL2(IMPUN)
HRROI T1,[ASCIZ / DOWN
/]
PSOUT
JRST CHKN2]
AOBJN IMPUN,CHKN2 ;SCAN TABLES
> ;END OF IFDEF POLLF AT CHKNET
;FALL THRU
;FURTHER BACKGROUND PROCESS CHECKS.
;FALLS THRU FROM ABOVE
SKIPE NETTCH ;CHANGE OF STATE?
CALL CHKN5 ;YES
SKIPE IMPGDM ;ANY "IMP GOING DOWN" MESSAGES?
CALL CHKN7 ;YES, GO PRINT IT
RET
;LOG NWORK CHANGE OF STATE
CHKN5: HRROI T1,[ASCIZ /
***** NETWORK /]
PSOUT
HRROI T1,[ASCIZ /ON/]
SKIPN NETON
HRROI T1,[ASCIZ /OFF/]
PSOUT
HRROI T1,[ASCIZ /, IMP /]
PSOUT
HRROI T1,[ASCIZ /ON/]
SKIPN IMPRDY
HRROI T1,[ASCIZ /OFF/]
PSOUT
MOVEI T1," "
PBOUT
SETZM NETTCH ;NOTE THAT CHANGE HAS BEEN REPORTED
CALL LGTAD ;REPORT TIME OF THIS CHANGE
SKIPGE T2,T1 ;IF TIME KNOWN
JRST CHKN5X ;NOT KNOWN.
MOVEI T1,.PRIOU ;STILL ON CTY
MOVEI T3,0
ODTIM
CHKN5X: TMSG <
>
RET
;BROADCAST IMP GOING DOWN MESSAGE
CHKN7: HRROI T1,1(P) ;BUFFER ON PDL
ADJSP P,20 ;20 WORDS OF BUFFER
HRROI T2,[ASCIZ /IMP GOING DOWN FOR /]
SETZ T3, ;END ON NULL
SOUT
LDB T2,[POINT 10,IMPGDM,31] ;GET NUMBER OF FIVE MINUTE INTERVALS
IMULI T2,5 ;MULTIPLY BY 5 TO GET MINUTES
MOVEI T3,^D10 ;AND REPORT AS DECIMAL NUMBER
NOUT
ERJMP .+1
HRROI T2,[ASCIZ / MIN IN /]
SETZ T3, ;END ON NULL
SOUT
LDB T2,[POINT 4,IMPGDM,21] ;GET 5 MIN. INTERVALS
IMULI T2,5 ;MULTIPY BY 5 TO GET MINUTES
MOVEI T3,^D10 ;REPORT AS DECIMAL NUMBER
NOUT
ERJMP .+1
HRROI T2,[ASCIZ / MIN DUE TO /]
SETZ T3, ;TERMINATE ON NULL
SOUT
LDB T2,[POINT 2,IMPGDM,17] ;GET REASON
HRRO T2,[[ASCIZ /PANIC
/]
[ASCIZ /SCHED HDWRE PM
/]
[ASCIZ /SOFTWRE RELOAD
/]
[ASCIZ /EMRGNCY RESTRT
/]](T2)
SOUT
HRROI T2,-17(P) ;GET POINTER TO BUFFER ON STACK
SETO T1, ;SEND TO EVERYONE
TTMSG
ADJSP P,-20 ;CLEAN UP STACK
SETZM IMPGDM ;ZERO MESSAGE WORD
RET
RESCD
;ROUTINES TO MAKE FOOTPRINTS FOR DEBUGGING
;TAKE IMP FOOTPRINTS JSYS
;CALL: T1 JFN OF OUTPUT FILE
; T2 WORD COUNT (STOPS AT FIRST OPPORTUNITY PAST THIS)
; T3 RE-INIT FLAG (NON-ZERO TO RESET POINTERS)
;THERE IS NO JSYS DEFINED FOR DBGIM
REPEAT 0,<
.DBGIM::MCENT
HRRZS T1 ;DON'T ALLOW BYTE POINTERS
MOVX T4,SC%WHL!SC%NWZ
TDNN T4,CAPENB ;MUST BE WHEEL OR NET-WIZARD
EMRETN (NTWZX1) ;GIVE ERROR TRAP
JUMPE T3,DBGIM0 ;SKIP INIT STUFF
NOSKED
SETZM DBGNWD ;ZERO NUMBER OF WORS IN BUFFER
SETZM DBGSP ;ZERO POINTER FOR ADDING ENTRIES
SETZM DBGFAC ;ZERO COUNT OF FAILURES
OKSKED
SETZM DBGRP ;ZERO POINTER FOR REMOVING ENTRIES
AOS DBGRP ;POINT AT FIRST WORD
DBGIM0: PUSH P,T2 ;SAVE COUNT ON STACK
PUSH P,T1 ;AND JFN
DBGDBL: SKIPG T3,DBGNWD ;ANYTHING IN BUFFER?
JRST DBGDBW ;NO. WAIT
MOVEI T4,DBGNBF ;GET SIZE OF BUFFER
SUB T4,DBGRP ;GET SPACE TO END OF BUFFER
CAMGE T3,T4
MOVEM T3,T4 ;KEEP MIN COUNT OF HOW MUCH TO WRITE
MOVN T3,T4 ;GET NEGATIVE COUNT OF WORDS USED
MOVE T2,DBGRP ;GET POINTER FOR REMOVING FROM BUFFER
ADD T2,[POINT 36,DBGBUF] ;MAKE IT POINT TO BUFFER
SOUT ;WRITE TO FILE
MOVN T3,T4 ;GET NEGATIVE OF AMOUNT WRITTEN
ADDM T3,DBGNWD ;UPDATE NUMBER OF WORDS USED IN BUFFER
ADDB T4,DBGRP ;AND POINTER FOR REMOVING WORDS
CAIL T4,DBGNBF ;AT END OF BUFFER
SETZB T4,DBGRP ;YES RESET POINTER FOR REMOVING
ADDB T3,-1(P) ;COUNT WORDS WRITTEN
JUMPG T3,DBGDBL ;CONTINUE IF STILL .GR. 0
UMOVEM T3,T3 ;ELSE RETURN UPDATED COUNT
ADJSP P,-2 ;CLEAN UP STACK
SMRETN ;SKIP RETURN
DBGDBW: MOVEI T1,DBGNWD ;SET UP FOR WAIT.
CALL DISG ;GO WAIT
MOVE T1,0(P) ;GET JFN BACK
JRST DBGDBL ;GO WRITE THEM TO THE FILE
;DBGIIM - STASH INPUT IRREGULAR MSG
; T1/ IRREGULAR MESSAGE HEADER
DBGIIM: PUSH P,T2 ;SAVE T2
MOVEI T2,1 ;ADDINF 1 WORD ENTRY
DBGSIM: CALL DBGCKS ;CHECK FOR SPACE
JRST DBGXIT ;NO SPACE LEAVE
CALL DBGS2B ;STORE COUNT AND TIME STAMP
MOVE T2,T1 ;GET HEADER IN T2
CALL DBGS1B ;STORE HEADER
DBGXIT: OKSKED
POP P,T2 ;RESTORE T2
RET
;DBGIM - STASH HEADER OF INCOMMING MSG. BUFFER IN T1
DBGIM: PUSH P,T2 ;SAVE T2
MOVE T2,1(T1) ;GET HEADER
TXNE T2,LD%LNK ;LINK = 0
SKIPA T2,[3] ;NO. SAY 3 WORD ENTRY
HRRZ T2,0(T1) ;YES. SAVE ENTIRE MESSAGE
DBGSM: SOS T2 ;DO NOT SAVE BUFFER HEADER
CALL DBGCKS ;GO RESERVE SPACE
JRST DBGXIT ;NO SPACE. EXIT
PUSH P,T1 ;SAVE BUFFER ADDRESS
CALL DBGS2B ;WHRITE HEADER AND TIME STAMP
HRRZS T2 ;GET NUMBER OF WORDS
MOVE T1,0(P) ;GET BUFFER ADDRESS BACK
PUSH P,T2 ;SAVE WORD COUNT
DBGSLP: SOSGE 0(P) ;DECREMENT COUNT
JRST DBGSL1 ;FINISHED. GET OUT
MOVE T2,1(T1) ;GET WORD
CALL DBGS1B ;STORE IT
AOJA T1,DBGSLP ;GO DO NEXT WORD
DBGSL1: POP P,T2 ;CLEAN UP STACK
POP P,T1 ;RESTORE T1
JRST DBGXIT ;LEAVE
;DBGOM - STASH HEADERS OF OUTPUT MSG. BUFFER IN T1
DBGOM: PUSH P,T2 ;SAVE T2
MOVE T2,1(T1) ;GET HEADER
TXNE T2,LD%MST ;WAS IT A NOP
JRST [ HRROI T2,2 ;RESERVE TO WORDS AND INDICATE OUTPUT
JRST DBGSM]
TXNE T2,LD%LNK ;IS LINK ZERO?
SKIPA T2,[-1,,3] ;NO JUST DO HEADER, INDICATE OUT.
HRRO T2,0(T1) ;YES. DO ENTIRE MSG. INDICATE OUT.
JRST DBGSM
;STORE HEADER WORD (IN T2) AND TIME STAMP
DBGS2B: CALL DBGS1B ;STORE ENTRY HEADER WORD
PUSH P,T2 ;SAVE T2
EXCH T1,T2 ;EXCHANGE T1 AND T2
GTAD ;GET TIME AND DATE
EXCH T1,T2 ;PUT IT IN T2
CALL DBGS1B ;STORE TIME AND DATE
POP P,T2 ;RESTORE T2
RET
;STORE 1 WORD (IN T2) IN DEBUG BUFFER
DBGS1B: PUSH P,T1 ;SAVE T1
AOS T1,DBGSP ;GET POINTER FOR ADDING ENTRIES
CAIL T1,DBGNBF ;AT END OF BUFFER
SETZB T1,DBGSP ;YES. RESET POINTERS
MOVEM T2,DBGBUF(T1) ;STORE WORD IN BUFFER
AOS DBGNWD ;INCREMENT NUMBER OF WORDS IN BUFFER
POP P,T1 ;RESTORE T1
RET
;CHECK FOR SUFFICIENT SPACE TO MAKE NEW ENTRY
; NUMBER OF WORDS (NOT INCLUDING ENTRY HEADER AND TIME) IN RH OF T2
DBGCKS: SKIPE DBGFAC ;ANY INTERVENING FAILURES?
AOJA T2,DBGCK2 ;YES
DBGCK1: PUSH P,T1 ;SAVE T1
NOSKED
MOVE T1,DBGNWD ;GET NUMBER OF WORDS IN BUFFER
ADDI T1,2(T2) ;ADD IN WORDS FOR THIS ENTRY
CAIG T1,DBGNBF ;BUFFER FULL
AOSA -1(P) ;NO. SKIP RETURN
AOS DBGFAC ;INDICATE FAILURE
POP P,T1 ;RESTORE T1
DBGCK3: RET
DBGCK2: CALL DBGCK1 ;GO AHEAD AND DO CURRENT ENTRY + 1
SOJA T2,DBGCK3 ;DID NOT HAVE SPACE
EXCH T2,DBGFAC ;GET COUNT OF LOST ENTRIES
HRLI T2,1 ;INDICATE TYPE OF ENTRY
CALL DBGS1B ;TELL THEM HOW MANY WERE LOST
SOS T2,DBGFAC ;RESTORE T2 TO ORIGINAL VALUE
SETZM DBGFAC ;ZERO COUNTER OF LOST ENTRIES
RET
>
DBGIM: ;DUMMY ROUTINES
DBGIIM:
DBGOM: RET
;IMP ASYNCHRONOUS PROCESS
;STARTED ONCE, CALL FROM RUNDD
IMPBEG::MOVX T1,CR%CAP ;CREATE FORK OF JOB 0 WITH SAME CAPABILITIES
CFORK
BUG(HLT,IMPCCF,<CAN'T CREATE IMP FORK>)
MOVEI T2,IMPBP0
MSFRK ;START FORK IN MONITOR
RET
;INIT
IMPBP0: SE1ENT ;ENTER SECTION 1
MCENTR
MOVE T1,FORKX ;GET FORK NUMBER
MOVEM T1,NCPFRK ;AND SAVE IT AWAY
MOVE T1,[XWD ITFPC,IMPUXI] ;SET UP TRAP ADDRESS
MOVEM T1,MONBK
MOVE T1,CHNSON ;SET UP CHANNELS TO TRAP
MOVEM T1,MONCHN
MOVEI T1,NINBFS
MOVEM T1,IMPNIB ;INIT NUMBER OF BUFFERS TO KEEP ON TAP
CALL HSTINI ;GET THE SYSTEM TO KNOW NAMES OF SITES
BUG(INF,IMPHIF,<HSTINI FAILED TO FIND HOST NAME FILE>)
MOVEI T1,101 ;SET TO ALWAYS BE ON HIGH QUEUE
MOVEM T1,JOBBIT
CALL IMPINI ;INITIALIZE THE IMP
MOVEI T1,T2
MOVEM T1,IMCLST ;MAKE LAST CLOCK BE DUMMY (AC 2)
;FALL THRU
;FALLS THRU FROM ABOVE
; ALSO RETURNS HERE FROM JRST-EXITS OF BACKGROUD LOOP CHECKS
IMPBP1: IMSCLK (IMCIDL) ;START CHARGING TIME TO IMCIDL
PUSH P,[MSEC1,,IMPBP1] ;RETURN FOR FOLLOWING DISPATCHES
SETZM IMPFLG ;CLEAR REQUEST FLAG
SKIPL NLHOST ;DO NOTHING IF SETSPD HASNT SET SITE.
CALL IMPSTT ;CHECK STATE OF NET AND IMP
JRST IMPBP3 ;DOWN OR SITE NOT YET KNOWN
SKIPE IMINFB ;GARBAGE BUFFERS TO RELEASE?
JRST IMINRB ;YES
MOVE T1,LNKNDL ;DELETES IN LINK TABLE
CAIL T1,IMPNLK/2 ;TIME FOR GC?
JRST IMPGC ;YES
SKIPE IMPNCL ;CONTROL MSGS FOR PROCESSING?
JRST IMPCN0 ;YES
SKIPE IMPIBO ;INPUT BUFFERS READY?
JRST IMIP1 ;YES
SKIPE IMP8XC ;IRREG MSGS FOR PROCESSING?
JRST IMP8XM ;YES
MOVE T1,NETFRE+2 ;GET NUMBER OF WORDS OF BUFFER
; SPACE NOW AVAILABLE
SKIPE TTNOF ;SCAN OF NET TTYS REQUESTED?
CAMG T1,ASNTHR ;AND ENOUGH SPACE LEFT?
SKIPA ;NO, DON'T SCAN
JRST IMPTS ;YES
MOVE T1,IMPNFI
CAMGE T1,IMPNIB ;NEED INPUT BUFFERS?
CALL IMPGIB ;YES
SKIPE IMPNOS ;NEED OUTPUT SCAN?
CALL IMPOS ;YES
IMSCLK (IMCIDL) ;BACK TO IMCIDL FOR CHARGING
;FALL THRU
;FALLS THRU FROM ABOVE
IMPBP2: MOVE T1,TODCLK
CAML T1,IMPTIM ;TIME FOR LOCAL CHECKS?
JRST NETCH0 ;YES
CAML T1,RFNTIM ;TIME FOR OVERDUE RFNM CHECK?
JRST RFNCHK ;YES
CAML T1,NETTIM ;TIME FOR NETWRK CHECKS?
JRST [ IMSCLK (IMCNCC)
JRST NETCHK] ;YES
CAML T1,NEGTIM
JRST NEGCHK ;CHECK INCOMPLETE NEGOTIATIONS
CALL SIQCHK ;CHECK SPECIAL QUEUES
CAMLE T1,IMPTIM
MOVE T1,IMPTIM ;FIND MINIMUM CLOCK AND USE IT AS
CAMLE T1,NETTIM ;NEXT TIME TO WAKEUP
MOVE T1,NETTIM
CAMLE T1,RFNTIM
MOVE T1,RFNTIM
CAMLE T1,NEGTIM
MOVE T1,NEGTIM
MOVEM T1,IBPTIM ;SAVE TIME TO DIMISS TILL
MOVEI T1,IMPBPT ;ADDRESS OF DISMISS ROUTINE
MDISMS ;DISMISS UNTIL SOMETHING TO DO
SKIPN ITMSTM ;ANY TTMSG'S OUT
RET ;NOTHING TO DO RETURN
AOS TTNOF ;YES, INDICATE THEY NEED TO BE CHECKED
RET
;SCHEDULER ACTIVATION TEST FOR NCP FORK
IMPBPT: SKIPE IMPFLG ;FLAG SET?
JRST 1(T4) ;YES, WAKEUP
MOVE T1,TODCLK ;CHECK ALARM CLOCK
CAML T1,IBPTIM ;TIME YET?
JRST 1(T4) ;YES
SKIPGE IDVLCK ;LOCK CLEAR AND OUT SCAN NEEDED?
SKIPG IMPNOS
JRST 0(T4) ;NO
JRST 1(T4) ;YES, WAKEUP
IMPBP3: MOVE T1,TODCLK ;GET TIME OF DAY
CAML T1,NETTIM ;TIME TO CHECK
CALL NETCHK ;CONTINUE CALLING NETCHK IF NET DOWN
MOVEI T1,^D10000
DISMS ;WAIT 10 SEC
RET ;THEN TRY AGAIN
;UNEXPECTED INTERRUPT
IMPUXI: BUG(CHK,IMPUX0,<IMP JB0 FORK - UNEXPECTED INTERRUPT>)
SE1ENT ;ENTER SECTION 1
MCENTR
JRST IMPBP1 ;CONTINUE PROCESSING
;UPDATE IMP CLOCKS
IMUCLK: PUSH P,T1 ;SAVE T1
SUBI T1,IMCIDL ;SUBTACT ADDRESS OF FIRST CLOCK
AOS IMNIDL(T1) ;COUNT ENTRIES
CALL GETFRT ;GET FORK RUNTIME IN T1, IN HP UNITS
SUB T1,IMCCLK ;TIME SINCE LAST MEASUREMENT
ADDM T1,IMCCLK ;UPDATE TO BE TIME OF THIS CLOCK MEASUREMENT
ADDM T1,@IMCLST ;CHARGE TO CURRENT CLOCK
POP P,IMCLST ;SET TO NEW CLOCK
RET
;SET IDVLCK
IFE PIESLC,< ;VERSION FOR NON-PIE SLICE SCHEDULER
LCKIDV: PUSH P,T1 ;SAVE T1
NOINT
LOCK IDVLCK,<JRST LCKID1>
LCKID0: MOVE T1,JOBBIT ;SAVE THE OLD VALUE OF JOBBIT Q LIMITS.
MOVEM T1,IMPOJB ;THIS IS NOT A GOOD SYSTEM. SHOULD BE
;SEPARATE SCHEDULER INFO LIKE IN PIESLC.
MOVEI T1,101 ;HIGH-QUEUE MYSELF WHILE I HAVE LOCK
DPB T1,[POINT 12,JOBBIT,35] ;AND SAVE THE OLD VALUE.
MOVE T1,FORKX ;GET FORK NUMBER
MOVEM T1,IDVLLK ;AND SAVE IT
POP P,T1 ;RESTORE T1
RETSKP
LCKID1: MOVE T1,-1(P) ;GET ERROR RETURN INSTRUCTION
SKIPE (T1) ;IF 0 WAIT WANTED?
JRST ULKID2 ;NO ,RETURN
MOVEI T1,IDVTST
MDISMS
JRST LCKID0
> ;END NON-PIE-SLICE CONDITIONAL
IFN PIESLC,< ;VERSION FOR PIE-SLICE SCHEDULER
LCKIDV: NOINT
LOCK IDVLCK,<JRST LCKID1>,SPQ
LCKID0: PUSH P,FORKX ;SAVE FORK NUMBER
POP P,IDVLLK
RETSKP
LCKIDT1: PUSH P,1
MOVE T1,-1(P) ;GET ERROR RETURN INSTRUCTION
SKIPE (T1) ;IF 0 WAIT WANTED?
JRST [POP P,T1
OKINT
JRST RELSPQ##] ;RETURN VIA RELSPQ, NORMAL SCHEDULING
MOVEI T1,IDVTST
MDISMS
POP P,T1
JRST LCKID0
> ; END OF IFN PIESLC CONDITIONAL
;UNLOCK IDVLCK
ULKIDV:
IFE PIESLC,<
PUSH P,T1 ;SAVE T1
MOVE T1,IMPOJB ;RESTORE JOBBIT FROM LOCK ABOVE
DPB T1,[POINT 12,JOBBIT,35] ;JUST THE QUEUE LIMITS
ULKID2: POP P,T1
>
REPEAT 0,< UNLOCK IDVLCK,RESIDENT,SPQ>
REPEAT 1,< ;(TENEX LOCKING MECHANISM NOT SUPRTD
UNLOCK IDVLCK> ;FREE IMP LINK TABLES AND DEVICE
OKINT
RET
IDVTST: AOSE IDVLCK ;UNLOCKED YET?
JRST 0(T4) ;NO CONTINUE WAIT
JRST 1(T4) ;YES
;RELEASE BUFFERS LEFT BY PI ROUTINES
IMINRB: IMSCLK (IMCNRB) ;CHARGE TIME TO RELEASING BUFFERS
SETZ T4,
EXCH T4,IMINFB ;GET ALL GARBAGE BUFFERS
IMINR1: JUMPE T4,R ;QUIT WHEN ALL RELEASED
HRLI T4,ANBSEC ;SET SECTION NUMBER
MOVE T2,T4 ;GET BUFFER ADDRESS INTO T2
HLRZ T4,0(T4) ;GET NEXT BUFFER IN CHAIN
CALL RLNTBF ;RELEASE ONE
JRST IMINR1 ;TRY NEXT BUFFER
;GET ONE BUFFER FOR INPUT AND LOCK IT IN CORE
IMPGIB: IMSCLK (IMCGIB) ;CHARGE TO IMCGIB
IMPGI1: MOVEI T2,MAXWPM ;FOR MAX INPUT MSG
CALL ASNTBF ;ASSIGN FROM POOL
JRST IMPB03 ;NO BUFFERS
MOVE T2,T1 ;GET ADDRESS IN T2
CALL IMPLKB ;LOCK BUFFER
PIOFF
EXCH T2,IMPFRI ;PUT BFR ON INPUT FREE LIST
HRLM T2,0(T1) ;PUT OLD TOP OF LIST IN NEW BUFFER
AOS T2,IMPNFI ;COUNT NUMBER FREE, IF WAS 0, THEN
PION
SKIPN IMIB ;INPUT IS OFF?
SKIPG IMPNFI ;YES, BUFFERS AVAILABLE?
CAIA ;NO
CALL IMISRT ;YES, RESTART
MOVE T2,IMPNFI ;GOT ENOUGH BUFFERS?
CAMGE T2,IMPNIB
JRST IMPGI1 ;NO
RET
;SCAN NET TTY LINES
IMPTS: IMSCLK (IMCTS) ;CHARGE TO IMCTS
SETZM TTNOF ;INDICATE THAT NVTS HAVE BEEN SCANNED
MOVE P1,NVTPTR ;COUNT THRU NVT LINES
IMPTS1: HRR T2,P1 ;GET TERMINAL NUMBER IN T2
CALL LCKTTY ;GET ADDRESS OF DYNAMIC DATA
JUMPLE T2,IMPTS2 ;IF NON-STANDARD BLOCK CHECK FOR OUTPUT
PUSH P,T2 ;SAVE ADDRESS OF DYNAMIC DATA
CALL TTSOBE ;ANY OUTPUT?
CALL NETTCS ;YES
POP P,T2 ;GET BACK ADDRESS OF DYNAMIC DATA
IMPTS2: CALL ULKTTY ;UNLOCK TTY DATABASE
AOBJN P1,IMPTS1
SKIPN T2,ITMSTM ;ANY TTMSG'S OUT
RET ;NOTHING TO DO RETURN
CAMLE T2,TODCLK ;TIME TO FLUSH YET?
RET ;NO, RETURN
NOSKED ;PREVENT ANYONE ELSE FROM CHANGE DATA
CALL TMSNTR ;FLUSH ALL TTMSG'S TO NVT'S
OKSKED
SETZM ITMSTM ;CLEAR TIMER
RET
;SCAN ALL CONNECTIONS FOR OUTPUT POSSIBLE
;CALLED BY ASYNCH PROCESS
IMPOS: IMSCLK (IMCOS) ;CHARGE TO IMCOS
MOVSI Q2,-IMPNLK ;SET UP AOBJN POINTER -# LINKS,,0
SETZM IMPNOS ;CANCEL REQUEST FOR SCAN
IMPOS2: HRRZ T2,IMPLT1(Q2) ;GET STATE OF LINK
TXNE T2,L1%SND ;OUTPUT CONNECTION HAS SEND BIT ON
TXNE T2,L1%FRE ;AND NOT FREE
IMPOS1: AOBJN Q2,IMPOS2 ;NO. NOT OUTPUT TRY NEXT ONE
JUMPGE Q2,[ADJSP P,-1 ;RETURN TO CALLER'S CALLER (IMPBP1)
RET]
ILOCK(<JRST [AOS IMPNOS ;TRY AGAIN LATER
RET]>) ;RETURN IF CAN'T SET LOCK
MOVEI T1,0(Q2) ;GET INDEX IN T1
CALL IMPKO1 ;CHECK AND SEND IF POSSIBLE
JRST IMPOS1
;ASYNCH PROCESS TO PUT BUFFERS ON PROPER CONNECTION QUEUES
IMIP1: IMSCLK (IMCP1) ;CHARGE TO IMCP1
MOVE T2,IMPIBO ;TRY TO GET NEXT BUFFER
JUMPE T2,R ;NONE LEFT
PIOFF ;TURN OFF PI TO PROTECT BUFFERS
HLRZ T3,0(T2) ;GET NEXT BUFFER IN CHAIN
JUMPN T3,IMIP1A ;IS THERE ONE
SETZM IMPIBI ;NO. ZERO POINTER FOR REMOVING
SKIPA ;DO NOT SET SECT NUMBER SO PTR WILL = 0
IMIP1A: HRLI T3,ANBSEC ;SET SECTION NUMBER
MOVEM T3,IMPIBO ;UPDATE POINTER FOR REMOVING BUFFERS
PION ;FINISHED WITH POINTERS TURN PI ON
PUSH P,T2 ;SAVE BFR ADDRESS
MOVE T1,T2 ;GET BUFFER ADDRESS INTO T1
CALL DBGIM ;GO SAVE THINGS FOR DEBUGGING
NOSKED
HRRZ T2,0(T2) ;GET SIZE FIELD
CAILE T2,MAXWPM ;MAKE SURE ITS NOT ON FREELIST
BUG(HLT,IMPUFB,<IMIP1: ATTEMPT TO UNLOCK BUFFER ON FREELIST>)
MOVE T2,0(P) ;RESTORE T2
CALL MULKSP ;UNLOCK HEAD
HRRZS 0(T2) ;CLEAR FWD POINTER
MOVE T1,1(T2) ;GET HEADER
ANDX T1,<LD%FIM!LD%LNK> ;EXTRACT LINK + FROM IMP BIT
CAML T1,[MAXNCP] ;NORMAL LINK?
JRST IMIPSQ ;NO, DISPATCH TO SPECIAL Q
OKSKED
LOAD T1,<LD%HST!LD%LNK>,1(T2) ;GET HOST-LINK
ILOCK
CALL LNKLUK ;SEE IF CONNECTION EXISTS
JRST [ TXNE T1,L1%LNK ;DOESN'T, CONTROL LINK?
JRST IMIBB ;LINK NON-EXISTANT
MOVEI T3,^D8 ;CREATE CONNECTION, BYTE SIZE IS 8
CALL IMPOP1
HRROS IMPLT1(T1) ;MAKE UNIT -1
MOVEI T3,377777
HRRM T3,IMPLT4(T1) ;SET INFINITE MSG ALLOC
AOS IMPNCL ;COUNT CONTROL CONNECTIONS
JRST .+1]
POP P,T2 ;RESTORE T2 BUFFER ADDRESS
HRRZ T3,IMPLT2(T1) ;GET ADD. OF LAST BUFFER FOR THIS CONN
HRRM T2,IMPLT2(T1) ;SAVE NEW LAST BUFFER ADDRESS
JUMPE T3,[HRLM T2,IMPLT3(T1) ;NO OLD BUFFER. SET REMOVAL PTR
JRST IMIP1B] ;NO QUEUE TO UPDATE
HRLI T3,ANBSEC ;SET SECTION NUMBER FOR BUFFERS
HRLM T2,0(T3) ;PUT MSG ON QUEUE FOR CONN
IMIP1B: HLRE IMPUN,IMPLT1(T1) ;GET CONNECTION NUMBER
IUNLK
JUMPL IMPUN,R ;SEE IF NVT CONNECTION
LOAD T2,ANNVT,(IMPUN) ;GET NVT NUMBER
CALL NVTCHK ;IS IT AN NVT
RET ;ISN'T
PUSH P,T2 ;SAVE ADDRESS OF DYNAMIC DATA
PUSH P,T1 ;SAVE LT INDEX
IMSCLK (IMCNVI) ;ACCOUNT THE TIME FOR NVT INPUT
POP P,T1 ;RESTORE LT INDEX
POP P,T2 ;GET BACK ADDRESS OF TTY DYNAMIC DATA
CALL NVTUPI ;UNPACK NVT INPUT
CALL ULKTTY ;UNLOCK DATA BASE
RET
;IMIPSQ - ADD MESSAGE TO SPECIAL QUEUE
; T2/ BUFFER ADDRESS
IMIPSQ: MOVSI T3,-NSQ ;SET UP AOBJN POINTER. -# OF SP. Q,,0
IMIPS1: SKIPGE T1,SQJOB(T3) ;IN USE?
JRST IMIPQA ;NO
LSH T1,2 ;ALIGN VALUE WITH INTERNET DISPATCH
XOR T1,5(T2) ;COMPARE
LSH T1,6 ;ALIGN WITH MASK
AND T1,SQJOB(T3) ;MASK BITS TO COMPARE
TLNE T1,177400 ;ONLY CONSIDER THESE BITS
JRST IMIPQA ;NO MATCH
MOVE T1,1(T2) ;GET HEADER
XOR T1,SQVAL(T3) ;COMPARE TO VALUE
TDNE T1,SQMSK(T3) ;YES, EQUAL?
IMIPQA: AOBJN T3,IMIPS1 ;NO OR NO. TRY NEXT QUEUE
JUMPGE T3,IMIPS2 ;FOUND NOBODY, GO THROW AWAY
MOVE T1,SIQSPC(T3) ;HOW MUCH SPACE IN USE?
CAIL T1,SIQMAX ;LESS THAN MAX?
JRST IMIPS2 ;NO, TOO MUCH, GO THROW AWAY
MOVE T1,TODCLK ;GET TIME OF DAY
ADDI T1,SIQTM0 ;ADD SPECIAL Q TIME LIMIT
SKIPN T4,SIQIBI(T3) ;FIRST BUFFER (QUEUE EMPTY?)
JRST [MOVEM T1,SIQTIM(T3) ;RECORD DISCARD TIME
MOVEM T2,SIQIBO(T3) ;UPDATE REMOVAL POINTER ALSO
JRST IMPSQ4] ;NO QUEUE TO UPDATE
HRLM T2,0(T4) ;CHAIN IN NEW BUFFER
IMPSQ4: MOVEM T2,SIQIBI(T3) ;SAVE NEW BUFFER ADDRESS
AOS SIQSPC(T3) ;COUNT MESSAGES ON QUEUE
OKSKED
JRST IMIPS3 ;FIX UP STACK AND RETURN
IMIPS2: OKSKED
CALL RLNTBF ;THROW MESSAGE AWAY
IMIPS3: ADJSP P,-1 ;RETURN TO CALLER'S CALLER (IMPBP1)
RET
;IMIBB - SEND NXR AND DO UNKNOWN LINK BUGINF
; T1/ HOST AND LINK RIGHT JUSTIFIED
; BUFFER ADDRESS ON TOP OF STACK
IMIBB: IUNLK
LSHC T1,-8 ;HOST IN T1
ROT T2,8 ;LINK IN T2
ANDX T1,HSTMSK ;JUST HOST
ANDX T2,L1%LNK ;AND JUST LINK
PUSH P,T1 ;SAVE T1 AND T2 FOR BUGINF
PUSH P,T2
CALL IMPNXR ;SEND NXR
POP P,T2 ;RESTORE T1 AND T2
POP P,T1
BUG(INF,IMPMUL,<RECEIVED MSG FOR UNKNOWN LINK>,<T1,T2>)
POP P,T2 ;GET BUFFER ADDRESS BACK
CALLRET RLNTBF ;RELEASE BUFFER
;SEND RST TO ALL NAMED HOSTS ON STARTUP
NETCH0: IMSCLK (IMCNCK) ;CHARGE TO IMCNCK
SKIPGE Q3,IMPCCH ;SENDING RST'S?
JRST IMPET ;NO.
IMPRC1: MOVE T1,NETFRE+2 ;Don't deplete all buffers
CAMLE T1,ASNTHR ;Wait for reasonable reserve
CALL IMPRCC ;CHECK FOR SPACE IN LINK TABLE
JRST [ MOVEI T1,^D50 ;GO WAIT 50 MSEC.
JRST IMPET1]
HRRZ T2,Q3 ;GET THE HOST WE ARE WORKING ON
CAMN T2,NLHOST ;LOCAL HOST?
JRST IMPRC2 ;NEVER SEND RESET TO LOCAL HOST
MOVEI T1,377777 ;NIL DESIGNATOR FOR CVHST
CVHST ;SEE IF THE HOST HAS A NAME
JRST IMPRC2 ;IT DOESN'T. DON'T SWAMP NET WITH
; RESETS TO NONEXISTENT HOSTS.
HRRZ T1,Q3 ;RESTORE HOST NUMBER FOR IMSRST
HRRZ T2,Q3 ;HOST EXISTS. SEE IF IT'S UP ALREADY
IDIVI T2,^D36 ;GET WORD IN BIT TABLE
MOVE T3,BITS(T3) ;AND BIT
TDNN T3,IMPHRT(T2) ;NO RESET IF ALREADY UP
CALL IMSRST ;NOT UP SO SEND RESET
IMPRC2: CAIG Q3,NHOSTS ;DONE ALL HOST YET?
AOJA Q3,IMPRC1 ;NO GO DO NEXT ONE
IMPEET: SETZM IMPHCT ;YES. ZERO RECENT MESSAGE SENT
MOVE T1,[IMPHCT,,IMPHCT+1] ;BIT TABLE
BLT T1,IMPHCT+IMPLBT-1
MOVSI Q3,-IMPNLK ;INDICATE NOW ECHO CHECKING
MOVE T1,[UPROBI-UPROBT] ;SET TIME TO WAKE UP
JRST IMPET1 ;GO FINISH
IMPRCC: MOVE T1,IMPNOL ;NUMBER OF LINKS IN USE
CAIG T1,IMPNLK/4-10 ;QUATER FULL?
AOS 0(P) ;NO. INDICATE ROOM
RET ;YES INDICATE NO ROOM
;ECHO TESTER
IMPET: MOVEI T1,^D120000 ;TIME FOR NEXT TEST
SKIPL IMPRDY ;IMP UP?
JRST IMPCC6 ;DON'T PROBE IF NCP NOT FULLY UP
CALL IMPRCC ;CHECK SPACE IN LINK TABLE
JRST [ MOVEI T1,^D5000 ;TRY AGAIN IN 5 SECONDS
JRST IMPCC6]
MOVE T1,IMPLT1(Q3) ;GET STATE, HOST AND LINK #
TXNE T1,L1%FRE ;ACTIVE?
JRST IMPET4 ;NO, GET NEXT
LSH T1,-8
ANDX T1,HSTMSK ;GET THE HOST
MOVE T2,T1 ;GET HOST IN T2
IDIVI T2,^D36 ;COMPUTE BIT TABLE INDEX
MOVE T3,BITS(T3)
TDNE T3,IMPHCT(T2) ;RECENTLY SENT A MESSAGE
JRST [ ANDCAM T3,IMPHCT(T2)
JRST IMPET4] ;CLEAR SO WE WILL SEND NEXT TIME NOT THIS
IORM T3,IMPHCT(T2) ;REMEMBER WE HAVE SENT ONE
MOVE T2,T1 ;IF UP, DATA=HOST
CALL IMPNOP ;AND SEND NOP (ECHO MIGHT BE BETTER)
IMPET4: AOBJP Q3,IMPEET
TRNE Q3,7 ;WAIT EVERY EIGHTH ENTRY
JRST IMPET ;NOT TIME TO WAIT. TRY ANOTHER
MOVEI T1,UPROBT*8/IMPNLK ;DELAY FOR CORRECT INTERVAL
IMPET1: MOVEM Q3,IMPCCH ;SAVE CURRENT STATE
IMPCC6: ADD T1,TODCLK ;COMPUTE WHEN TO DO IT AGAIN
MOVEM T1,IMPTIM ;STORE TIME AWAY
RET
;CHECK FOR OVERDUE RFNM'S
;COUNT DOWN RFNM COUNT FIELD IF NON-ZERO.
;IF IT REACHES 0, THEN GENERATE BUGINF BECAUSE RFNM SEEMS LOST
RFNCHK: IMSCLK (IMCRFN) ;CHARGE IMCRFN
MOVSI P1,-IMPNLK ;SET TO SCAN CONN TABLE
RFNCK0: MOVX Q2,RFNMCM ;GET RFNM COUNT MASK
MOVX IMPUN,L1%FRE ;CONNECTION IN USE BIT
RFNCK2: TDNN IMPUN,IMPLT1(P1) ;CONNECTION IN USE?
TDNN Q2,IMPLT2(P1) ;YES. RFNM SET HERE?
RFNCK1: AOBJN P1,RFNCK2 ;NO. TRY NEXT ONE
JUMPGE P1,RFNCK4 ;FINISHED ALL OF TABLE
LOAD Q3,RFNMC,(P1) ;GET RFNM COUNT FIELD
SOJE Q3,RFNCK5 ;DECREMENT COUNT, JUMP IF EXHAUSTED
STOR Q3,RFNMC,(P1) ;STORE UPDATED COUNT
JRST RFNCK1 ;GO TRY NEXT ONE
RFNCK5: PIOFF ;PREVENT CONFUSION IF PI STORES BUFFER
HRRZ T2,IMPLT3(P1) ;WHILE WE GET MESSAGE TO RETRANSMIT
HLLZS IMPLT3(P1) ;AND CLEAR THE POINTER
PION
JUMPE T2,RFNCK3 ;APPARENTLY HASN'T MADE IT THRU Q YET
HRLI T2,ANBSEC ;SET THE BUFFER SECTION NUMBER
HRRZ T3,IMPLT1(P1) ;GET HOST/LINK
ROT T3,-8 ;SHIFT DOWN TO HOST
ANDX T3,HSTMSK ;RETAIN ONLY HOST
MOVSI IMPUN,(RXMTF) ;RETRANMISSION FLAG
CAME T3,NLHOST ;IF LOCAL HOST
TDNE IMPUN,IMPLT2(P1) ;OR RETRANSMISSION WANTED?
JRST RFNCK7 ;THEN RETRANSMIT
CALL RLNTBF ;ELSE RELEASE THE BUFFER
STOR Q3,RFNMC,(P1) ;ZERO RFNM COUNT
HRRZ T2,IMPLT1(P1) ;RFNM LOST. GET HOST-LINK
CALL IMP8X1 ;REFORMAT FOR BUG MSG
BUG(INF,IMPRNO,<RFNM OVERDUE>,T2)
AOS IMPNOS ;CAUSE OUTPUT SCAN TO RESTART OUTPUT
RFNCK6: AOBJN P1,RFNCK0 ;RESET IMPUN AND Q2
RFNCK4: MOVEI T1,RFNTMO ;FINISHED. GET RFNM TIME OUT INTERVAL
ADD T1,TODCLK ;SET NEXT CHECK FOR RFNTMO MSEC.
MOVEM T1,RFNTIM ;STORE TIME
RET
RFNCK7: IORM Q2,IMPLT2(P1) ;SET RFNM COUNT AGAIN
CALL IMPQOA ;PUT MESSAGE BACK ON OUTPUT QUEUE
JRST RFNCK6 ;GO TO NEXT ITEM
RFNCK3: IORM Q2,IMPLT2(P1) ;SET RFNM COUNT AGAIN
HRRZ T2,IMPLT1(P1) ;GET HOST/LINK
CALL IMP8X1 ;FORMAT FOR BUG MSG
BUG(INF,IMPMSO,<MESSAGE STUCK IN OUTPUT QUEUE>,T2)
JRST RFNCK6 ;GO ON TO NEXT ITEM
;QUEUE IRREG MSG
IMP8XQ::AOS T3,IMP8XI ;INCREMENT INPUT INDEX
CAIL T3,IMP8XS ;END OF BUFFER?
SETZB T3,IMP8XI ;YES. RESET POINTERS
CAMN T3,IMP8XO ;OVERFLOW?
BUG(INF,IMPXBO,<IRREG MSG BUFFER OVERFLOW>)
MOVEM T2,IMP8XB(T3) ;SAVE MESSAGE IN BUFFER
AOS IMP8XC ;ACCOUNT FOR THIS MESSAGE
RET
IMP8XM: IMSCLK (IMC8XM) ;CHARGE TO IMC8XM
AOS T3,IMP8XO ;RETRIEVE STUFF FROM QUEUE
CAIL T3,IMP8XS ;END OF BUFFER?
SETZB T3,IMP8XO ;YES. RESET POINTERS
MOVE T1,IMP8XB(T3) ;GET MESSAGE
SOS IMP8XC ;ACCOUNT FOR REMOVAL OF MESSAGE
CALL DBGIIM ;SAVE INFO FOR DEBUGING
LOAD T3,LD%MST,T1 ;GET MESSAGE TYPE CODE
LOAD T2,<LD%HST!LD%LNK>,T1 ;GET HOST-LINK
XCT IMPMTT(T3) ;DISPATCH TO APPROPRIATE ROUTINE
RET
XX==JRST IMP8XX ;UNIMPLEMENTED CODE
IMPMTT: BUG(HLT,IMPRMI,<IMP - REGULAR MESSAGE ON IRREG QUEUE>)
JRST IMPEC1 ;ERROR
JRST IMPDN2 ;IMP GOING DOWN
XX ;FORMERLY BLOCKED LINK
JFCL ;NOP
JRST IMRFNM ;RFNM
JRST IMPEC6 ;DEAD HOST STATUS
JRST IMPEC7 ;DESTINATION DEAD
JRST IMPEC8 ;ERROR
JRST IMPEC9 ;INCOMPLETE TRANSMISSION
JRST IMPE10 ;IMP DROPPED READY LINE
XX ;CEASE TIMEOUT
XX ;CEASE SENT
XX ;UNASSIGNED
XX ;"
JFCL ;TREAT LONG LEADER TYPE AS NOP
;IRREGULAR MESSAGE PROCESSORS
; T1/ CONTAINS MESSAGE
; T2/ CONTAINS HOST-LINK
; T3/ CONTAINS MESSAGE TYPE
;ERROR IN LEADER (TYPE 1)
IMPEC1: TXNN T1,<LD%HST!LD%LNK> ;ARE HOST AND LINK BOTH ZERO?
RET ;YES. DISCARD, ELSE WILL BE ERROR.
TRNN T1,377B31 ;SUB-TYPE 0?
JRST IMPEC8 ;YES, RETRANSMIT
JRST BADIRM ;GO CAUSE IT TO BE PRINTED
;IMP GOING DOWN (TYPE 2)
IMPDN2: MOVEM T1,IMPGDM ;SAVE IT FOR PRINTING
AOS JB0FLG ;REQUEST JOB 0 SERVICE
MOVEM T1,IGDMSG ;SAVE FOR LAST IMP GOING DOWN MSG
GTAD ;GET TIME AND DATE
MOVEM T1,IGDTIM ;SAVE TIME MESSAGE WAS RECIEVED
RET
;RFNM (TYPE 5)
IMRFNM: MOVEI T1,L1%SND(T2) ;HOST AND LINK, DENOTE SEND CONNECTION
ILOCK
CALL LNKLUK ;LOOKUP IN LINK TABLE
JRST BADIRY ;NOT FOUND. GO DO BUGINF
PUSH P,T1 ;SAVE INDEX TO LINK TABLES
MOVX T2,RFNMCM ;GET RFNM COUNT BITS
PIOFF ;IF RFNM RETURNS BEFORE MSG OUT DONE
ANDCAM T2,IMPLT2(T1) ; CLEAR RFNM AND CHECK FLAGS
HRRZ T2,IMPLT3(T1) ;GET RETRANSMIT BUFFER
HLLZS IMPLT3(T1) ;ZERO RETRANSMISSION BUFFER ADD.
PION
HRLI T2,ANBSEC ;SET BUFFER SECTION NUMBER
TRNE T2,-1 ;WAS THERE A BUFFER
CALL RLNTBF ;YES. RELEASE IT
POP P,T1 ;GET LINK TABLE INDEX BACK
HLRE IMPUN,IMPLT1(T1) ;GET IMPUN
MOVSI T2,(RXMTF) ;GET RETRANSMISSION FLAG
TDNN T2,IMPLT2(T1) ;HAVE WE BEEN RETRANSMITTING?
JRST IMPKO1 ;NO. JUST SEND NEXT MESSAGE
ANDCAM T2,IMPLT2(T1) ;YES. STOP RETRANSMITTING
CALL IMPKO1 ;SEND NEXT MESSAGE
JUMPGE IMPUN,SVCRST ;IF NOT CTRL GENERATE SERVICE RESTORED
RET
;DEAD HOST STATUS (TYPE 6)
IMPEC6: TLNE T1,(1B1) ;USUAL TYPE?
RET ;NO. IGNORE IT
ROT T2,-9 ;GET HOST NUMBER/2 LOW BIT IN B0
LSH T1,-4 ;GET MSG ID -- SUBTYPE
ANDI T1,177777 ;KEEP 16 BITS
IORI T1,1B18+1B19 ;MARK INFO VALID AND DEAD
HRRZ T3,T2 ;GET JUST RIGHT HALF FOR INDEX
JUMPL T2,[ ;ODD HOST?
HRRM T1,HSTSTS(T3) ;YES, STORE IN RH
JRST .+2]
HRLM T1,HSTSTS(T3) ;NO, STORE IN LH
ANDI T1,17 ;EXTRACT SUB-TYPE
CAIE T1,2 ;IS IT SIMPLY TARDY?
CAIN T1,^D10 ;OR AT A BPT
RET ;YES, NO FURTHER ACTION
ROT T2,9 ;NO. GET BACK HOST/LINK
JRST IMPDD1 ;AND DECLARE IT DEAD
;DESTINATION DEAD (TYPE 7)
IMPEC7: PUSH P,T2 ;SAVE HOST-LINK
LOAD T1,L1%HST,T2 ;EXTRACT HOST NUMBER
IDIVI T1,^D36
MOVE T1,IMPHRT(T1) ;GET HOST UP BITS
AND T1,BITS(T2) ;MASK IN THE CORRECT ONE
POP P,T2 ;RETORE HOST-LINK
JUMPE T1,IMPDD1 ;IF ALREADY DOWN, CALL IT DOWN
MOVE T1,T2 ;HOST/LINK
IORX T1,L1%SND ;SEND
ILOCK
CALL LNKLUK ;FIND THE LINK
JRST BADIRY ;GO LOG ERROR WITH BUGINF
IMPECC: MOVSI T2,(RXMTF) ;GET RETRANSMISSION FLAG
IORM T2,IMPLT2(T1) ;CAUSE RETRANSMISSION
HLRE IMPUN,IMPLT1(T1) ;GET "UNIT"
IUNLK
JUMPL IMPUN,R ;DONE IF CONTROL CONNECTION
CALL SVCINT ;ELSE PERFORM SERVICE INTERRUPTION
RET
IMPDD1: LOAD T1,L1%HST,T2 ;EXTRACT HOST NUMBER
HSTDED::MOVEI T3,0(T1) ;GET HOST NUMBER IN T3
IDIVI T3,^D36 ;GET WORD AND BIT FOR TABLE
MOVE IMPUN,BITS(T4)
TDNE IMPUN,IMPHRT(T3) ;DID WE ALREADY KNOW HE WAS DOWN?
IFDEF POLLF,<
IORM IMPUN,IMPHL1(T3)> ;REQUEST OBITUARY
ANDCAM IMPUN,IMPHRT(T3) ;MARK HIM DOWN
CALL IMPXLT ;CLEAR LINK TABLE FOR DEAD HOST
CALL NETHDN ;CLEAN UP ANY CONNECTIONS TO HOST
RET
;ERROR IN DATA & INCOMPLETE TRANSMISSION (TYPES 8 & 9)
IMPEC8:
IMPEC9: MOVEI T1,L1%SND(T2) ;SEND CONNECTION
ILOCK
CALL LNKLUK ;GET LT INDEX FOR THIS ONE
JRST BADIRY ;NOT THERE, CAN'T RETRANSMIT. LOG ERROR
PIOFF ;PREVENT PI FROM STORING IN IMPLT3
HRRZ T2,IMPLT3(T1) ;GET BUFFER FOR RETRANSMISSION
HLLZS IMPLT3(T1) ;CLEAR RETRANSMISSION BUFFER ADDRESS
PION
JUMPE T2,IMPECC ;NONE THERE NOW. RETRANSMIT LATER
IUNLK
HRLI T2,ANBSEC ;SET SECTION NUMBER
CALL IMPQOA ;PUT IT BACK ON OUTPUT QUEUE
RET
;INTERFACE RESET (TYPE 10)
IMPE10: MOVSI T1,-IMPNLK ;SET UP TO SCAN LINK TABLES
IMPRSY: PUSH P,T1 ;SAVE INDEX
ILOCK
MOVE T2,IMPLT1(T1) ;GET STATE HOST AND LINK
TXNE T2,L1%FRE ;IN USE?
JRST IMPZSY ;NO
TXNN T2,L1%LNK ;LINK ZERO?
JRST IMPZSY ;YES. CONTROL
TXNE T2,L1%SND ;SEND?
JRST IMPSSY ;YES
LOAD T2,LTLINK,(T1) ;GET LINK NUMBER
LOAD T1,LTHOST,(T1) ;GET HOST NUMBER
IUNLK
CALL IMPRAP ;SEND RAP
JRST IMPXSY
IMPSSY: CALL IMPSYN ;RESYNC ALLOCATION
IMPZSY: IUNLK
IMPXSY: POP P,T1 ;RESTORE INDEX
AOBJN T1,IMPRSY ;TRY NEXT ENTRY
AOS IMPNOS ;DONE. SCAN FOR OUTPUT TO PICK UP RARRF'S
RET
;CHECK IF HOST FOR CONTROL MESSAGE KNOWS ABOUT NEW PROTOCOL STUFF
; T1/ HOST NUMBER
CHKNWP: PUSH P,T2 ;SAVE T2 AND T1
PUSH P,T1
IDIVI T1,^D36 ;CALCULATE WORD AND BIT FOR TABLE
MOVE T2,BITS(T2)
TDNE T2,NWPBT(T1) ;DOES IT UNDERSTAND NEW PROTOCOL
AOS -2(P) ;YES SKIP RETURN
POP P,T1 ;RESTORE T1 AND T2
POP P,T2
RET
; MARK NEW PROTOCOL BIT FOR HOST
; T1/ HOST NUMBER
MRKNWP: PUSH P,T1 ;SAVE T1 AND T2
PUSH P,T2
IDIVI T1,^D36 ;CALCULATE WORD AND BIT FOR TABLE
MOVE T2,BITS(T2)
IORM T2,NWPBT(T1) ;INDICATE THAT HE UNDERSTANDS NEW PROTOCOL
POP P,T2 ;RETORE T2 AND T1
POP P,T1
RET
;ERROR TAIL ENDS FOR IRREGULAR MSG PROCESSORS
BADIRY: IUNLK
MOVE T2,IMP8XO ;GET POINTER FOR REMOVING IRREG. MSG.
MOVE T1,IMP8XB(T2) ;GET IRREGULAR MESSAGE AGAIN
LOAD T2,<LD%HST!LD%LNK>,T1 ;GET HOST-LINK
BADIRM:
IMP8XX: CALL IMP8X1 ;FORMAT HOST LINK
BUG(INF,IMPXUT,<RECEIVED IRREG MSG WITH UNKNOWN LINK OR TYPE>,<T1,T2,T3>)
RET
IMP8X1: DPB T2,[POINT 8,T2,9] ;UNPACK HOST-LINK IN B20-35 INTO
LSH T2,-^D8 ;XWD LINK,HOST
TRZ T2,777400
RET
;SCAN FOR INPUT READY ON CONTROL LINK CONNECTION
IMPCN0: IMSCLK (IMCCNP) ;CHARGE TO IMCCNP
MOVX IMPUN,L1%SND!L1%FRE!L1%LNK ;CONNECTION MUST BE RECEIVE, LINK 0
PUSH P,BHC ;PUT A ZERO ON STACK
MOVSI Q2,-IMPNLK ;SET UP TO SCAN ENTIRE TABLE
IMPCN4: TDNE IMPUN,IMPLT1(Q2) ;DESIRED CONNECTION?
AOBJN Q2,IMPCN4 ;NO. TRY NEXT ONE
JUMPGE Q2,IMPCN5 ;DONE?
AOS 0(P) ; NO. COUNT NUMBER OF MSGS SEEN
MOVEI T1,0(Q2) ;CONN INDEX
PUSH P,IMPUN ;SAVE IMPUN AND Q2
PUSH P,Q2
CALL IMPCNP ;GO PROCESS THIS HOST'S CONTROL MSGS
POP P,Q2 ;RESTORE Q2 AND IMPUN
POP P,IMPUN
MOVEI T1,0(Q2) ;GET INDEX IN T1 AGAIN
CALL IMPCLL ;CLOSE "CONNECTION"
JRST IMPCN4
IMPCN5: POP P,T1 ;DONE. GET COUNT OF PROCESSED MSGS
JUMPN T1,R ;IF ANY, DONE.
BUG(INF,IMPCTH,<IMPNCL TOO HIGH>)
SOS IMPNCL ;COUNT IT DOWN SO DON'T LOOP.
RET
;CONTROL TABLE FOR CONTROL OPCODES
DEFINE CTOP (A,C)
< XWD IM8'A,C>
IM8RTS=RECRTS ;CODE IN NETWRK
IM8STR=RECSTR ;CODE IN NETWRK
IM8CLS=RECCLS ;CODE IN NETWRK
I8CCM: CTOP NOP,0
CTOP RTS,441000
CTOP STR,441000
CTOP CLS,440000
CTOP ALL,124000
CTOP GVB,111000
CTOP RET,124000
CTOP INR,100000
CTOP INS,100000
CTOP ECO,100000
CTOP ERP,100000
CTOP ERR,144200
CTOP RST,0
CTOP RRP,0
CTOP RAR,100000
CTOP RAS,100000
CTOP RAP,100000
CTOP NXR,100000
CTOP NXS,100000
I8NCCM==.-I8CCM
;PROCESS CONTROL MESSAGE
IMPCNP: LOAD T2,LTHOST,(T1) ;GET HOST NUMBER
MOVEM T2,IMPCHO ;AND LEAVE IT FOR FOLLOWING COMMANDS
IDIVI T2,^D36 ;COMPUTE INDEX TO BIT TABLES
MOVE T3,BITS(T3)
TDNE T3,IMPBHT(T2) ;BAD HOST?
RET ;YES. LET IMPCLL FLUSH IT
SETZM IMPCHU ;SAY HOST NOT READY (NO RST/RRP)
TDNE T3,IMPHRT(T2) ;UNLESS IT IS UP
SETOM IMPCHU ;THEN SAY IT'S UP
IMP8T6: CALL UPBYT ;GET NEXT OP CODE
RET ;NONE LEFT...DONE
CAIL T3,I8NCCM ;LEGAL CODE?
JRST IMP8T4 ;NO, FLUSH WHOLE MESSAGE
MOVEI Q2,I8CCM(T3) ;ADDRESS OF TABLE ENTRY FOR THIS CODE
HRLI Q2,220300 ;PNTR FOR 3-BIT BYTES SPECIFYING FIELDS
HLRZ Q3,I8CCM(T3) ;GET ROUTINE DISPATCH ADDRESS
MOVEI T4,I8CAL ;ARGS BUFFER
IMP8T1: ILDB IMPUN,Q2 ;NUMBER OF (8-BIT) BYTES IN NEXT ARG
SETZ T2, ;CLEAR WORD TO CONSTRUCT ARG
JUMPN IMPUN,IMP8T2 ;0 MEANS NO MORE ARGS
CAIN Q3,IM8NOP ;CHECK FOR NOP'S AT THIS LEVEL
JRST IMP8T6 ;NOP. GO GET NEXT OP CODE
CAIE Q3,IM8RST ;IS RST?
CAIN Q3,IM8RRP ;OR RRP?
SETOM IMPCHU ;YES, CONSIDER HIM UP
SKIPN IMPCHU ;IS HE UP?
MOVEI Q3,IMSRST ;NO. FORCE CALL TO SEND RST
PUSH P,T1 ;PRESERVE T1
MOVE Q2,[XWD IMPCHO,1] ;MOVE ARGS TO ACS 1-6
BLT Q2,Q2 ;T1 (IMPCHO) ALWAYS GETS HOST NUMBER
CALL 0(Q3) ;DO FUNCTION
POP P,T1 ;RESTORE 1 (LT INDEX)
JRST IMP8T6 ;SEE IF ANOTHER
IMP8T2: PUSH P,T2 ;PRESERVE T2
CALL UPBYT ;GET A BYTE OF ARGUMENT
JRST IMP8T5 ;WHOOPS, SHORT MESSAGE
POP P,T2
ROT T3,-8 ;AND SHIFT IT
LSHC T2,8 ;INTO THE ARG BEING ACCUMULATED
SOJG IMPUN,IMP8T2 ;ALL BYTES PACKED?
MOVEM T2,0(T4) ;YES, STORE ARG IN BUFFER
AOJA T4,IMP8T1 ;AND SEE IF MORE ARGS
IMP8T5: ADJSP P,-1 ;CLEAN UP STACK
IMP8T4: MOVE T2,IMPCHO ;SCREWED UP CONTROL MSG
BUG(INF,IMPIFC,<ILL FMT CTL MSG>,<T2,T3>)
RET ;LET IMPCLL FLUSH REST OF MESSAGE(S)
;CONTROL ROUTINES
; T1/ HOST NUMBER
; T2/ LINK NUMBER USUALLY
; T3-T6/ 8 BITS OF ARGUMENT
;NOP (TYPE 0)
IM8NOP: RET ;NOTHING TO DO
;RECEIVER TO SENDER REQUEST FOR CONNECTION (TYPE 1)
;IM8RTS=RECRTS ;CODE IN NETWRK
;SENDER TO RECEIVER REQUEST FOR CONNECTION (TYPE 2)
;IM8STR=RECSTR ;CODE IN NETWRK
;CLOSE CONNECTION (TYPE 3)
;IM8CLS=RECCLS ;CODE IN NETWRK
;ALLOCATE (TYPE 4)
IM8ALL: LSH T1,^D8 ;CONCAT HOST AND LINK
IORI T1,L1%SND(T2) ;BIT FOR SEND CONNECTION
ILOCK
CALL LNKLUK ;LOOKUP IN CONNECT TABLE
CALL BADLKS ;NOT FOUND
HLRE IMPUN,IMPLT1(T1) ;GET UNIT
JUMPL IMPUN,ULKIDV ;CONTROL CONNECTION, SHOULDN'T HAPPEN
MOVSI T2,(RARF) ;WAITING FOR RAR?
TDNE T2,IMPLT2(T1)
JRST ULKIDV ;YES, IGNORE ALL ALLOCATES
HRRZ T2,IMPLT4(T1) ;GET CURRENT MSG ALLOC
ADD T2,T3 ;ADD REQUESTED ALLOCATION
CAILE T2,777777 ;BIGGER THAN MAX?
JRST IMPB06 ;YES
HRRM T2,IMPLT4(T1) ;STORE NEW ALLOCATION
ADDB T4,NETBAL(IMPUN) ;UPDATE BIT ALLOCATION
CAML T4,[1B3] ;EXCESSIVE?
JRST IMPB06 ;YES.
LOAD T2,ANNVT,(IMPUN) ;GET NVT NUMBER
CALL NVTCHK ;NVT ATTACHED?
JRST IMPKO1 ;NO, TEST MORE OUTPUT FOR REG. CONNET'N
IUNLK
PUSH P,T2 ;SAVE ADDRESS OF DYNAMIC DATA FOR TTY
CALL NETTCS ;PACK UP MORE CHARACTERS
POP P,T2 ;GET BACK ADDRESS OF DYNAMIC DATA
CALL ULKTTY ;UNLOCK DATA BASE
JRST IMPCKO ;AND TRY TO SEND
IMPB06: IUNLK
MOVE T2,T1 ;GET HOST-LINK NUMBER
CALL IMP8X1 ;FORMAT AS LINK,,HOST
BUG(INF,IMPREA,<RECD EXCESS ALL>,T2)
RET
;GIVE BACK (CODE 5)
IM8GVB: LSH T1,^D8 ;GIVE BACK REQUESTED
IORI T1,L1%SND(T2) ;CONSTRUCT HOST-LINK FOR SEND SOCKET
ILOCK
CALL LNKLUK
CALL BADLKS ;NOT FOUND
HLRE IMPUN,IMPLT1(T1) ;GET UNIT
JUMPL IMPUN,ULKIDV ;CONTROL CONN, SHOULDN'T HAPPEN
HRRZ T2,IMPLT4(T1) ;MSG ALLOC
CAIL T3,200 ;ALL?
JRST IM8GV1 ;YES
IMUL T2,T3 ;NO, CALC HOW MUCH
IDIVI T2,200
IM8GV1: HRRZ T3,IMPLT4(T1)
SUB T3,T2 ;REDUCE CURRENT MSG ALLOC
HRRM T3,IMPLT4(T1) ;AND STORE IT
PUSH P,T2 ;SAVE AMOUNT TO BE RETURNED
MOVE T2,NETBAL(IMPUN) ;BIT ALLOCATION
CAIL T4,200 ;RETURN ALL?
JRST IMPGV2 ;YES
MUL T2,T4 ;NO, CALC HOW MUCH
DIVI T2,200
IMPGV2: MOVN T3,T2 ;GET NEGATIVE OF AMOUNT REQUESTED
ADDM T3,NETBAL(IMPUN) ;REDUCE BIT ALLOC
MOVE T4,T2 ;SETUP CALL FOR RET
POP P,T3 ;GET BACK AMOUNT OF MSG ALLOC. RETURNED
LOAD T2,LTLINK,(T1) ;GET LINK NUMBER
LOAD T1,LTHOST,(T1) ;GET HOST NUMBER
IUNLK
CALL IMPRET ;SEND THE RET
RET
;RETURN (CODE 6)
IM8RET: RET ;NEVER SEND GVB/ NVER GET RET
;INTERRUPT FROM RECEIVER (CODE 7)
IM8INR: MOVE T3,T1 ;GET HOST NUMBER INTO T3
LSH T1,^D8 ;CONSTRUCT HOST-LINK FOR LOOKUP
IORI T1,L1%SND(T2) ;WE MUST BE A SEND CONNECTION
ILOCK
CALL LNKLUK ;SEE IF CONNECTION EXIST
CALL BADLKS ;NO SUCH CONNECTION
HLRE IMPUN,IMPLT1(T1) ;UNIT
IUNLK
JUMPL IMPUN,R ;CONTROL CONNECTION, SHOULDN'T HAPPEN
; NOT SPECIFIED FOR NVT
MOVE T1,T3 ;GET HOST BACK INTO T1
CALLRET RECINR
;INTERRUPT FROM SENDER (CODE 8)
IM8INS: MOVE T3,T1 ;GET HOST NUMBER INTO T3
LSH T1,^D8
IORI T1,0(T2) ;COMBINE HOST-LINK
ILOCK
CALL LNKLUK ;LOOK UP HOST-LINK CONNECTION
CALL BADLKR ;NOT THERE REPORT ERROR
HLRE IMPUN,IMPLT1(T1)
IUNLK
JUMPL IMPUN,R ;IGNORE IF CONTROL CONNECTION
MOVE T1,T3 ;GET HOST NUMBER BACK IN T1
LOAD T2,ANNVT,(IMPUN) ;GET NVT NUMBER
CALL NVTCHK ;IS IT AN NVT
JRST RECINS ;ISN'T NVT, GO DO REGULAR CONNECTION
PUSH P,T2 ;SAVE ADDRESS OF DYNAMIC DATA FOR TTY
CALL NVTDSC ;DECREMENT SYNC COUNT AND RE-ALLOCATE
; IF NECESSARY
POP P,T2 ;GET BACK ADDRESS OF DYNAMIC DATA
CALL ULKTTY ;UNLOCK DATA BASE
RET
;ECHO AND ECHO REPLY (CODE 9 & 10)
IM8ECO: CALL IMPERP ;SEND REPLY
RET
IM8ERP: CAME T1,T2 ;WE SEND ECHO WITH DATA = HOST
JFCL ;NOT EQUAL ... OH WELL
RET
;ERROR (CODE 11)
; T1/ HOST NUMBER
; T2/ TPYE OF ERROR
IM8ERR: BUG(INF,IMPRNE,<RECD NCP ERR>,<T1,T2>)
RET
;RESET AND RESET-REPLY CTRL MSG (CODES 12 & 13)
IM8RST: PUSH P,T1 ;SAVE HOST NUMBER
CALL RECRST ;NOTIFY FSM
POP P,T1 ;RESTORE HOST NUMBER
IM8RRP: ROT T1,-1 ;HALVE
MOVX T2,1B18 ;VALID INFO, HOST UP
JUMPL T1,[ ;IF ODD HOST NUMBER
HRRM T2,HSTSTS(T1);PUT INTO RH
JRST .+2]
HRLM T2,HSTSTS(T1) ;EVEN GOES IN LEFT HALF
ROT T1,1 ;RESTORE HOST NUMBER
IDIVI T1,^D36 ;GET BIT FOR HOST TABLES
MOVE IMPUN,BITS(T2)
IORM IMPUN,IMPHRT(T1) ;MARK HOST ALIVE
RET
;RESET ALLOCATE BY RECEIVER (CODE 14)
IM8RAR: CALL MRKNWP ;MARK THIS HOST AS USING NEW PROTOCOL
LSH T1,^D8 ;MAKE HOST-LINK NUMBER
IORI T1,L1%SND(T2) ;AND SEND CONNECTION
ILOCK
CALL LNKLUK ;LOOK UP CONNECTION
CALL BADLKS ;REPORT ERROR
HLRE IMPUN,IMPLT1(T1)
JUMPL IMPUN,ULKIDV ;IGNORE CONTROL CONNECTIONS
MOVSI T2,(RARF)
ANDCAM T2,IMPLT2(T1) ;CLEAR RESYNC IN PROGRESS FLAG
CALLRET ULKIDV
;RESET ALLOCATE BY SENDER (CODE 15)
IM8RAS: CALL MRKNWP ;MARK THIS HOST AS USING NEW PROTOCOL
LSH T1,8 ;FORM HOST-LINK NUMBER
IORI T1,0(T2)
ILOCK
CALL LNKLUK ;LOOK UP CONNECTION
CALL BADLKR ;REPORT ERROR
HLRE IMPUN,IMPLT1(T1)
JUMPL IMPUN,ULKIDV ;IGNORE CONTROL CONNECTIONS
HLLZS IMPLT4(T1) ;ZERO MSG ALLOCATION
HLRZ T4,IMPLT4(T1) ;ANY CURRENT BUFFER?
JUMPE T4,IM8RA1 ;NO
HRLI T4,ANBSEC ;SET SECTION NUMBER
MOVE T4,2(T4) ;ACCUMULATE BYTES
IM8RA1: HLRZ T2,IMPLT3(T1) ;GET BUFFER
JUMPE T2,IM8RA3 ;NONE
IM8RA2: HRLI T2,ANBSEC ;SET SECTION NUMBER
LOAD T3,LD%BYC,2(T2) ;NUMBER OF BYTES
ADD T4,T3 ;ACCUMULATE BYTES
AOS IMPLT4(T1) ;COUNT MSGS
HLRZ T2,0(T2) ;GET NEXT BUFFER
JUMPN T2,IM8RA2 ;WAS THERE ONE
IM8RA3: LOAD T3,IMPBS,(T1) ;GET BYTE SIZE
IMUL T3,T4 ;CALCULATE BITS IN MSGS
MOVEM T3,NETBAL(IMPUN) ;SAVE NEW BIT ALLOACATION
IUNLK
LOAD T2,LTLINK,(T1) ;GET LINK NUMBER
LOAD T1,LTHOST,(T1) ;GET HOST NUMBER
CALL IMPRAR ;SEND RAR
LOAD T2,ANNVT,(IMPUN) ;GET NVT NUMBER
CALL NVTCHK ;NVT ?
JRST NETRAL ;NO. DO NORMAL REALLOCATION
PUSH P,T2 ;SAVE ADDRESS OF DYNAMIC DATA FOR TTY
CALL NVTRAL ;REALLOCATE FOR NVT
POP P,T2 ;GET BACK ADDRESS OF DYNAMIC DATA
CALL ULKTTY ;UNLOCK DATA BASE
RET
;RESET ALLOCATE PLEASE (CODE 16)
IM8RAP: CALL MRKNWP ;MARK THIS HOST AS USING NEW PROTOCOL
LSH T1,8 ;MAKE HOST-LINK NUMBER
IORI T1,L1%SND(T2) ;MUST BE A SEND CONNECTION
ILOCK
CALL LNKLUK ;GO LOOKUP HOST-LINK
CALL BADLKS ;ERROR. GO REPORT IT
HLRE IMPUN,IMPLT1(T1)
JUMPL IMPUN,ULKIDV ;IGNORE CONTROL CONNECTIONS
MOVSI T2,(RARF!RARRF) ;GET RAR EXPECTED AND SEND RAS WHEN NO
IORM T2,IMPLT2(T1) ; RFNM'S OUT FLAGS AND SET THEM
CALLRET IMPKO1 ;GO CHECK CONNECTION FOR OUTPUT POSSIBLE
;NON-EXISTENT LINK FROM RECEIVER AND SENDER (CODES 17 & 18)
IM8NXR: IORX T2,L1%SND ;INDICATE SEND CONNETION FOR LOOKUP
IM8NXS: CALL MRKNWP ;MARK THIS HOST AS USING NEW PROTOCOL
LSH T1,8 ;MAKE HOST-LINK NUMBER
IOR T1,T2
ILOCK
CALL LNKLUK ;GO LOOKUP HOST-LINK
JRST ULKIDV ;NOT THERE GO UNLOCK
HLRE IMPUN,IMPLT1(T1) ;GET IMPUN
JUMPL IMPUN,ULKIDV ;IGNORE IF CONTROL CONN
IUNLK
CALL SK2DWN ;GO CLOSE CONNECTION
RET
;LINK LOOKUP FAILURE FOR RECEIVERS AND SENDERS
BADLKR: SKIPA T3,[IMPNXR] ;CLOSE ROUTINE FOR RECIEVE CONNECTION
BADLKS: MOVEI T3,IMPNXS ;CLOSE ROUTINE FOR SEND CONNECTION
IUNLK
MOVE T2,T1 ;GET COPY OF HOST-LINK NUMBER IN T2
LSH T1,-8 ;SHIFT LINK OUT OF T1, LEAVING HOST
ANDX T1,HSTMSK ;SAVE JUST HOST IN T1
ANDX T2,L1%LNK ;SAVE JUST LINK IN T2
PUSH P,T2 ;SAVE LINK FOR BUGINF
PUSH P,T1 ;SAVE HOST TOO.
CALL 0(T3) ;GO CLOSE CONNECTION
POP P,T1 ;GET BACK HOST
POP P,T2 ;AND LINK
POP P,T3 ;AND ADDRESS OF CALLER
BUG(INF,IMPCUL,<RECD CTL MSG FOR UNKNOWN LINK>,<T1,T2,T3>)
RET
;CALLS FROM NCP
;OPEN LINK, I.E. ASSOCIATE HOST-LINK AND UNIT
; T1/ HOST
; T2/ LINK
; T3/ BYTE SIZE
IMPOPL::ILOCK
LSH T1,^D8
IORI T1,0(T2) ;CONCAT HOST AND LINK
CALL LNKLUK ;NOW IN TABLE?
JRST IMPOP0 ;NO, SLOT TO USE RETURNED IN T2
IUNLK
PUSH P,T1 ;SAVE HOST-LINK
EXCH T1,T2 ;GET A COPY INT0 T2
CALL IMP8X1 ;GO GET LINK,,HOST IN T2
BUG(INF,IMPLAE,<IMPOPL: LINK ALREADY EXISTS>,T2)
EXCH T1,T2 ;RETORE T2
POP P,T1 ;AND T1
RET
IMPOP0: CALL IMPOP1 ;NEW CONNECTION GO UPDATE TABLES
IUNLK
RET
IMPOP1: EXCH T1,T2 ;GET HOST-LINK INTO T1
MOVEM T2,IMPLT1(T1) ;SAVE HOST-LINK
HRLM IMPUN,IMPLT1(T1) ;SAVE UNIT NUMBER
SETZM T2,IMPLT2(T1) ;ZERO ADDING POINTER AND FLAGS
SETZM IMPLT3(T1) ;ZERO OUT AND RETRANS. BUFFER ADD.
SETZM IMPLT4(T1) ;ZERO CURRENT BUFFER AND MSG. ALLOC.
STOR T3,IMPBS,(T1) ;SET BYTE SIZE
RET
;CLOSE LINK, INVERSE OF ABOVE
; T1/ LT INDEX
IMPCLL::ILOCK
CALL IMPLL0 ;GO DO THE WORK
IUNLK
RET
IMPLL0: MOVX T2,L1%FRE ;GET IN USE BIT
TDNE T2,IMPLT1(T1) ;WAS CONNECTION IN USE?
RET ;NO, DO NOTHING ELSE
EXCH T2,IMPLT1(T1) ;SET ENTRY TO DELETED
TXNE T2,L1%LNK ;CONTROL LINK?
JRST IMPLL9 ;NO, SKIP THIS
TXNE T2,L1%SND ;SEND?
SOSA IMPNOL ;YES, DECREASE COUNT OF SEND CL'S
SOS IMPNCL ;ELSE DECREASE COUNT OF RECV CL'S
IMPLL9: AOS LNKNDL ;COUNT DELETES
CALL IMPLL1 ;FLUSH MESSAGES
RET
;SET DONE FLAG FOR CONNECTION
; T1/ CONN INDEX
IMPSDB::MOVSI T2,(LTDF) ;GET DONE FLAG
IORM T2,IMPLT2(T1) ;SET IT
AOS IMPNOS ;MAKE OUTPUT BE LOOKED AT
RET
;ABORT LINK (CALLED BY NCP IF TRANSMISSION ABORTED)
IMPABL::ILOCK
CALL IMPLL3 ;CLEAR QUEUES, DON'T CLEAR RFNM COUNT
IUNLK
RET
;CLEAR LINK TABLE FOR PARTICULAR HOST
IMPXLT: STKVAR <IMPXT1,IMPXHS>
MOVEM T1,IMPXT1 ;SAVE T1
HRRZ T1,T1 ;GET JUST HOST
MOVEM T1,IMPXHS ;SAVE IT
ILOCK ;LOCK
MOVSI T1,-IMPNLK ;SET TO SCAN CONN TABLE
IMPXLL: LOAD T2,LTHOST,(T1) ;GET HOST NUMBER
CAME T2,IMPXHS ;SPECIFIED ONE?
JRST IMPXLN ;NO. GO TRY NEXT ONE
LOAD T2,LTLINK,(T1) ;GET LINK NUMBER
JUMPE T2,[CALL IMPLL0 ;IF CONTROL LINK, FLUSH ALL
JRST IMPXLN] ;GO TRY NEXT ONE
CALL IMPLL1 ;ELSE FLUSH QUEUED MESSAGES
IMPXLN: AOBJN T1,IMPXLL ;ANY MORE?
IUNLK ;UNLOCK
MOVE T1,IMPXT1 ;RESTORE T1
RET
;RESYNC ALLOCATION
IMPSYN::PUSH P,1 ;SAVE T1, LT INDEX
LOAD T1,LTHOST,(T1) ;GET HOST NUMBER
CALL CHKNWP ;NEW PROTOCOL?
JRST [ POP P,T1 ;NO RETURN
RET]
POP P,T1 ;RETORE LT INDEX
MOVSI T2,(RARF!RARRF) ;SET RAR EXPECTED AND SEND RAS WHEN
IORM T2,IMPLT2(T1) ; NO RFNM'S OUT
AOS IMPNOS ;MAKE IT SCAN OUTPUT CONNECTIONS
RET
;FLUSH ALL MESSAGES FOR A CONNECTION
IMPLL3: TDZA T2,T2 ;DON'T CLEAR RFNM COUNT
IMPLL1: MOVX T2,RFNMCM ;CLEAR RFNM COUNT
STKVAR <IMPLFG,IMPLLT>
MOVEM T2,IMPLFG ;SAVE FOR A BIT LATER ON
HLRZ T2,IMPLT4(T1) ;GET CURRENT BUFFER ADDRESS
HRRZS IMPLT4(T1) ;ZERO CURRENT BUFFER IN TABLE
MOVEM T1,IMPLLT ;SAVE T1, LT INDEX
HRLI T2,ANBSEC ;SET SECTION NUMBER
TRNE T2,-1 ;IS THERE A CURRENT BFR?
CALL RLNTBF ;YES. RELEASE IT
MOVE T1,IMPLLT ;GET BACK LT INDEX
HLLZS IMPLT2(T1) ;FIX POINTER FOR ADDING BUFFERS
PIOFF
MOVE T2,IMPLFG ;GET BITS TO CLEAR, 0 OR RFNM COUNT
ANDCAM T2,IMPLT2(T1) ;CANCEL OUTSTANDING RFNM
HRRZ T2,IMPLT3(T1) ;GET RETRANSMIT BUFFER
HLLZS IMPLT3(T1) ;ZERO RETRANSMIR BUFFER IN TABLE
PION
HRLI T2,ANBSEC ;SET SECTION NUMBER
TRNE T2,-1 ;WAS THERE A BUFFER
IMPLL2: CALL RLNTBF ;YES, RELEASE IT
MOVE T1,IMPLLT ;RETORE T1, LT INDEX
HLRZ T2,IMPLT3(T1) ;RELEASE ANY BUFFERS ON QUEUE
JUMPE T2,R ;NO. RETURN
HRLI T2,ANBSEC ;SET SECTION NUMBER
HLLZ T3,0(T2) ;GET NEXT BUFFER IN CHAIN
HLLM T3,IMPLT3(T1) ;SAVE IT'S ADDRESS
SKIPN T3 ;NO MORE BUFFERS
HRRM T3,IMPLT2(T1) ;IF NO MORE ZERO ADDING POINTER TOO
JRST IMPLL2 ;GO RELEASE BUFFER
;CONTROL MESSAGE SENDERS
;NOP, RTS, STR, CLS, ALL, GVB, RET, INR, INS, ECO, ERP
;PUT ADDRESS OF [ARG DESCRIPTOR,,OPCODE] IN LH OF T1 AND CALL IMPSCM
IMPNOP: HRLI T1,[XWD 0,0] ;NOP, NO ARGS
JRST IMPSCM ;CONSTRUCT MESSAGE AND OUTPUT
IMPRTS::HRLI T1,[XWD 441000,1] ;ARG DESCRIPTOR,,OPCODE
JRST IMPSCM ;CONSTRUCT MESSAGE AND OUTPUT
IMPSTR::HRLI T1,[XWD 441000,2]
JRST IMPSCM ;CONSTRUCT MESSAGE AND OUTPUT
IMPCLS::HRLI T1,[XWD 440000,3]
JRST IMPSCM ;CONSTRUCT MESSAGE AND OUTPUT
IMPALL::CAIGE T3,0 ;DON'T SEND NEG ALLOCS
SETZ T3, ;IF NEGATIVE MAKE ZERO
CAIGE T4,0
SETZ T4,
PUSH P,T1 ;SAVE T1
LOAD T1,LTIDX,(IMPUN) ;GET CONNECTION INDEX
PUSH P,T2 ;SAVE T2
MOVSI T2,(RARF) ;WAITING FOR RAS?
TDNE T2,IMPLT2(T1)
JRST [ POP P,T2 ;YES. DO NOTHING
POP P,T1 ;RESTORE T2 AND T1
RET]
POP P,T2 ;NO, GET BACK AC2
ADDM T3,IMPLT4(T1) ;UPDATE MSG ALLOC
POP P,T1 ;GET BACK T1
ADDM T4,NETBAL(IMPUN) ;BITS
HRLI T1,[XWD 124000,4]
JRST IMPSCM ;CONSTRUCT MESSAGE AND OUTPUT
;CONTROL MESSAGE SENDERS (CONTINUED)
;GVB, RET, INR, INS, ECO, ERP, ERR, RST
IMPGVB: HRLI T1,[XWD 111000,5]
JRST IMPSCM ;CONSTRUCT MESSAGE AND OUTPUT
IMPRET: HRLI T1,[XWD 124000,6]
JRST IMPSCM ;CONSTRUCT MESSAGE AND OUTPUT
IMPINR::HRLI T1,[XWD 100000,^D7]
JRST IMPSCM ;CONSTRUCT MESSAGE AND OUTPUT
IMPINS::HRLI T1,[XWD 100000,^D8]
JRST IMPSCM ;CONSTRUCT MESSAGE AND OUTPUT
IMPECO: HRLI T1,[XWD 100000,^D9]
JRST IMPSCM ;CONSTRUCT MESSAGE AND OUTPUT
IMPERP: HRLI T1,[XWD 100000,^D10]
JRST IMPSCM ;CONSTRUCT MESSAGE AND OUTPUT
IMPERR::HRLI T1,[XWD 144200,^D11]
JRST IMPSCM ;CONSTRUCT MESSAGE AND OUTPUT
IMSRST::HRLI T1,[XWD 0,^D12]
JRST IMPSCM ;CONSTRUCT MESSAGE AND OUTPUT
;CONTROL MESSAGE SENDERS (CONTINUED)
;RRP, RAR, RAS, RAP, NXR, NXS
IMPRRP::HRLI T1,[XWD 0,^D13]
JRST IMPSCM ;CONSTRUCT MESSAGE AND OUTPUT
IMPRAR: CALL CHKNWP ;IS HE USING NEW PROTOCOL
RET ;NO. RETURN
HRLI T1,[100000,,^D14] ;YES
JRST IMPSCM ;CONSTRUCT MESSAGE AND OUTPUT
IMPRAS: CALL CHKNWP ;IS HE USING NEW PROTOCOL
JRST IM8RAR ;NO. RESYNC NOT IMPLEMENTED -- SIM RAR
HRLI T1,[100000,,^D15]
JRST IMPSCM ;CONSTRUCT MESSAGE AND OUTPUT
IMPRAP: CALL CHKNWP ;IS HE USING NEW PROTOCOL
RET ;DOES NOT UNDERSTAND NEW PROTOCOL
HRLI T1,[100000,,^D16]
JRST IMPSCM ;CONSTRUCT MESSAGE AND OUTPUT
IMPNXR: CALL CHKNWP ;IS HE USING NEW PROTOCOL
RET ;NO RETURN
HRLI T1,[100000,,^D17]
JRST IMPSCM ;CONSTRUCT MESSAGE AND OUTPUT
IMPNXS: CALL CHKNWP ;IS HE USING NEW PROTOCOL
RET ;NO RETURN
HRLI T1,[100000,,^D18]
JRST IMPSCM ;CONSTRUCT MESSAGE AND OUTPUT
;SEND CONTROL MESSAGE
; T1/ ADDRESS OF [ARG DESCRIPTOR,,OPCODE],,DEST HOST
; T2 - ?? ARGUMENTS
IMPSCM: SAVEPQ ;SAVE IMPUN, Q2-Q3 AND P1-P6
STKVAR <IMPSBP,<IMPSBF,5>>
HLRZ P4,T1 ;GET ADDRESS OF ARG DESCRIPTOR
MOVE P4,0(P4) ;GET THE ARG DESCRIPTOR
HRRZS T1 ;GET RID OF ADDRESS IN LH
MOVEI P1,IMPSBF ;GET ADDRESS OF BUFFER
HRLI P1,(<POINT 8,0,31>);CONSTRUCT BYTE POINTER, 8-BITS
MOVEM P1,IMPSBP ;SAVE IT FOR LATER USE
IDPB P4,P1 ;STORE OPCODE AS FIRST BYTE OF MESSAGE
MOVEI P2,1 ;INIT MESSAGE BYTE COUNT
MOVEI P5,2 ;INDEX TO ARGS
IMPSC4: SETZ P3, ;ZERO P3 BEFORE GETTING NEXT ARG DESC.
LSHC P3,3 ;NEXT ARG DESCRIPTOR BYTE
JUMPN P3,IMPSC3 ;0 MEANS DONE
LSH T1,^D8
IORX T1,L1%SND ;SEND CONNECTION
ILOCK
CALL LNKLUK ;SEE IF CONNECTION NOW EXISTS
JRST [ MOVEI T3,^D8 ;DOESN'T, CREATE IT 8 BIT BYTES.
CALL IMPOP1
AOS IMPNOL ;COUNT OPEN OUTPUT LINKS
HRROS IMPLT1(T1) ;SET UNIT NEG
MOVEI T3,377777 ;SET INFINITE MSG ALLOC
HRRM T3,IMPLT4(T1)
MOVSI T3,(HIPFLG)
IORM T3,IMPLT2(T1) ;SET HIGH PRIORITY FLAG
JRST .+1]
MOVE T3,IMPSBP ;GET BYTE PTR
MOVEI T4,0(P2) ;GET COUNT
CALL PKMSG0 ;PACK MESSAGE AND SEND IF POSSIBLE
; DOES IUNLK
RET
IMPSC3: ADDI P2,0(P3) ;ACCUMULATE BYTE COUNT OF MESSAGE
MOVNI Q2,0(P3) ;COMPUTE NUMBER OF BITS TO LEFT OF ARG
IMULI Q2,^D8 ;NUMBER BYTES TIMES BITS PER BYTE
ADDI Q2,^D36 ;SUBTRACTED FROM SIZE OF WORD
MOVE Q3,0(P5) ;GET NEXT ARG
LSH Q3,0(Q2) ;SHIFT OUT UNUSED BITS
IMPSC2: ROT Q3,^D8 ;SHIFT NEXT BYTE INTO PLACE
IDPB Q3,P1 ;STORE IT IN MESSAGE BUFFER
SOJG P3,IMPSC2 ;FOR ALL BYTES
AOJA P5,IMPSC4 ;INDEX ARG POINTER
;SPECIAL RAW MESSAGE ROUTINES
;.ASNSQ - ASSIGN A SPECIAL MESSAGE QUEUE
; T1/ MASK
; T2/ HEADER VALUE
; ASNSQ
;RETURNS
; +1 FAILURE
; T1/ ERROR CODE
; +2 SUCCESS
; T1/ SPECIAL QUEUE HANDEL
.ASNSQ::MCENT
CALL CKNTWZ ;CHECK TO SEE IF NET-WIZARD
RETERR ;NO. GIVE ERROR
NOINT
AOSE SQLCK ;SET SPECIAL QUEUE LOCK
CALL SQLWAT ;SOMEONE ALREADY HAS IT GO WAIT
MOVSI T3,-NSQ ;SET UP TO SCAN SPECIAL QUEUES
SETZ T4, ;INIT T4 TO KEEP TRACK OF Q TO BE ASSGND
ASNSQL: SKIPGE SQJOB(T3) ;ASSIGNED?
JRST [JUMPL T4,ASNSQN ;NO. HAVE WE ALREADY FOUND A FREE ONE
MOVE T4,T3 ;NO. SAVE Q NUMBER IN T4
JRST ASNSQN] ;CHECK MASK AND VALUE AGAINST THE REST
UMOVE T1,T1 ;GET MASK
AND T1,SQMSK(T3) ;JOINT MASK
UMOVE T2,T2 ;GET VALUE
XOR T2,SQVAL(T3) ;DIFFERENCE
TDNN T1,T2 ;MUST BE DIFFERENT IN JOINT MASK BITS
JRST ASNSQF ;ELSE FAIL
ASNSQN: AOBJN T3,ASNSQL ;TEST ALL POSSIBILITIES
MOVEI T1,ASNSX1 ;ASSUME WE DID NOT FIND ONE.
JUMPGE T4,ASNSF1 ;DID WE FIND ONE?
UMOVE T1,T1 ;YES. GET MASK
MOVEM T1,SQMSK(T4) ;STORE MASK IN TABLE
XCTU [AND T1,T2] ;MASK GOOD BITS OF VALUE
MOVEM T1,SQVAL(T4) ;AND SAVE THEM
MOVE T1,JOBNO ;GET THE JOB NUMBER
MOVEM T1,SQJOB(T4) ;AND SAVE IT AS OWNER OF Q
SETOM SQLCK ;CLEAR LOCK
XCTU [HRRZM T4,T1] ;RETURN QUEUE NUMBER
SMRETN ;SKIP RETURN
ASNSQF: MOVEI T1,ASNSX2 ;TELL HIM NOT UNIQUE MASK AND VALUE
ASNSF1: SETOM SQLCK ;CEAR LOCK
RETERR
;.RELSQ - RELEASE SPECIAL Q
; T1/ SPECIAL QUEUE HANDLE OR -1 FOR ALL
; RELSQ
;RETURNS +1 ALWAYS
.RELSQ::MCENT
NOINT
AOSE SQLCK ;TRY TO LOCK SPECIAL QUEUES
CALL SQLWAT ;COULDN'T LOCK GO WAIT
CAMN T1,[-1] ;IS HE ASKING FOR ALL OF THEM
JRST RELASQ ;YES GO DO IT
CAIL T1,0 ;LEGAL QUEUE NUMBER
CAIL T1,NSQ
JRST RELSQ1 ;NO RETURN
CALL REL1SQ ;YES. GO RELEASE IT
RELSQ1: SETOM SQLCK ;CLEAR LOCK
MRETNG ;RETURN
RELASQ: MOVSI T4,-NSQ ;SET UP TO SCAN ALL QUEUES
RELAS1: HRRZ T1,T4 ;GET QUEUE NUMBER IN T1
CALL REL1SQ ;GO RELEASE IT
AOBJN T4,RELAS1 ;DO NEXT ONE
JRST RELSQ1 ;FINISHED GO CLEAR LOCK AND EXIT
REL1SQ: MOVE T2,JOBNO ;GET JOB NUMBER
CAME T2,SQJOB(T1) ;DOES HE OWN THIS QUEUE
RET ;NO. RETURN
SETOM SQJOB(T1) ;YES. INDICATE QUEUE NO LONGER OWNED
REL1S1: CALL SIQGET ;ANY MESSAGES ON THE QUEUE
RET ;NO. RETURN
PUSH P,T1 ;YES. SAVE QUEUE NUMBER
CALL RLNTBF ;RELEASE BUFFER
POP P,T1 ;RESTORE SPECIAL QUEUE NUMBER
JRST REL1S1 ;SEE IF ANYMORE MESSAGES
;.RCVIM RECEIVE RAW MESSAGES
;ACCEPTS:
; T1/ SPECIAL QUEUE HANDLE
; T2/ BUFFER ADDRESS
; RCVIM
;RETURNS:
; +1 FAILURE
; T1/ ERROR CODE
; +2 SUCCESS
.RCVIM::MCENT
RCVIM1: NOINT
UMOVE T1,T1 ;GET SPECIAL QUEUE HANDLE
CALL CHKSQ ;CHECK FOR ACCESSIBILITY TO SPECIAL Q
RETERR ;NO ACCESS
CALL SIQGET ;GET THE MESSAGE
JRST [ OKINT ;NONE THERE
MDISMS ;WAIT
JRST RCVIM1] ;TRY AGAIN
HRRZS 0(T2) ;ZERO LINK FIELD, SO USER DOESN'T SEE IT
PUSH P,T2 ;SAVE BUFFER ADDRESS
UMOVE T3,T2 ;GET USER'S BUFFER
MOVE T1,0(T2) ;GET LENGTH FROM BUFFER HEADER
CALL BLTMU ;TRANSFER TO USER
POP P,T2 ;GET BUFFER ADDRESS BACK
CALL RLNTBF ;RELEASE THE BUFFER
SMRETN ;RETURN
SIQGET: MOVE T2,TODCLK ;GET TIME OF DAY
ADDI T2,SIQTM0 ;ADD IN SPECIAL QUEUE TIME LIMIT
MOVEM T2,SIQTIM(T1) ;RESET TIME
NOSKED
MOVE T2,SIQIBO(T1) ;GET BUFFER ADDRESS
JUMPE T2,SIQEMT ;NO BUFFER WAIT
HLRZ T3,0(T2) ;GET NEXT BUFFER IN CHAIN
JUMPN T3,SIQGT1 ;IS THERE ONE
SETZM SIQIBI(T1) ;NO. ZERO POINTER FOR ADDING BUFFERS
SKIPA ;SKIP ADDING SEC. NO SO PTR = ZERO
SIQGT1: HRLI T3,ANBSEC ;SET BUFFER SECTION NUMBER
MOVEM T3,SIQIBO(T1) ;UPDATE POINTER
SOS SIQSPC(T1) ;CREDIT SPACE USED
OKSKED
RETSKP
SIQEMT: OKSKED
HRLZI T1,SIQIBO(T1) ;GET ADDRESS OF POINTER FOR REMOVING
HRRI T1,DISNT ;AND ADDRESS OF TEST ROUTINE
RET
;.SNDIM - SEND SPECIAL MESSAGE
;ACCEPTS:
; T1/ SPECIAL QUEUE HANDLE
; T2/ BUFFER ADDRESS
; SNDIM
;RETURNS:
; +1 FAILURE
; T1/ ERROR CODE
; +2 SUCCESS
.SNDIM::MCENT
CALL CHKSQ ;CHECK ACCESS TO SPECIAL Q
RETERR ;ERROR RETURN
UMOVE T4,T2 ;GET BUFFER ADDRESS
UMOVE T2,0(T4) ;GET SIZE
CAIL T2,2 ;MUST BE LARGER THAN 2
CAILE T2,^D224 ;AND LESS THAN MAXIMUM BUFFER SIZE
RETERR (SNDIX1) ;BAD SIZE
UMOVE T1,1(T4) ;GET HEADER WORD
MOVE T3,T1 ;SAVE A COPY IN T3
ANDX T1,<LD%FIM!LD%LNK> ;GET RID OF EVERYTHING BUT LINK NUMBER
CAMG T1,[MAXNCP] ;IS IT GREATER THAN LAST NCP LINK NUMBER
RETERR (SNDIX3) ;NO. DON'T ALLOW MESSAGES WITH NCP LINKS
UMOVE T1,T1 ;GET SQ INDEX
XOR T3,SQVAL(T1) ;DIFFERENCE WITH VALUE
TDNE T3,SQMSK(T1) ;MUST BE EQUAL IN MASKED BITS
RETERR (SNDIX4) ;NOT EQUAL.
NOINT
CALL ASNTBF ;GET A BUFFER
RETERR (SNDIX2) ;NO ROOM
MOVE T3,T1 ;GET MONITOR BUFFER ADDRESS IN T3
MOVE T2,T4 ;GET USER'S BUFFER ADDRESS
MOVE T4,T1 ;GET A COPY OF MONITOR BUFFER ADD. IN T4
MOVE T1,0(T1) ;GET USERS SIZE. LEFT BY ASNTBF
AOS T2 ;DON'T TRANSFER FIRST WORD
AOS T3
SOS T1 ;SO ONE LESS WORD IN LENGTH
CALL BLTUM ;TRANSFER MESSAGE TO MONITOR SPACE
MOVE T2,T4 ;GET THE BUFFER ADDRESS BACK
NOSKED
SKIPL IMPRDY ;LAST MINUTE CHECK IF IMP IS UP
RETERR (SNDIX5,<OKSKED
CALL RLNTBF>) ;NOT UP
CALL IMPQOA ;PUT ONTO OUTPUT Q
OKSKED
SMRETN ;SUCCESS RETURN
;CHKSQ - CHECK FOR ACCESS TO SPECIFIC SPECIAL Q
;ACCEPTS:
; T1/ SPECIAL QUEUE HANDLE
; CALL CHKSQ
;RETURNS:
; +1 FAILURE
; T1/ ERROR CODE
; +2 SUCCESS
;CLOBBERS T2
CHKSQ: CAIL T1,0 ;MUST BE GREATER THAN 0
CAIL T1,NSQ ;AND LESS THAN THE NUMBER OF SPECIAL Q'S
RETBAD (SQX1) ;NOT IN RANGE
MOVE T2,JOBNO ;GET JOB NUMBER
CAMN T2,SQJOB(T1) ;DOES HE OWN THIS SPECIAL QUEUE
RETSKP ;YES RETURN SUCESS
MOVEI T1,SQX2 ;NO. SET UP ERROR NUMBER
RETBAD
;CKNTWZ - CHECK FOR NET WIZARDRY
;RETURNS:
; +1 NOT WIZARD ERROR CODE IN T1
; +2 WIZARD
;CLOBBERS T2
CKNTWZ: MOVEI T2,SC%NWZ ;GET NET-WIZARD BIT
TDNE T2,CAPENB ;DOES HE HAVE THIS CAPABILITY
RETSKP ;YES. SKIP RETURN
MOVEI T1,NTWZX1 ;NO. GET ERROR NUMBER
RET
;SQLWAT - WAIT FOR SPECIAL QUES TO BECOME UNLOCKED
SQLWAT: PUSH P,T1 ;SAVE T1
MOVEI T1,SQLTST ;GET SCHEDULAR TEST
MDISMS ;WAIT
POP P,T1 ;RESTORE T1
RET
SQLTST: AOSE SQLCK ;STILL LOCKED
JRST 0(T4) ;YES
JRST 1(T4) ;NO
;SIQCHK - CHECK FOR UNCLAIMED MESSAGES
;ACCEPTS:
; T1/ TIME OF DAY
;RETURNS:
; T1/ TIME TO SCAN QUEUES AGAIN
SIQCHK: HRLOI T3,377777 ;INITIALIZE T3 TO INFINITY TIME
MOVE T2,T1 ;GET TIME IN T2
MOVSI T1,-NSQ ;SET UP TO SCAN ALL QUEUES
SIQCKL: SKIPGE SQJOB(T1) ;IS THIS QUEUE OWNED?
JRST SIQCKE ;NO.
CAMG T2,SIQTIM(T1) ;YES. IS ITS TIME UP?
JRST SIQCKX ;NO
PUSH P,T1 ;YES SAVE T1, T2 AND T3
PUSH P,T2
PUSH P,T3
REPEAT 0,< ;CODE TO DELETE JUST ONE BUFFER
CALL SIQGET ;GO GET NEXT MSG
SKIPA ;WASN'T ANY
CALL RLNTBF ;RELEASE IT
> ;END OF REPEAT 0 TO DELETE JUST ONE BUFFER
REPEAT 1,< ;CODE TO FLUSH THE WHOLE QUEUE
CALL REL1S1 ;FLUSH THE ENTIRE QUEUE
> ;END OF REPEAT 1 TO FLUSH ALL MSGS IN QUEUE
POP P,T3 ;RESTORE T3, T3 AND T1
POP P,T2
POP P,T1
SIQCKX: CAML T3,SIQTIM(T1) ;THIS TIME LESS THAN NEXT TIME TO SCAN
MOVE T3,SIQTIM(T1) ;YES. SAVE IT INSTEAD
SIQCKE: AOBJN T1,SIQCKL ;CHECK NEXT QUEUE
MOVE T1,T3 ;RETURN NEXT TIME TO REMOVE MSG. IN T1
RET
;LOOKUP HOST-LINK
;ACCEPTS T1/ B20-27, HOST; B28-35, LINK; B18, DIRECTION (1=SEND)
;RETURNS +1 ENTRY NOT FOUND
; T1/ UNCHANGED
; T2/ LINK TABLE INDEX
; +2 ENTRY FOUND
; T1/ LINK TABLE INDEX
; T3/ CONTAINS FLAGS
;PRESERVES T3 AND T4
LNKLUK: STKVAR <LNKLT3,LNKLT4,LNKLPT> ;NOTE THAT THIS STKVAR IS
; ALSO AT IMPHFL AND IMPPIL
MOVEM T3,LNKLT3 ;SAVE T3
MOVSI T3,(1B1) ;BIT SAYS NO DELETED ENTRY FOUND
LNKL6: MOVEM T4,LNKLT4 ;SAVE T4
MOVEM T1,LNKLPT ;SAVE ARG
IMUL T1,[5654123] ;COMPUTE HASH
LSH T1,-^D9
IDIVI T1,IMPNLK ;REMAINDER GIVES INITIAL INDEX
MOVE T1,T2 ;GET COPY OF REMAINDER
EXCH T1,LNKLPT ;GET HOST-LINK BACK SAVE AWAY REMAINDER
HRLI T2,-IMPNLK(T2) ;SETUP PTR FOR REMAINDER OF TABLE
LNKL2: HRRZ T4,IMPLT1(T2) ;GET HOST-LINK OF ENTRY
CAIN T4,0(T1) ;DESIRED ENTRY?
JRST [MOVEI T1,0(T2) ;YES GET INDEX IN T1
MOVE T3,LNKLT3 ;RESTORE T3 AND T4
MOVE T4,LNKLT4
RETSKP] ;SKIP RETURN
TXNE T4,L1%FRE ;SPECIAL? I.E. FREE OR DELETED?
JRST [TLNE T3,(1B2) ;YES, CALLED BY REHASH OR PI LEVEL?
JRST LNKL4 ;YES
TXNE T4,L1%SND ;THIS A FREE ENTRY?
JRST LNKL3 ;YES, SEARCH DONE, NOT FOUND
TLZE T3,(1B1) ;THIS FIRST DELETED ENTRY ENCOUNTERED?
HRRI T3,0(T2) ;YES, SAVE ITS POSITION
JRST .+1]
LNKL5: AOBJN T2,LNKL2 ;TRY NEXT ENTRY DOWN
JUMPL T3,[TLNN T3,(1B1) ;TABLE FULL, WAS DELETE SEEN?
JRST LNKL3 ;YES, USE IT
BUG(CHK,IMPLTF,<IMPLT FULL>)
JRST LNKL1] ;RETURN NOT FOUND
MOVN T2,LNKLPT ;WRAPAROUND PTR, SETUP COUNT
MOVSI T2,0(T2) ;TO LOOK UP TO INITIAL INDEX
TLO T3,(1B0) ;REMEMBER WRAPAROUND
JRST LNKL2 ;GO CHECK FIRST ENTRY
LNKL3: TLNN T3,(1B1) ;NOT FOUND, DELETE ENCOUNTERED?
MOVEI T2,0(T3) ;YES, USE THAT FOR NEW ENTRY
LNKL1: MOVE T3,LNKLT3 ;RESTORE T3 AND T4
MOVE T4,LNKLT4
RET ;RETURN NOT FOUND
LNKL4: TLNE T3,(1B3) ;PI LEVEL CALL?
JRST LNKL5 ;YES. IGNORE DELETED/FREE ENTRIES
MOVX T4,L1%FRE ;MAKE DELETED
MOVEM T4,IMPLT1(T2)
JRST LNKL5 ;GO TRY NEXT ENTRY
;SPECIAL ENTRY USED ONLY BY REHASH ROUTINE
;IT ASSUMES ITEM WILL BE FOUND, AND IT SETS ANY 'FREE' ENTRIES
;ENCOUNTERED TO BE 'DELETED'
IMPHFL: STKVAR <LNKLT3,LNKLT4,LNKLPT> ;NOTE THAT THIS STKVAR IS
; ALSO AT IMPHFL AND LNKLUK
MOVEM T3,LNKLT3 ;SAVE T3
MOVSI T3,(1B2) ;CONTROLS ACTION ON SPECIAL ENTRIES
JRST LNKL6 ;GO DO SCAN
;SPECIAL ENTRY FROM IMODN2 TO FIND ENTRY TO STORE RETRANSMIT BUFFER
;SEARCHES ENTIRE TABLE FOR ENTRY REGARDLESS OF DELETES AND FREES
IMPPIL: STKVAR <LNKLT3,LNKLT4,LNKLPT> ;NOTE THAT THIS STKVAR IS
; ALSO AT LNKLUK AND IMPPIL
MOVEM T3,LNKLT3 ;SAVE T3
MOVSI T3,(1B2+1B3)
JRST LNKL6 ;GO DO SCAN
;ROUTINE TO GARBAGE COLLECT HASH TABLE.
;SETS ALL DELETED ENTRIES TO FREE THEN CALLS LOOKUP ROUTINE TO
;MARK ALL NEEDED ENTRIES DELETED TO ENABLE ALL ENTRIES TO BE FOUND.
;LOOKUP ROUTINE WILL CHANGE ANY 'FREE' ENTRIES PASSED OVER DURING
;A SEARCH TO 'DELETED'. THUS ALL 'DELETED' ENTRIES NOT CURRENTLY
;NECESSARY WILL BE FLUSHED.
IMPGC: IMSCLK (IMCGC) ;CHARGE TIME TO IMCGC
ILOCK
SETZM LNKNDL ;CLEAR DELETE COUNT
MOVSI Q3,-IMPNLK ;PREPARE TO SCAN LINK TABLE
MOVX T1,L1%FRE ;GET FREE OR DELETED FLAG
MOVX T2,L1%SND!L1%FRE ;GET FREE FLAG
IMPGC1: TDNE T1,IMPLT1(Q3) ;FREE OR DELETED?
MOVEM T2,IMPLT1(Q3) ;YES, SET IT TO FREE
AOBJN Q3,IMPGC1 ;DO NEXT ENTRY
MOVSI Q3,-IMPNLK ;PREPARE TO SCAN AGAIN
IMPGC2: HRRZ T1,IMPLT1(Q3) ;FOR EVERY ENTRY
TXNE T1,L1%FRE ;THAT IS NOT
JRST IMPGC3 ;DELETED OR FREE
CALL IMPHFL ;MARKED NECESSARY DELETED ENTRIES
BUG(CHK,IMPIFH,<IMPGC-IMPOSSIBLE FAILURE OF IMPHFL>)
IMPGC3: AOBJN Q3,IMPGC2 ;TRY NEXT ENTRY
IUNLK
RET
;UPBYT - UNPACK BYTE FROM CURRENT MSG FOR A CONNECTION
; T1/ CONNECTION INDEX
; RETURNS +1 BYTE IN T3
UPBYT:: ILOCK
HLRZ T2,IMPLT4(T1) ;GET CURRENT BUFFER
JUMPN T2,UPBYT1 ;IS THERE A BUFFER
CALL UPBGNB ;NO BUFFER, TRY TO GET ONE
RET ;FAILED, RETURN NOSKIP
UPBYT1: HRLI T2,ANBSEC ;SET SECTION NUMBER
ILDB T3,1(T2) ;GET BYTE, BYTE PTR IN BFR HEADER
SOSG 2(T2) ;COUNT DOWN BYTES IN BFR
CALL UPBRB ;NOW EMPTY, RELEASE BFR
IUNLK
RETSKP
;UPMSG - UNPACK MESSAGE
;ACCEPTS
; T1/ LT INDEX
; T3/ STORE BYTE POINTER
; T4/ MAX BYTE COUNT
;RETURNS +1 FAILURE NO BUFFER T1 SET UP FOR WAIT
; +2 SUCCESS
; T1/ UNCHANGED
; T2/ CLOBBERED
; T3/ UPDATED
; T4/ UPDATED
UPMSG:: STKVAR <UPMSBP,UPMSCT,<UPMST1,2>>
ILOCK
MOVEM T3,UPMSBP ;SAVE STORE POINTER
HLRZ T2,IMPLT4(T1) ;GET CURRENT BUFFER
JUMPN T2,UPMSG1 ;IS THERE ONE
CALL UPBGNB ;NONE, TRY TO GET ONE
RETBAD (,<MOVE T3,UPMSBP>) ;FAILED, RETURN BAD, IUNLK DONE
UPMSG1: HRLI T2,ANBSEC ;SET SECTION NUMBER
MOVE T3,2(T2) ;GET BUFFER COUNT
CAML T3,T4 ;LESS THAN WHAT HE WANTED?
MOVE T3,T4 ;NO. GIVE HIM ONLY AS WHAT HE ASKED FOR
SUB T4,T3 ;UPDATE USER'S COUNT
MOVEM T4,UPMSCT ;SAVE UPDATED COUNT
JUMPE T3,UPMSG3
MOVN T4,T3 ;GET NEG. NO. OF CHAR. TO PROCESS
ADDM T4,2(T2) ;UPDATE BUFFER COUNT
CAIG T3,1 ;DON'T BOTHER FOR JUST ONE
JRST UPMSG2
MOVE T3,1(T2) ;CHECK FOR START OF WORD
TLNE T3,700000 ;AS THE P FIELD IN BOTH POINTERS
JRST UPMSG2 ;IF SO DO A BLT
MOVE T3,UPMSBP
TLNE T3,700000
JRST UPMSG2
DMOVEM T1,UPMST1 ;SAVE LT AND BUFFER ADR
MOVN T3,T4 ;GET COUNT
ADJBP T3,1(T2)
MOVEI T1,(T3) ;GET FINAL ADR
EXCH T3,1(T2) ;CONVERT POINTER TO ADR
SUBI T1,(T3) ;FINAL - (START - 1)
ADDI T2,1(T3)
MOVN T3,T4 ;GET COUNT
ADJBP T3,UPMSBP
EXCH T3,UPMSBP ;CONVERT POINTER TO ADR
MOVEI T3,1(T3)
CALL XBLTA ;DO RIGHT BLT
DMOVE T1,UPMST1 ;RESTORE LT AND ADR
JRST UPMSG3 ;BYPASS BYTE LOOP
UPMSG2: ILDB T3,1(T2) ;LOAD BYTE FROM BUFFER USING BYTE
; POINTER IN BUFFER (IT IS INDEXED BY T2
; TO GET TO ANBSEC SECTION.)
IDPB T3,UPMSBP ;STORE BYTE
AOJL T4,UPMSG2 ;GO DO ANOTHER BYTE
UPMSG3: MOVE T4,UPMSCT ;GET UPDATED COUNT BACK
SKIPG 2(T2) ;IMP BFR NOW EXHAUSTED?
CALL UPBRB ;YES, RELEASE IT
IUNLK
MOVE T3,UPMSBP ;GET UPDATED BYTE POINTER
RETSKP
;UPBGNB - TRY TO GET NEXT INPUT BFR
;ACCEPTS
; T1/ LINK TABLE INDEX
;RETURNS +1 FAILURE
; T1/ SET UP FOR WAIT
; +2 SUCESS
; T1/ UNCHANGED
; T2/ BUFFER ADDRESS
;CLOBBERS T3
UPBGNB: HLRZ T2,IMPLT3(T1) ;CHECK QUEUE OF IN BFRS
JUMPE T2,UPBG1 ;NONE?
PUSH P,T4 ;GOT A BUFFER SAVE T4
HRLI T2,ANBSEC ;SET SECTION NUMBER
HLLZ T3,0(T2) ;UNQUEUE THIS BUFFER
SKIPN T3 ;IS THERE ANOTHER BUFFER?
HLLZS IMPLT2(T1) ;NO. MAKE INPUT BUFFER LIST EMPTY
HLLM T3,IMPLT3(T1) ;SAVE NEW OUTPUT BUFFER POINTER
HRLM T2,IMPLT4(T1) ;SAVE CURRENT BFR ADR
PUSH P,1(T2) ;SAVE HEADER IN CASE OF ERROR
PUSH P,2(T2)
HRRZ T4,0(T2) ;NUMBER WORDS IN BUFFER
CAIGE T4,3 ;AT LEAST OVERHEAD WORDS PRESENT?
JRST UPBGNE ;NO, MSG TOO SHORT
LOAD T3,LD%BYC,2(T2) ;NUMBER OF BYTES
JUMPE T3,UPBGNE ;0 IS ILLEGAL, BUT IN CASE...
LOAD T4,LD%BYS,2(T2) ;GET BYTE SIZE
MOVEM T3,2(T2) ;LEAVE BYTE COUNT IN FULL WORD
LOAD T3,IMPBS,(T1) ;GET BYTE SIZE FOR CONNECTION
CAME T3,T4 ;SAME AS THAT IN BUFFER?
JRST UPBGNE ;NO
MOVE T3,[POINT 0,2(T2),35] ;SET UP BYTE POINTER. NOTE IDEXED BY T2
TRNN T4,7 ;GET BYTE OFFSET RIGHT
HRLI T3,(<POINT 0,(T2),31>)
DPB T4,[POINT 6,T3,11] ;PUT BYTE SIZE IN POINTER IN T3
MOVEM T3,1(T2) ;SAVE POINTER IN BUFFER
MOVEI T3,^D36 ;COMPUTE MAX BYTES WHICH COULD BE
IDIV T3,T4 ;AS WORDS*(BYTES/WD)
HRRZ T4,0(T2) ;NUMBER OF WORDS
IMULI T3,-3(T4) ;BUT NOT COUNTING OVERHEAD
CAMGE T3,2(T2) ;ACTUAL GREATER THAN MAX?
JRST UPBGNE ;YES, LOSSAGE
ADJSP P,-2 ;CLEAN UP STACK
POP P,T4 ;RESTORE T4
RETSKP
UPBGNE: CALL UPBRB ;RELEASE BUFFER
POP P,T2 ;GET SECOND WORD OF HEADER
EXCH T1,0(P) ;GET 1ST WORD OF HEADER SAVING LT INDEX
BUG(INF,IMPBSC,<MESSAGE HAS BAD SIZE OR COUNT>,<T1,T2>)
POP P,T1 ;GET LT INDEX BACK INTO T1
POP P,T4 ;RESTORE T4
JRST UPBGNB ;TRY NEXT BUFFER
;NO INPUT READY, RETURN ACTIVATION TEST
UPBG1: MOVSI T1,0(T1) ;CONNECTION INDEX INTO LEFT HALF
HRRI T1,UPBGT ;WAIT FOR INPUT OR CLOSED CONN
IUNLK
RET
;UPBGT - SCHEDULER ACTIVATION TEST
UPBGT: MOVSI T3,-1 ;GET -1 IN LEFT HALF FOR TEST FOR BUFFER
MOVSI T2,(LTDF) ;CHECK DONE FLAG
TDNN T2,IMPLT2(T1) ;IF SET, OR
TDNE T3,IMPLT3(T1) ;IF BFR(S) APPEARED
JRST 1(T4) ;WAKEUP
JRST 0(T4) ;OTHERWISE WAIT SOME MORE
;UPBRB - RELEASE INPUT BUFFER
; T1/ LINK TABLE INDEX
; T2/ BUFFER ADDRESS
UPBRB: HRRZS IMPLT4(T1) ;CLEAR CURRENT BUFFER FIELD
PUSH P,T1 ;SAVE T1
CALL RLNTBF ;RELEASE BFR BACK TO POOL
POP P,T1 ;RESTORE T1
SOSL IMPLT4(T1) ;COUNT MSGS PROCESSED
RET
HRRZ T2,IMPLT1(T1) ;GET HOST-LINK NUMBER
CALL IMP8X1 ;GO UNPACK IT TO LINK,,HOST
BUG(CHK,IMPREM,<UPBRB: RECEIVED EXCESSIVE MESSAGES>,T2)
SETZM IMPLT4(T1) ;ZERO COUNT OF MESSAGES
RET
;IMPCKO AND IMPKO1 - CHECK CONNECTION FOR OUTPUT POSSIBLE
;CALLED ON RECEIPT OF RFNM, ALLOCATION, ETC.
; T1/ CONNECTION INDEX
;DO OUTPUT IF RFNM CLEAR, MSG ALLOC NON-0, AND OUTPUT EXISTS
IMPCKO: ILOCK (JRST IMPROS) ;IF CAN'T CHECK NOW, SET REQUEST FLAG
IMPKO1: MOVX T3,RFNMCM!ILCKB ;RFNM COUNT AND CONNECTION LOCKED FLAGS
TDNE T3,IMPLT2(T1) ;RFNM OUT OR CONNECTION LOCKED?
JRST IMPKO2 ;YES, WILL TRY AGAIN LATER
HLRZ T2,IMPLT3(T1) ;GET PTR FOR REMOVING BUFFS FROM CHAIN
JUMPN T2,[HRLI T2,ANBSEC ;IF BUFFER EXIST SET SECTION NUMBER
CALL IMPQO1 ;IF COMPLETED BUFFERS ON OUTPUT QUEUE,
JRST IMPKO1] ;GIVE ONE TO IMP TO SEND AND TRY AGAIN
HLRZ T2,IMPLT4(T1) ;SEE IF PARTIAL BFR EXISTS
JUMPN T2,[HRLI T2,ANBSEC ;IF BUFFER EXIST SET SECTION NUMBER
CALL PKQOB ;COMPLETE IT AND SEND
JRST IMPKO1] ;AND TRY AGAIN
LOAD T2,LTLINK,(T1) ;GET LINK NUMBER
JUMPE T2,[CALL IMPLL0 ;CONTROL LINK?
JRST IMPKO2] ;FLUSH CONN IF CTL LINK
MOVSI T2,(RARRF) ;GET RAS REQUESTED FLAG
TDNN T2,IMPLT2(T1) ;RAS REQUESTED?
JRST IMPKO4 ;NO
PUSH P,T1 ;YES. SAVE LT TABLE INDEX
ANDCAM T2,IMPLT2(T1) ;CLEAR REQUEST FOR RAS
HLRZ IMPUN,IMPLT1(T1) ;GET UNIT
SETZM NETBAL(IMPUN) ;ZERO BIT ALLOCATION
HLLZS IMPLT4(T1) ;AND MSG ALLOCATION
IUNLK
LOAD T2,LTLINK,(T1) ;GET LINK NUMBER
LOAD T1,LTHOST,(T1) ;GET HOST NUMBER
CALL IMPRAS ;SEND RAS
POP P,T1 ;RESTORE LT INDEX
JRST IMPKO3
IMPKO4: IUNLK
IMPKO3: HLRZ IMPUN,IMPLT1(T1) ;PICK UP PSEUDO-UNIT
MOVSI T2,(LTDF) ;GET DONE FLAG
TDNN T2,IMPLT2(T1) ;DONE FLAG SET?
RET ;NO. DONE
ANDCAM T2,IMPLT2(T1) ;CLEAR DONE SO WE ONLY SEE IT ONCE
PUSH P,Q2 ;PRESERVE Q2
CALL RCFRFN ;YES, NOTIFY NCP
POP P,Q2 ;RESTOR Q2
RET
IMPKO2: IUNLK ;ALWAYS RETURNS WITH LOCK CLEAR
RET
IMPROS: AOS IMPNOS ;INDICATE OUPUT SCAN NEEDED
RET
;PKBYT - PACK BYTE FOR OUTPUT
; T1/ CONNECTION INDEX
; T3/ BYTE
;CLOBBERS T2
;RETURNS +2 ALWAYS
PKBYT:: ILOCK
HLRZ T2,IMPLT4(T1) ;GET CURRENT BUFFER
JUMPN T2,PKBY2 ;IS THERE A CURRENT BUFFER
CALL PKBY1 ;NO CURRENT BUFFER, GET A NEW ONE
JRST PKBY5 ;NO BUFFERS
PKBY2: HRLI T2,ANBSEC ;SET SECTION NUMBER
IDPB T3,1(T2) ;STORE BYTE IN BUFFER (BUFF ADD MUST BE IN T2)
MOVSI T3,(ILCKB) ;GET CONNECTION LOCKED FLAG
ANDCAM T3,IMPLT2(T1) ;CLEAR LOCK
SOSG 2(T2) ;OR IF BUFFER NOW FULL
CALL PKQOB ;PUT BFR ON OUTPUT QUEUE
CALL IMPKO1 ;SEND IF POSSIBLE (DOES IUNLK)
RETSKP
PKBY5: IUNLK ;NO BUFFERS
CALL IMPB03 ;GO TRY TO FREE UP SOME
JRST PKBYT ;AND TRY AGAIN
;PKCHK - CHECK MAXIMUM BYTES THAT CAN BE SENT DUE TO MSG ALLOCATION
;RESTRICTION AND PARTIAL MSG ALREADY CONSTRUCTED. LEAVE CONNECTION
;LOCKED.
; T1/ LT INDEX
;RETURNS +1 ALWAYS
; T2/ MAXIMUM BYTES THAT CAN BE SENT
PKCHK:: ILOCK
PUSH P,T3 ;SAVE T3
SETZ T2, ;INDICATE ZERO BYTES INITIALLY
MOVSI T3,(ILCKB) ;GET CONNECTION LOCKED FLAG
TDNE T3,IMPLT2(T1) ;THERE SHOULD ONLY BE ONE FORK TRYING
JRST PKCHK2 ;AT A TIME SINCE FILES ARE INTERLOCKED
;BY FILLCK, NVT TRANSMISSION IS DONE BY
;NCP FORK AND CONTROL LINKS HAVE NO
;FLOW CONTROL.
IORM T3,IMPLT2(T1) ;LOCK CONNECTION SO STATE CAN'T CHANGE
LOAD T3,IMPBS,(T1) ;GET BYTE SIZE
HLRZ T2,IMPLT4(T1) ;GET CURRENT BUFFER
JUMPE T2,PKCHK1 ;IF NONE, CONTRIBUTION IS ZERO
HRLI T2,ANBSEC ;SET SECTION NUMBER
MOVE T2,2(T2) ;GET BYTES LEFT
IMUL T2,T3 ;TIMES BYTE SIZE IS BITS
PKCHK1: PUSH P,T3 ;SAVE BYTE SIZE
HRRZ T3,IMPLT4(T1) ;GET MSG ALLOCATION
JUMPG T3,[IMULI T3,MAXBPM ;TIMES BITS PER MESSAGE
ADD T2,T3 ;ADD TO CURRENT BUFFER RESIDUE
JRST .+1] ;AND CHECK AGAINST BIT ALLOCATION
CAMLE T2,NETBAL(IMPUN) ;MORE THAN BIT ALLOCATION
MOVE T2,NETBAL(IMPUN) ;YES. LIMIT IS THAT
IDIV T2,(P) ;GET BYTES
POP P,T3 ;RESTORE BYTE SIZE
CAIE T3,^D8 ;IF 8 BIT AND GEQ 4 BYTES
JRST PKCHK2
CAILE T2,4 ;MAKE MULTIPLE OF 4 BYTES
TRZ T2,3
PKCHK2: POP P,T3 ;RESTORE CALLERS T3
IUNLK
RET
;UNLOCK CONNECTION
PKULCK::MOVSI T2,(ILCKB) ;GET CONNECTION LOCKED FLAG
ANDCAM T2,IMPLT2(T1) ;CLEAR IT
MOVE T2,IMPLT3(T1) ;ANY BUFFERS TO BE SENT
IOR T2,IMPLT4(T1) ;AND CURRENT BUFFER
TLNE T2,-1 ;WAS THERE ANYTHING THERE
JRST IMPCKO ;YES. GO CHECK CONN FOR OUTPUT POSSIBLE
RET ;NO
;PKMSG AND PKMSG0 - PACK MSG AND TRY TO SEND
; T1/ CONNECTION INDEX
; T3/ BYTE PTR
; T4/ BYTE COUNT
PKMSG:: ILOCK
PKMSG0: CALL PKMSG2 ;GET THE MESSAGE PACKED UP
PUSH P,T3 ;SAVE CALLERS POINTER
CALL IMPKO1 ;SEND IF POSSIBLE (DOES IUNLK)
POP P,T3 ;RESTORE CALLERS POINTER
RET
;PKMSG1 - SAME AS PKMSG, BUT DOESN'T ATTEMPT TO SEND THE MSG
PKMSG1::ILOCK
CALL PKMSG2 ;PACK IT UP
IUNLK
RET
;PKMSG2 - MOVE BYTES FROM SOURCE BUFFER TO NETWORK OUTPUT BUFFER
; T1/ CONNECTION INDEX
; T3/ SOURCE BYTE PTR
; T4/ BYTE COUNT
PKMSG2: STKVAR <PKMSCT,PKMSBP,<PKMST1,2>>
PKMS1: MOVSI T2,(ILCKB) ;LOCK CONNECTION
IORM T2,IMPLT2(T1)
MOVEM T4,PKMSCT ;SAVE BYTE COUNT
MOVEM T3,PKMSBP ;SAVE CALLERS BYTE POINTER
HLRZ T2,IMPLT4(T1) ;GET CURRENT BFR
JUMPN T2,PKMS2 ;IS THERE ONE?
PKMS4: CALL PKBY1 ;TRY TO GET A BUFFER
JRST PKMS5 ;COULDN'T GET ONE. GO TRY TO FREE UP ONE
MOVE T4,PKMSCT ;GET COUNT BACK
CAMLE T4,2(T2) ;NEW BUFFER BIG ENOUGH?
JRST PKMSL ;MESSAGE TOO LONG
PKMS3: JUMPE T4,PKMSD
MOVNS T4 ;NEGATIVE COUNT TO 4
ADDM T4,2(T2) ;UPDATE BUFFER COUNT
ADDM T4,PKMSCT ;MAINTAIN RESIDUAL COUNT
MOVN T3,T4 ;GET COUNT
CAIG T3,1 ;DON'T BOTHER FOR JUST ONE
JRST PKMS0
MOVE T3,1(T2) ;CHECK FOR START OF WORD
TLNE T3,700000 ;AS THE P FIELD IN BOTH POINTERS
JRST PKMS0 ;IF SO DO A BLT
MOVE T3,PKMSBP
TLNE T3,700000
JRST PKMS0
DMOVEM T1,PKMST1 ;SAVE LT AND BUFFER ADR
MOVN T3,T4 ;GET COUNT
ADJBP T3,1(T2)
MOVEI T1,(T3) ;GET FINAL ADR
EXCH T3,1(T2) ;CONVERT POINTER TO ADR
SUBI T1,(T3) ;FINAL - (START - 1)
MOVEI T3,1(T3)
ADD T3,T2
MOVN T2,T4 ;GET COUNT
ADJBP T2,PKMSBP
EXCH T2,PKMSBP
MOVEI T2,1(T2)
CALL XBLTA ;DO RIGHT BLT
DMOVE T1,PKMST1 ;RESTORE LT AND ADR
JRST PKMSD ;BYPASS BYTE LOOP
PKMS0: ILDB T3,PKMSBP ;LOAD BYTE
IDPB T3,1(T2) ;STORE BYTE IN BUFFER USING BYTE
; POINTER IN BUFFER (IT IS INDEXED BY T2
; TO GET TO ANBSEC SECTION.)
AOJL T4,PKMS0 ;GO DO ANOTHER BYTE
PKMSD: MOVSI T3,(ILCKB) ;GET CONNECTION LOCKED FLAG
ANDCAM T3,IMPLT2(T1) ;CLEAR IT
SKIPG 2(T2) ;BUFFER NOW FULL?
CALL PKQOB ;YES. GO PUT BUFFER ON QUEUE
MOVE T3,PKMSBP ;GET UPDATED BYTE POINTER BACK
MOVE T4,PKMSCT ;GET BACK RESIDUAL COUNT
JUMPG T4,PKMS1 ;GO BACK IF ANYTHING LEFT
SKIPE T4 ;MAKE SURE WE HAVEN'T SCREWED UP
BUG(HLT,IMPNBC,<PKMSG: NEGATIVE RESIDUAL BYTE COUNT>)
RET
PKMSL: BUG(CHK,IMPMSL,<PKMSG - MSG TOO LARGE>)
MOVE T4,2(T2) ;JUST SEND AS MUCH AS BUFFER WILL HOLD
JRST PKMS3 ;GO BACK AND FINISH
PKMS2: HRLI T2,ANBSEC ;SET SECTION NUMBER
CAMG T4,2(T2) ;ENOUGH ROOM IN CURRENT BFR?
JRST PKMS3 ;YES
HLRZ T4,IMPLT1(T1) ;GET UNIT NUMBER
CAIN T4,-1 ;CONTROL LINK?
JRST PKMS6 ;YES, CONTROL MESSAGE CAN'T CROSS
;NET MESSAGE BOUNDARY
MOVE T4,2(T2) ;GET RESIDUAL BYTE COUNT OF BUFFER
JRST PKMS3 ;GO DO IT
PKMS6: CALL PKQOB ;FINISH CURRENT BUFFER
JRST PKMS4 ;START A NEW ONE
PKMS5: IUNLK
CALL IMPB03 ;SEE IF WE CAN FREE UP SOME BUFFERS
ILOCK
MOVE T4,PKMSCT ;GET COUNT BACK
JRST PKMS1 ;GO TRY AGAIN
;PKBY1 - ASSIGN AND INIT A BUFFER FOR OUTPUT USE
;ACCEPTS: T1/ LINK TABLE INDEX
;RETURNS: +1 NO BUFFER
; +2 BUFFER ADDRESS IN T2
;CLOBBERS T4
PKBY1: PUSH P,T3 ;SAVE T3
HRRZ T3,IMPLT4(T1) ;GET MSG ALLOCATION
JUMPG T3,PKBY4 ;OK
HRRZ T2,IMPLT1(T1) ;GET HOST-LINK NUMBER
CALL IMP8X1 ;GO UNPACK IT TO LINK,,HOST
BUG(CHK,IMPNMA,<PKBY1: NO MSG ALLOCATION>,T2)
AOS IMPLT4(T1) ;GIVE HIM ONE MESSAGE
PKBY4: MOVEI T2,^D36 ;COMPUTE NUMBER OF BITS PER OUTPUT WD
LOAD T4,IMPBS,(T1) ;GET BYTE SIZE
IDIVI T2,0(T4) ;AS (36/BS)*BS
IMULI T2,0(T4)
MOVEI T4,0(T2) ;GET BITS IN T4
MOVE T2,IMPLT1(T1) ;GET PROPER SIZE FOR OUTPUT MSG
TXNE T2,L1%LNK ;FOR LINK 0?
SKIPA T2,[MAXBPM] ;NO, USUAL REGULAR MAX
MOVEI T2,^D<120*8> ;FOR CTRL LINK, MAX IS 120 BYTES
IDIVI T2,0(T4) ;WDS = BITS / (BITS/WD)
ADDI T2,3 ;PLUS OVERHEAD
PUSH P,T1 ;SAVE LT INDEX
CALL ASNTBF ;ASSIGN BUFFER
JRST [POP P,T1 ;NO BUFFERS. RESTORE T1 AND T3
POP P,T3
RET]
MOVE T2,T1 ;GET BUFFER ADDRESS IN T2
POP P,T1 ;GET LT INDEX BACK
HRLM T2,IMPLT4(T1) ;SET AS CURRENT BUFFER
SOS IMPLT4(T1) ;CONSUME ALLOCATION
MOVEI T3,^D36 ;COMPUTE NUMBER OF BYTES
LOAD T4,IMPBS,(T1) ;WHICH WILL FIT IN BUFFER.
IDIVI T3,0(T4) ;I.E. WORDS*(36/BYTESIZE)
HRRZ T4,0(T2) ;NUMBER OF WORDS IN BFR
IMULI T3,-3(T4) ;LESS HEADER OVERHEAD
MOVEM T3,2(T2) ;SETUP COUNTER
HRLM T3,0(T2) ;REMEMBER ORIGINAL COUNT
LOAD T4,IMPBS,(T1) ;GET BYTE SIZE
MOVE T3,[POINT 0,2(T2),35] ;SET UP BYTE POINTER. NOTE IDEXED BY T2
TRNN T4,7 ;GET BYTE OFFSET RIGHT
HRLI T3,(<POINT 0,(T2),31>)
DPB T4,[POINT 6,T3,11] ;PUT BYTE SIZE IN POINTER IN T3
MOVEM T3,1(T2) ;SAVE POINTER IN BUFFER
SETZM 3(T2) ;CLEAR FIRST FEW BYTES
POP P,T3 ;RESTORE T3
RETSKP
;PKQOB - PUT OUTPUT BUFFER ON QUEUE
;ACCEPTS: T1/ LINK TABLE INDEX
;CLOBBERS T2, T3 AND T4
PKQOB: HLRZ T2,IMPLT4(T1) ;GET CURRENT BUFFER
HRRZS IMPLT4(T1) ;CLEAR CURRENT BUFFER PTR
HRLI T2,ANBSEC ;SET SECTION NUMBER
HRRZ T4,1(T2) ;OFFSET OF LAST WORD CONTAINING DATA
AOS T4 ;PLUS ONE
HRRM T4,0(T2) ;GIVES ACTUAL WORDS IN USE
HLRZ T3,0(T2) ;GET ORIGINAL BYTE COUNT
SUB T3,2(T2) ;MINUS CURRENT COUNT GIVES BYTES IN BFR
LSH T3,^D8 ;SHIFT TO PROPER POSITION FOR HEADER
MOVEM T3,2(T2) ;STORE IT IN HEADER
LOAD T3,IMPBS,(T1) ;GET BYTE SIZE
STOR T3,LD%BYS,2(T2) ;PUT IN HEADER
SETZM 1(T2) ;CLEAR IMP HEADER
MOVE T3,IMPLT1(T1) ;GET HOST-LINK
STOR T3,<LD%HST!LD%LNK>,1(T2) ;PUT IN IMP HEADER
MOVX T4,LD%HIP ;GET HIGH PRIORITY BIT FOR LEADER
MOVE T3,IMPLT2(T1) ;GET FLAG BITS FOR CONNECTION,,INPUT PTR
TLNE T3,(HIPFLG) ;IF HIGH PRIORITY CONNECTION,
IORM T4,1(T2) ;SET PRIORITY BIT IN LEADER
HRRZS 0(T2) ;PUT BFR ON QUEUE
TRNN T3,-1 ;IS THERE A POINTER THERE ALREADY?
JRST [HRLM T2,IMPLT3(T1) ;NO GO FIX UP IMPLT3 ALSO
JRST PKQOB1] ;GO SET INPUT POINTER
HRLI T3,ANBSEC ;SET SECTION NUMBER FOR BUFFERS
HRLM T2,0(T3) ;CHAIN THIS BUFFER TO LAST ONE
PKQOB1: HRRM T2,IMPLT2(T1) ;AND SET TOP OF CHAIN PTR TO THIS ONE
;FALL INTO OUTPUT CHECK
;PUT BUFFER ON IMP OUTPUT QUEUE IF NO RFNM OUTSTANDING
IMPQOB: MOVX T3,RFNMCM!ILCKB ;GET RFNM COUNT AND CONN LOCKED FLAGS
TDNE T3,IMPLT2(T1) ;RFNM NOW OUT OR LOCKED?
RET ;YES, DON'T SEND
HLRZ T2,IMPLT3(T1) ;GET FIRST BUFFER ON QUEUE
JUMPE T2,R ;RETURN IF NO BUFFERS TO GO
HRLI T2,ANBSEC ;SET SECTION NUMBER
IMPQO1: MOVX T3,RFNMCM ;GET RFNM COUNT
IORM T3,IMPLT2(T1) ;SET RFNM FLAG
HLLZ T3,0(T2) ;UNQUEUE THIS BUFFER
SKIPN T3 ;IS THERE ANOTHER BUFFER?
HLLZS IMPLT2(T1) ;ZERO POINTER FOR ADDING
HLLM T3,IMPLT3(T1) ;UPDATE POINTER FOR REMOVING
CALLRET IMPQOA ;ACTUALLY PUT IT ON OUTPUT QUEUE
;IMPQOA - HERE FOR QUEUEING HOST-IMP MESSAGES
;ACCEPTS: T2/ BUFFER POINTER
IMPQOA: SKIPN IMPORD ;IS OUTPUT ON?
JRST RLNTBF ;NO. DON'T QUEUE IT UP
PUSH P,T1 ;SAVE T1
CALL IMPLKB ;LOCK BFR FOR PI SERVICE ROUTINE
MOVE T1,T2 ;GET A COPY OF THE BUFFER ADDRESS
CALL DBGOM ;SAVE HEADER FOR DEBUGGING
MOVX T1,LD%HIP ;HIGH PRIORITY MESSAGE BIT
PIOFF
HRRZS 0(T2) ;ZERO POINTER TO NEXT BUFFER
TDNN T1,1(T2) ;IS PRIORITY BIT SET IN MESSAGE HEADER
JRST IMPQOL ;NO, LO PRIORITY QUEUE
MOVE T1,IMPHBI ;GET POINTER FOR ADDING TO HIGH Q
JUMPN T1,IMPQO2 ;IS THERE A BUFFER ON THE Q
MOVEM T2,IMPHBO ;NO. MUST UPDATE REMOVAL POINTER TOO
SKIPA ;SKIP CHAINING BUFFER TO QUEUE
IMPQO2: HRLM T2,0(T1) ;CHAIN THIS ONE ONTO Q IF ANYTHING ON Q
MOVEM T2,IMPHBI ;MAKE THIS BUFFER NEW TOP OF QUEUE
JRST IMPQOC ;FINISH PROCESSING
IMPQOL: MOVE T1,IMPOBI ;GET TOP OF LOW PRI. Q
JUMPN T1,IMPQO3 ;IS THERE A BUFFER ON THE Q ALREADY
MOVEM T2,IMPOBO ;NO. MUST UPDATE REMOVAL POINTER TOO
SKIPA ;AND SKIP CHAINING NEW BUFFER TO QUEUE
IMPQO3: HRLM T2,0(T1) ;CHAIN TO CURRENT BUFFER IF THERE IS 1
MOVEM T2,IMPOBI ;MAKE CURRENT BUFFER TOP OF Q
IMPQOC: PION
SKIPN IMPOB ;OUTPUT NOW IN PROGRESS?
JSP T4,IMPXOU ;NO, START IT
POP P,T1 ;RESTORE T1
RET
;IMODUN - HERE ON PI LEVEL FROM DEVICE ROUTINE AFTER SENDING OUT
;LAST WORD OF A BUFFER. PUT IT ON RETRANSMISSION QUEUE IF
;REGULAR LINK, AND RFNM STILL OUTSTANDING. ELSE PUT IT
;ON FREE LIST.
IMODUN::MOVE T1,IMPOB ;GET BUFFER LOCATION
MOVE T2,1(T1) ;GET HEADER
ANDX T2,<LD%FIM!LD%LNK>
CAMLE T2,[MAXNCP] ;REGULAR LINK?
JRST IMODN4 ;NO. JUST FLUSH THE MESSAGE
LOAD T1,<LD%HST!LD%LNK>,1(T1) ;GET HOST-LINK
IORX T1,L1%SND ;MARK AS SEND CONNECTION
CALL IMPPIL ;GET LT INDEX FOR THIS MESSAGE
JRST IMODN6 ;NOT THERE
MOVX T2,RFNMCM ;BE SURE RFNM HAS NOT RETURNED ALREADY
TDNN T2,IMPLT2(T1) ;RFNM OUTSTANDING?
JRST IMODN4 ;NO. WELL WHAT DO YOU KNOW!
HRRZ T2,IMPLT3(T1) ;BE SURE NOTHING IS THERE
JUMPN T2,IMODN6 ;ANOMALOUS, BUT WHAT CAN YOU DO?
MOVE T2,IMPOB ;GET CURRENT BUFFER ADDRESS AGAIN
HRRM T2,IMPLT3(T1) ;SAVE ADDRESS FOR RETRANSMISSION
RET
IMODN6: MOVE T2,IMPOB ;GET ADDRESS OF MESSAGE AGAIN
DMOVE T1,1(T2) ;GET LEADER
BUG(INF,IMPLEO,<CAN'T FIND LT ENTRY FOR OUTPUT MESSAGE>,<T1,T2>)
IMODN4: MOVE T1,IMPOB ;GET OUTPUT BUFFER ADDRESS
MOVE T2,T1 ;SAVE A COPY IN T2
EXCH T1,IMINFB ;PUT BFR BACK ON FREE LIST
HRLM T1,0(T2) ;CHAIN OLD TOP OF LIST TO NEW ENTRY
AOS IMPFLG ;REQUEST JOB 0 SERVICE
RET ;BACK TO PHYSICAL DEVICE RTN
;LOCK IMP BUFFER. IF BUFFER SIZE CHANGES MUST LOCK BEGINNING AND
;END IN CASE IT CROSSES PAGE BNDRY
;ACCEPTS T2/ BUFFER ADDRESS
IMPLKB: PUSH P,T1 ;SAVE T1 AND T2
PUSH P,T2
HRRZ T1,0(T2) ;GET SIZE FIELD
CAILE T1,MAXWPM ;MAKE SURE NOT ON FREELIST
BUG(HLT,IMPALF,<IMPLKB: ATTEMPT TO LOCK BUFFER ON FREELIST>)
MOVE T1,T2 ;GET BUFFER ADDRESS INTO T1
CALL MLKMA ;LOCK BEGINNING OF BUFFER
REPEAT 0,< ;THIS CODE SHOULD BE REPLACED IF BUFFER
; SIZE CHANGES
MOVE T1,0(P) ;GET BUFFER ADDRESS BACK
ADD T1,0(T1) ;COMPUTE END
SOS T1 ;MAKE IT POINT TO LAST WORD IN USE
CALL MLKMA ;LOCK END
> ;END OF REPEAT 0
POP P,T2 ;RESTORE T2 AND T1
POP P,T1
RET
;IMPCLQ - CLEAR IMP QUEUES
IMPCLQ: NOSKED ;PREVENT CONFUSION
SKIPLE T1,IMPOB ;ANYTHING HERE?
CALL IMPCQ6 ;UNLOCK AND RELEASE
SETZB T2,IMPOB ;ZERO CURRENT OUTPUT BUFFER
EXCH T2,IMPHBO ;AND POINTER FOR REMOVING HIGH Q MSGS
SETZM IMPHBI ;AND POINTER FOR ADDING THEM
CALL IMPCQ8 ;DEQUEUE EVERYTHING ON HIGH Q
SETZB T2,IMPOBI ;ZERO T2 AND PTR FOR ADDING TO LOW Q
EXCH T2,IMPOBO ;ZERO PTR FOR REMOVING FROM LOW Q
CALL IMPCQ8 ;DEQUEUE EVERYTHING ON LOW Q
SKIPE T1,IMIB ;IS THERE A CURRENT INPUT BUFFER
CALL IMPCQ5 ;YES, CLEAR IT
SETZB T2,IMIB
EXCH T2,IMPIBO ;ZERO PTR FOR REMOVING FROM INPUT Q
CALL IMPCQ3 ;CLEAN UP INPUT Q
SETZB T2,IMPIBI ;ZERO PTR FOR ADDING TO INPUT Q
EXCH T2,IMPFRI ;CLEAR INPUT FREE LIST
CALL IMPCQ2 ;CLEAR BUFFERS ON INPUT FREE LIST
SETZB T2,IMPNFI ;ZERO NUMBER OF FREE BUFFERS
EXCH T2,IMINFB ;GET RELEASE QUEUE
CALL IMPCQ4 ;RELEASE 0 LOCKED THINGS
OKSKED
RET
;IMPCQ6 - CLEAR RFNM COUNT, RETRANSMISSION FLAG AND BUFFER BEFORE UNLOCKING
IMPCQ6: PUSH P,T1 ;SAVE BUFFER ADDRESS
PUSH P,T2 ;AND T2
LOAD T1,<LD%HST!LD%LNK>,1(T1) ;GET HOST-LINK NUMBER
IORX T1,L1%SND ;INDICATE SEND CONNECTION
CALL LNKLUK ;LOOK UP CONNECTION
JRST IMPCQ7 ;NOT FOUND MAY HAVE BEEN DELETED
MOVX T2,RFNMCM!RXMTF ;GET RFNM COUNT MASK AND RETRANS. FLAG
ANDCAM T2,IMPLT2(T1) ;ZERO THEM
HLLZS IMPLT3(T1) ;ZERO RETRANMISSION BUFFER ADDRESS
IMPCQ7: POP P,T2 ;RESTORE T2
POP P,T1 ;AND BUFFER ADDRESS
CALLRET IMPCQ5 ;GO RELEASE BUFFER
;IMPCQ8 - CLEAR RFNM COUNT, RETRANSMISSION FLAG AND BUFFER BEFORE UNLOCKING
IMPCQ8: TRNN T2,-1 ;0 -- NO BUFFERS LEFT
RET ;NO BUFFERS RETURN
MOVE T1,T2 ;GET BUFFER ADDRESS IN T1
HLRZ T2,0(T1) ;GET NEXT BUFFER
HRLI T2,ANBSEC ;SET SECTION NUMBER
CALL IMPCQ6 ;UNLOCK AND RELEASE
JRST IMPCQ8 ;CONTINUE WITH NEXT IN CHAIN
;IMPCQ2 - UNLOCK BUFFERS ON A QUEUE (TWICE IF BUFFER SIZE CHANGES)
REPEAT 0,< ;THIS CODE SHOULD BE REPLACED IF BUFFER
; SIZE CHANGES
IMPCQ2: MOVEI T3,2 ;TELL IT TO UNLOCK THEM TWICE
JRST IMPCQ0
> ;END OF REPEAT 0
;UNLOCK BUFFERS ON A QUEUE 0 OR 1 TIMES
IMPCQ4: TDZA T3,T3 ;ZERO TIMES
IMPCQ2: ;MAKE IT ONLY UNLOCK ONCE
IMPCQ3: MOVEI T3,1 ;ONCE
IMPCQ0: TRNN T2,-1 ;COMMON CODE. 0 -- NO BUFFERS LEFT
RET ;NO BUFFERS RETURN
MOVE T1,T2 ;GET BUFFER ADDRESS IN T1
HLRZ T2,0(T1) ;GET NEXT BUFFER
HRLI T2,ANBSEC ;SET SECTION NUMBER
CALL IMPCQ1 ;UNLOCK AND RELEASE
JRST IMPCQ0 ;CONTINUE WITH NEXT IN CHAIN
;RELEASE INDIVIDUAL BUFFER
REPEAT 0,< ;THIS CODE SHOULD BE REPLACED IF BUFFER
; SIZE CHANGES
IMPCQ5: MOVEI T3,2 ;ENTRY FOR TWICE LOCKED BUFFER
> ;END OF REPEAT 0
IMPCQ5: MOVEI T3,1 ;ENTRY FOR ONCE LOCKED BUFFER
IMPCQ1: PUSH P,T3 ;COMMON ROUTINE
PUSH P,T2 ;TRANSPARENT TO T2
PUSH P,T1 ;SAVE BUFFER ADDRESS
HRRZ T1,0(T1) ;GET COUNT FIELD
CAILE T1,MAXWPM ;MAKE SURE NOT ON FREELIST
BUG(HLT,IMPAFB,<IMPCQ: ATTEMPT TO UNLOCK BUFFER ON FREELIST>)
MOVE T1,0(P) ;RESTORE T1
CALL @[ IFIW!R ;NOT LOCKED
IFIW!MULKSP ;LOCKED ONCE
IFIW!IMULKB](T3) ;CALL APPROPRIATE ROUTINE
POP P,T2 ;GET BUFFER ADDRESS
CALL RLNTBF ;AND RELEASE
POP P,T2 ;RESTORE T2 AND T3
POP P,T3
RET
;IMULKB - UNLOCK IMP BUFFER
;ACCEPTS T1/ BUFFER ADDRESS
IMULKB::PUSH P,T1 ;SAVE BUFFER ADDRESS
HRRZ T1,0(T1) ;GET SIZE FIELD
CAILE T1,MAXWPM ;MAKE SURE NOT ON FREELIST
BUG(HLT,IMPUBF,<IMULKB: ATTEMPT TO UNLOCK BUFFER ON FREELIST>)
MOVE T1,0(P)
CALL MULKSP ;UNLOCK FIRST ADR IN BFR
POP P,1
REPEAT 0,< ;THIS CODE SHOULD BE REPLACED IF BUFFER
; SIZE CHANGES
ADD T1,0(T1) ;COMPUTE END OF BFR
SOS T1 ;MAKE IT POINT TO LAST WORD IN BUFFER
CALL MULKSP ;UNLOCK END OF BFR IN CASE PAGE BDRY
> ;END OF REPEAT 0
RET
;IMP AND NCP STATUS CHECK
;PROCESS LEVEL, IN NCPFRK. CHECK STATE OF IMP AND NETWORK ON.
IMPSTT: AOSE IMPRDL ;WAS ERROR FLOP NOTICED SET?
CALL IMPRLQ ;IS IMP READY LINE ON?
JRST IMPSTA ;NO, MARK DOWN
SKIPGE IMPRDT ;YES, WAS IT DOWN?
JRST IMPSTB ;NO, CONTINUE
SETOM IMPRDT ;YES, RESET FLAG
GTAD ;GET TIME AND DATE
MOVEM T1,IMPUPT ;RECORD TIME BACK UP
JRST IMPSTB ;CONTINUE
;IMP IS OR WAS DOWN. RECORD TIME THEREOF
IMPSTA: SKIPN IMPRDY ;NCP OFF?
JRST IMPSTB ;YES. DON'T RECORD IMP DOWN IF OFF
SKIPL T1,IMPRDT ;WAS IT DOWN?
JRST IMPSTC ;YES, CHECK HOW LONG
MOVE T1,TODCLK ;NO, GET CURRENT TIME OF DAY
MOVEM T1,IMPRDT ;RECORD WHEN IN WENT OFF
GTAD ;GET TIME AND DATE
MOVEM T1,IMPDNT ;RECORD IT
MOVSI T4,-NHOSTS ;SET UP TO SCAN ALL HOST
IMPSTD: HRRZ T1,T4 ;GET HOST NUMBER IN ONE
CALL CHKNWP ;DOES THIS HOST UNDERSTAND?
JRST [ PUSH P,T4 ;NO
MOVEI T3,(T4) ;IF WE THINK IT'S UP, MARK IT DOWN.
IDIVI T3,^D36 ;BUT ONLY IF WE THINK IT'S UP, CAUSE
MOVE T4,BITS(T4) ; THERE MAY BE A RST ON OUTPUT QUEUE
TDNE T4,IMPHRT(T3) ;OR A RFNM OUTSTANDING.
CALL HSTDED ;WE THINK IT'S UP. MARK IT DOWN.
POP P,T4
JRST .+1]
AOBJN T4,IMPSTD ;TRY NEXT HOST
JRST IMPSTB ;CONTINE
IMPSTC: ADDI T1,^D10000
CAMG T1,TODCLK ;DOWN FOR MORE THAN 10 SEC?
SETOM IMPDRQ ;YES, DECLARE IMP DOWN & RECYCLE NCP
JRST IMPSTB ;CONTINUE
;BRING STATE OF NCP INTO AGREEMENT WITH STATE OF IMP AND NETON/IMPDRQ
IMPSTB: SKIPLE T1,IMPRDY ;DOWN CYCLE IN PROGRESS?
JRST IMPNO1 ;YES. COMPLETE IT.
JUMPL T1,IMPSTU ;NO. JUMP IF WE THINK IMP IS UP
SKIPE NETON ;NCP IS SHUT OFF. DO WE WANT IT OFF?
SKIPLE NETTCH ;NO. BUT IF STATE CHANGE UNREPORTED,
RET ; THEN WAIT. DO NOTHING IF ALL AGREES.
JRST IMPRSS ;ELSE BRING NCP BACK UP.
IMPSTU: SKIPLE NOPCNT ;ARE ANY NOPS NEEDED
JSP T4,IMPXOU ;YES, BE SURE OUTPUT IS GOING
SKIPN IMPDRQ ;WE THINK IT'S UP, WANT IT DOWN
SKIPN NETON
JRST IMPNOF ;YES, TAKE IT DOWN
SETZM HSTGDM ;ELSE IT'S UP. BE SURE TO CANCEL
RETSKP ; HOST GOING DOWN MSG AND SKIP
;SHUT DOWN NCP
IMPNOF: SKIPLE NETTCH ;STAT CHANGE UNREPORTED
RETSKP ;BUT NOT UNTIL STATE CHANGE REPORTED
MOVEI T1,^D30000 ;BEGIN DOWN SEQUENCE
ADD T1,TODCLK
MOVEM T1,IMPRDY ;WHEN TO GIVE UP AND TURN NCP OFF.
CALL NETDWN ;START CLEAR OF NCP
CALL CLRHRT ;CLEAR HOST READY TABLE
SETZM IMPCCH ;SEND RST'S TO EVERYONE
SETZM IMPTIM ;NOW.
AOS NETTCH ;NOTE STATE CHANGE
AOS JB0FLG ;ASK FOR JOB 0 SERVICE
JRST IMPSTT ;GO CHECK STATUS
;DOWN SEQUENCE IN PROGRESS
IMPNO1: CALL IMPRLQ ;IS IMP READY LINE ON?
JRST IMPNF3 ;NO. IMP IS DOWN.
CAMG T1,TODCLK ;OR TIME HAS RUN OUT?
JRST IMPNF3 ;YES. JUST PULL THE PLUG.
SKIPG NETTCH ;ELSE IF CHANGE UNREPORTED
SKIPL IMPCCH ;OR RST'S NOT ALL SENT
RETSKP ;THEN WAIT.
SETZM IMPORD ;SHUT OFF OUTPUT
SKIPN IMPOBO ;CHECK IF BOTH OUTPUT QUEUES ARE EMPTY.
SKIPE IMPHBO
RETSKP ;IF NOT, THEN WAIT.
SKIPLE IMPOB ;IF LAST MESSAGE NOT COMPLETELY SENT
RETSKP ; THEN WAIT.
SETZM HSTGDM ;NOW STOP SENDING HOST GOING DOWN.
SKIPE IMPOB ;ARE ALL MESSAGES SENT?
RETSKP ;NO. WAIT.
IMPNF3: SETZM IMPRDY ;NOW SAY TOTALLY DOWN
CALL IDVKIL ;CLEAR/DISABLE THE HARDWARE COMPLETELY
AOS NETTCH ;REPORT FINAL STATE CHANGE
AOS JB0FLG ;TELL JOB 0 HE AS WORK
CALL NVTDWN ;CLEAR UP ALL NVTS
MOVSI T1,-IMPNLK ;SET UP TO SCAN LINK TABLES
CALL IMPCLL ;CLEAR ALL ENTRIES FROM LINK TABLE
AOBJN T1,.-1
CALL IMPCLQ ;CLEAR QUEUES
RET ;NOT UP - NONSKIP RETURN
;INITIALIZATION
;CALLED BY NCPFRK, PROCESS LEVEL.
IMPINI: MOVSI T2,-NSQ ;FREE ALL SPECIAL QUEUES
SETOM SQJOB(T2)
AOBJN T2,.-1
SETOM SQLCK
MOVX T2,L1%SND!L1%FRE ;FREE ENTRY FOR IMPLT1
MOVSI T1,-IMPNLK ;SET UP TO SCAN LINK TABLE
MOVEM T2,IMPLT1(T1) ;MAKE ALL LINKS UNUSED
AOBJN T1,.-1
SETOM IDVLCK ;INIT IDVLCK
IMPRSN::SETZM IMPNCL ;CLEAR IRREG MSG Q VARIABLES
SETZM IMP8XI
SETZM IMP8XO
SETZM IMP8XC
CALL IMPRSD ;RESET DISPATCHES IN DEVICE DRIVER
MOVEI T1,^D120000 ;START TIMERS
ADD T1,TODCLK ;IN TWO MINUTES
MOVEM T1,NETTIM ;SET ALARM CLOCKS TO INFINITY
MOVEM T1,RFNTIM
SETZM IMPTIM
SETZM IGDTIM ;CLEAR TIME OF LAST IMP-GOING-DOWN MSG
SETZM HSTGDM ;CANCEL ANY RESIDUAL HOST GOING DOWN
SETZM IMPCCH ;CAUSE SEND OF RST TO ALL HOSTS
CLRHRT: SETZM IMPHRT ;CLEAR "HOST READY" BIT TABLE
MOVE T1,[XWD IMPHRT,IMPHRT+1]
BLT T1,IMPHRT+IMPLBT-1
RET
;VARIOUS IMPBUG'S FROM ABOVE
;IMPB03 - TRY TO GET A BUFFER
IMPB03: SKIPN IMINFB ;ANY BUFFERS RELEASE BY PI ROUTINES?
JRST IMPB04 ;NO
PUSH P,T1 ;SAVE T1, T2 AND T4
PUSH P,T2
PUSH P,T4
CALL IMINRB ;GO RELEASE FREE BUFFERS
POP P,T4 ;RESTORE T4, T2 AND T1
POP P,T2
POP P,T1
RET
IMPB04: PUSH P,T1 ;SAVE T1
BUG(INF,IMPABF,<ASNTBF FAILED>)
MOVEI T1,^D5000
DISMS ;WAIT FOR 5 SEC, THEN TRY AGAIN
POP P,T1 ;RESTORE T1
RET
;TAKE NETWORK DOWN
;ACCEPTS IN
; T1/ ;REASON FOR GOING DOWN (A LA 1822)
; T2/ ;TIME WHEN BACK UP (GTAD STANDARD FORM)
IMPHLT::SKIPN NETON ;IS IT ON?
RET ;NO. DO NOTHING
PUSH P,T1 ;SAVE T1
GTAD ;GET NOW
CAMG T2,T1 ;IS SHUTDOWN LATER THAN NOW?
JRST [ MOVEI T1,177776 ;NO
JRST IMPHL1] ;TIME BACK UP NOT KNOWN
ADD T1,[6,,0]
CAMG T1,T2 ;MORE THAN 6 DAYS AWAY?
JRST [ MOVEI T1,177777 ;YES
JRST IMPHL1]
MOVX T4,<IC%DSA!IC%UTZ> ;USE GMT STANDARD TIME
ODCNV ;SEPARATE INTO DAY, SECOND ETC
HRRZ T1,T3 ;DAY OF WEEK
HRRZ T2,T4 ;GET SECONDS
IDIVI T2,^D300 ;CONVERT SECONDS TO 5 MIN
IDIVI T2,^D12 ;SEPARATE INTO HOUR AN 5 MIN
LSH T1,5 ;5 BITS FOR HOUR
IOR T1,T2 ;INSERT HOUR OF DAY
LSH T1,4 ;4 BITS FOR 5 MIN. INTERVALS
IOR T3,3 ;AND 5 MIN PART OF HOUR
IMPHL1: LSH T1,4 ;4 BIT FOR REASON
IOR T1,0(P) ;INSERT REASON
LSH T1,4
TLO T1,(2B7)
PIOFF
SETZM NETON ;START NET DOWN
MOVEM T1,HSTGDM ;SAVE MESSAGE
PION
JSP T4,IMPXOU ;GO START OUTPUT
ADJSP P,-1 ;CLEAN UP STACK
RET
;RESTART CODE. CALLED BY SYSRST
IMPRST: SETOM IMPDRQ ;REQUEST DOWN CYCLE
MOVEI T1,1
SKIPLE IMPRDY ;GOING DOWN ALREADY?
MOVEM T1,IMPRDY ;SHORTEN DELAY
RET
TNXEND
END