Trailing-Edge
-
PDP-10 Archives
-
BB-M080H-SM
-
monitor-sources/nspsrv.mac
There are 31 other files named nspsrv.mac in the archive. Click here to see a list.
;Edit 6714 to NSPSRV.MAC by GRANT on Fri 29-Mar-85
; Another suspected problem with the merge of Edit 3155.
;; Replace the instruction which got lost.
;Edit 3189 to NSPSRV.MAC by GRANT on Fri 21-Dec-84, for SPR #20435
; Prevent NFT/FAL hangs by eliminating spurious data-available
;; PSI when a segment has timed out
;Edit 3186 to NSPSRV.MAC by GRANT on Mon 3-Dec-84
; In NSPTMR, skip over links which are "stopped" or the block
;; is locked.
;Edit 3179 to NSPSRV.MAC by GRANT on Thu 8-Nov-84
; Prevent running out of resident free space
;Edit 3171 to NSPSRV.MAC by GRANT on Thu 4-Oct-84, for SPR #19772
; Something funny happen with REDIT to edit 3155. This edit
;; simply removes 2 extraneous lines of code.
;Edit 3167 to NSPSRV.MAC by TBOYLE on Thu 20-Sep-84, for SPR #19832
; PREVENT NSPTSK FROM STAYING IN BALSET
;Edit 3155 to NSPSRV.MAC by GRANT on Thu 30-Aug-84, for SPR #19772
; Insure all bytes get sent at CLOSF% time
;Edit 3108 to NSPSRV.MAC by EVANS on Tue 15-May-84
; Fix NSPBAD in KL2116 (W.Nichols edit)
;Edit 3059 to NSPSRV.MAC by CJOHNSON on Mon 19-Dec-83, for SPR #19770
; Make TURNON send a 0 allocation LS, even when write-only
;Edit 3029 to NSPSRV.MAC by GRANT on Thu 13-Oct-83
; In STRMSG, make sure it's really node init
;Edit 2985 to NSPSRV.MAC by WEETON on Tue 5-Jul-83
; Keep large networks from causing ILMNRFs
;Edit 2963 to NSPSRV.MAC by LOMARTIRE on Thu 19-May-83
; In NSPTM5, retrieve message address earlier
;Edit 2962 to NSPSRV.MAC by LOMARTIRE on Tue 10-May-83, for SPR #19025
; Use SIZ39 in GTSBLK - prevents ILMNRF from clobbered free space
;Edit 2940 by COBB on Tue 29-Mar-83 - FIX TYPO IN 2935
;EDIT 2940 - Fix TYPO in 2935
;EDIT 2935 - In DCDCS, fix management of LL block lock
;<COBB.5-1-MAINTENANCE>AM51-NSPSRV.MAC.26, 22-Mar-83 13:52:04, Edit by COBB
;EDIT 2934 - Make ONSRVQ and UNQSRV run NOSKED
;<COBB.5-1-MAINTENANCE>AM51-NSPSRV.MAC.23, 22-Mar-83 13:44:06, Edit by COBB
;EDIT 2933 - In INTLS, remove setting of inactivity timer. In INACOR, reorder
; the tests to make elimination faster.
;<COBB.5-1-MAINTENANCE>AM51-NSPSRV.MAC.20, 22-Mar-83 10:56:09, Edit by COBB
;EDIT 2932 - rewrite part of incoming CI message processing and modify BADNOD
;<COBB.5-1-MAINTENANCE>AM51-NSPSRV.MAC.15, 22-Mar-83 10:38:02, Edit by COBB
;EDIT 2931 - redo the logic in ACKRUN and DATRUN
;<COBB.5-1-MAINTENANCE>AM51-NSPSRV.MAC.12, 22-Mar-83 10:26:37, Edit by COBB
;EDIT 2930 - add missing OKINT in DCDCS
;<COBB.5-1-MAINTENANCE>AM51-NSPSRV.MAC.9, 22-Mar-83 10:16:32, Edit by COBB
;EDIT 2929 - remove extraneous instruction at MTSNIN
;<COBB.5-1-MAINTENANCE>AM51-NSPSRV.MAC.8, 22-Mar-83 10:11:01, Edit by COBB
;EDIT 2927 - rewrite CHKSCT
; UPD ID= 92, SNARK:<5.1.MONITOR>NSPSRV.MAC.18, 12-Nov-82 14:06:06 by GRANT
;TCO 5.1.1105 - Eliminate some unused internal links code
; UPD ID= 84, SNARK:<5.1.MONITOR>NSPSRV.MAC.17, 2-Nov-82 11:54:42 by GRANT
;TCO 5.1.1100 - release swappable block in CLRBLK
; UPD ID= 83, SNARK:<5.1.MONITOR>NSPSRV.MAC.16, 2-Nov-82 11:15:02 by GRANT
;Minor fix to TCO 5.1.1089
; UPD ID= 79, SNARK:<5.1.MONITOR>NSPSRV.MAC.15, 11-Oct-82 10:01:06 by GRANT
;TCO 5.1.1092 - Change a few IFNSK. to IFSKP.
; UPD ID= 74, SNARK:<5.1.MONITOR>NSPSRV.MAC.14, 9-Oct-82 10:17:51 by GRANT
;TCO 5.1.1089 - Rewrite MCBCQ, process link IDs rather than LL blocks
; UPD ID= 72, SNARK:<5.1.MONITOR>NSPSRV.MAC.13, 8-Oct-82 09:24:27 by GRANT
;TCO 5.1.1087 - Add call to DELNOD in NSPTMO
; UPD ID= 71, SNARK:<5.1.MONITOR>NSPSRV.MAC.12, 8-Oct-82 08:54:04 by GRANT
;TCO 5.1.1086 - In RELLNK and DEDMCB, lock LL tree before calling DELNOD
; UPD ID= 70, SNARK:<5.1.MONITOR>NSPSRV.MAC.11, 7-Oct-82 13:34:02 by GRANT
;TCO 5.1.1085 - In UNQSEG, stop incorrect removal from the resend queue
; UPD ID= 67, SNARK:<5.1.MONITOR>NSPSRV.MAC.10, 6-Oct-82 08:52:33 by GRANT
;TCO 5.1.1074 - Add debugging code for verifying logical link blocks
; UPD ID= 60, SNARK:<5.1.MONITOR>NSPSRV.MAC.9, 1-Oct-82 17:43:28 by GRANT
;TCO 5.1.1080 - In NSPMSG, toss messages which have LLDED set
; UPD ID= 59, SNARK:<5.1.MONITOR>NSPSRV.MAC.8, 1-Oct-82 14:29:34 by GRANT
;TCO 5.1.1079 - Use MOVE instead of LOAD in NSPNXT
; UPD ID= 53, SNARK:<5.1.MONITOR>NSPSRV.MAC.7, 28-Sep-82 19:07:10 by GRANT
;TCO 5.1.1072 - don't retransmit data segments when flow is turned off
; UPD ID= 47, SNARK:<5.1.MONITOR>NSPSRV.MAC.6, 23-Sep-82 12:04:32 by GRANT
;TCO 5.1.1067 - Don't send a disconnect when a link times out
; UPD ID= 46, SNARK:<5.1.MONITOR>NSPSRV.MAC.5, 23-Sep-82 09:23:34 by GRANT
;TCO 5.1.1066 - If link has been aborted, have synchronous CLOSF return success
; UPD ID= 44, SNARK:<5.1.MONITOR>NSPSRV.MAC.4, 21-Sep-82 13:16:30 by GRANT
;TCO 5.1.1063 - In NSNSCH, return characteristics by parameter number
; UPD ID= 43, SNARK:<5.1.MONITOR>NSPSRV.MAC.3, 21-Sep-82 10:50:00 by GRANT
;Fix bug in SNDCTL introduced by an incorrect test in TCO 5.1.1057
; UPD ID= 42, SNARK:<5.1.MONITOR>NSPSRV.MAC.2, 14-Sep-82 12:28:31 by MCINTEE
;TCO 5.1.1061 - Change routine NDGNT to not use so much stack.
; UPD ID= 38, SNARK:<5.1.MONITOR>NSPSRV.MAC.5, 30-Aug-82 14:03:08 by MCINTEE
;TCO 5.1.1058 - Change error message in MTOBJ1
; UPD ID= 36, SNARK:<5.1.MONITOR>NSPSRV.MAC.4, 27-Aug-82 07:02:36 by GRANT
;TCO 5.1.1057 - make proper check for remote node's NSP version
; UPD ID= 34, SNARK:<5.1.MONITOR>NSPSRV.MAC.3, 25-Aug-82 11:49:52 by GRANT
;TCO 5.1.1055 - check for CC sent state in MTRDCK
; UPD ID= 33, SNARK:<5.1.MONITOR>NSPSRV.MAC.2, 25-Aug-82 10:08:46 by GRANT
;TCO 5.1.1054 - prevent CLZRUN from wrongly sending 0-length data messages
; UPD ID= 32, SNARK:<5.1.MONITOR>NSPSRV.MAC.19, 18-Aug-82 09:21:15 by GRANT
;TCO 5.1692 - incorrect test at SQI4
; UPD ID= 31, SNARK:<5.1.MONITOR>NSPSRV.MAC.18, 17-Aug-82 09:50:49 by GRANT
;TCO 5.1.1053 - make NTRNAM return updated user BP to its caller
; UPD ID= 29, SNARK:<5.1.MONITOR>NSPSRV.MAC.17, 10-Aug-82 11:57:17 by GRANT
;TCO 5.1.1051 - Change RETBAD to JRST SRCFAL in SRCOPN
; UPD ID= 28, SNARK:<5.1.MONITOR>NSPSRV.MAC.16, 10-Aug-82 11:26:42 by GRANT
;TCO 5.1.1050 - Change RETERR to RET in DCNOPN's GTOKM
; UPD ID= 25, SNARK:<5.1.MONITOR>NSPSRV.MAC.15, 18-Jul-82 13:48:48 by MURPHY
;TCO 5.1.1048 - Check LLTTA when closing; keep LL block locked until return
; from TTSETH.
; UPD ID= 21, SNARK:<5.1.MONITOR>NSPSRV.MAC.14, 13-Jul-82 10:51:11 by GRANT
;TCO 5.1.1045 - In NTSNH, unlock LL block when call to TTYSRV fails
; UPD ID= 19, SNARK:<5.1.MONITOR>NSPSRV.MAC.13, 6-Jul-82 09:24:35 by GRANT
;TCO 5.1.1042 - Make NSLDWS resident
; UPD ID= 16, SNARK:<5.1.MONITOR>NSPSRV.MAC.12, 30-Jun-82 09:19:55 by GRANT
;Fix edit history - change TCO 6.1153 to TCO 5.1.1040
; UPD ID= 14, SNARK:<5.1.MONITOR>NSPSRV.MAC.11, 30-Jun-82 08:37:03 by GRANT
;TCO 5.1.1037 - setting local node number requires privileges
; UPD ID= 12, SNARK:<5.1.MONITOR>NSPSRV.MAC.10, 17-Jun-82 09:44:20 by GRANT
;TCO 5.1.1035 - make interrupt messages work again
; UPD ID= 8, SNARK:<5.1.MONITOR>NSPSRV.MAC.9, 8-Jun-82 08:21:51 by GRANT
;Rewrite UNQSEG
; UPD ID= 7, SNARK:<5.1.MONITOR>NSPSRV.MAC.8, 7-Jun-82 16:53:06 by GRANT
;More fixing of TCO 5.1.1022
; UPD ID= 6, SNARK:<5.1.MONITOR>NSPSRV.MAC.7, 7-Jun-82 08:04:44 by GRANT
;TCO 5.1.1033 - Return proper error message in NANUE2
; UPD ID= 5, SNARK:<5.1.MONITOR>NSPSRV.MAC.6, 7-Jun-82 06:58:15 by GRANT
;TCO 5.1.1040 - Fix protocol error of sending data before LS ACK
; UPD ID= 590, SNARK:<5.MONITOR>P3-NSPSRV.MAC.55, 4-Jun-82 21:43:18 by GRANT
;Fix bug in TCO 5.1.1022 change - RESBAZ and RESCHK problems fixed
; UPD ID= 589, SNARK:<5.MONITOR>P3-NSPSRV.MAC.54, 4-May-82 11:55:06 by GRANT
;TCO 5.1.1032 - turn off LLNLS and LLALS in ACKLI not in SNDACK
; UPD ID= 587, SNARK:<5.MONITOR>P3-NSPSRV.MAC.53, 30-Apr-82 13:24:01 by GRANT
;TCO 5.1.1031 - make NTMAN% set and read retransmit factor
; UPD ID= 585, SNARK:<5.MONITOR>P3-NSPSRV.MAC.52, 28-Apr-82 10:36:35 by GRANT
;TCO 5.1.1029 - Process all incoming, non-control messages at scheduler level
; UPD ID= 584, SNARK:<5.MONITOR>P3-NSPSRV.MAC.51, 22-Apr-82 13:40:44 by GRANT
;TCO 5.1.1028 - apply Local Delay Factor in proper place
; UPD ID= 580, SNARK:<5.MONITOR>P3-NSPSRV.MAC.50, 16-Apr-82 12:24:33 by GRANT
;TCO 5.1.1027 - Unlock LL block when CALL ASMCB fails
; UPD ID= 579, SNARK:<5.MONITOR>P3-NSPSRV.MAC.49, 16-Apr-82 07:44:16 by GRANT
;TCO 5.1.1026 - Let background task wake up whenever it has a message to process
; UPD ID= 576, SNARK:<5.MONITOR>P3-NSPSRV.MAC.48, 14-Apr-82 11:12:40 by GRANT
;Performance improvement to TCO 5.1.1022
; UPD ID= 573, SNARK:<5.MONITOR>P3-NSPSRV.MAC.47, 13-Apr-82 15:13:31 by GRANT
;TCO 5.1.1025 - Make Local Delay Factor and Local Delay Weight settable and
;readable by NTMAN%
; UPD ID= 572, SNARK:<5.MONITOR>P3-NSPSRV.MAC.46, 13-Apr-82 14:26:11 by GRANT
;Slight modification to TCO 5.1.1023 - send LS messgae earlier
; UPD ID= 567, SNARK:<5.MONITOR>P3-NSPSRV.MAC.45, 6-Apr-82 10:46:15 by GRANT
;Undo more debugging code
; UPD ID= 566, SNARK:<5.MONITOR>P3-NSPSRV.MAC.44, 31-Mar-82 14:12:28 by GRANT
;TCO 5.1.1024 - Impose a minimum on the round trip calculation
; UPD ID= 564, SNARK:<5.MONITOR>P3-NSPSRV.MAC.43, 31-Mar-82 13:40:41 by GRANT
;TCO 5.1.1023 - Fix free space bug in NETSET
;TCO 5.1.1022 - don't time messages on Phase II links
;More of TCO 5.1.1020
;Remove debugging BUGHLTs
; UPD ID= 560, SNARK:<5.MONITOR>P3-NSPSRV.MAC.42, 23-Mar-82 06:48:09 by GRANT
;Undo previous edit
; UPD ID= 559, SNARK:<5.MONITOR>P3-NSPSRV.MAC.41, 22-Mar-82 11:19:48 by GRANT
;TCO 5.1.1021 - Release message block in DCDCS
; UPD ID= 557, SNARK:<5.MONITOR>P3-NSPSRV.MAC.40, 21-Mar-82 18:22:12 by GRANT
;TCO 5.1.1020 - NAK "too new" segments from Phase II nodes
; UPD ID= 554, SNARK:<5.MONITOR>P3-NSPSRV.MAC.39, 19-Mar-82 17:43:23 by MURPHY
;TCO 5.1.1019 - Make NSPTST wake up less often.
; UPD ID= 548, SNARK:<5.MONITOR>P3-NSPSRV.MAC.38, 17-Mar-82 12:27:28 by GRANT
;TCO 5.1.1018 - Check for CCS state in NTMTCZ
; UPD ID= 541, SNARK:<5.MONITOR>P3-NSPSRV.MAC.37, 16-Mar-82 09:26:52 by GRANT
;TCO 5.1.1017 - Change state transition table for CLOSF in CCS state
; UPD ID= 540, SNARK:<5.MONITOR>P3-NSPSRV.MAC.36, 16-Mar-82 09:11:26 by GRANT
;TCO 5.1.1016 - Remove check for 0 bytes in CLZRUN
; UPD ID= 538, SNARK:<5.MONITOR>P3-NSPSRV.MAC.35, 15-Mar-82 08:58:06 by GRANT
;TCO 5.1.1015 - CALL FLUSH in DCDCS
; UPD ID= 534, SNARK:<5.MONITOR>P3-NSPSRV.MAC.34, 12-Mar-82 08:08:23 by GRANT
;Minor change to UPD 526
; UPD ID= 531, SNARK:<5.MONITOR>P3-NSPSRV.MAC.33, 11-Mar-82 21:32:59 by GRANT
;Fix typo in UPD 522
; UPD ID= 530, SNARK:<5.MONITOR>P3-NSPSRV.MAC.32, 11-Mar-82 16:30:35 by GRANT
;TCO 5.1.1014 - CALL BLKLLK in DATCSS
; UPD ID= 527, SNARK:<5.MONITOR>P3-NSPSRV.MAC.31, 11-Mar-82 16:13:03 by GRANT
;TCO 5.1.1012 - Reset inactivity wake up even if nothing to do
; UPD ID= 526, SNARK:<5.MONITOR>P3-NSPSRV.MAC.30, 11-Mar-82 16:01:25 by GRANT
;TCO 5.1.1013 - Don't turn off inactivity timer unless LS message gets sent
; UPD ID= 525, SNARK:<5.MONITOR>P3-NSPSRV.MAC.29, 11-Mar-82 15:53:39 by GRANT
;TCO 5.1.1011 - Make scheduler send ACKs every 200 milliseconds.
;Previous edit should be TCO 5.1.1010
; UPD ID= 524, SNARK:<5.MONITOR>P3-NSPSRV.MAC.28, 11-Mar-82 15:41:55 by GRANT
;TCO 5.1.1011 - Always go to LLSRVR upon leaving NSPCH7
; UPD ID= 522, SNARK:<5.MONITOR>P3-NSPSRV.MAC.27, 9-Mar-82 14:36:42 by GRANT
;TCO 5.1.1009 - Make .NDGNT function of NODE% return info even on failure
; UPD ID= 521, SNARK:<5.MONITOR>P3-NSPSRV.MAC.26, 9-Mar-82 09:53:18 by GRANT
;Add missing ENDIF. in UPD 512
; UPD ID= 516, SNARK:<5.MONITOR>P3-NSPSRV.MAC.25, 6-Mar-82 21:31:29 by GRANT
;TCO 5.1.1008 - Use BLKSIZ in node init
; UPD ID= 515, SNARK:<5.MONITOR>P3-NSPSRV.MAC.24, 6-Mar-82 21:26:41 by GRANT
;TCO 5.1.1007 - Comment out development paranoid checks
; UPD ID= 512, SNARK:<5.MONITOR>P3-NSPSRV.MAC.23, 6-Mar-82 21:15:00 by GRANT
;TCO 5.1.1006 - Rewrite ONTIMQ and UNQTIM
; UPD ID= 479, SNARK:<5.MONITOR>P3-NSPSRV.MAC.22, 17-Feb-82 14:23:42 by GRANT
;TCO 5.1.1005 - ACKCCS needs to use CALL BLKLLK instead of CALL BLKLOK
; UPD ID= 476, SNARK:<5.MONITOR>P3-NSPSRV.MAC.21, 12-Feb-82 15:26:41 by GRANT
;TCO 5.1729 - NSPINT no longer loaded, remove calls to OUTSEG
; UPD ID= 465, SNARK:<5.MONITOR>P3-NSPSRV.MAC.20, 7-Feb-82 20:35:59 by GRANT
;TCO 5.1721 Make NODE JSYS function .NDGLN use 30-bit addressing
; UPD ID= 461, SNARK:<5.MONITOR>P3-NSPSRV.MAC.19, 5-Feb-82 09:23:31 by GRANT
;TCO 5.1.1004 - put in call to the new code
; UPD ID= 460, SNARK:<5.MONITOR>P3-NSPSRV.MAC.18, 5-Feb-82 07:56:18 by GRANT
;TCO 5.1.1004 - figure out "number of active links" in the NTMAN% JSYS
; UPD ID= 373, SNARK:<5.MONITOR>P3-NSPSRV.MAC.17, 5-Jan-82 08:53:02 by GRANT
;TCO 5.1649 - Add null message handling
; UPD ID= 362, SNARK:<5.MONITOR>P3-NSPSRV.MAC.16, 13-Dec-81 10:48:40 by GRANT
;TCO 5.1636 - use SEGSZ
; UPD ID= 343, SNARK:<5.MONITOR>P3-NSPSRV.MAC.15, 4-Dec-81 14:01:33 by GRANT
;More TCO 5.1503 - make consistent use of symbols
; UPD ID= 340, SNARK:<5.MONITOR>P3-NSPSRV.MAC.14, 4-Dec-81 08:52:03 by GRANT
;TCO 5.1626 - In NODINI, make an extensible field for the node number.
;Another attempt at TCO 5.1510
; UPD ID= 316, SNARK:<5.MONITOR>P3-NSPSRV.MAC.13, 9-Nov-81 11:20:29 by GRANT
;TCO 5.1.1001 - add explicit check for 8-bit bytes in NTMAN%
; UPD ID= 315, SNARK:<5.MONITOR>P3-NSPSRV.MAC.12, 9-Nov-81 10:12:06 by GRANT
;Under DN20SW, enhance checking for multiple MCBs
; UPD ID= 309, SNARK:<5.MONITOR>P3-NSPSRV.MAC.11, 4-Nov-81 08:55:26 by GRANT
;TCO 5.1604 - Only do inactivity checking when link is in the run state
; UPD ID= 286, SNARK:<5.MONITOR>P3-NSPSRV.MAC.10, 22-Oct-81 09:00:19 by GRANT
;TCO 5.1593 - Defensive code in RESEND to prevent looping caused by bad counter
; UPD ID= 276, SNARK:<5.MONITOR>P3-NSPSRV.MAC.9, 21-Oct-81 11:37:09 by GRANT
;TCO 5.1594 - Create TTGETS and TTREMS for TTYSRV to use
; UPD ID= 274, SNARK:<5.MONITOR>P3-NSPSRV.MAC.8, 21-Oct-81 10:01:59 by GRANT
;TCO 5.1592 - Fix failure return in LLSRVR
; UPD ID= 273, SNARK:<5.MONITOR>P3-NSPSRV.MAC.7, 19-Oct-81 16:11:05 by GRANT
;Minor change to UPD ID= 194 - Error return from ACKRMT needs to be different
; UPD ID= 271, SNARK:<5.MONITOR>P3-NSPSRV.MAC.6, 19-Oct-81 10:07:57 by GRANT
;TCO 5.1587 - fix segment number wrap around in VERSEG
; UPD ID= 263, SNARK:<5.MONITOR>P3-NSPSRV.MAC.5, 15-Oct-81 14:07:14 by GRANT
;Fix bug in TCO 5.1534
; UPD ID= 230, SNARK:<5.MONITOR>NSPSRV.MAC.111, 29-Sep-81 10:30:51 by GRANT
;Typo in previous edit - LLCIR should be LLSCIR
; UPD ID= 221, SNARK:<5.MONITOR>NSPSRV.MAC.110, 28-Sep-81 12:51:18 by GRANT
;TCO 5.1534 - make RDSTS reflect MO%WFC correctly
; UPD ID= 220, SNARK:<5.MONITOR>NSPSRV.MAC.109, 28-Sep-81 12:40:10 by GRANT
;TCO 5.1537 - smarter calculation of time out value on retransmission
; UPD ID= 215, SNARK:<5.MONITOR>NSPSRV.MAC.108, 24-Sep-81 22:05:34 by GRANT
;PREVIOUS EDIT NEEDS EXPANDED ACVAR IN NSPTMR
; UPD ID= 214, SNARK:<5.MONITOR>NSPSRV.MAC.107, 24-Sep-81 16:52:00 by GRANT
;TCO 5.1533 - New resend algorithm in NSPTMR.
;Comments added in VERSEG and ONRAWQ.
;Reorganize so scheduler related routines are in one place.
; UPD ID= 207, SNARK:<5.MONITOR>NSPSRV.MAC.106, 22-Sep-81 22:59:02 by GRANT
;TCO 5.1528 - FIX THE CHECK FOR "NEEDS AN ACK" IN LLSRVR
;TCO 5.1529 - FIX THE OUT-OF-ORDER MESSAGE PROCESSING IN GOTSEG
; UPD ID= 203, SNARK:<5.MONITOR>NSPSRV.MAC.105, 21-Sep-81 16:34:29 by GRANT
;More TCO 5.1490 - In DELNOD, CALL UNQSRV so old addresses don't remain on LLSRVQ
; UPD ID= 201, SNARK:<5.MONITOR>NSPSRV.MAC.104, 21-Sep-81 10:09:06 by GRANT
;Fix DSCMOV to accommodate TCO 5.1503 (bigger userid, password, account)
; UPD ID= 194, SNARK:<5.MONITOR>NSPSRV.MAC.103, 17-Sep-81 13:23:21 by GRANT
;TCO 5.1490 - Create a pool of free space blocks reserved for sending ACKs
;Piggyback ACKs in data segments
;Eliminate raw queue, do ACKs in scheduler
; UPD ID= 178, SNARK:<5.MONITOR>NSPSRV.MAC.102, 15-Sep-81 13:54:42 by GRANT
;More of TCO 5.1508
; UPD ID= 177, SNARK:<5.MONITOR>NSPSRV.MAC.101, 15-Sep-81 11:55:12 by GRANT
;TCO 5.1510 - Fix Network Management counter "number of active links"
; UPD ID= 174, SNARK:<5.MONITOR>NSPSRV.MAC.100, 14-Sep-81 16:38:16 by GRANT
;TCO 5.1508 - LL not cleaned up on abort close if other side doesn't answer
; UPD ID= 170, SNARK:<5.MONITOR>NSPSRV.MAC.99, 14-Sep-81 10:53:00 by GRANT
;TCO 5.1503 - Allow user ids, passwords, and accounts to be up to 39 chars
; UPD ID= 169, SNARK:<5.MONITOR>NSPSRV.MAC.98, 14-Sep-81 09:23:33 by GRANT
;TCO 5.1502 - Fix cause of ILLUUO BUGHLT caused by NODE JSYS
; UPD ID= 83, SNARK:<5.MONITOR>NSPSRV.MAC.93, 28-Jul-81 11:48:23 by GRANT
;Move test for NSSNTQ empty from NSPTSK to NSPTMR - prevents unnecessary wakeups
; UPD ID= 39, SNARK:<5.MONITOR>NSPSRV.MAC.92, 16-Jul-81 17:09:25 by GRANT
;Use symbols in NDRNM function of NODE JSYS
; UPD ID= 28, SNARK:<5.MONITOR>NSPSRV.MAC.91, 13-Jul-81 14:50:17 by GRANT
;Add resend queue checking interval to NSPTST
; UPD ID= 21, SNARK:<5.MONITOR>NSPSRV.MAC.90, 12-Jul-81 21:23:54 by GRANT
;IN DATCCS AND IN ACKCCS, RELEASE FREE SPACE AFTER DEQUEUING MESSAGE
; UPD ID= 2297, SNARK:<5.MONITOR>NSPSRV.MAC.89, 6-Jul-81 14:15:47 by GRANT
;TCO 5.1394 - Return correct error when OBJSRC fails in DSCNO2
; UPD ID= 2273, SNARK:<5.MONITOR>NSPSRV.MAC.88, 30-Jun-81 11:47:55 by GRANT
;Add inactivity checking interval to NSPTST
; UPD ID= 2266, SNARK:<5.MONITOR>NSPSRV.MAC.87, 27-Jun-81 22:10:21 by GRANT
;CHANGE BADMSG TO TOSMSG IN ACKMSG ROUTINE - JUST THROW AWAY A CA
;CHANGE BADMSG TO TOSMSG IN DOMSGQ ROUTINE - JUST THROW AWAY TRANSPORT INITS
; UPD ID= 2254, SNARK:<5.MONITOR>NSPSRV.MAC.86, 25-Jun-81 07:20:52 by GRANT
;TCO 5.1385 - Remove CIDON, revise BADMSG, add TOSMSG
;Don't zero LLLSC in INACOR
; UPD ID= 2215, SNARK:<5.MONITOR>NSPSRV.MAC.85, 18-Jun-81 16:53:15 by GRANT
;Fix bugs in NODE JSYS function NDGNT failure returns
; UPD ID= 2204, SNARK:<5.MONITOR>NSPSRV.MAC.84, 17-Jun-81 09:50:15 by GRANT
;Send ACKs to background task
;TCO 5.1371 - Check for resident free space threshold in OPNWRK, NSPSPC, and SNDCHK
; UPD ID= 2186, SNARK:<5.MONITOR>NSPSRV.MAC.83, 11-Jun-81 15:54:37 by MURPHY
;CHANGE TQNx TO TMNx REFLECTING CHANGE IN MACSYM
; UPD ID= 2172, SNARK:<5.MONITOR>NSPSRV.MAC.82, 10-Jun-81 15:48:23 by MURPHY
;MAKE TEMP BUGCHK'S INTO BUGHLT'S
; UPD ID= 2136, SNARK:<5.MONITOR>NSPSRV.MAC.81, 7-Jun-81 21:41:13 by GRANT
;ADD CHECKING INTERVAL TO NSPTMR
;MORE INTELLIGENCE NEEDED IN COMPAR
; UPD ID= 2105, SNARK:<5.MONITOR>NSPSRV.MAC.80, 28-May-81 14:59:02 by GRANT
;Remove calls to RETIDN - Network Management will handle this parameter
;Minor fixes in NTNRAC
; UPD ID= 2096, SNARK:<5.MONITOR>NSPSRV.MAC.79, 28-May-81 09:48:17 by GRANT
;Add range checking on timer value in NSNIAT
; UPD ID= 2092, SNARK:<5.MONITOR>NSPSRV.MAC.78, 27-May-81 16:49:37 by GRANT
;Implement NSP 3.2 logical link inactivity timers
;NTMAN% - add return list of active nodes
; UPD ID= 2043, SNARK:<5.MONITOR>NSPSRV.MAC.77, 20-May-81 09:20:14 by GRANT
;Eliminate DELNDF BUGxxx
; UPD ID= 1980, SNARK:<5.MONITOR>NSPSRV.MAC.76, 12-May-81 16:15:47 by GRANT
;Fix BP bug in NDXLT2 debug conditional
; UPD ID= 1968, SNARK:<5.MONITOR>NSPSRV.MAC.75, 8-May-81 16:41:07 by GRANT
;Give PSI when a message is retransmitted due to timeout
; UPD ID= 1960, SNARK:<5.MONITOR>NSPSRV.MAC.74, 7-May-81 11:52:29 by GRANT
;Obtain a new block of space for the remote descriptor in CLRBLK
; UPD ID= 1936, SNARK:<5.MONITOR>NSPSRV.MAC.73, 5-May-81 13:05:45 by GRANT
;Put CHKLLT in RJECT1 and NSPTMO
; UPD ID= 1933, SNARK:<5.MONITOR>NSPSRV.MAC.72, 4-May-81 15:25:16 by GRANT
;Fix failure returns from CALL SNDLS in RDINT and from CALL SNDDI in NSPTMO
;Add caller's PC as optional data to DELNDF
; UPD ID= 1907, SNARK:<5.MONITOR>NSPSRV.MAC.71, 30-Apr-81 08:37:38 by GRANT
;Generate PSI when LL is squashed due to timeout
; UPD ID= 1906, SNARK:<5.MONITOR>NSPSRV.MAC.70, 29-Apr-81 11:59:26 by GRANT
;Just return after a DELNDF BUGINF
; UPD ID= 1895, SNARK:<5.MONITOR>NSPSRV.MAC.69, 28-Apr-81 16:23:53 by GRANT
;Fix resident free space bugs - DIs and CCs not getting cleaned up
;<5.MONITOR>NSPSRV.MAC.68, 26-Apr-81 22:09:27, EDIT BY GRANT
; UPD ID= 1889, SNARK:<5.MONITOR>NSPSRV.MAC.67, 26-Apr-81 21:01:20 by GRANT
;TCO 5.1279 - DECNET PHASE II+ STUFF (TOPOLOGY, NETWORK MANAGEMENT, AND
;NSP MESSAGE TIMER)
;UPD ID= 1430, SNARK:<5.MONITOR>NSPSRV.MAC.62, 9-Jan-81 17:47:22 by MURPHY
;MOVE STMXDF HERE FROM NSPINT
; UPD ID= 1408, SNARK:<5.MONITOR>NSPSRV.MAC.61, 6-Jan-81 15:02:35 by MURPHY
;MAKE CERTAIN CODE RESIDENT THAT MAY NOW BE CALLED FROM SKED
; UPD ID= 1372, SNARK:<5.MONITOR>NSPSRV.MAC.60, 22-Dec-80 09:48:02 by GRANT
;TCO 5.1218 - Change error message in OPNDFT
; UPD ID= 1360, SNARK:<5.MONITOR>NSPSRV.MAC.59, 17-Dec-80 15:46:00 by MURPHY
;CHKLLT INSTEAD OF CHKMCB
; UPD ID= 1348, SNARK:<5.MONITOR>NSPSRV.MAC.58, 12-Dec-80 11:19:45 by MURPHY
;CHKMCB AT LSIDON
; UPD ID= 1318, SNARK:<5.MONITOR>NSPSRV.MAC.57, 26-Nov-80 07:17:11 by GRANT
;TYPO IN PREVIOUS EDIT
; UPD ID= 1316, SNARK:<5.MONITOR>NSPSRV.MAC.56, 25-Nov-80 16:58:23 by GRANT
;New version of NTMAN% JSYS - NSP node counters and formatted data return
; UPD ID= 1312, SNARK:<5.MONITOR>NSPSRV.MAC.55, 25-Nov-80 09:43:28 by GRANT
;TCO 5.1202 - Verification of message flags subtype field
; UPD ID= 1309, SNARK:<5.MONITOR>NSPSRV.MAC.54, 24-Nov-80 16:49:42 by MURPHY
;Make abort close release LL block immediately
;Certain subroutines need to be resident
; UPD ID= 1299, SNARK:<5.MONITOR>NSPSRV.MAC.53, 19-Nov-80 16:59:45 by MURPHY
;XON, XOFF OPTION FOR NVT
; UPD ID= 1291, SNARK:<5.MONITOR>NSPSRV.MAC.52, 18-Nov-80 16:45:58 by MURPHY
;NRT BUGS
; UPD ID= 1283, SNARK:<5.MONITOR>NSPSRV.MAC.51, 18-Nov-80 14:04:39 by GRANT
;TCO 5.1159 - more, don't shut off line if a Phase III transport msg appears,
; just throw the message away
; UPD ID= 1281, SNARK:<5.MONITOR>NSPSRV.MAC.50, 18-Nov-80 11:14:34 by GRANT
;TCO 5.1159 - again, put test in a better place
; UPD ID= 1274, SNARK:<5.MONITOR>NSPSRV.MAC.49, 14-Nov-80 17:52:09 by MURPHY
;NRT BUGS
; UPD ID= 1266, SNARK:<5.MONITOR>NSPSRV.MAC.48, 11-Nov-80 17:53:58 by MURPHY
;NRT bug - MCBQC
; UPD ID= 1225, SNARK:<5.MONITOR>NSPSRV.MAC.47, 3-Nov-80 16:29:36 by GRANT
;TCO 5.1187 - Make segment size calculation in STRMSG
; UPD ID= 1191, SNARK:<5.MONITOR>NSPSRV.MAC.46, 23-Oct-80 16:08:38 by GRANT
;Fix GETBYM arguments in GTASC0
; UPD ID= 1186, SNARK:<5.MONITOR>NSPSRV.MAC.45, 21-Oct-80 15:46:05 by GRANT
;Add segment size check to DOSRVS and FILLIN
; UPD ID= 1183, SNARK:<5.MONITOR>NSPSRV.MAC.44, 21-Oct-80 09:12:26 by GRANT
;TCO 5.1177 - Rewrite DEDCOR to fix bug and become more efficient
; UPD ID= 1178, SNARK:<5.MONITOR>NSPSRV.MAC.43, 20-Oct-80 17:12:20 by MURPHY
;MAKE GETBYT OPEN CODE (GETBYM MACRO)
; UPD ID= 1168, SNARK:<5.MONITOR>NSPSRV.MAC.42, 15-Oct-80 16:14:55 by GRANT
;Add flow control threshold logic in SQI
; UPD ID= 1150, SNARK:<5.MONITOR>NSPSRV.MAC.41, 10-Oct-80 16:19:28 by GRANT
;More of previous edit
; UPD ID= 1140, SNARK:<5.MONITOR>NSPSRV.MAC.40, 8-Oct-80 10:51:01 by GRANT
;TCO 5.1169 - Make PRSNAM call PARNO1
;<5.MONITOR>NSPSRV.MAC.39, 6-Oct-80 13:31:25, EDIT BY MURPHY
;<5.MONITOR>NSPSRV.MAC.38, 6-Oct-80 11:43:48, EDIT BY MURPHY
; UPD ID= 1124, SNARK:<5.MONITOR>NSPSRV.MAC.37, 5-Oct-80 15:02:30 by MURPHY
;DITTO
; UPD ID= 1119, SNARK:<5.MONITOR>NSPSRV.MAC.36, 3-Oct-80 12:21:08 by MURPHY
;DITTO
; UPD ID= 1111, SNARK:<5.MONITOR>NSPSRV.MAC.35, 3-Oct-80 01:00:34 by MURPHY
;MAKE NSP NOTIFY TTYSRV UPON RECEIPT OF DATA AND ACKS
; UPD ID= 1105, SNARK:<5.MONITOR>NSPSRV.MAC.34, 2-Oct-80 09:35:12 by MURPHY
;DITTO
; UPD ID= 1092, SNARK:<5.MONITOR>NSPSRV.MAC.33, 1-Oct-80 13:35:09 by MURPHY
;FIX ACVAR
; UPD ID= 1067, SNARK:<5.MONITOR>NSPSRV.MAC.32, 30-Sep-80 11:02:43 by GRANT
;TCO 5.1160 - make NSPRTH BUGCHK more meaningful
; UPD ID= 1065, SNARK:<5.MONITOR>NSPSRV.MAC.31, 30-Sep-80 10:46:39 by GRANT
;TCO 5.1159 - must reject Phase III Transport init message
; UPD ID= 1064, SNARK:<5.MONITOR>NSPSRV.MAC.30, 30-Sep-80 10:31:05 by GRANT
;Fix sequential input again and init NMAPLK in NSPINI
; UPD ID= 1061, SNARK:<5.MONITOR>NSPSRV.MAC.29, 30-Sep-80 10:16:15 by MURPHY
;NVT bugs
; UPD ID= 1059, SNARK:<5.MONITOR>NSPSRV.MAC.28, 26-Sep-80 13:30:48 by GRANT
;Add NTMAN% JSYS
; UPD ID= 1056, SNARK:<5.MONITOR>NSPSRV.MAC.27, 26-Sep-80 12:12:52 by MURPHY
;Make BLKULK preserve T2; fix various NVT bugs
; UPD ID= 1036, SNARK:<5.MONITOR>NSPSRV.MAC.26, 24-Sep-80 11:48:18 by GRANT
;TCO 5.1153 - NETSQI must save T2 over the call to BLKULK
; UPD ID= 1023, SNARK:<5.MONITOR>NSPSRV.MAC.25, 16-Sep-80 16:07:18 by GRANT
;Change MONX01 to NSPX26 in NDSIC routine
; UPD ID= 1019, SNARK:<5.MONITOR>NSPSRV.MAC.24, 16-Sep-80 15:34:14 by GRANT
;TCO 5.1146 - Fix free space bug in MTRDIN
; UPD ID= 1007, SNARK:<5.MONITOR>NSPSRV.MAC.23, 11-Sep-80 18:17:22 by GRANT
;Change MONX01 to MONX06 in GETBLK routine
; UPD ID= 943, SNARK:<5.MONITOR>NSPSRV.MAC.21, 20-Aug-80 20:09:04 by MURPHY
;Merge FILNSP into NSPSRV
; UPD ID= 920, SNARK:<5.MONITOR>NSPSRV.MAC.20, 19-Aug-80 15:17:32 by MURPHY
;File open mode 1 for small segsiz
; UPD ID= 902, SNARK:<5.MONITOR>NSPSRV.MAC.19, 14-Aug-80 22:54:49 by MURPHY
;Locks again
; UPD ID= 892, SNARK:<5.MONITOR>NSPSRV.MAC.18, 13-Aug-80 18:21:01 by MURPHY
;Handle locks at scheduler level
; UPD ID= 846, SNARK:<5.MONITOR>NSPSRV.MAC.17, 6-Aug-80 17:32:48 by MURPHY
;ULOKLL again
; UPD ID= 845, SNARK:<5.MONITOR>NSPSRV.MAC.16, 6-Aug-80 14:25:32 by MURPHY
;BUGCHK at ULOKLL if lock not already locked; make few more routines resident
; UPD ID= 820, SNARK:<5.MONITOR>NSPSRV.MAC.15, 1-Aug-80 13:21:31 by GRANT
;TCO 5.1119 - Fix cause of "overly OKINT" BUGCHKs when DN20 gets reloaded
; UPD ID= 790, SNARK:<5.MONITOR>NSPSRV.MAC.14, 23-Jul-80 20:13:13 by MURPHY
;MORE OF THE SAME
; UPD ID= 777, SNARK:<5.MONITOR>NSPSRV.MAC.13, 22-Jul-80 17:07:09 by MURPHY
;MAKE A FEW ROUTINES GLOBAL
; UPD ID= 753, SNARK:<5.MONITOR>NSPSRV.MAC.12, 11-Jul-80 17:05:41 by MURPHY
;MAKE VARIOUS THINGS RESIDENT WITH VIEW TOWARD MAKING THEM RUN AT SKED LEVEL
; UPD ID= 623, SNARK:<5.MONITOR>NSPSRV.MAC.11, 11-Jun-80 11:06:36 by GRANT
;Wrong AC being loaded in PRUNE
; UPD ID= 621, SNARK:<5.MONITOR>NSPSRV.MAC.10, 10-Jun-80 13:23:07 by MURPHY
; UPD ID= 606, SNARK:<5.MONITOR>NSPSRV.MAC.9, 5-Jun-80 10:23:04 by GRANT
;More of UPD ID= 330
; UPD ID= 605, SNARK:<5.MONITOR>NSPSRV.MAC.8, 5-Jun-80 08:40:19 by ENGEL
;MAKE ASCIIZ RESIDENT
; UPD ID= 593, SNARK:<5.MONITOR>NSPSRV.MAC.7, 3-Jun-80 09:44:15 by ENGEL
;MAKE NODINI RESIDENT
; UPD ID= 590, SNARK:<5.MONITOR>NSPSRV.MAC.6, 3-Jun-80 09:03:33 by ENGEL
;FIX ONEBYT
; UPD ID= 588, SNARK:<5.MONITOR>NSPSRV.MAC.5, 2-Jun-80 17:24:28 by ENGEL
;MAKE PORTIONS OF NODINI CODE RESIDENT
; UPD ID= 502, SNARK:<5.MONITOR>NSPSRV.MAC.4, 1-May-80 15:02:52 by GRANT
;TCO 5.1031 - Make CI processing distinguish between busy and non-existent
; UPD ID= 477, SNARK:<5.MONITOR>NSPSRV.MAC.3, 24-Apr-80 16:52:51 by GRANT
;In DEDMCB, use DCN instead of DTEN for valid port number test -
;DTEN won't work on the 2020
; UPD ID= 455, SNARK:<5.MONITOR>NSPSRV.MAC.2, 22-Apr-80 14:02:03 by MURPHY
;FIX UP ENTRY SEQUENCE IN INFERIOR FORK
; UPD ID= 351, SNARK:<4.1.MONITOR>NSPSRV.MAC.421, 25-Mar-80 08:58:26 by GRANT
;Undo the previous edit
; UPD ID= 339, SNARK:<4.1.MONITOR>NSPSRV.MAC.420, 17-Mar-80 18:11:26 by GRANT
;At OUTRR7, don't include SEGNUM bytes in MSDTC count
; UPD ID= 330, SNARK:<4.1.MONITOR>NSPSRV.MAC.419, 14-Mar-80 09:58:02 by GRANT
;In STRSAV, reverse the search order of the DTEs when looking for the MCB
; UPD ID= 226, SNARK:<4.1.MONITOR>NSPSRV.MAC.418, 25-Jan-80 13:30:56 by GRANT
;TCO 4.2599 - DEDMCB should not clear the loopback word
; UPD ID= 190, SNARK:<4.1.MONITOR>NSPSRV.MAC.417, 8-Jan-80 13:34:55 by GRANT
;Fix DTE range check in DEDMCB
; UPD ID= 124, SNARK:<4.1.MONITOR>NSPSRV.MAC.416, 10-Dec-79 15:40:10 by GRANT
;Fix typeo in UPD ID=100 in MOVSEG
; UPD ID= 114, SNARK:<4.1.MONITOR>NSPSRV.MAC.415, 8-Dec-79 13:09:40 by MILLER
;FIX BUGS IN NETINP AND NETSQI.
; UPD ID= 100, SNARK:<4.1.MONITOR>NSPSRV.MAC.413, 5-Dec-79 17:20:06 by MILLER
;REPLACE MISSING CODE IN MOVSEG. FIX ANCIENT RACE BETWEEN MOVSEG AND
; THE SCHEDULER
; UPD ID= 85, SNARK:<4.1.MONITOR>NSPSRV.MAC.412, 3-Dec-79 15:06:50 by GRANT
;TCO 4.2588 - Change CCMSG: and DCMSG: to be compatible with Phase III
;<4.MONITOR>NSPSRV.MAC.411, 20-Nov-79 11:40:56, EDIT BY GRANT
;Previous edit lines removed
;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,1979 BY DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.
SEARCH NSPPAR,PROLOG,PROKL
TTITLE (NSPSRV,,< - Network Services Protocol Interface to TOPS20 >)
;THIS MODULE CONTAINS THE CONTROL ROUTINES AND JSYS INTERFACES
;FOR THE HOST-TO-HOST PROTOCOL OF DECNET KNOWN AS NSP.
;NSP ALLOWS COMMUNICATION BETWEEN PROCESSES ON HOSTS BY MEANS
;OF LOGICAL LINKS. A LOGICAL LINK IMPLIES AN "OBJECT" ON ONE
;OF THE HOSTS AND A PROCESS ON ANOTHER HOST WISHING TO AVAIL ITSELF
;OF THE OBJECT'S SERVICES, A PHYSICAL COMMUNICATIONS PATH BETWEEN
;THE HOSTS WHICH IS ERROR-FREE( SEE DDCMP SPECIFICATION FOR THE
;MAGIC BEHIND THIS ASSUMPTION), AND A TON OF LOGIC IN EACH OF
;THE HOSTS AND IN THE INTERVENING MCB NODES (IF ANY) WHICH ROUTE
;AND CONTROL THE FLOW OF THE DATA. THIS MODULE IS RESPONSIBLE
;FOR COMMUNICATING WITH ADJACENT MCB NODES AND FOR MAINTAINING AND
;ESTABLISHING LOGICAL LINKS ON DEMAND OF PROCESSES IN THIS TOPS20
;HOST OR OF PROCESSES IN THE NETWORK.
;THIS MODULE CONTROLS, ALLOCATES, AND DEALLOCATES ENTRIES
;IN THE LOGICAL LINK TABLE. AN ENTRY IN THE LOGICAL LINK TABLE
;CONTAINS INFORMATION NEEDED BY NSPSRV TO PROPERLY MANAGE
;THE LINK. THE INFORMTION IS FALLS INTO ONE OF TWO CLASSES:
;LOGICAL PARAMETERS AND PROCESS PARAMETERS. AMONG THE LOGICAL
;LINK PARAMETERS ARE: CURRENT LINK STATE, BUFFER COUNTS, FLOW
;CONTROL OPTIONS, AND SEGEMENT NUMBERS. AMONG THE PROCESS
;PARAMETERS ARE: PI CHANNELS FOR VARIOUS EVENTS, OWNING FORK,
;WINDOW PAGE BYTE COUNTS
;THE LINK TABLE IS STORED AS A BINARY TREE. ENTRIES ARE LINKED IN
;THE TREE IN ORDER BY LINK NUMBER, AND THE SEARCH ALGORTIHM INSURES
;THAT A LINK CAN BE LOCATED IN LOG(2) OF THE NUMBER OF ENTRIES.
;WITHIN THE LOGICAL LINK TABLE ARE ENTRIES WHICH REPRESENT
;"LISTENING" OBJECTS. THESE ARE PROCESSES WHICH HAVE DECLARED THEIR
;INTEREST IN PARTICIPATING IN A DIALOGUE, BUT NO NETWORK ENTITY HAS
;ATTEMPTED AS YET TO CONNECT TO THE OBJECT. UPON RECEIPT OF A
;CONNECT-INITIATE, THE LOGICAL LINK TABLE IS SEARCHED FOR A LISTENING
;OBJECT WHICH COORESPONDS TO THE REQUIREMENTS OF THE CONNECTOR. THIS
;SEARCH IS,UNFORTUNATELY, EXHAUSTIVE AND MAY REQUIRE A CONSIDERABLE
;AMOUNT OF TIME.
;MESSAGES ARE STORED IN MONITOR RESIDENT FREE SPACE. EACH MESSAGE
;HAS A HEADER ON IT OF THE FORM:
; POINTER TO NEXT MESSAGE IN THE CHAIN
; DTE#, FLAGS, SEG #, LOGICAL LINK ADDRESS OF OWNING LINK
; MESSAGE FLAGS, # OF DATA BYTES, TOTAL # OF BYTES
; BYTE POINTER TO DATA BYTES (EXCLUDES NSP HEADER)
;THIS MODULE ALSO CONTAINS ROUTINES FOR PARSING AND VERIFYING NETWORK
;FILE SPECS. A FILE SPEC IS OF THE FORM:
;DCN:HOST-OBJECT-DESCRIPTOR.TASKNAME;ATTRIBUTES
; TO MAKE A CONNECTION, OR:
;SRV:OBJECT-DESCRIPTOR.TASKNAME
; TO DECLARE A SERVER
NSPSW==0 ;SWITCH FOR LOGICAL LINK BLOCK VERIFYING
LLSIGN==101010 ;THE VERIFICATION SYMBOL
;DEFINE LOCAL MACROS
DEFINE LLLOCK<
CALL LOKLL> ;;GO LOCK UP THE TREE
DEFINE LLLULK<
CALL ULOKLL> ;;GO UNLOCK THE TREE
DEFINE ATTENT (VALUE,BIN,COUNT,EXCLU)<
<BIN>B0+<COUNT>B17+EXCLU*1000+VALUE>
DEFSTR (NTATR,,35,9)
DEFSTR (NTATC,,17,6)
DEFSTR (NTATE,,26,9)
DEFSTR (NTATB,,0,1)
DEFAC (STS,P1)
DEFAC (JFN,P2)
DEFAC (DEV,P4)
DEFAC (F1,P5)
RS NSLDWS,1 ;LOCAL DELAY WEIGHT SETTING
NR NSLDFS,1 ;LOCAL DELAY FACTOR SETTING
NR NSTRYS,1 ;RETRANSMIT COUNT SETTING
SUBTTL Device Dispatch Vectors for SRV: and DCN: Devices
;FOR DEVICE SRV
SWAPCD
SRVDTB::DTBDSP (NETDIR) ;DIRECTORY SET
DTBDSP (SRNSET) ;NAME LOOKUP
DTBDSP (EXTSET) ;EXTENSION LOOKUP
DTBDSP (VERSET) ;VERSION LOOKUP
DTBBAD (DESX9) ;NO PROTECTION
DTBBAD (DESX9) ;NO ACCOUNT
DTBBAD (DESX9) ;NO STATUS
DTBDSP (SRCOPN) ;OPEN
DTBDSP (NETSQI) ;INPUT
DTBDSP (NETSQO) ;OUTPUT
DTBDSP (NETCLZ) ;CLOSE
REPEAT 7,<
DTBBAD (DESX9)> ;ILLEGAL FUNCTIONS
DTBDSP (NTMTOP) ;MTOPR
REPEAT 2,<DTBBAD (DESX9)> ;ILLEGAL FUNCTIONS
DTBDSP (NETSQR) ;SOUTR
DTBDSP (RFTADN) ;NO TIME AND DATE
DTBDSP (RFTADN) ;NO TIME AND DATE
DTBDSP (NETINP) ;SET FOR INPUT
DTBDSP (NETOUP) ;SET FOR OUTPUT
DTBBAD (GJFX49) ;NO ATTRIBUTES
;FOR THE DCN DEVICE
DCNDTB::DTBDSP (NETDIR) ;DIR SET
DTBDSP (DCNSET) ;NAME LOOKUP
DTBDSP (EXTSET) ;EXTENSION LOOKUP
DTBDSP (VERSET) ;VERSION LOOKUP
REPEAT 3,<
DTBBAD (DESX9)> ;ILLEGAL FUNCTIONS
DTBDSP (DCNOPN) ;OPEN
DTBDSP (NETSQI) ;INPUT
DTBDSP (NETSQO) ;OUTPUT
DTBDSP (NETCLZ) ;CLOSE
REPEAT 7,<
DTBBAD (DESX9)> ;ILLEGAL FUNCTIONS
DTBDSP (NTMTOP) ;MTOPR
REPEAT 2,<DTBBAD (DESX9)> ;ILLEGAL FUNCITONS
DTBDSP (NETSQR) ;SOUTR
DTBDSP (RFTADN) ;NO TIME AND DATE
DTBDSP (SFTADN) ;NO TIME AND DATE
DTBDSP (NETINP) ;SET FOR INPUT
DTBDSP (NETOUP) ;SET FOR OUTPUT
DTBDSP (NETATR) ;PARSE ATTRIBUTES
SUBTTL GTJFN Routines
;ROUTINES CALLED FROM GTJFN PROCESSING TO LOOK UP FILE NAMES
;NAME LOOKUP FOR SRC DEVICE
SRNSET::JUMPE T1,[RETBAD (GJFX18,<OKINT>)] ;CANT'T STEP IT
CALL [ TRVAR <NTCNT,NTPNT,NTOBJ,NTDDSC,NTDSS>
CALL SRCNAM ;GO PARSE THE NAME
RETBAD() ;HAD AS ERROR
RETSKP] ;GOOD
RETBAD () ;FAILED
OKRET: TQNE <UNLKF> ;WANT TO UNLOCK?
JRST SK2RET ;NO. RETURN
OKINT ;YES. GO OKINT THEN
JRST SK2RET ;AND RETURN
;ROUTINE TO DO NAME LOOKUP FOR DCN DEVICE
DCNSET::JUMPE T1,[RETBAD (GJFX18,<OKINT>)] ;CANT'T STEP IT
CALL [ TRVAR <NTCNT,NTPNT,NTOBJ,NTDSC,NTDSS,NTHST,NTHSC>
CALL DCNNAM ;GO PARSE NAME
RETBAD() ;SOME SORT OF ERROR
RETSKP] ;GOOD
RETBAD () ;SOME SORT OF FAILURE
JRST OKRET ;AND DONE
;EXTENSION CHECKER
EXTSET::JUMPE T1,[RETBAD (GJFX18,<OKINT>)] ;CANT'T STEP IT
CALL [ TRVAR <NTCNT,NTPNT>
CALL NETEXT ;CHECK EXTENSION
RETBAD() ;SOME SORT OF ERROR
RETSKP] ;AND DONE
RETBAD () ;SOME SORT OF FAILURE
JRST OKRET ;AND DONE
;ROUTINE TO LOOK UP DIRECTORY COMPONENT IN NETWORK FILE SPEC
NETDIR::TQNE <STEPF> ;WANT TO STEP?
RETBAD (GJFX17) ;YES. CAN'T DO IT
NOINT ;PREVENT INTS
JRST SK2RET ;AND SAY IT IS SET
;VERSION LOOKUP
VERSET::TQNN <STEPF> ;TRYING TO STEP?
JRST OKRET ;NO. ALLOW IT THEN
JUMPGE T1,OKRET ;IF NOT STEPPING, OKAY
RETBAD (GJFX18,<OKINT>) ;ALL ELSE IS WRONG
;ROUTINE TO ASSIGN WINDOW PAGES TO A JFN.
;ACCEPTS: NORMAL FILE SYSTEM REGISTER (JFN,ETC...)
;RETURNS: +1 FAILED
; +2 SUCCESS.
ASGWDW::SETZM FILWND(JFN)
SETZM FILBCT(JFN) ;AND CLEAR COUNTS
TQNN <READF> ;WANT READ ON THIS FILE?
JRST ASGWRT ;NO. TRY WRITE
CALL ASGPAG ;GET A JSB PAGE
RETBAD (MONX02) ;COULDN'T
HRRM T1,FILWND(JFN) ;SAVE WINDOW PAGE
LDB T3,PBYTSZ ;GET BYTE SIZE
CALL MAKINP ;GET A POINTER FOR INPUT
MOVEM T1,FILBFI(JFN) ;INIT INPUT POINTER
ASGWRT: TQNN <WRTF> ;WANT WRITE
RETSKP ;NO ALL DONE
CALL ASGPAG ;GET A PAGE FOR OUTPUT
JRST [ SKIPE T1,FILWND(JFN) ;FAILED. HAVE READ WINDOW?
CALL RELPAG ;RELEASE THE INPUT PAGE
SETZM FILWND(JFN) ;NOTE NO PAGE WAS ASSIGNED
SETZM FILBFI(JFN) ;PREVENT RELEASE OF FREE SPACE BY RLJFN
RETBAD (MONX02)] ;AND FAIL
HRLM T1,FILWND(JFN) ;STORE WINDOW
RETSKP ;AND DONE
;ROUTINE TO COMPUTE NUMBER OF USEFUL BYTES IN A JSB STRING.
;CALLED FROM ROUTINES THAT PROCESS NETWORK FILE NAMES.
;ACCEPTS: T1/FREE BLOCK ADDRESS
; TRVAR <NTCNT,NTPNT,.....>
;RETURNS: +1 ALWAYS WITH COUNT IN NTCNT AND POINTER IN NTPNT
COMPUT: HRRZ T3,0(T1) ;GET COUNT OF WORDS IN BLOCK
SOS T3 ;DISCOUNT THE HEADER
IMULI T3,5 ;GET BYTE COUNT
AOS T3 ;ADD IN FINAL TERMINATOR
HRLI T1,(<POINT 7,0,35>) ;GET STRING POINTER TO THE BLOCK
MOVEM T1,NTPNT ;AND SAVE THE STARTING POINTER
CALL CMPLEN ;GET LENGTH OF STRING
MOVEM T3,NTCNT ;SAVE COUNT
RET ;DONE, RETURN
;CMPLEN - ROUTINE TO COMPUTE LENGTH OF STRINGS
;
;ACCEPTS IN T1/ POINTER TO START OF STRING
; T3/ MAX NUMBER OF BYTES IN STRING
; CALL CMPLEN
;RETURNS: +1 ALWAYS, WITH T3/ ACTUAL NUMBER OF BYTES IN STRING
CMPLEN::STKVAR <CPLCNT>
MOVEM T3,CPLCNT ;STARTING COUNT
MOVE T2,[POINT 0,0,2] ;GET DUMMY POINTER
SETZ T4,
SIN ;FIND NUMBER OF USEFUL BYTES IN THE STRING
JUMPE T3,R ;IF NO NULLS, ALL SET
SUB T3,CPLCNT ;FOUND A NULL THEN. GET CHARACTERS SKIPPED
MOVNS T3 ;GET COUNT
RET ;AND DONE
;ROUTINE TO SCAN NAME STRING FOR NETWORK PUNCTUATION CHARACTER AND
;UPDATE COUNTS.
;ACCEPTS: IN TRVAR'S
; NTPNT CURRENT TEXT POINTER
; NTCNT CURRENT BYTE COUNT
;RETURNS:
; NTPNT UPDATED POINTER
; NTCNT UPDATED COUNT
; T1/ ORIGINAL POINTER
; T3/ NUMBER OF CHARCTERS FOUND BEFORE PUNCTUATION
NETDSH: MOVE T1,NTPNT ;GET BYTE POINTER
MOVE T2,[POINT 0,0,2] ;DUMMY
MOVE T3,NTCNT ;THE COUNT
MOVEI T4,"-" ;STOP ON THE END OF THE HOST FIELD
SIN ;GET IT
EXCH T1,NTPNT ;STORE NEW POINTER. GET OLD
EXCH T3,NTCNT ;STORE NEW COUNT. GET OLD COUNT
SUB T3,NTCNT ;GET BYTES TRANSPIRED
RET ;AND DONE
;ROUTINE TO PARSE THE NAME FIELD OF A SOURCE SPECIFICATION.
;A NAME FIELD LOOKS LIKE:
; OBJECT-DESCRIPTOR
;OR
; -
;WHERE THE FORMER IS THE SYNTAX FOR A GENERIC OBJECT
;AND THE LATTER IS THE SYNTAX FOR A TASK ONLY
;ACCEPTS:
; T1/ POINTER TO NAME BLOCK
; TRVAR <NTCNT,NTPNT,NTOBJ,NTDSC,NTDSS>
;RETURNS:
; +1 SYNTAX OR SEMANTICS ERROR. CODE IN T1
; +2 ACCEPTABLE NAME.
; WITH TRVAR'S FILLED IN
SRCNAM::CALL COMPUT ;COMPUTE STRING COUNT
SETOM NTOBJ ;ASSUME NO OBJECT
CALL NETDSH ;GO FIND OBJECT NAME
CAIG T3,1 ;WAS IT NULL?
JRST SRCNOB ;YES. NO GENERIC OBJECT GIVEN
LDB T4,NTPNT ;GET TERMINATOR
MOVEM T4,NTOBJ ;SAVE IT
SETZ T4, ;GET A NULL
DPB T4,NTPNT ;TIE OFF OBJECT NAME
CALL OBJLOK ;GO LOOK UP THE OBJECT
RETBAD (DCNX3) ;NO SUCH OBJECT. COMPLAIN
SKIPG T1 ;A LEGAL OBJECT TYPE?
RETBAD (DCNX3) ;NO. COMPLAIN
CAIG T1,DECOBJ ;IS IT A DEC RESERVED OBJECT?
JRST [ MOVX T3,SC%WHL!SC%OPR ;YES. MUST BE PRIVILEGED THEN
TDNE T3,CAPENB ;IS IT ENABLED?
JRST .+1 ;YES. PROCEED
RETBAD (DCNX3)] ;NO. ERROR
EXCH T1,NTOBJ ;SAVE GENERIC OBJECT TYPE
DPB T1,NTPNT ;AND PUT BACK TERMINATOR
SRCNOB: SETZM NTDSC ;ASSUME NO DESCRIPTOR
SKIPE T3,NTCNT ;ANY BYTES LEFT IN STRING?
CAIG T3,1 ;YES. ENOUGH TO MAKE A DESCRIPTOR?
RETSKP ;NO ALL DONE THEN
MOVEM T3,NTDSC ;STORE COUNT OF DESCRIPTOR
SKIPGE NTOBJ ;HAVE AN OBJECT?
RETBAD (DCNX3) ;NO. ILLEGAL SPECIFICATION
CAILE T3,MAXDSC ;WITHIN RANGE?
RETBAD (DCNX12) ;NO.ILLEGAL DESCRIPTOR
MOVE T1,NTPNT ;GET POINTER
MOVEM T1,NTDSS ;SAVE BEGINNING OF DESCRIPTOR
RETSKP ;AND DONE
;ROUTINE TO PARSE NAME FOR A CONNECT ATTEMPT.
;AACEPTS: T1/ BLOCK ADDRESS OF NAME
; TRVAR <NTCNT,NTPNT,NTOBJ,NTDSC,NTDSS,NTHST,NTHSC>
;RETURNS:
; +1 SYNTAX ERROR
; +2 NAME IS GOOD. TRVAR'S FILLED IN
DCNNAM::CALL COMPUT ;FIND COUNT
CALLRET PRSNAM ;GO PARSE NAME FIELD
;PRSNAM - ROUTINE TO DO THE PARSING OF THE NAME
;
;ACCEPTS: IN TRVAR'S
; NTPNT CURRENT TEXT POINTER
; NTCNT CURRENT BYTE COUNT
; CALL PRSNAM
;RETURNS: +1 FAILED, SYNTAX ERROR
; +2 SUCCESS, WITH APPROPRIATE TRVARS FILLED IN
PRSNAM::CALL NETDSH ;GO PICK OFF HOST NAME
SKIPN NTCNT ;MORE IN THE STRING?
RETBAD (DCNX1) ;NO. SYNTAX ERROR THEN
SETOM NTHSC ;ASSUME LOCAL CONNECTION
SOSG T3 ;HAVE A REAL STRING?
JRST DCNOBJ ;NO. GO LOOK FOR OBJECT THEN
CAILE T3,MAXHST ;WITHIN BOUNDS?
RETBAD (COMX19) ;NO. STRING TOO LONG
MOVEM T1,NTHST ;SAVE POINTER TO HOST
MOVEM T3,NTHSC ;AND SAVE COUNT
AOS T1 ;POINT TO THE ACTUAL TEXT
HRLI T1,440700 ;MAKE A BYTE POINTER FOR PARSING
MOVE T2,T3 ;GET NODE NAME CHARACTER COUNT
CALL PARNO1 ;SEE IF VALID NODE NAME SYNTAX
RETBAD () ;INVALID NODE NAME - RETURN THE ERROR
DCNOBJ: CALL NETDSH ;GO FIND OBJECT
CAIG T3,1 ;HAVE A REAL STRING?
RETBAD (DCNX3) ;NO. INVALID OBJECT THEN
LDB T4,NTPNT ;GET BACK TERMINATOR
MOVEM T4,NTOBJ ;SAVE IT
SETZ T4, ;GET A NULL
DPB T4,NTPNT ;TIE OFF STRING
CALL OBJLOK ;GO LOOK UP THE OBJECT
RETBAD (DCNX3) ;NO SUCH
EXCH T1,NTOBJ ;SAVE OBJECT
DPB T1,NTPNT ;AND PUT BACK TERMINATOR
JRST SRCNOB ;FINISH UP ON DESCRIPTOR
;ROUTINE TO PARSE EXTENSION. THIS FIELD WILL BE THE TASKNAME
NETEXT: CALL COMPUT ;GET COUNT
MOVE T1,NTCNT ;GET THE COMPUTED COUNT
CAILE T1,TSKMAX ;WITHING RANGE
RETBAD (DCNX12) ;NO. TOO LONG
RETSKP ;AND DONE
SUBTTL Routines to open DCN: or SRV: links
;COMMON ROUTINE FOR OPENF JSYS. THIS CODE IS CALLED BY BOTH SRCOPN
;AND DCNOPN TO ASSIGN A LL BLOCK, ASSIGN A LL ADDRESS, AND FILL
;IN COMMON VALUES.
; RETURNS +1 FAILED. T1/ ERROR CODE
; +2 SUCCESS T1/ LL BLOCK ADDRESS
; AND LL TREE LOCKED
OPNDNC::TDZA T4,T4 ;NOTE OPENING DCN:
OPNSRC::SETOM T4 ;NOTE OPENING SRV:
TQZE <RNDF> ;WANT APPEND?
TQO <WRTF> ;YES. FORCE ON WRITE THEN
TQNN <READF,WRTF> ;WANT SOME FORM OF ACCESS?
RETBAD (OPNX14) ;NO. ILLEGAL OPEN
LDB T2,PBYTSZ ;LOOK AT REQUESTED BYTE SIZE
CAIE T2,10 ;BYTES?
CAIN T2,7 ;OR ASCII?
JRST BYTGUD ;YES. ACCEPTS IT
CAIE T2,44 ;-10 WORD MODE?
RETBAD (SFBSX2) ;NO. ILLEGAL BYTE SIZE
BYTGUD: HRRZ T1,FILNEN(JFN) ;GET ADDRESS OF STRING BLOCK
ADDI T1,1 ;GET ADDRESS OF STRING
LDB T2,PBYTSZ ;GET BYTESIZE OF OPENF
SKIPE T4 ;OPENING DCN: ?
JRST [ CALL OPNSWK ;NO, CALL WORK ROUTINE TO OPEN SRV:
RETBAD () ;FAILED, RETURN ERROR CODE
JRST SAVLLB ] ;GO SAVE LL BLOCK ADDRESS IN JFN BLOCK
CALL OPNDWK ;CALL WORK ROUTINE TO OPEN DCN:
RETBAD () ;FAILED, RETURN ERROR CODE
SAVLLB: MOVEM T1,FILLLB(JFN) ;SAVE BLOCK ADDRESS
IFN NSPSW,<
MOVEI T2,LLSIGN ;GET LL BLOCK UNIQUE INDICATOR
MOVEM T2,LLMSG(T1) ;PUT IT IN BLOCK (LLMSG IS NOT USED BY 5.1)
>
TQNE <READF> ;WANT BI-DIRECTIONAL LINK?
CALL SETOPI ;SET INPUT FLAG FOR LOGICAL LINK
TQNE <WRTF> ;WANT WRITE?
CALL SETOPW ;SET OUTPUT FLAG FOR LOGICAL LINK
CALL STMXDF ;SET INPUT/OUTPUT MAX QUEUE DEFAULTS
RETSKP ;AND DONE
;STMXDF - SET MAX INPUT/OUTPUT QUEUE DEFAULTS
;
;ACCEPTS: T1/ ADDRESS OF LOGICAL LINK BLOCK
;
;RETURNS: +1,ALWAYS
;
;DESTROYS T2
STMXDF::MOVEI T2,MAXSEG ;ASSUME READ ONLY
OPSTR <SKIPE>,LLOPW,(T1) ;OPEN FOR WRITE AS WELL?
MOVEI T2,MAXSG1 ;YES. USE A SMALLER NUMBER
STOR T2,LLMQI,(T1) ;SAVE THE INPUT QUEUE LENGTH (ALSO FLOW CONTROL)
MOVEI T2,MAXSGQ ;SET OUTPUT QUEUE LENGTH
STOR T2,LLMQO,(T1) ;SAVE IN LINK BLOCK
RET
;VERIFY A LOGICAL LINK BLOCK
;ACCEPTS: T1/ LL BLOCK ADDRESS
;RETURNS: +1 PASSED THE TEST
IFN NSPSW,<
CHKLLB: PUSH P,T2 ;PRESERVE T2
MOVE T2,LLMSG(T1) ;GET THE VERIFICATION WORD
CAIE T2,LLSIGN ;IS IT GOOD?
JSR BUGHLT ;NO, TOO BAD
POP P,T2 ;OK, RETRIEVE T2
RET ;YES
>
;ROUTINE CALLED FROM THE OPENF JSYS TO OPEN A DCN NETWORK CONNECTION
DCNOPN::TRVAR <NTCNT,NTPNT,NTOBJ,NTDSC,NTDSS,NTHST,NTHSC,NTCIB>
GTOKM (.GODNA,,[RET]) ;ASK ACJ TO GIVE ITS BLESSING
HLRZ T1,FILNEN(JFN) ;GET NAME FOR THE CONNECTION
CALL DCNNAM ;GO PARSE THE NAME FIELD
RETBAD () ;FAILED
CALL OPNDNC ;GO DO COMMON SETUP
RETBAD () ;FAILED
CALL ASGWDW ;NOW SET UP WINDOWS
RETBAD (,<CALL CLENUP>) ;FAILED, RETURN ERROR
MOVE T1,FILLLB(JFN) ;GET ADDRESS OF LOGICAL LINK BLOCK
HRL T2,NTHSC ;GET COUNT OF HOST STRING BYTES
HRR T2,NTDSC ;GET COUNT OF DESCRIPTOR STRING BYTES
MOVE T3,NTHST ;GET ADDRESS OF BLOCK HOLDING HOST NAME STRING
MOVE T4,NTDSS ;GET POINTER TO DESCRIPTOR STRING
CALL STRSAV ;GO MOVE PERMANENT LL STRINGS
RETBAD (,<CALL CLENUP>) ;FAILED, RETURN ERROR
MOVE T1,FILLLB(JFN) ;GET LOGICAL LINK BLOCK ADDRESS
LOAD T2,FILATL,(JFN) ;GET POINTER TO ATTRIBUTE LIST
HRL T3,NTOBJ ;GET OBJECT
HRR T3,NTDSC ;GET DESCRIPTOR COUNT
MOVE T4,NTDSS ;GET DESCRIPTOR POINTER
CALL CRTLNK ;GO CREATE THE LOGICAL LINK
RETBAD (,<CALL CLENUP>) ;FAILED
RETSKP ;DONE, RETURN SUCCESS
;CLENUP - ROUTINE TO CLEAN UP JFN BLOCK IF OPEN OF DCN: FAILS
;
;ACCEPTS IN JFN/ OFFSET TO JFN BLOCK
; CALL CLENUP
;RETURNS: +1 ALWAYS
CLENUP: STKVAR <CLNERR>
MOVEM T1,CLNERR ;SAVE ERROR CODE
DECR DCCUR ;ONE LESS LINK ON FAILURE
MOVE T1,FILLLB(JFN) ;GET ADDRESS OF LOGICAL LINK BLOCK
CALL DELNOD ;FREE THE NODE
HLRZ T1,FILWND(JFN) ;GET WINDOW PAGE ADDRESS
SKIPE T1 ;ANY WINDOW PAGE ASSIGNED YET ?
CALL RELPAG ;YES, RELEASE IT
HRRZ T1,FILWND(JFN) ;GET OTHER WINDOW PAGE
SKIPE T1 ;ANY ASSIGNED ?
CALL RELPAG ;YES, RELEASE IT ALSO
SETZM FILBFI(JFN) ;PREVENT RELEASE OF SPACE BY RLJFN
CALL ULOKLL ;UNLOCK THE LL TREE
MOVE T1,CLNERR ;RESTORE ERROR CODE
RET
SUBTTL MTOPR Routines
NTMTOP: TQNN <OPNF> ;CHECK FOR OPENED
RETBAD (CLSX1) ;NO IT IS ILLEGAL
CALL NETINP ;SET UP FOR INPUT
MOVE T1,FILLLB(JFN) ;MUST LOCK UP BLOCK
CALL BLKLLK ;DO IT
JRST [ TQO BLKF ;CANNOT LOCK IT, INDICATE BLOCK NEEDED
RET ] ;RETURN AND TRY AGAIN LATER
XCTU [HRRZ T2,2] ;GET FUNCTION CODE
MOVSI T3,-NTMTCT ;SCAN TABLE FOR THE FUNCTION
NTMTO1: HLRZ T4,NTMTTB(T3) ;GET NEXT ENTRY
CAIN T2,0(T4) ;IS THIS IT?
JRST [ HRRZ T2,NTMTTB(T3) ;GET DISPATCH ADDRESS
JRST 0(T2)] ;AND GO DO IT
AOBJN T3,NTMTO1 ;DO ENTIRE TABLE
MOVE T1,FILLLB(JFN) ;GET LOGICAL LINK BLOCK ADDRESS
CALL BLKULK ;UNLOCK THE BLOCK
RETBAD (MTOX1) ;FAIL
NTMTTB: .MOACN,,MTASGN ;SET CONNECT INTERRUPT
.MORLS,,NTSTS ;READ LINK STATUS
.MORHN,,NTRHN ;READ FOREIGN HOST NAME
.MORTN,,NTRTN ;READ LINK TASK NAME
.MORUS,,NTRUS ;READ USER STRING
.MORPW,,NTRPW ;READ PASSWORD
.MORAC,,NTRAC ;READ ACCOUNT STRING
.MORDA,,NTRDA ;READ OPTIONAL DATA
.MORIM,,MTRDIN ;READ INT MESSAGE
.MOSIM,,MTSNIN ;SEND INT MESSAGE
.MOROD,,NTRCOB ;READ OBJ-DESC OF CONNECT OBJECT
.MOCLZ,,NTMTCZ ;CLOSE/REJECT A CONNECTION
.MOCC,,NTACPT ;ACCEPT A CONNECTION
.MORCN,,NTRCN ;READ CONNECT OBJECT NUMBER
.MORSS,,MTGSS ;GET LINK SEGMENT SIZE
.MOANT,,NTANT ;ATTACH NETWORK TERMINAL
.MOSNH,,NTSNH ;SET NETWORK HOST FOR TERMINAL
NTMTCT==.-NTMTTB ;LENGTH OF TABLE
;ATTACH NETWORK TERMINAL TO JOB
; JFN, etc. setup by .MTOPR entry code
;returns with LL connected to terminal and JFN released
; T2/ terminal line number assigned
NTANT: MOVE T1,FILLLB(JFN) ;GET LL BLOCK
CALL ASMCB ;ASSIGN "MCB" TERMINAL AND CONNECT TO LL
IFNSK. ;COULDN'T
MOVE T1,FILLLB(JFN) ;RETRIEVE LL BLOCK
CALL BLKULK ;RELEASE THE LOCK
RETBAD (ANTX01) ;RETURN ERROR
ENDIF.
UMOVEM T1,T2
SETZ T1,
EXCH T1,FILLLB(JFN) ;DISASSOCIATE JFN FROM LL
SETONE LLFRK,(T1) ;NO FORK
SETZRO <LLDRC,LLPII,LLPIC>,(T1) ;NO INTERRUPTS
CALL BLKULK ;UNLOCK LL
HLRZ T1,FILWND(JFN) ;GET OUTPUT WINDOW
SKIPE T1
CALL RELPAG ;RELEASE IT
HRRZ T1,FILWND(JFN) ;GET INPUT WINDOW
SKIPE T1
CALL RELPAG ;RELEASE IT
SETZM FILBFO(JFN)
SETZM FILBFI(JFN)
CALL RELJFN
RETSKP
;SET NETWORK HOST
; T1/ JFN of LL (JFN, STS, etc setup at .MTOPR entry)
; T2/ ptr to arg block:
; 0 - size in words (including this one)
; 1 .SHTTY - terminal ident
; 2 .SHESC - flags,,escape char
; returns with line connected to LL, JFN unchanged
NTSNH: SAVEAC <Q1>
UMOVE Q1,T3 ;GET ARG PTR
UMOVE T1,.SHTTY(Q1)
CALL [ SAVEAC <JFN,STS,DEV> ;KEEP THESE FOR ORIGINAL JFN
CALLRET CHKTTM] ;GET LINE NUMBER IN T2
IFNSK. ;COULDN'T
MOVE T1,FILLLB(JFN) ;RETRIEVE LL BLOCK
CALL BLKULK ;RELEASE THE LOCK
RETBAD (ANTX01) ;RETURN ERROR
ENDIF.
MOVE T1,FILLLB(JFN)
UMOVE T3,.SHESC(Q1) ;GET ESC CHAR AND FLAGS
CALL TTSETH
IFNSK.
CALL BLKULK ;FAILED, UNLOCK LL
RETBAD()
ENDIF.
CALL BLKULK ;UNLOCK LL
RETSKP
;SET INTERRUPT CHANNEL NUMBERS
MTASGN: ACVAR <W1> ;GET A WORK REG
UMOVE W1,3 ;GET ARGUMENT
LOAD T2,MO%CDN,W1 ;GET CONNECT INTERRUPT
CALL MTSETC ;GO SET IT
JRST NTMERR ;BAD
LOAD T2,MO%INA,W1 ;GET INT CHANNEL
CALL MTSETI ;GO DO INT CHANNEL
JRST NTMERR ;BAD
LOAD T2,MO%DAV,W1 ;GET DATA CHANNEL
CALL MTSETD ;SET IT
JRST NTMERR ;BAD
CALL BLKULK ;FREE BLOCK
RETSKP ;AND DONE
; HERE ON AN ERROR SETTING THE INTERRUPT CHANNELS
NTMERR: EXCH T1,FILLLB(JFN) ;SAVE ERROR CODE, GET LL BLOCK ADDRESS
CALL BLKULK ;UNLOCK THE BLOCK
IFN NSPSW,<
CALL CHKLLB
>
EXCH T1,FILLLB(JFN) ;RESTORE LL BLOCK ADDRESS, GET ERROR CODE
RETBAD () ;FAIL
ENDAV. ;END ACVAR
;READ LINK STATUS
NTSTS: CALL RDSTS ;GO GET THE STATUS
UMOVEM T3,3 ;RETURN RESULT
CALL BLKULK ;FREE BLOCK
RETSKP ;AND DONE
;UNDO OUTPUT
NETUOU::TQZN <FILOUP> ;NOW DOING OUTPUT?
RET ;NO. ALL DONE
MOVE T1,FILLLB(JFN) ;GET LL BLOCK
CALL SKPFLO ;IS FLOW FROM THE FILE-SYSTEM ?
RET ;NO. DONE
MOVE T1,FILCNT(JFN) ;GET COUNT
SKIPGE T1
SETZM T1 ;ONLY ALLOW DOWN TO ZERO
HRLM T1,FILBCT(JFN) ;STORE NEW COUNT
MOVE T1,FILBYT(JFN) ;GET BYTE POINTER
MOVEM T1,FILBFO(JFN) ;SAVE IT
RET ;DONE
;UNDO INPUT
NETUIN::TQZN <FILINP> ;NOW DOING INPUT?
RET ;NO. ALL DONE
MOVE T1,FILLLB(JFN) ;GET LL BLOCK
CALL SKPFLI ;IS FLOW TO THE FILE-SYSTEM ?
RET ;NO. ALL DONE
MOVE T1,FILCNT(JFN) ;GET COUNT
SKIPGE T1 ;VALID COUNT?
SETZM T1 ;ONLLY ALLOW DOWN TO ZERO
HRRM T1,FILBCT(JFN) ;SAVE IT
MOVE T1,FILBYT(JFN) ;GET BYTE POINTER
MOVEM T1,FILBFI(JFN) ;SAVE IT
RET ;AND DONE
SUBTTL Sequential I/O JSYS's.
;SEQUENTIAL OUTPUT.
NETSQO: ASUBR <NETCHR> ;SAVE THE CHARACTER
MOVE T1,FILLLB(JFN) ;GET LL BLOCK ADDRESS
CALL BLKLLK ;LOCK IT UP
JRST [ TQO <BLKF> ;CANNOT LOCK IT,
RETBAD() ] ; WAIT UNTIL LOCK IS FREE
CALL GETSTA ;GO GET CURRENT LOGICAL LINK STATE
JRST @SQOSTA-1(T2) ;AND DO PROPER THING
NETSQ1::SOSGE FILCNT(JFN) ;HAVE ANY CHARACTERS?
JRST [ CALL OUTRR ;AND SEND SOME MESSAGES
RETBAD() ;FAILED
CALL NETOUP ;SET UP FOR OUTPUT
MOVE T1,FILLLB(JFN) ;GET BACK LL BLOCK
JRST NETSQ1] ;AND TRY AGAIN
MOVE T2,NETCHR ;GET BYTE
IDPB T2,FILBYT(JFN) ;STASH BYTE
CALLRET BLKULK ;RELEASE BLOCK AND RETURN
;FORCE OUT ALL BUFFERED CHARACTERS. CALLED FROM SOUTR
NETSQR: MOVE T1,FILLLB(JFN) ;GET LL BLOCK ADDRESS
CALL BLKLLK ;LOCK IT
JRST [ TQO <BLKF> ;CANNOT LOCK IT,
RETBAD() ] ; WAIT UNTIL LOCK IS FREE
CALL GETSTA ;GO GET CURRENT LOGICAL LINK STATE
JRST @SQOOTR-1(T2) ;DO WORK
NETSR1::CALL SETEOM ;NOTE THAT NEXT OUTPUT IS AN ENTIRE MESSAGE
CALL OUTRR ;DO THE WORK
RETBAD() ;FAILED
MOVE T1,FILLLB(JFN) ;GET BACK LL BLOCK
CALL BLKULK ;UNLOCK BLOCK
RETSKP ;AND RETURN GOOD
SUBTTL NSP Initialization
;NAMINI INITIALIZES NODE NAME TO "TOPS20"
RESCD
NAMINI::UNLOCK NODLOK ;INIT THE "REACHABLE NODES TABLE" LOCK
UNLOCK NMAPLK ;INIT THE "NODE NAME MAPPING TABLE" LOCK
DMOVE T1,[ASCIZ /TOPS20/] ;GET OUR DEFAULT NODE NAME
DMOVEM T1,OURNAM ;SET IT (ASSUME SETSPD HASN'T RUN YET!)
MOVEI T1,6 ;COUNT OF CHARS IN "OURNAM"
MOVEM T1,OURCNT ;STORE IT (OURNAM COPIED TO LLSR EVEN ON
;NON-DECNET SYSTEMS, AND .SJLL,
;.JILLO REFERENCE IT!)
MOVEI T1,NODNUM ;GET OUR DEFAULT NODE NUMBER
MOVEM T1,OURNUM ;SET IT
CALL ININOD ;INIT REACHABLE NODES TABLE
BUG(NDINIT)
RET
;ROUTINE TO INIT NETWORK DATA BASES,ETC.
SWAPCD ;SWAPPABLE
NSPINI::ACVAR <INDEX> ;INDEX INTO ACKLST
MOVEI INDEX,AKLSTL-1 ;GET LENGTH OF ACK LIST
NSPIN1: MOVEI T1,ACKLEN+MSHDR ;GET NUMBER OF WORDS NEEDED FOR AN ACK MSG
CALL GETRES ;GET THE SPACE
IFSKP. ;OK
MOVEM T1,ACKLST(INDEX) ;SAVE THE ADDRESS
ELSE. ;COULDN'T GET SPACE
SETZM ACKLST(INDEX) ;NO ENTRY IN LIST
ENDIF.
NSPIN2: SOJGE INDEX,NSPIN1 ;IF NOT DONE, GO GET ANOTHER
UNLOCK LLLLCK ;UNLOCK LOCK
UNLOCK OUTLOK ;INITIALIZE LOCK ON BACKGROUND TASK'S QUEUE
MOVX T1,INIWAT ;GET TIME BEFORE BLOCKED OUTPUT RETRY
MOVEM T1,OUTIVL ;SAVE DEFAULT TIME INTERVAL
CALL OBJINI ;INIT OBJECT TABLE
CALL LLINIT ;AND INIT LL ADDRESS BIT TABLE
MOVEI T1,SEGSIZ ;GET DEFAULT SEGMENT SIZE
MOVEM T1,SEGSZ ;SET IT UP
MOVEI T1,NSINTM ;GET DEFAULT INACTIVITY TIMEOUT VALUE
MOVEM T1,NSINAC ;SET IT UP
MOVEI T1,NSLDWD ;GET DEFAULT LOCAL DELAY WEIGHT
MOVEM T1,NSLDWS ;SET IT
MOVEI T1,NSLDFD ;GET DEFAULT LOCAL DELAY FACTOR
MOVEM T1,NSLDFS ;SET IT
MOVEI T1,NSTRYD ;GET DEFAULT RETRANSMIT COUNT
MOVEM T1,NSTRYS ;SET IT
SETZM LSTINT ;INIT THE INACTIVITY TIME CHECKER
MOVX T1,1B1 ;MAKE FORK HAVE ALL CAPS
SETZ T2,
CFORK ;GET A FORK
BUG (NSPFRK,<<T1,REASON>>)
MOVEI T2,TSKINI ;THE STARTING ADDRESS
MSFRK ;START IT
MOVX T2,FRKRUN ;SAY FORK IS RUNNING
IORM T2,MCBDTE ;SET FLAG
RET ;DONE
ENDAV.
; INITIALIZE TABLE OF KNOWN NODES
ININOD: NOINT ;NO INTERRUPTIONS
LOCK NODLOK ; WHILE TABLE IS LOCKED
SETZM NODTBL ;ZERO
HRLI T1,NODTBL ; THE
HRRI T1,NODTBL+1 ; ENTIRE
BLT T1,NODTBL+<BIGNOD/22> ; TABLE
UNLOCK NODLOK ;DONE WITH
OKINT ; THE LOCK
MOVE T1,OURNUM ;GET OUR NODE NUMBER
MOVX T2,.NDSON ;SAY NODE IS TO BE ADDED
MOVEI T3,2 ;WE ARE PHASE II
CALL ADDNOD ;PUT US IN
RETBAD () ;FAILED
RETSKP ;SUCCESS
;ADDNOD - ROUTINE TO ADD A NODE TO THE TABLE OF REACHABLE NODES
;
;ACCEPTS: T1/ NODE NUMBER
; T2/ STATE OF NODE
; T3/ 2 - IF DECNET PHASE II
; 3 - IF DECNET PHASE III
;
;RETURNS: +1 FAILED
; +2 SUCCESS, NODE ADDED IF NOT ALREADY IN TABLE
ADDNOD: CAIN T2,.NDSOF ;NODE OFF?
JRST [CALL REMNOD ;YES, REMOVE FROM REACHABLE NODES TABLE
RET ;FAILED
JRST ADDTEL] ;NOTIFY INTERESTED USERS OF TOPOLOGY CHANGE
NOINT ;NO INTERRUPTIONS
LOCK NODLOK ; WHILE TABLE LOCKED
MOVE T4,[POINT 2,NODTBL] ;MAKE BYTE POINTER TO TABLE
ADJBP T1,T4 ;POINT TO THE NODE BEING ADDED
DPB T3,T1 ;INSERT DECNET PHASE
UNLOCK NODLOK ;DONE WITH
OKINT ; THE LOCK
;HERE TO NOTIFY INTERESTED USERS THAT TOPOLGY HAS CHANGED
ADDTEL: MOVEI Q1,NTCTAB ;START LOOKING AT TOP OF TABLE
NTCIN1: SKIPN (Q1) ;IS THERE AN ENTRY?
JRST NTCIN2 ;NO. KEEP LOOKING.
LOAD T2,NTCFRK,(Q1) ;GET FORK NUMBER
LOAD T1,NTCCHN,(Q1) ;GET THE CHANNEL NUMBER
CALL PSIRQ ;INTERRUPT USER
NTCIN2: CAIE Q1,NTCTAB+<NTCMAX-1> ;DID WE SEARCH WHOLE TABLE?
AOJA Q1,NTCIN1 ;NO - CHECK NEXT ENTRY
RETSKP
;REMNOD - ROUTINE TO REMOVE A NODE FROM THE TABLE OF REACHABLE NODES
;
;ACCEPTS IN T1/ NODE NUMBER
;
;RETURNS: +1 FAILED
; +2 SUCCESS
REMNOD: NOINT ;NO INTERRUPTIONS
LOCK NODLOK ; WHILE TABLE LOCKED
MOVE T2,[POINT 2,NODTBL] ;MAKE BYTE POINTER TO TABLE
ADJBP T1,T2 ;POINT TO THE NODE WE WANT
SETZ T3, ;INIT TEST WORD
DPB T3,T1 ; NO LONGER REACHABLE
UNLOCK NODLOK ;DONE WITH
OKINT ; THE LOCK
RETSKP
SUBTTL Routines to Manipulate Logical Link Blocks and Object Tables
RESCD ;CALLED ONLY IN PROCESS CONTEXT
;ROUTINES USED TO LOCK AND UNLOCK LL TREE
LOKLL::
SKIPN INSKED ;SKED LEVEL?
NOINT ;PREVENT INTS
LOCK LLLLCK,<CALL LCKTST> ;LOCK UP THE TREE
RET ;DONE
ULOKLL::SKIPGE LLLLCK ;NOW LOCKED?
JRST [ BUG(LLLKBD) ;NO, CONFUSION
RET]
UNLOCK LLLLCK
SKIPN INSKED
OKINT
RET
;ROUTINES TO LOCK AND UNLOCK INDIVIDUAL LL BLOCKS
;LOCK A BLOCK.
; T1/ BLOCK ADDRESS
;RETURNS: +1 FAILED. BLOCK ROUTINE IN T1
; +2 SUCCESS
;ENTRY POINT IF LLLLCK NOT LOCKED
BLKLLK::NOINT
LOCK LLLLCK,<JRST [
MOVEI T1,LLLCKT ;BUSY, RETURN TEST
RET]>
CALL BLKLOK
CALLRET ULOKLL ;UNLOCK AND GIVE UP
CALL ULOKLL
RETSKP
;ENTRY POINT IF LLLLCK ALREADY LOCKED
BLKLOK::SAVEAC <T4> ;PRESERVE TEMP AC
REPEAT 0,<
SKIPGE LLLLCK ;*** TEMP - ENSURE OUTER LOCK ALREADY SET ***
JSR BUGHLT
SKIPE INSKED ;MAKE SURE ONLY PROPER SCHEDULER CONTEXT
SKIPGE FORKX
SKIPA
JSR BUGHLT
>;END REPEAT 0
JE LLRCT,(T1),BLKLK0 ;IF FIRST LOCKER, NO CHECKS NEEDED
LOAD T4,LLRFK,(T1) ;GET PREVIOUS LOCKER'S ID
CAME T4,FORKX ;WERE WE PREVIOUS LOCKER
JRST BLKLK1 ;NO, FAIL RETURNING SCHED TEST
BLKLK0: INCR LLRCT,(T1) ;OK TO LOCK (EITHER FIRST LOCKER OR LAST WAS US)
MOVE T4,FORKX ;GET OUR FORK ID
STOR T4,LLRFK,(T1) ;STORE OUR ID AS LAST LOCKER
SKIPN INSKED
NOINT ;PREVENT INTERRUPT WHILE BLOCK LOCKED
RETSKP ;DONE, BLOCK NOW LOCKED
; HERE IF LOCK WILL NOT BE PERMITTED - RETURN A SCHEDULER TEST
BLKLK1: LOAD T1,LLLNK,(T1) ;GET LL ADDRESS
HRLS T1 ;TO THE LH
HRRI T1,CHKLOK ;THE TEST ROUTINE
RET ;AND DONE
;UNLOCK A BLOCK
; T1/ BLOCK ADDRESS
;RETURNS: +1 ALWAYS
BLKULK::SAVEAC <T2> ;BE TRANSPARENT
LOAD T2,LLRCT,(T1) ;GET LOCK COUNT
CAIE T2,1 ;OUTERMOST?
JRST [ DECR LLRCT,(T1) ;NO, JUST DECREMENT
JRST BLKUK1]
SETZRO LLRFK,(T1) ;LOCK BECOMING CLEAR, CLEAR LAST FORK
SETZRO LLRCT,(T1)
BLKUK1: SKIPN INSKED
OKINT
RET
;SCHED TEST FOR ABOVE
LLLCKT: SKIPL LLLLCK
JRST 0(T4) ;STILL BUSY
JRST 1(T4) ;FREE
;ROUTINE TO INIT LL ADDRESS BIT TABLE. CALLED AT SYSTEM STARTUP
LLINIT: ACVAR <W1> ;GET A WORK REGISTER
MOVSI W1,-MAXLNK ; GET MAX LINK VALUE
AOS W1 ;SKIP ENTRY 0
LLINI1: HRRZ T1,W1 ;GET LINK ADDRESS
CALL FRELNK ;FREE LINK #
AOBJN W1,LLINI1 ;DO 'EM ALL
RET ;AND DONE
ENDAV. ;END ACVAR
;LOKPIP - ROUTINE TO LOCK AN ATS DATA DATA OR CONTROL PIPE
;
;ACCEPTS IN T3/ ATS PIPE IDENTIFIER
; CALL LOKPIP
;RETURNS: +1 FAILED, SCHEDULER TEST IN T1
; +2 SUCCESS, PROCESS NOINT AND PIPE LOCKED
LOKPIP::TRVAR <LKPCOD,LKPLLB>
MOVEM T3,LKPCOD ;SAVE ATS ID
; GET THE ADDRESS OF THE LOGICAL LINK BLOCK
LLLOCK ;LOCK THE LOGICAL LINK TREE
MOVEI T1,CHKPIP ;GET COROUTINE TO FIND ATS PIPE
SETOM T2 ;ANY LINK
CALL OBJSRC ;GO FIND BLOCK
JRST [ LLLULK ;DOES NOT EXIST
BUG(NSPPWA)
RET ] ;UNLOCK THE TREE AND RETURN FAILURE
MOVEM T1,LKPLLB ;SAVE LOGICAL LINK BLOCK ADDRESS
; LOCK THE BLOCK
MOVE T1,LKPLLB ;GET LOGICAL LINK BLOCK ADDRESS
CALL BLKLOK ;GO LOCK THE LOGICAL LINK BLOCK
JRST [ LLLULK ;CANNOT LOCK IT NOW, UNLOCK THE TREE
RET ] ;RETURN SCHED TEST
LLLULK ;BLOCK IS NOW RESERVED. UNLOCK THE TREE
RETSKP ;DONE, RETURN WITH PIPE LOCKED
;CHKPIP - COROUTINE TO FIND ATS LINK BLOCK WITH GIVEN ATS DATA PIPE
;
;ACCEPTS IN TRVAR LKPCOD/ ATS ID FOR PIPE
; T1/ ADDRESS OF LINK BLOCK TO CHECK
; CALL CHKPIP
;RETURNS: +1 NOT DESIRED BLOCK
; +2 SUCCESS, FOUND BLOCK WITH REQUESTED ID
CHKPIP: SAVET ;PRESERVE TERMPORARY AC'S
JE LLINT,(T1),R ;LOOK AT INTERNAL LINKS ONLY
LOAD T2,LLDRV,(T1) ;GET DRIVER CORRELATION CODE
CAME T2,LKPCOD ;DESIRED ATS ID ?
RET ;NO, RETURN FAILURE
RETSKP ;YES, RETURN SUCCESS
;ULKPIP - ROUTINE TO UNLOCK AN ATS DATA OR CONTROL PIPE
;
;ACCEPTS IN T3/ ATS PIPE IDENTIFIER
; CALL ULKPIP
;RETURNS: +1 ALWAYS, WITH PIPE UNLOCKED
ULKPIP::TRVAR <LKPCOD>
MOVEM T3,LKPCOD ;SAVE ATS ID FOR COROUTINE
LLLOCK ;LOCK THE LOGICAL LINK TREE
MOVEI T1,CHKPIP ;GET COROUTINE ADDRESS
SETOM T2 ;ANY LINK
CALL OBJSRC ;GO FIND BLOCK
JRST [ LLLULK ;DOES NOT EXIST
BUG(NSPPHV)
RET ] ;UNLOCK THE TREE AND RETURN FAILURE
LLLULK ;UNLOCK THE TREE
CALLRET BLKULK ;UNLOCK PIPE AND RETURN
;ROUTINE TO FIND INDEX INTO LOGICAL LINK TABLES.
;ACCEPTS: T1/ LOGICAL LINK
; T2/ FOREIGN LINK I.D. -1 FOR ANY
; T3/ HOST NAME STRING IF LLLKUH USED
;RETURNS: +1 FAILED. LINK NOT FOUND
; T1/ INSERT POINT FOR NEW ENTRY
; +2 SUCCESS. T1/ ADDRESS OF LINK ENTRY
; T2/ PREVIOUS NODE ADDRESS
;PRESERVES T4
RESCD ;NEEDS TO BE RESIDENT
LLLKUP::SETOM T3 ;NO HOST MATCH IF ENTERED HERE
LLLKUH: SAVEAC <T4> ;PRESERVE AC
STKVAR <LASTM,LNKID,LLHO> ;REMEMBER INSERT POINT
MOVEM T3,LLHO ;SAVE HOST STRING POINTER
SETZM LASTM ;NO INSERT FOUND YET
MOVEM T1,LNKID ;SAVE DESIRED ADDRESS
MOVE T1,LLHEAD ;GET HEAD OF TREE
LLLKU1: JUMPE T1,LLFAIL ;NO THERE. ERGO, NOT FOUND
LOAD T3,LLLNK,(T1) ;GET THE LINK I.D.
CAME T3,LNKID ;IS THIS IT?
JRST [ MOVEM T1,LASTM ;REMEMBER THIS AS INSERT POINT
CAMG T3,LNKID ;NEED TO GO UP OR DOWN?
JRST [ LOAD T1,LLUPL,(T1) ;GET UP POINTER
JRST LLLKU1] ;AND GO SEE ABOUT IT
LOAD T1,LLDWN,(T1) ;DOWN. GET DOWN POINTER
JRST LLLKU1] ;AND GO SEE ABOUT IT
JUMPL T2,LLLKU2 ;IF NO HOST CHECK, FOUND IT
OPSTR <CAME T2,>,LLHLK,(T1) ;DOES THE HOST MATCH?
RETBAD (NSPX2) ;NO. GIVE ERROR
LLLKU2: MOVE T2,LASTM ;RETURN PREVIOUS NODE
SKIPG LLHO ;WANT HOST MATCH?
RETSKP ;NO. ALL DONE THEN
LOAD T2,LLHST,(T1) ;GET HOST STRING
EXCH T1,LLHO ;SAVE LINK. GET SOURCE HOST NAME
CALL CMPSTR ;DO COMPARE
RETBAD (NSPX2) ;NO MATCH
MOVE T1,LLHO ;A MATCH. GET LINK
MOVE T2,LASTM ;GET PREVIOUS
RETSKP ;AND DONE
;COULDN'T FIND REQUIRED LINK. RETURN INSERT POINT
LLFAIL: MOVE T1,LASTM ;FOUND AN INSERT POINT?
RET ;AND RETURN
;ALL OF THIS CODE IS UNSUITABLE FOR EXTENDED ADDRESSING. SINCE
;OBJECT NAMES CAN RESIDE IN SWAPPABLE FREE SPACE, OBJTBL
;NEEDS TO HAVE 36 BIT ADDRESSES POINTING TO THE STRINGS. ALSO,
;A REPLACEMENT FOR TBLUK IS NEEDED WHICH WILL DO LOOK UP, DELETE
;AND ADD ENTRIES TO SUCH AN "EXTENDED" TABLE. FOR THE TIME BEING,
;HOWEVER, THE CODE AS WRITTEN WILL SUFFICE.
;ROUTINE TO INITIALIZE THE OBJECT TABLE FOR THE MONITOR.
SWAPCD
OBJINI: MOVE T1,[OBJPRO,,OBJTBL]
BLT T1,OBJTBL+OBJENT ;INIT THE TABLE
RET ;AND DONE
;THIS TABLE SHOULD BE MOVED TO STG SOMEDAY*****************
;PROTOTYPE OBJECT TABLE
OBJPRO: OBJENT,,OBJMAX
[ASCIZ /ATS/],,3
[ASCIZ /FAL/],,21
[ASCIZ /NCU/],,23
[ASCIZ /NRM/],,7
[ASCIZ /TASK/],,0
OBJENT==.-OBJPRO-1 ;# OF ENTRIES
;ROUTINE TO LOOK UP AN OBJECT NAME IN THE SYSTEM OBJECT TABLES
;ACCEPTS: T1/ POINTER TO TEST OBJECT NAME
;RETURNS: +1 NOT FOUND. NO SUCH OBJECT
; +2 OBJECT FOUND
; T1/ OBJECT NUMBER
OBJLOK::ASUBR <OBJPTR> ;SAVE POINTER
MOVE T2,T1 ;COPY POINTER
MOVE T1,[OBJTBL] ;GET THE OBJECT TABLE
TBLUK ;LOOK UP THE OBJECT
TXNN T2,TL%EXM ;FOUND IT?
JRST OBJLO1 ;NO. GO CHECK FOR NUMBER
HRRZ T1,0(T1) ;YES. GET OBJECT NUMBER
RETSKP ;AND RETURN WITH IT
;TBLUK DIDNT'T FIND IT. SEE IF IT IS NUMERIC
OBJLO1: SETZ T1, ;GET AN ACCUMULATOR
OBJLO2: ILDB T2,OBJPTR ;GET NEXT BYTE
JUMPE T2,RSKP ;IF AT THE END, GOOD NUMBER
CAIL T2,"0" ;A VALID NUMBER
CAILE T2,"9" ;STILL?
RET ;NO. NOT A VALID NUMBER
IMULI T1,^D10 ;YES. ADJUST ACCUMULATOR
ADDI T1,-"0"(T2) ;AND ADD IN NEW QUANTITY
CAILE T1,OBJMAX ;STILL VALID?
RET ;NO. GIVE AN ERROR
JRST OBJLO2 ;GO DO ALL OF IT
;ROUTINE TO FIND A "LISTENING" OR ACTIVE OBJECT IN THE LOGICAL
;LINK TABLE. WILL ALSO DO SCAN OF ENTIRE TREE
;ACCEPTS:
; T1/ COUROUTINE ADDRESS TO CALL WHEN OBJECT IS FOUND
; T2/ 0 IF OBJECT MAY BE LISTENING OR ACTIVE
; 1 IF OBJECT MUST BE LISTENING ONLY
; -1 IF ANY LINK IS ACCEPTBLE
;RETURNS:
; +1 OBJECT NOT FOUND
; +2 OBJECT FOUND.
; T1/ POINTER INTO LINK TABLE FOR THIS OBJECT
; T2/ LINK I.D. OF THE OBJECT
;THE COROUTINE IS CALLED TO CHECK IF THE OBJECT IS THE ONE
;WANTED. THE COROUTINES ARE CALLED WITH THE FOLLOWING ARGS:
; T1/ ADDRESS OF LOGICAL LINK ENTRY
; ALL OF THE P AND Q REGISTERS INTACT
;THE COROUTINES RETURN AS FOLLOWS:
; +1 DON'T WANT THIS OBJECT
; +2 THIS IS THE ONE
;THE COROUTINE MUST PRESERVE ALL TEMPORARY AC'S
OBJSRC::SETZM GUDOBJ ;INIT "GOOD OBJECT" FLAG
DMOVE T3,T1 ;SAVE ARGS
SKIPN T1,LLHEAD ;ANY LINKS?
JRST [MOVEI T2,.DCX4 ;NO, SAY "DESTINATION PROCESS
RET] ; DOES NOT EXIST"
PUSH P,[0] ;PUT A "FENCE" ON THE STACK
OBJSND: PUSH P,T1 ;SAVE THIS ONE
JUMPL T4,OBJSN2 ;IF ANY MATCH, GO HANDLE THIS ONE
JE LLFOB,(T1),OBJSNO ;IF NOT OBJECT, CAN'T BE A MATCH
OBJSN2: JUMPE T3,OBJSFD ;IF NO COROUTINE, DONE
CALL 0(T3) ;CALL THE COROUTINE
SKIPA ;NOT THE ONE
JRST OBJSFD ;FOUND IT
OBJSNO: LOAD T1,LLUPL,(T1) ;NOT THE ONE. GET THE UP POINTER
JUMPN T1,OBJSND ;HAVE ONE. GO LOOK AT IT
OBJSN1: POP P,T1 ;NOT FOUND. GET PREVIOUS ONE
JUMPE T1,[MOVEI T2,.DCX4 ;NO MORE, SAY "DESTINATION PROCESS
SKIPE GUDOBJ ; DOES NOT EXIST"
MOVEI T2,.DCX33 ;OR "TOO MANY CONNECTIONS"
RET]
LOAD T1,LLDWN,(T1) ;GET DOWN SIDE
JUMPN T1,OBJSND ;IF HAVE ONE, GO LOOK AT IT
JRST OBJSN1 ;IF NOT, KEEP POPING
;FOUND THE OBJECT
OBJSFD: SETOM GUDOBJ ;FOUND THE RIGHT SERVER
JUMPG T4,[LOAD T2,LLSTA,(T1) ;GET LL STATE
CAIE T2,LLSLIS ;IS IT LISTENING?
JRST OBJSNO ;NO, TRY AGAIN
JRST .+1] ;YES, EVERYTHING OK
POP P,T2 ;MUST CLEAN UP THE STACK
JUMPN T2,.-1 ;KEEP CLEANING
LOAD T2,LLLNK,(T1) ;GET LOGICAL LINK I.D.
RETSKP ;DONE. RETURN GOOD
;ROUTINE TO GET A UNIQUE TASK NAME.
;ACCEPTS: T1/ LL POINTER
; LL TREE MUST BE LOCKED
;RETURNS: +1 ALWAYS
; LLTSK FILLED IN WITH NAME
;PRESERVES T1
GETTSK: TRVAR <LLADDR,TSKBLK>
MOVEM T1,LLADDR ;SAVE LL BLOCK ADDRESS
MOVEI T1,3 ;NEED A BLOCK OF THIS SIZE
CALL GETBLK ;GO GET A BLOCK
RET ;NO MORE SPACE
MOVEM T1,TSKBLK ;SAVE ADDRESS
GETTS1: HRLI T1,(<POINT 7,>) ;MAKE A BYTE POINTER
AOS T2,LASTSK ;GET A NUMBER FOR THE TASK NAME
MOVEI T3,10 ;CONVERT OCTAL
NOUT ;MOVE NUMBER
JFCL ;WILL WORK
XMOVEI T1,TSKLOK ;MAKE SURE IS UNIQUE
SETOM T2 ;ANY LINK
CALL OBJSRC ;GO LOOK FOR A MATCH
JRST [ MOVE T1,LLADDR
MOVE T2,TSKBLK ;GET BLOCK ADDRESS
STOR T2,LLTSK,(T1)
RETSKP] ;AND DONE
MOVE T1,TSKBLK ;FOUND IT
JRST GETTS1 ;TRY AGAIN
;COROUTINE TO CHECK FOR TASK MATCH
TSKLOK: SAVET ;SAVE ALL TEMPS
LOAD T2,LLTSK,(T1) ;GET THIS ONE'S ADDRESS
JUMPE T2,R ;IF NONE, CAN'T BE IT
MOVE T1,TSKBLK ;GET BLOCK ADDRESS
CALLRET CMPSTR ;GO DO THE COMPARE
;COLLECTION OF UTILITIES
;MOVE ONE STRING TO ANOTHER.
;ACCEPTS: T1/ DEST STRING BLOCK
; T2/ SOURCE STRIGN BLOCK
; T3/ COUNT OR -1
;RETURNS: +1 ALWAYS.
;ALL REGISTERS PRESERVED
MOVSTR::SAVET ;SAVE ALL TEMPS
ACVAR <W1,W2> ;GET SOME WORK REGS
MOVE W1,[POINT 7,0(T1)]
MOVE W2,[POINT 7,0(T2)] ;SET UP ARGS
MOVST0: ILDB T4,W2 ;GET NEXT BYTE
IDPB T4,W1 ;STASH IT
JUMPE T4,R ;IF NULL, ALL DONE
JUMPL T3,MOVST0 ;IF NO COUNT, KEEP GOING
SOJG T3,MOVST0 ;MORE IN THE COUNT?
RET ;NO. ALL DONE
ENDAV. ;END ACVAR
;ROUTINE TO "FREE" A LL ADDRESS.
;ACCEPTS: T1/ LL ADDRESS TO FREE
;RETURNS: +1 ALWAYS
FRELNK: ANDI T1,MAXLNK ;ISOLATE LOCAL INDEX
IDIVI T1,44 ;COMPUTE WORD AND OFFSET
ADD T1,[LLBITS] ;GET BIT TABLE OFFSET
MOVE T2,BITS(T2) ;GET A BIT
IORM T2,0(T1) ;TURN OF THE BIT
RET ;AND DONE
;ROUTINES TO GET AND RETURN SWAPPABLE FREE SPACE
;ROUTINE TO GET A BLOCK FROM THE LL STRING SPACE POOL
;ACCEPTS: T1/ SIZE TO GET
;RETURNS: +1 FAILED. T1/ERROR CODE
; +2 SUCCESS T1/ BLOCK ADDRESS
GETBLK::MOVEI T2,1(T1) ;ACCOUNT FOR HEADER
ADD T2,BLKASG ;COMPUTE AMOUNT THIS WOULD MAKE
CAILE T2,MAXBLK ;WITHIN BOUNDS?
RETBAD (MONX06) ;NO. INSUFFICIENT RESOURCES - NO SWAPPABLE FREE SPACE
AOS T1 ;GET SPACE +1
CALL ASGSWP ;GET SOME SPACE
RETBAD ;FAILED. GIVE IT UP
HRRZ T2,0(T1) ;GET COUNT ASSIGNED
ADDM T2,BLKASG ;ACCOUNT FOR IT
AOS T1 ;POINT TO FIRST USEFUL BLOCK
RETSKP ;AND GOOD
;ROUTINE TO RETURN A STRING BLOCK
;ACCEPTS: T1/ ADDRESS OF FIRST DATA LOCATION (HEADER+1)
;RETURNS: +1 ALWAYS
RELBLK::SOS T1 ;POINT TO HEADER
HRRZ T2,0(T1) ;GET WORDS IN THIS BLOCK
EXCH T2,BLKASG
SUBM T2,BLKASG ;COMPUTE NEW COUNT
HRRZ T2,0(T1) ;GET SIZE OF THE BLOCK AGAIN
CALLRET RELSWP ;RELEASE THE BLOCK
;ROUTINE TO GET A RESIDENT FREE SPACE BLOCK
;ACCEPTS: T1/ SIZE REQUIRED
;RETURNS: +1 FAILED, T1/ ERROR CODE
; +2 SUCCESS, T1/ ADDRESS OF FREE SPACE BLOCK
RESCD
;**;[3179] Add 2 lines CEG 5-Nov-84
GETRES::SKIPE RESNET ;[3179] LOW ON SPACE?
RETBAD (MONX05) ;[3179] YES
HRLI T1,.RESP3 ;NO, ASSUME PROCESS CONTEXT
SKIPE INSKED ;SKED CONTEXT?
HRLI T1,.RESP2 ;YES, NO PAGE FAULTS PLEASE
MOVE T2,[RS%SE0!.RESNP] ;FROM THE NETWORK
CALL ASGRES ;GET SOME SPACE
;**;[3179] Return an error code CEG 5-Nov-84
RETBAD (MONX05) ;[3179] COULDN'T
RETSKP ;GOT IT
SWAPCD
;ROUTINE TO MOVE A STRING FROM JSB FREE SPACE TO SWAPPABLE FREE SPACE.
;ACCEPTS: T1/ DESTINATION BLOCK ADDRESS
; T2/ SP TO JSB FREE SPACE
; T3/ COUNT
;CLOBBERS ALL TEMPS
MOVST1::STKVAR <MVSPTR>
MOVE T4,[POINT 7,0(T1)] ;FORM STRING POINTER
MOVEM T4,MVSPTR ;SAVE POINTER
MOVST2: ILDB T4,T2 ;GET A BYTE
IDPB T4,MVSPTR ;STORE IT
SOJG T3,MOVST2 ;DO ALL BYTES
RET ;DONE
SUBTTL Logical Link Creation
; ROUTINES TO SET INPUT/OUTPUT FLAGS IN LOGICAL LINK BLOCKS
;
;ACCEPTS IN T1/ LOGICAL LINK BLOCK ADDRESS
; CALL SETOPI/SETOPW
;RETURNS: +1 ALWAYS
SETOPI::SETONE LLOPI,(T1) ;SET INPUT FLAG
RET ;DONE, RETURN
SETOPW::SETONE LLOPW,(T1) ;SET OUTPUT FLAG
RET ;DONE, RETURN
; ROUTINES TO TEST THE DIRECTION OF I/O
;
;ACCEPTS IN T1/ LOGICAL LINK BLOCK ADDRESS
SKPFLO::JE LLFLO,(T1),R ;NON-SKIP IF FLOW NOT FROM FILE-SYSTEM
RETSKP ;SKIP IF FLOW IS FROM THE FILE-SYSTEM
SKPFLI::JE LLFLI,(T1),R ;NON-SKIP IF FLOW NOT TO THE FILE-SYSTEM
RETSKP ;SKIP if FLOW IS TO THE FILE-SYSTEM
; ROUTINES TO SET/CLEAR DIRECTION-OF-FLOW BITS
CLRFLO::SETZRO LLFLO,(T1) ;SWITCH FLOW TO BE "TO THE NETWORK"
RET ;DONE, RETURN
SETFLO::SETONE LLFLO,(T1) ;SWITCH FLOW TO BE "FROM FILE-SYSTEM"
RET ;DONE, RETURN
;GETBSZ - ROUTINE TO OBTAIN THE BYTE SIZE FOR A LOGICAL LINK
;
;ACCEPTS IN T1/ LOGICAL LINK BLOCK ADDRESS
; CALL GETBSZ
;RETURNS: +1 ALWAYS, WITH T3/ BYTE SIZE
;
; PRESERVES LOGICAL LINK BLOCK ADDRESS IN T1
GETBSZ::LOAD T3,LLBSZ,(T1) ;GET BYTE SIZE
RET ;DONE, RETURN
;GETSTA - ROUTINE TO RETURN CURRENT STATE OF A LOGICAL LINK
;
;ACCEPTS IN T1/ LOGICAL LINK BLOCK ADDRESS
; CALL GETSTA
;RETURNS: +1 ALWAYS, WITH T2/ LINK STATE
;
; PRESERVES LOGICAL LINK BLOCK ADDRESS IN T1
GETSTA::LOAD T2,LLSTA,(T1) ;GET CURRENT STATE
RET
;SETEOM - ROUTINE TO SET "END-OF-MESSAGE-NEEDED" FLAG FOR A LOGICAL LINK
;
;ACCEPTS IN T1/ ADDRESS OF LOGICAL LINK BLOCK
; CALL SETEOM
;RETURNS: +1 ALWAYS
SETEOM::SETONE LLFEM,(T1) ;SAY SHOULD GET EOM ON OUTPUT
RET ;DONE, RETURN
;GETMXS - ROUTINE TO GET MAX SEGMENT SIZE
;
;ACCEPTS IN T1/ LOGICAL LINK BLOCK ADDRESS
GETMXS::LOAD T4,LLSWG,(T1) ;GET MAX SEG SIZE
RET ;DONE, RETURN
;WORK ROUTINES TO OPEN DCN: OR SRV:
;
; OPNDWK - OPEN A FILESYSTEM DCN: LINK
; OPNSWK - OPEN A FILESYSTEM SRV: LINK
; OPNIWK - OPEN AN INTERNAL LINK
;
;ACCEPTS IN T1/ ADDRESS OF TASK STRING
; T2/ BYTE SIZE OF OPEN
; CALL OPNSWK/OPNDWK
;RETURNS: +1 FAILED, ERROR CODE IN T1
; +2 SUCCESS, WITH T1/ ADDRESS OF LOGICAL LINK BLOCK
OPNDWK::MOVEI T3,LKSIZE ;BASIC LL BLOCK SIZE
JRST OPNWRK ;CALL WORK ROUTINE
OPNSWK::MOVEI T3,LKSIZE+LKOBJS ;BASIC SIZE PLUS WORDS NEEDED FOR SRV: LINKS
JRST OPNWRK ;CALL WORK ROUTINE
OPNIWK::MOVEI T3,LKSIZE+LKISIZ ;BASIC SIZE PLUS WORDS NEEDED FOR INTERNAL LINKS
JRST OPNWRK ;GO DO THE OPEN
;OPNWRK - WORK ROUTINE TO OPEN A LOGICAL LINK
;
;ACCEPTS IN T1/ ADDRESS OF TASK STRING
; T2/ BYTE SIZE OF OPEN
; T3/ SIZE OF LOGICAL LINK BLOCK NEEDED
; CALL OPNWRK
;RETURNS: +1 FAILED, ERROR CODE IN T1
; +2 SUCCESS, WITH T1/ ADDRESS OF LOGICAL LINK BLOCK
OPNWRK: TRVAR <SAVBLK,SAVERR,SAVSTR,SAVBSZ>
; NOTE: TRVAR IS NEEDED HERE INSTEAD OF STKVAR
;**;[3179] Remove 4 lines CEG 5-Nov-84
MOVEM T1,SAVSTR ;SAVE STRING BLOCK ADDRESS
MOVEM T2,SAVBSZ ;SAVE BYTE SIZE
MOVEM T3,SAVERR ;SAVE SIZE OF BLOCK OVER SUBROUTINE CALL
MOVX T2,FRKRUN ;SEE IF NETWORK IS INTIALIZED
TDNN T2,MCBDTE ;IS IT?
RETBAD (DCNX11) ;NO. ILLEGAL TO USE IT THEN
;**;[3179] Call GETRES rather than ASGRES CEG 5-Nov-84
MOVE T1,SAVERR ;GET # OF ADDITIONAL WORDS NEEDED FOR LL BLOCK
CALL GETRES ;(T1/T1) GET SPACE FOR LL BLOCK
RETBAD () ;COULDN'T. MUST FAIL
MOVEM T1,SAVBLK
MOVEI T1,OPTSIZ ;SIZE OF OPTDATA BLOCK
CALL GETBLK ;GET A BLOCK OF PROPER SIZE
JRST RLBLK ;COULDN'T. FREE BLOCK
MOVE T2,SAVBLK ;GET BACK BLOCK ADDRESS
STOR T1,LLOPT,(T2) ;SAVE BLOCK ADDRESS
MOVE T1,T2 ;GET LL BLOCK ADDRESS
LLLOCK ;LOCK UP THE TREE
CALL MAKLNK ;GET LL ADDRESS AND INSERT ENTRY
JRST [ MOVEM T1,SAVERR ;SAVE ERROR CODE
LLLULK
MOVE T1,SAVBLK ;GET BLOCK
LOAD T1,LLOPT,(T1)
CALL RELBLK ;FREE UP OPT BLOCK
JRST RLBLK1] ;AND GET RID OF LL BLOCK
LLLULK ;RELEASE LOCK
; ..
;OPEN CONTINUED. CHECK QUOTA TO SEE IF CAN MAKE THIS LINK
INCR DCCUR ;INCREMENT COUNT
LOAD T2,DCCUR ;GET IT
LOAD T4,DCMAX ;GET MAX COUNT ALLOWED
CAMLE T2,T4 ;NO. ALLOWED TO MAKE ANOTHER LINK?
JRST [ MOVE T3,CAPENB ;NO, SEE IF CAPS
TXNE T3,SC%WHL!SC%OPR
JRST .+1 ;OK
MOVEI T1,DCNX5 ;NO. GIVE ERROR
JRST OPNFAI] ;AND GO FAIL
MOVE T2,SAVBLK ;GET LL BLOCK ADDRESS
MOVEI T3,LLHNM1(T2) ;GET PLACE TO PUT REMOTE HOST NAME STRING
STOR T3,LLHST,(T2) ;SET IT
MOVEI T1,<MAXDSC+4>/4 ;A BLOCK FOR REMOTE DESCRIPTOR
CALL GETBLK ;GET ONE
JRST OPNFAI ;COULDN'T
MOVE T2,SAVBLK ;GET LL BLOCK
STOR T1,LLFDS,(T2) ;SAVE BLOCK
MOVE T1,SAVSTR ;GET POINTER TO EXTENSION BLOCK
JUMPE T1,OPNDFT ;NONE. GO DEFAULT TASK NAME
LDB T2,[POINT 7,(T1),6] ;GET FIRST BYTE
JUMPE T2,OPNDFT ;IF NULL EXTENSION. GO DEFAULT TASK NAME
; ..
;USER SPECIFIED EXTENSION. CHECK FOR DUPLICATE
HRLI T1,(POINT 7,) ;FORM POINTER TO THE STRING
MOVX T3,MAXLC ;GET MAX SIZE OF EXTENSION
CALL CMPLEN ;COMPUTE ACTUAL NUMBER OF BYTES IN STRING
IDIVI T3,5 ;COMPUTE NUMBER OF WORDS IN STRING
SKIPE T4 ;AND ROUND RESULT UP
ADDI T3,1 ; IF NEEDED
MOVE T1,T3 ;COPY SIZE OF STRING
CALL GETBLK ;GET A BLOCK TO HOLD IT
OPNFAI: JRST [ LLLOCK ;LOCK UP TREE
EXCH T1,SAVBLK ;GET BLOCK ADDRESS
CALL DELNOD ;RELEASE LL BLOCK
LLLULK ;RELEASE LOCK
MOVE T1,SAVBLK ;GET ERROR CODE
DECR DCCUR ;DISCOUNT THIS LINK
RET] ;DONE
MOVEM T1,SAVERR ;SAVE BLOCK ADDRESS
MOVE T2,SAVSTR ;GET STRING BLOCK
SETOM T3 ;NO COUNT
CALL MOVSTR ;MOVE THE STRING
MOVEI T1,TSKCHK ;COROUTINE ADDRESS
SETOM T2 ;SEARCH ALL LOGICAL LINKS
LLLOCK ;LOCK UP THE TREE
CALL OBJSRC ;DO IT
SKIPA ;NOT FOUND. CAN USE IT
JRST [ MOVE T1,SAVERR ;GET TASK NAME BLOCK
CALL RELBLK ;RELEASE IT
MOVE T1,SAVBLK ;GET LL BLOCK ADDRESS
CALL DELNOD ;RELEASE THE BLOCK
LLLULK ;FREE THE TREE LOCK
MOVEI T1,DCNX4 ;ILLEGAL TASK NAME
DECR DCCUR ;DISCOUNT THIS LINK
RET] ;AND DONE
MOVE T2,SAVERR ;GET TASK BLOCK
MOVE T1,SAVBLK ;GET LL BLOCK ADDRESS
STOR T2,LLTSK,(T1) ;STORE BLOCK ADDRESS
OPNEXT: SETONE LLBOM,(T1) ;NEXT OUTPUT WILL BE BOM
MOVE T3,SAVBSZ ;GET BYTE SIZE
STOR T3,LLBSZ,(T1) ;SAVE BYTE SIZE IN LOGICAL LINK BLOCK
CAIE T3,44 ;WORD MODE?
JRST OPENX1 ;NO. GO ON
SETONE LLFDI,(T1) ;YES. REMEMBER THIS
OPENX1: MOVEI T2,NSPTIM ;GET INITIAL RESEND TIME OUT VALUE
MOVEM T2,LLTIMO(T1) ;PUT IT IN LL BLOCK
RETSKP ;DONE, RETURN SUCCESS WITH T1/ LL BLOCK ADDRESS
;ROUTINE TO GET RID OF LL BLOCK AFTER ERROR
RLBLK: MOVEM T1,SAVERR ;SAVE ERROR
RLBLK1: MOVE T1,SAVBLK ;GET BLOCK ADDRESS
CALL RELRES ;FREE IT
MOVE T1,SAVERR ;GET ERROR
RET ;AND DONE
;ROUTINE TO GET DEFAULT TASK NAME FOR A LINK
OPNDFT: LLLOCK ;LOCK UP THE TREE
MOVE T1,SAVBLK ;GET BLOCK ADDRESS
CALL GETTSK ;GO GET A NAME
JRST [ MOVE T1,SAVBLK ;FAILED
CALL DELNOD ;SO RELEASE LL BLOCK
LLLULK ;FREE TREE LOCK
MOVEI T1,MONX06 ;"NO MORE SWAPPABLE FREE SPACE"
RET] ;DONE
MOVE T1,SAVBLK ;GET BACK LL BLOCK ADDRESS
JRST OPNEXT ;AND DONE
;COROUTINE OF OPEN CODE TO CHECK VALIDITY OF A USER-SUPPLIED
;TASK NAME
TSKCHK: SAVET ;SAVE TEMPS
LOAD T2,LLFRK,(T1) ;SEE IF THE SAME FORK
HLRZ T2,FKJOB(T2) ;GET FORK'S JOB NUMBER
MOVE T4,FORKX ;GET THIS FORK'S NUMBER
HLRZ T4,FKJOB(T4) ;GET THIS FORK'S JOB NUMBER
CAMN T2,T4 ;IS IT?
RET ;YES. NO NEED TO CHECK ANYMORE
LOAD T2,LLTSK,(T1) ;GET THIS ONE'S ADDRESS
JUMPE T2,R ;IF NONE, CAN'T BE IT
MOVE T1,SAVERR ;GET TASK BLOCK ADDRESS
CALLRET CMPSTR ;GO DO THE COMPARE
SUBTTL Routines to Manipulate the Logical Link Tree
;DELETE NODE FROM LL TREE
; T1/ BLOCK ADDRESS
DELNOD::MOVE T2,(P) ;GET CALLER'S ADDRESS
ASUBR <SAVBLK,SAVCAL> ;SAVE BLOCK ADDRESS AND PC OF CALLER
LOAD T1,LLLNK,(T1) ;GET ITS ADDRESS
SETOM T2 ;ANY MATCH
CALL LLLKUP ;GO LOOK IT UP
JRST [
; MOVE T2,SAVCAL ;DIDN'T FIND IT, RETRIEVE CALLER'S PC
; BUG (DELNDF,<<T2,CALLER>>)
RET] ;ALL DONE
JUMPE T2,[SETZM LLHEAD ;IF THE HEAD. CLEAR HEADER
JRST DELNO1] ;AND PROCEED
LOAD T3,LLUPL,(T2) ;SEE IF THIS IS UP OR DOWN
NOSKD1
CHNOFF DLSCHN ;TURN OFF INTERRUPTS
CAMN T3,T1
JRST [ SETZRO LLUPL,(T2) ;UP
JRST DELINS] ;GO DO INSERTS
SETZRO LLDWN,(T2) ;DOWN
DELINS: CHNON DLSCHN
OKSKD1
DELNO1: LOAD T1,LLLNK,(T1) ;GET ADDRESS
CALL FRELNK ;RELEASE THE LINK #
MOVE T1,SAVBLK ;GET BACK LL BLOCK ADDRESS
LOAD T2,LLUPL,(T1) ;DOES THIS HAVE AN UP POINTER?
JUMPE T2,DELDWN ;NO
MOVE T1,T2 ;YES.
CALL ADDLNK ;GO PUT IT IN
MOVE T1,SAVBLK ;GET BACK ADDRESS
DELDWN: LOAD T2,LLDWN,(T1) ;SEE IF IT HAS A DOWN
JUMPE T2,DELDNE ;AND GO RELEASE BLOCKS
MOVE T1,T2 ;GET ADDRESS
CALL ADDLNK
MOVE T1,SAVBLK ;GET BACK BLOCK ADDRESS
DELDNE: OPSTR <SKIPE T2,>,LLOPT,(T1) ;HAVE AN OPTDATA STRING?
CALL DELREL ;YES. GET RID OF IT
OPSTR <SKIPE T2,>,LLTSK,(T1) ;HAVE A TASK NAME?
CALL DELREL ;YES. GET RID OF IT
OPSTR <SKIPE T2,>,LLFDS,(T1) ;HAVE A DESCRIPTOR STRING?
CALL DELREL ;YES. GET RID OF IT
JE LLFOB,(T1),DELBLK ;AN OBJECT?
OPSTR <SKIPE T2,>,LLDSC,(T1) ;YES. HAVE A DESCRIPTOR STRING?
CALL DELREL ;YES. GET RID OF IT
; ..
; ..
OPSTR <SKIPE T2,>,LLUSR,(T1) ;HAVE A USER STRING?
CALL DELREL ;YES. GET RID OF IT
OPSTR <SKIPE T2,>,LLACT,(T1) ;HAVE AN ACCOUNT STRING?
CALL DELREL ;YES. GET RID OF IT
OPSTR <SKIPE T2,>,LLPSW,(T1) ;HAVE A PASSWORD STRING?
CALL DELREL ;YES. GET RID OF IT
DELBLK: CALL REMQUE ;REMOVE BLOCK FROM OUTQUE OF NEEDED
CALL UNQSRV ;REMOVE LL BLOCK FROM "NEEDS SERVICE" QUEUE
CALLRET RELRES ;FREE BLOCK AND RETURN
DELREL: SAVET
NOINT ;PREVENT INTERRUPTS WHILE DEASSIGNING SPACE
MOVE T1,T2 ;GET BLOCK ADDRESS
CALL RELBLK ;FREE BLOCK
OKINT ;PREMIT INTERRUPTS AGAIN
RET ;RETURN
ENDAS.
;REMQUE - ROUTINE TO REMOVE A LINK FROM OUTQUE
;
;ACCEPTS IN T1/ ADDRESS OF LOGICAL LINK BLOCK
; CALL REMQUE
;RETURNS: +1 ALWAYS, WITH LINK REMOVED IF QUEUED
REMQUE: JE LLQUE,(T1),R ;NOTHING TO DO IF THIS LINK WAS NOT QUEUED
; INITIALIZATION
LOCK OUTLOK ;LOCK THE QUEUE
MOVEI T4,0 ;INITIALIZE CURRENT QUEUE ITEM
HRRZ T3,OUTQUE ;GET ITEM AT HEAD OF QUEUE
; SEARCH THE QUEUE FOR THE DESIRED LINK
RMQ010: CAMN T3,T1 ;FOUND DESIRED ITEM ?
JRST RMQ020 ;YES, GO REMOVE IT FROM THE QUEUE
MOVE T4,T3 ;NO, SAVE CURRENT ITEM AS PREVIOUS ITEM
LOAD T3,LLOUT,(T3) ;MAKE NEXT ITEM CURRENT ITEM
JUMPN T3,RMQ010 ;AND GO CHECK NEW CURRENT ITEM
BUG(NSPLNQ)
RET ;SHOULD NEVER HAPPEN
; HERE WITH THE DESIRED LINK ADDRESS IN T3, PREVIOUS ITEM IN T4
RMQ020: HLRZ T2,OUTQUE ;GET POINTER TO TAIL OF QUEUE
CAMN T2,T3 ;REMOVING TAIL OF QUEUE ?
HRLM T4,OUTQUE ;YES, SAVE POINTER TO NEW TAIL OF QUEUE
LOAD T2,LLOUT,(T3) ;GET POINTER TO NEXT BLOCK
SKIPN T2 ;REMOVING HEAD OF QUEUE ?
JRST [ HRRM T2,OUTQUE ;YES, SAVE NEXT BLOCK AS NEW HEAD
JRST RMQ030 ] ;AND CLEAN UP
STOR T2,LLOUT,(T4) ;STORE NEXT BLOCK IN PREVIOUS
; HERE WITH ITEM REMOVED FROM QUEUE
RMQ030: SETZRO LLQUE,(T1) ;CLEAR "LINK ON OUTQUE" FLAG
UNLOCK OUTLOK ;UNLOCK THE QUEUE
RET ;DONE, RETURN
;ROUTINE TO RESET AN LL BLOCK SO THAT IT CAN REVERT TO
;THE LISTENING STATE. USED WHEN A SERVER REJECTS A CONNECTION.
;ACCEPTS: T1/ LL BLOCK ADDRESS
;RETURNS: +1 FAILED
; +2 SUCCESS
CLRBLK: ASUBR <CLRLLB> ;LL BLOCK ADDRESS
CALL FLUSH ;FIRST GET RID OF MESSAGES
SETZRO LLFNM,(T1) ;CLEAR CONNECTOR
SETZRO LLHLK,(T1)
SETZRO LLUCT,(T1) ;NO OPTDATA
LOAD T2,LLHST,(T1)
SETZM 0(T2) ;NO REMOTE HOST NAME
OPSTR <SKIPE T2,>,LLFDS,(T1) ;HAVE A DESCRIPTOR?
CALL DELREL ;YES, RELEASE THE SPACE
MOVEI T1,<MAXDSC+4>/4 ;MAX CHARS IN DESCRIPTOR
CALL GETBLK ;GET SWAPPABLE FREE SPACE BLOCK
RETBAD () ;COULDN'T
MOVE T2,T1 ;POSITION THE ADDRESS
MOVE T1,CLRLLB ;RETRIEVE THE LL BLOCK ADDRESS
STOR T2,LLFDS,(T1) ;PUT BLOCK ADDRESS IN LL BLOCK
SETZRO LLRSN,(T1) ;NO DISCONNECT REASON
JE LLFOB,(T1),RSKP ;IN CASE CALLED FOR NON-OBJECT
SETZM LLUSGP(T1) ;NO GROUP,USER
SETZRO LLSOB,(T1) ;NO OBJECT #
LOAD T2,LLUSR,(T1) ;GET USER BLOCK
SETZM 0(T2) ;NO USER
LOAD T2,LLACT,(T1) ;GET ACCOUNT BLOCK
SETZM 0(T2) ;NONE
SETZRO LLPCT,(T1) ;NO PASSWORD DATA
RETSKP ;AND DONE
;ROUTINE TO GET A LL ADDRSS AND INSERT A NODE IN THE TREE
;MUST BE CALLED WITH LL LOCK LOCKED.
;ACCEPTS: T1/ BLOCK ADDRESS
;RETURNS: +1 SOME SORT OF FAILURE (SHOULDN'T HAPPEN)
; +2 INSERTED.
MAKLNK: ASUBR <SAVADR> ;SAVE BLOCK ADDRESS
MOVSI T1,-LLBIT ;# OF WORDS IN BIT TABLE
MOVE T2,[LLBITS] ;THE TABLE ITSELF
MAKLN1: SKIPN T3,0(T2) ;HAVE SOME BITS?
JRST [ AOS T2 ;NO. NEXT WORD THEN
AOBJN T1,MAKLN1 ;SEE IF ANY MORE
MOVEI T1,DCNX5 ;NO MORE LINKS
RET] ;AND DONE
JFFO T3,.+1 ;COMNPUTE LEADING ZEROES
MOVE T3,BITS(T4) ;GET THE BIT
ANDCAM T3,0(T2) ;TURN IT OFF
HRRZS T1 ;GET # OF FULL WORDS SKIPPED
IMULI T1,44 ;COMPUTE SKIPPED BITS
ADDI T1,0(T4) ;THE INDEX
HRRZ T2,TODCLK ;GET THE CURRENT CLOCK
LSH T2,MAXEXP ;ZERO RIGHT-HAND BITS
ANDI T2,177777 ;GET A 16 BIT QUANTITY
ADDI T2,0(T1) ;FORM LL ADDRESS
MOVE T1,SAVADR ;GET BACK BLOCK ADDRESS
STOR T2,LLLNK,(T1) ;PUT IN THE ADDRESS
MOVE T2,FORKX ;PUT IN FORK OWNER
STOR T2,LLFRK,(T1) ;TO THE BLOCK
CALL ADDLNK ;AND GO ADD IN THE LINK
RETSKP ;DONE
;ROUTINE TO ADD A BLOCK TO THE LL TREE
;ACCEPTS: T1/BLOCK TO ADD
;RETURNS: +1 ALWAYS.
;MUST BE CALLED WITH TREE LOCKED
ADDLNK: ASUBR <SAVBLK> ;SAVE BLOCK ADDRESS
LOAD T1,LLLNK,(T1) ;GET LINK I.D.
SETO T2, ;NO HOST CHECK
CALL LLLKUP ;GO GET INSERT POINT
SKIPA ;GOOD
BUG (ADDONF)
MOVE T2,SAVBLK ;GET BACK LL BLOCK
JUMPE T1,[MOVEM T2,LLHEAD ;FIRST ONE
RET] ;AND DONE
LOAD T3,LLLNK,(T2) ;GET THIS LINK I.D.
LOAD T4,LLLNK,(T1) ;GET INSERT I.D.
CAML T3,T4
JRST [ STOR T2,LLUPL,(T1)
RET] ;DONE
STOR T2,LLDWN,(T1) ;NEW LINK
RET ;AND DONE
SUBTTL More Link Creation Routines
;ROUTINE CALLED FROM GTJFN TO VERIFY AN ATTRIBUTE
;ACCEPTS: T1/ BLOCK ADDRESS
; T2/ ATTRIBUTE VALUE
;RETURNS: +1 INVALID. ERROR CODE IN T1
; +2 GOOD ATTRIBUTE
NETATR::ACVAR <W1> ;GET A WORK REG
MOVSI T3,-MAXNTA ;# OF ATTRIBUTES IN TABLE
NETAT2: OPSTR <CAME T2,>,NTATR,ATTRTB(T3) ;IS THIS IT?
JRST [ AOBJN T3,NETAT2 ;DO ALL OF THEM
RETBAD (GJFX49)] ;COULDN'T FIND IT
LOAD W1,NTATB,ATTRTB(T3) ;FOUND IT. GET BINARY BIT
LOAD T2,NTATC,ATTRTB(T3) ;GET MAX COUNT
SKIPE W1 ;BINARY?
IMULI T2,3 ;YES. ADJUST COUNT
HRLI T1,(<POINT 7,0,34>) ;FORM A BYTE POINTER
CNTLOP: ILDB T4,T1 ;GET NEXT BYTE
JUMPE T4,NETAT1 ;IF NULL, DONE
SOJL T2,[RETBAD (GJFX50)] ;ATTRIBUTE TOO LONG
JUMPE W1,CNTLOP ;IF NOT BINARY, GO GET MORE
CAIL T4,"0" ;IS BINARY. CHECK RANGE
CAILE T4,"7" ;""
SKIPA
JRST CNTLOP ;GOOD RANGE
RETBAD (GJFX50) ;INVALID
NETAT1: LOAD T2,NTATE,ATTRTB(T3) ;GET EXCLUSION PARTNER
SKIPE T2 ;HAVE ONE?
CALL FNDATR ;YES. GO LOOK FOR IT
RETSKP ;NOT THERE. ERGO, GOOD ARG
RETBAD (GJFX45) ;CONFLICT
ENDAV. ;END ACVAR
;THE ATTRIBUTE TABLE
ATTRTB: ATTENT (.PFUDT,0,MAXUAP,0)
ATTENT (.PFPWD,0,MAXUAP,.PFBPW)
ATTENT (.PFBPW,1,MAXUAP,.PFPWD)
ATTENT (.PFACN,0,MAXUAP,0)
ATTENT (.PFOPT,0,MAXOPT,.PFBOP)
ATTENT (.PFBOP,1,MAXOPT,.PFOPT)
MAXNTA==.-ATTRTB
;ROUTINES TO OPEN NETWORK CONNECTION. CALLED FROM OPENF JSYS
;OPEN SRC JFN
SRCOPN::ACVAR <W1> ;GET A WORK REG
TRVAR <NTCNT,NTPNT,NTOBJ,NTDSC,NTDSS>
HLRZ T1,FILNEN(JFN) ;GET NAME FOR THE CONNECTION
CALL SRCNAM ;PARSE NETWORK NAME
RETBAD() ;ERROR
CALL OPNSRC ;GO DO COMMON OPEN SETUP
RETBAD() ;FAILED
MOVE W1,T1 ;SAVE LL BLOCK
SKIPG T2,NTOBJ ;GET OBJECT TYPE
JRST NOOOBJ ;NONE GIVEN
STOR T2,LLNAM,(W1) ;SAVE OBJECT
NOOOBJ: SKIPN T1,NTDSC ;HAVE A DESCRIPTOR?
JRST NODESC ;NO. GO ON
ADDI T1,4
IDIVI T1,5 ;COMPUTE WORDS NEEDED
CALL GETBLK ;GET ONE
JRST SRCFAL ;COULDN'T
STOR T1,LLDSC,(W1) ;SAVE POINTER
MOVE T2,NTDSS ;GET STRING POINTER
MOVE T3,NTDSC ;GET COUNT
CALL MOVST1 ;MOVE THW STRING
MOVEI T1,OPNUNQ ;MUST VERIFY UNIQUENESS OF NAME
SETZM T2 ;NEED TO CHECK OBJECTS ONLY
CALL OBJSRC ;DO IT
JRST NODESC ;NOT FOUND. CAN HAVE IT
LOAD T2,LLFRK,(T1) ;FOUND ONE. WHICH JOB?
HLRZ T2,FKJOB(T2) ;""
MOVEI T1,DCNX9 ;DUPICATE NAME ERROR
CAME T2,JOBNO ;THIS JOB?
JRST SRCFAL ;NO. CAN'T HAVE IT
NODESC: CALL GTSBLK ;GET A BLOCK FOR USER NAME
JRST SRCFAL ;NONE
STOR T1,LLUSR,(W1) ;SAVE IT
CALL GTSBLK ;GET A BLOCK FOR THE ACCOUNT
JRST SRCFAL ;NONE
STOR T1,LLACT,(W1) ;SAVE IT
CALL GTSBLK ;GET A BLOCK FOR THE PASSWORD
JRST SRCFAL ;NONE
STOR T1,LLPSW,(W1) ;SAVE IT
CALL ASGWDW ;GO GET WINDOW PAGES
JRST SRCFAL ;FAILED
MOVEI T1,LLSLIS ;GET INITIAL STATE
STOR T1,LLSTA,(W1) ;SET UP THIS LISTENER
SETONE LLFOB,(W1) ;SAY THIS IS AN OBJECT
LLLULK ;FREE LOCK
RETSKP ;AND DONE
;COROUTINE OF SRCOPN TO CHECK FOR UNIQUE NAME
OPNUNQ: SAVET ;SAVE TEMPS
LOAD T2,LLNAM,(T1) ;GET OBJECT NUMBER
OPSTR <CAME T2,>,LLNAM,(W1) ;SAME AS OURS?
RET ;NO. NO CONFLICT THEN
LOAD T1,LLDSC,(T1) ;GET ITS DESCRIPTOR
LOAD T2,LLDSC,(W1) ;GET OURS
CALL CMPSTR ;SEE IF A MATCH
RET ;NO.
RETSKP ;YES. COULD BE A PROBLEM
;OPEN FAILURE ROUTINE. CLEAN UP FROM ATTEMPT
SRCFAL: DECR DCCUR ;ONE LESS LINK ON FAILURE
EXCH T1,W1 ;GET BLOCK ADDRESS
CALL DELNOD ;FREE THE NODE
LLLULK ;UNLOCK THE TREE
MOVE T1,W1 ;GET ERROR CODE
RET ;AND FAIL
;LOCAL ROUTINE TO GET A STRING BLOCK FOR SRCOPN.
;**;[2962] Change 1 line at GTSBLK:+0 DML 10-MAY-83
GTSBLK: MOVEI T1,SIZ39 ;[2962] THE PROPER SIZE
CALL GETBLK ;GET ONE
RET ;FAILED
RETSKP ;GOT IT
ENDAV. ;END ACVAR
;CRTLNK - ROUTINE TO CREATE A LOGICAL LINK
;
;ACCEPTS IN T1/ ADDRESS OF LOGICAL LINK BLOCK
; T2/ ADDRESS OF ATRIBUTE LIST
; T3/ OBJECT,,COUNT OF BYTES IN DESCRIPTOR
; T4/ POINTER TO DESCRIPTOR STRING
; TRVARS -- NTCNT,NTPNT,NTOBJ,NTDSC,NTDSS,NTHST,NTHSC
;
; CALL CRTLNK
;RETURNS: +1 FAILED, ERROR CODE IN T1
; +2 SUCCESS
CRTLNK::ACVAR <W1,W2,W3> ;GET A WORK REGISTER
STKVAR <CRLATR,CRLCIB,CRLCNT,CRLOBJ,CRLHST,CRLHSC,CRLDSS,CRLDSC>
; SAVE INPUT ARGUMENTS
MOVE W1,T1 ;SAVE LL BLOCK ADDRESS
MOVEM T2,CRLATR ;SAVE ATTRIBUTE LIST POINTER
HLRZM T3,CRLOBJ ;SAVE OBJECT
HRREM T3,CRLDSC ;SAVE COUNT OF BYTES IN DESCRIPTOR
MOVEM T4,CRLDSS ;SAVE DESCRIPTOR POINTER
MOVE T1,CRLOBJ ;GET OBJECT
STOR T1,LLFNM,(W1) ;SAVE IT
SKIPG T3,CRLDSC ;ANY DESCRIPTOR GIVEN
JRST DSCNUL ;NO, SKIP MOVING STRING
LOAD T1,LLFDS,(W1) ;GET DESCRIPTOR BLOCK
MOVE T2,CRLDSS ;GET JSB STRING POINTER
CALL MOVST1 ;AND MOVE IT
;ALL STRINGS ARE MOVED. MUST GENERATE CONNECT-INITIATE MESSAGE
DSCNUL: MOVEI T1,CONLEN+MSHDR+RTHLEN ;GET A BLOCK FOR THE CI
CALL GETRES ;GET A RESIDENT BLOCK
RETBAD () ;FAILED, RETURN ERROR
MOVEM T1,CRLCIB ;SAVE BLOCK ADDRESS
HRLI T1,(<POINT 8,>) ;MAKE A BYTE POINTER
ADDI T1,MSHDR ;RESERVE HEADER
MOVEM T1,LLBPTR(W1) ;SAVE IN LL BLOCK
SETZM LLBPCT(W1) ;ZERO COUNT
MOVE T1,W1 ;LL BLOCK ADDRESS
MOVEI T2,CNMRFL+CNMCI ;MESSAGE FLAGS
CALL RTHDCI ;PUT ON ROUTING HEADER AND FLAGS
CALL DOSRVS ;INSERT LL ADDRESSES AND STANDARD SERVICES
;..
; ..
;NOW BUILD OBJECT ADDRESSING FIELDS
SKIPG CRLDSC ;HAVE A COUNT FOR DESCRIPTOR
JRST [ MOVEI T2,OBJZRO ;GET OBJECT TYPE ZERO INDICATOR
CALL ONEBYT
MOVE T2,CRLOBJ ;GET OBJECT TYPE
CALL ONEBYT
LOAD T1,LLFDS,(W1) ;GET DESCRIPTOR STRING
SETZRO LLFDS,(W1) ;CLEAR LOCATION
CALL RELBLK ;RELEASE UNUSED BLOCK
MOVE T1,W1 ;RESTORE LL BLOCK ADDRESS
JRST DSCDON] ;DONE WITH THIS
MOVEI T2,OBJONE ;GET OBJECT TYPE 1
CALL ONEBYT ;STORE HEADER
MOVE T2,CRLOBJ ;GET OBJECT NUMBER
CALL ONEBYT ;PUT IT IN
LOAD T3,LLFDS,(T1) ;GET DESCRIPTOR STRING
CALL ASCIIZ ;PUT IT IN
;MESSAGE BUILT. INSERT SENDER'S NAME AND USER DATA
DSCDON: MOVEI T2,OBJONE ;SENDER IS A TASK
CALL ONEBYT
MOVEI T2,OBJTSK ;THE I.D. FOR TASK
CALL ONEBYT
LOAD T3,LLTSK,(T1) ;GET POINTER TO TASK NAME
CALL ASCIIZ ;AND INSERT IT
;NOW CHECK FOR AND INSERT ANY OPTIONAL DATA
MOVE T1,W1 ;GET LOGICAL LINK BLOCK ADDRESS
MOVE T2,CRLATR ;GET ADDRESS OF ATTRIBUTE LIST
CALL INSATR ;GO INSERT ATTRIBUTES IN MESSAGE
MOVEI T2,LLSCIS ;GET NEW STATE
STOR T2,LLSTA,(T1) ;STORE NEW STATE
LLLULK ;RELEASE TREE NOW
MOVE T2,CRLCIB ;GET BLOCK ADDRESS
LOAD T3,LLHSN,(T1) ;GET NODE NUMBER
ADD T3,[NSCONS] ;OFFSET INTO "CONNECTS SENT" TABLE
AOS (T3) ;INCR THE COUNT
CALL SNDCTL ;SEND MESSAGE TO THE NETWORK
RETSKP ;AND DONE FOR NOW
ENDAV. ;END ACVAR
;INSATR - ROUTINE TO INSERT ATTRIBUTE VALUES INTO THE CI MESSAGE
;
;ACCEPTS IN T1/ LOGICAL LINK BLOCK ADDRESS
; T2/ ADDRESS OF ATTRIBUTE TABLE
; CALL INSATR
;RETURNS: +1 ALWAYS
INSATR: STKVAR <INALLB,INAATR,INAPNT,INACNT>
MOVEM T1,INALLB ;SAVE LOGICAL LINK ADDRESS
MOVEM T2,INAATR ;SAVE ATTRIBUTE LIST ADDRESS
MOVE T1,INALLB ;GET LOGICAL LINK BLOCK ADDRESS
SETZ T2, ;DEFAULT MENU BYTE
CALL ONEBYT ;PUT IT IN
MOVE T3,LLBPTR(T1) ;GET POINTER TO MENU
MOVEM T3,INAPNT ;SAVE IT
MOVEI T2,1 ;ASSUME WILL BE PRESENT
MOVEM T2,INACNT ;SET IT
MOVEI T2,.PFUDT ;SEE IF USER I.D. GIVEN
MOVE T3,INAATR ;GET ATTRIBUTE LIST ADDRESS
CALL GETATR ;IS IT?
JRST [ SETZM T2 ;NOT THERE.
CALL ONEBYT ;SAY IS NULL
JRST DOSPW1] ;AND GO ON TO PASSWORD
CALL ASCIIZ ;PUT IN THE DATA
DOSPW1: MOVEI T2,.PFPWD ;SEE IF A PASSWORD IS GIVEN
MOVE T3,INAATR ;GET ATTRIBUTE LIST ADDRESS
CALL GETATR ;IS IT?
JRST [ MOVEI T2,.PFBPW ;NO. SEE ABOUT ALTERNATE FORM
MOVE T3,INAATR ;GET ATTRIBUTE LIST ADDRESS
CALL GETATR ;IS IT?
JRST [ SETZ T2, ;NO.
CALL ONEBYT ;INSERT A PLACEHOLDER
JRST DOACT] ;AND GO ON
MOVEI T4,BININ ;YES. INSERT BINARY VALUE
JRST DOPSWD]
MOVEI T4,ASCIIZ ;YES. INSERT ASCII FORM
DOPSWD: CALL 0(T4) ;PUT IT IN
DOACT: MOVEI T2,.PFACN ;SEE IF AN ACCOUNT
MOVE T3,INAATR ;GET ATTRIBUTE LIST ADDRESS
CALL GETATR ;IS IT?
MOVEI T3,[0] ;NO. PUT IN NULL STRING
CALL ASCIIZ ;YES. PUT IT IN
; ..
; ..
MOVEI T2,.PFOPT ;HAVE OPTIONAL USER DATA?
MOVE T3,INAATR ;GET ATTRIBUTE LIST ADDRESS
CALL GETATR ;IS IT?
JRST [ MOVEI T2,.PFBOP ;NO. TRY OTHER FORM
MOVE T3,INAATR ;GET ATTRIBUTE LIST ADDRESS
CALL GETATR ;IS IT?
JRST INMENU ;NO USER DATA
MOVEI T4,BININ ;FOUND IT
JRST DOOPT] ;PUT IT IN
MOVEI T4,ASCIIZ ;FOUND ASCII FORM
DOOPT: MOVEI T2,2 ;SAY FOUND OPTDATA
IORM T2,INACNT ;TO THE MENU
CALL 0(T4) ;INSERT IT
INMENU: MOVE T2,INACNT ;GET FINAL MENU
DPB T2,INAPNT ;PUT IT IN THE MESSAGE
RET ;DONE, RETURN
;STRSAV - ROUTINE TO SAVE NAME STRINGS ON LINK CREATION
;
;ACCEPTS IN TRVARS: NTHST, NTHSC, NTDSS, NTDSC, NTOBJ
; T1/ ADDRESS OF LL BLOCK
; T2/ COUNT OF HOST STRING BYTES,,COUNT OF DESCRIPTOR STRING BYTES
; T3/ ADDRESS OF HOST NAME STRING BLOCK
; T4/ ADDRESS OF DESCRIPTOR STRING BLOCK
; CALL STRSAV
;RETURNS: +1 FAILED, ERROR CODE IN T1
; +2 SUCCESS, STRINGS SAVED
STRSAV::SAVEQ
STKVAR <SSVHST,SSVHSC>
HLREM T2,SSVHSC ;SAVE HOST STRING BYTE COUNT
MOVEM T3,SSVHST ;SAVE HOST NAME STRING POINTER
MOVE Q1,T1 ;SAVE LL BLOCK ADDRESS
SKIPG T3,SSVHSC ;HAVE A HOST NAME?
JRST [SETONE LLLOC,(Q1) ;NOTE THIS IS A LOCAL LINK
RETSKP] ;DONE
CAME T3,OURCNT ;SAME COUNT AS OUR NAME?
JRST DCNOP0 ;NO. CAN'T BE LOCAL
MOVE T1,SSVHST ;YES, COULD BE US - GET BLOCK POINTER
AOS T1 ;POINT TO ACTUAL TEXT STRING
HRLI T1,440700 ;MAKE A BYTE POINTER
MOVE T2,[POINT 7,OURNAM] ;GET POINTER TO OUR NAME
SETZ T4, ;NO OFFSET IN COMPARISON
CALL COMPAR ;SEE IF THE SAME
JRST DCNOP0 ;NO. SAVE IT THEN
SETONE LLLOC,(Q1) ;YES, NOTE LOCAL LINK
MOVE Q3,OURNUM ;GET LOCAL NODE NUMBER
STOR Q3,LLHSN,(Q1) ;PUT IT IN LL BLOCK
RETSKP ;DONE
;THE ATTEMPTED CONNECTION IS NOT LOCAL
DCNOP0: MOVE T1,SSVHST ;GET ADDRESS OF STRING BLOCK
AOS T1 ;POINT TO ACTUAL TEXT
HRLI T1,440700 ;MAKE A BYTE POINTER
MOVEM T1,SSVHST ;SAVE THE BYTE POINTER
MOVNI Q2,BIGNOD ;MAKE
HRLZS Q2 ; AOBJN
HRRI Q2,1 ; WORD
MOVE T3,SSVHSC ;GET HOST NAME CHARACTER COUNT
MOVEI T4,40 ;COMPARE ASCII
MOVNS T4 ; TO SIXBIT
NOINT ;NO INTERRUPTIONS
LOCK NMAPLK ; WHILE TABLE LOCKED
DCNOP4: MOVE T1,SSVHST ;RETRIEVE THE BYTE POINTER TO THE HOST
HRLI T2,440600 ;MAKE A BYTE POINTER
HRRI T2,NODMAP(Q2) ; TO THE NAME IN THE TABLE
TLO T3,400000 ;MAY BE DIFFERENT LENGTH STRINGS
CALL COMPAR ;ARE THEY THE SAME?
JRST [AOBJN Q2,DCNOP4 ;NO, TRY FOR MORE
UNLOCK NMAPLK ;DONE WITH
OKINT ; THE LOCK
RETBAD (NSPX24)] ;DIDN'T FIND IT
UNLOCK NMAPLK ;DONE WITH
OKINT ; THE LOCK
;USER'S NODE NAME IS IN NODE NAME MAPPING TABLE
IFN DN20SW,< ;LOOK FOR OTHER MCBS
MOVEI Q3,2 ;NEXT DTE TO CHECK
DCNOP7: MOVE T2,Q3 ;PRESERVE DTE NUMBER
IMULI T2,2 ;CALC CORRECT OFFSET FOR NODE NAME
HRRI T2,ITSNAM(T2) ;MAKE A BP
HRLI T2,440700 ; TO THE NODE NAME
MOVE T1,SSVHST ;GET BP TO HOST NAME
MOVE T3,SSVHSC ;GET NO. OF CHARS IN HOST NAME
SETZ T4, ;NO CONVERSION FACTOR
CALL COMPAR ;DO THEY MATCH?
JRST DCNOP2 ;NO, NOT FOR THIS MCB
SKIPGE T2,MCBDTE(Q3) ;DTE ACTIVE?
TXNE T2,NTSHUT ;YES, NODE SHUTTING DOWN?
RETBAD (NSPX18) ;ERROR RETURN - NO PATH
MOVEI Q3,(Q3) ;GET DTE #
MOVEI T1,3 ;SAY PHASE III NODE
JRST DCNOP5 ;MOVE ON
DCNOP2: CAIGE Q3,3 ;DONE ALL DTES YET?
IFNSK. ;NO
AOS Q3 ;MAKE NEXT DTE
JRST DCNOP7 ;TRY IT
ENDIF.
>
MOVE T1,[POINT 2,NODTBL] ;POINT TO REACHABLE NODES TABLE
HRRZ T2,Q2 ;GET NODE NUMBER TO PLAY WITH
ADJBP T2,T1 ;POINT TO NODE
LDB T1,T2 ;GET ITS INFO
SKIPN T1 ;IS IT REACHABLE
RETBAD (NSPX18) ;ERROR - NO PATH TO DESTINATION NODE
;NODE IS REACHABLE
MOVSI Q3,-DCN ;MAKE AOBJN WORD FOR MCB SEARCH
DCNOP1: SKIPGE T2,MCBDTE(Q3) ;IS THIS FE ACTIVE?
TXNE T2,NOTMCB ;YES, IS IT AN MCB?
JRST DCNOP3 ;NO, CAN'T USE IT
TXNN T2,NTSHUT ;YES, IS IT SHUTTING DOWN?
JRST DCNOP5 ;NO, EVERYTHING OK
RETBAD (NSPX18) ;YES - NO PATH TO DESTINATION NODE
DCNOP3: AOBJN Q3,DCNOP1 ;TRY NEXT FE
RETBAD (NSPX18) ;ERROR - NO PATH TO DESTINATION NODE
;STORE INFO IN LL BLOCK
DCNOP5: CAIE T1,2 ;PHASE II ROUTING?
IFSKP. ;YES
MOVX T1,.NSP31 ;SAY NSP 3.1
ELSE. ;NO, PHASE III
MOVX T1,.NSP32 ;SAY NSP 3.2
ENDIF.
STOR T1,LLLKP,(Q1) ;IN LL BLOCK
DCNOP6: STOR Q3,LLPRT,(Q1) ;SAVE PORT NUMBER
LOAD T1,LLHST,(Q1) ;GET PLACE TO PUT HOST'S NUMERIC NAME
HRLI T1,440700 ;MAKE A BYTE POINTER
HRRZ T2,Q2 ;GET THE NODE NUMBER
STOR T2,LLHSN,(Q1) ;SAVE REMOTE HOST NUMBER
MOVEI T3,^D10 ;IN DECIMAL
NOUT ;MAKE IT 7-BIT ASCII
JFCL
RETSKP
ENDSV.
;COMPARE TWO STRINGS
;ACCEPTS: T1/ BYTE POINTER TO STRING 1
; T2/ BYTE POINTER TO STRING 2
; T3/ FLAGS ,, COUNT OF CHARS. IN STRING
; 1B0 = STRINGS MAY BE OF DIFFERENT LENGTH
; T4/ OFFSET (IF NEEDED)
;RETURNS: +1 NO MATCH
; +2 MATCH
;PRESERVES T3,T4
COMPAR: ACVAR <W1,W2,W3> ;GET SOME REGS
MOVE W1,T1 ;COPY POINTER TO FIRST STRING
MOVE W2,T2 ;COPY POINTER TO SECOND STRING
HRRZ W3,T3 ;SAVE COUNT
SOS W3 ;FIXUP COUNTER FOR THE LOOP
CMPRLP: ILDB T1,W1 ;GET NEXT BYTE
ILDB T2,W2 ;GET THIS ONE'S NEXT
SKIPE T4 ;IS THERE AN OFFSET?
ADD T1,T4 ;YES, MAKE THE ADJUSTMENT
CAME T1,T2 ;MATCH?
RET ;NO. NO MATCH THEN
SOJGE W3,CMPRLP ;DO ALL THE BYTES
TLZN T3,400000 ;CHECKING WITH NODMAP?
RETSKP ;NO, MATCH
CAIL T3,6 ;DONE MAX CHARACTERS IN A NODE NAME?
RETSKP ;YES, MATCH
ILDB W3,W2 ;NO, GET THE NEXT BYTE
SKIPE W3 ;ONE THERE?
RET ;YES, NO MATCH
RETSKP ;A MATCH!!!!
ENDAV.
;ROUTINE TO INSERT THE LL ADDRESSES IN A MESSAGE.
;ACCEPTS: T1/ LL BLOCK ADDRESS
RESCD
PUTLLR: TDZA T2,T2 ;SAY SEND 0 SOURCE IF IN CIR
PUTLLA: SETOM T2 ;SAY ALWAYS SEND CURRENT SOURCE
ACVAR <W1> ;GET A WORK REG
MOVE W1,T2 ;SAVE ENTRY FLAG
LOAD T2,LLHLK,(T1) ;GET DEST ADDRESS
CALL TWOBYT ;PUT IT IN
LOAD T2,LLLNK,(T1) ;GET SOURCE ADDRESS
JUMPN W1,PUTLL1 ;IF NO REJECT CHECK, GO ON
LOAD W1,LLSTA,(T1) ;GET LINK STATE
CAIN W1,LLSCIR ;IS THIS A LINK REJECT THEN?
SETZM T2 ;YES. SEND 0 SOURCE ADDRESS
PUTLL1: CALLRET TWOBYT ;AND PUT IT IN
ENDAV. ;END ACVAR
SWAPCD
;ROUTINE TO INSERT CI/CC COMMON FIELDS
; T1/ LL BLOCK
DOSRVS: STKVAR <MSGFLG>
MOVEM T2,MSGFLG ;SAVE FLAGS
CALL PUTLLA ;PUT IN LL ADDRESSES
MOVEI T2,CISRVS+CIMSCT ;ASSUME SEG COUNTS
TMNE LLIMS,(T1) ;WANT MESSAGE COUNTS?
MOVEI T2,CISRVS+CIMCNT ;YES
CALL ONEBYT ;PUT IN SERVICES BYTE
MOVEI T2,LNKPRI ;GET DEFAULT PRIORITY
CALL ONEBYT
LOAD T3,IOMODE ;GET FILE OPEN MODE
CAIN T3,.GSSMB ;SMALL BUFFER MODE?
SKIPA T3,[SMLSEG] ;YES, USE SMALL SEGSIZ
MOVE T3,SEGSZ ;NO, USE NORMAL SEGMENT SIZE
MOVE T2,MSGFLG ;GET MESSAGE TYPE
CAIE T2,CIMMFL ;IS IT A CI?
JRST [ LOAD T2,LLSWG,(T1) ;NO, A CC - GET CI'S SEG SIZE
CAMLE T2,T3 ;LESS THAN OURS?
MOVE T2,T3 ;NO, USE OURS
TMNE LLLOC,(T1) ;LOCAL CONNECTION?
JRST DOSRV1 ;YES, NO NEED TO CHECK FURTHER
LOAD T4,LLPRT,(T1) ;GET PORT NUMBER
CAMLE T2,NSPMAX(T4) ;LESS THAN PORT'S SEGSIZ?
MOVE T2,NSPMAX(T4) ;NO, USE PORT'S
JRST DOSRV1]
MOVE T2,T3 ;USE SEGSIZE SELECTED ABOVE
DOSRV1: STOR T2,LLSWG,(T1) ;PUT SEG SIZE IN LL BLOCK
TMNE LLFDI,(T1) ;OPEN IN WORD MODE?
MOVEI T2,WSEGSZ ;YES. GET PROPER SEG SIZE
JN LLINT,(T1),[ MOVEI T2,ISEGSZ ;IF INTERNAL LINK USE DIFFERENT
JRST .+1 ] ; SEGMENT SIZE
SETZRO LLFDI,(T1) ;INIT THIS FLAG
CALLRET TWOBYT
ENDSV.
;ROUTINE TO BUILD A ROUTING HEADER.
;ACCEPTS: T1/ LL BLOCK ADDRESS
; T2/ PROPER MESSAGE FLAGS
RESCD
RTHDCI: SAVEAC <T2> ;PRESERVE THE FLAGS
STKVAR <MSGFLG> ;TO SAVE THE FLAGS
MOVEM T2,MSGFLG ;SAVE FLAGS
JN LLLOC,(T1),RTHDC1 ;JUMP IF LOCAL
MOVEI T2,RTFLG ;ROUTING FLAGS ARE FIRST
CALL ONEBYT ;PUT IN FLAGS
LOAD T3,LLHST,(T1) ;GET HOST STRING POINTER
CALL ASCIIZ ;GO PUT IN IMAGE ASCII FIELD
MOVEI T3,OURNAM ;GET OUR NAME
CALL ASCIIZ ;PUT IT IN
RTHDC1: MOVE T2,MSGFLG ;GET MESSAGE FLAGS
CALLRET ONEBYT ;AND PUT IT IN THE MESSAGE
;ROUTINE TO INSERT IMAGE-ASCII FIELD INTO MESSAGE
; T2/ COUNT OF BYTES
;ACCEPTS: T3/ BLOCK ADDRESS
ASCIIZ: MOVX T2,1B1 ;ENTRY FOR ZERO TERMINATED STRING
ASCIIC: ACVAR <W1,W2,W3> ;GET A REGISTER
MOVE W1,[POINT 7,0(T3)] ;GET A BYTE POINTER
STKVAR <ASCCNT> ;THE COUNT
MOVEM T2,ASCCNT ;SAVE COUNT
SETZB T2,W3 ;SET COUNT REGS
CALL ONEBYT ;PUT IN ZERO COUNT
MOVE W2,LLBPTR(T1) ;SAVE BYTE POINTER
ASCIIL: SOSGE ASCCNT ;HAVE ANY MORE BYTES?
JRST ASCIID ;NO. GO WRAP UP
ILDB T2,W1 ;GET NEXT BYTE
JUMPG T2,ASCII1 ;NO. IS THIS A NULL?
ASCIID: DPB W3,W2 ;YES.
RET ;ALL DONE
ASCII1: CALL ONEBYT ;STASH IT
AOJA W3,ASCIIL ;AND DO ENTIRE STRING
ENDAV. ;END ACVAR
SWAPCD
;MOVE A BINARY FIELD
MVBNRY: ACVAR <W1,W2> ;GET WORK REGS
MOVE W1,[POINT 8,0(T3)] ;GET A POINTER
MOVE W2,T2 ;SAVE COUNT
MVBNR1: CALL ONEBYT ;PUT IN THE BYTE
SOJL W2,R ;ANY MORE?
ILDB T2,W1 ;GET NEXT BYTE
JRST MVBNR1 ;GO STASH IT
ENDAV. ;END ACVAR
;MORE ROUTINES
;INSERT BINARY QUANTITY IN A MESSAGE
;ACCEPTS: 3/ BLOCK ADDRESS
BININ: ACVAR <W1,W2,W3> ;GET A WORK REG
SETZB T2,W2
HRLI T3,(<POINT 7,>) ;FORM A BYTE POINTER
CALL ONEBYT ;PUT IN COUNT BYTE
MOVE W3,LLBPTR(T1) ;SAVE POINTER
BININ1: MOVSI W1,-3 ;DO 3 BYTES
SETZ T2, ;AN ACCUMULATOR
BININ2: CALL BINXT ;GET NEXT BYTE
JRST BININ3 ;DONE
LSH T2,3 ;ADJUST ACCUMULATOR
ADDI T2,-"0"(T4) ;PUT IN NEXT BYTE
AOBJN W1,BININ2 ;DO AN OCTET
BININ3: TRNN W1,-1 ;FOUND ANY?
JRST BININ4 ;NO. ALL DONE
CALL ONEBYT ;YES. PUT IT IN
AOS W2 ;ONE MORE IN
JUMPGE W1,BININ1 ;IF MORE TO DO, DO THEM
BININ4: DPB W2,W3 ;PUT IN FINAL COUNT
RET ;AND DONE
BINXT: ILDB T4,T3 ;GET NEXT BYTE
JUMPE T4,R ;IF THE NULL, ALL DONE
RETSKP ;A VALID BYTE
ENDAV. ;END ACVAR
;ROUTINES TO INSERT BYTES IN MESSAGE AND ACCOUNT FOR THEM
;INSERT ONE BYTE. ACCEPTS: T2/ THE BYTE
; T1/ LL BLOCK ADDRESS
;PRESERVES ALL REGISTERS
RESCD
ONEBYT: IDPB T2,LLBPTR(T1) ;STASH BYTE
AOS LLBPCT(T1) ;ACCOUNT FOR IT
RET ;DONE
;ROUTINE TO INSERT TWO BYTES, EXTENDED OR NOT
;ACCEPTS: T1/ LL BLOCK ADDRESS
; T2/ THE BYTE
;MAY CLOBBER T2.
TWOBYT: CALL ONEBYT ;STORE LOW ORDER BYTE
ROT T2,-^D8 ;GET HIGH ORDER BYTE
CALLRET ONEBYT ;STORE IT
SWAPCD
;ROUTINES TO FIND AND PARSE ARBITRARY ATTRIBUTES
;FIND ATTRIBUTE:
;ACCEPTS: T2/ PREFIX VALUE
;RETURNS: +1/ NO SUCH PREFIX
; +2/ FOUND. T3=POINTER TO VALUE STRING
FNDATR: LOAD T3,FILATL,(JFN) ;GET LIST OF ATTRIBUTES
CALLRET GETATR ;GO FIND ATTRIBUTE
;GETATR - ROUTINE TO FIND AN ATTRIBUTE
;
;ACCEPTS IN T2/ PREFIX VALUE
; T3/ ADDRESS OF ATTRIBUTE LIST
; CALL GETATR
;RETURNS: +1 FAILED, NO SUCH PREFIX
; +2 SUCCESS, WITH T3/ POINTER TO VALUE STRING
GETATR: JUMPE T3,R ;IF NO MORE, ALL DONE
OPSTR <CAME T2,>,PRFXV,(T3) ;IS THIS THE ONE WE WANT
JRST [ LOAD T3,PRFXL,(T3) ;NO. GET NEXT
JRST GETATR] ;AND LOOK AT IT
MOVEI T3,1(T3) ;GET POINTER TO BLCOK
RETSKP ;AND SAY WE FOUND IT
;ROUTINE TO MAKE PROPER BYTE POINTER AND RETURN MAX COUNT FOR A
;BUFFER.
;ACCEPTS: T1/ WINDOW ADDRESS
; T3/ BYTE SIZE
;RETURNS: +1
; T1/ BYTE POINTER
; T2/ COUNT
MAKPTR: MOVE T4,T3 ;SAVE IT
IORI T3,4400 ;MAKE A BYTE POINTER
DPB T3,[POINT 12,T1,11]
MOVEI T2,44 ;BITS IN A WORD
IDIVI T2,0(T4) ;COMPUTE BYTES IN A WORD
LSH T2,PGSFT ;COMPUTE BYTES IN A PAGE
RET ;AND DONE
;SPECIAL ROUTINE TO MAKE AN INPUT POINTER FOR FLOW FROM NETWORK
MAKINP::PUSH P,T3 ;SAVE BYTE SIZE
CALL MAKPTR ;GET A POINTER
POP P,T3 ;GET BACK BYTE SIZE
CAIN T3,44 ;WORD MODE?
HRRZS T1 ;YES. GET ADDRESS ONLY
RET ;DONE
SUBTTL MTOPR Utility Functions
;READ LINK TASK NAME
NTRTN:: LOAD T2,LLTSK,(T1) ;GET THE NAME
NTCPY: CALL NTACPY ;DO THE WORK
CALL BLKULK ;RELEASE LL BLOCK
RETSKP ;AND DONE
;READ FOREIGN HOST NAME
NTRHN:: CALL MTRDCK ;VERIFY LINK STATE
JRST [ MOVEI T1,DCNX11 ;SAY NOT CONNECTED ANYMORE
JRST SQOBAD] ;AND DONE
TMNE LLLOC,(T1) ;LOCAL LINK?
JRST [MOVEI T2,OURNAM ;YES
CALLRET NTCPY] ;GO COPY OUR NAME TO USER
LOAD T2,LLHSN,(T1) ;GET THE NODE NUMBER
NOINT ;NO INTERRUPTIONS
LOCK NMAPLK ; WHILE TABLE LOCKED
HRLI T2,440600 ;POINT TO NODE'S
HRRI T2,NODMAP(T2) ; ALPHABETIC NAME
UMOVE T3,3 ;GET USER'S STRING POINTER
CALL NTRNAM ;GO RETURN NAME TO USER
UMOVEM T3,3 ;RETURN UPDATED BP TO USER
SETZ T4, ;GIVE HIM
XCTBU [IDPB T4,T3] ; THE NULL
UNLOCK NMAPLK ;DONE WITH
OKINT ; THE LOCK
CALL BLKULK ;UNLOCK THE LL BLOCK
RETSKP
;RETURN A NODE NAME TO THE USER
;ACCEPTS: 2/ BP TO NODE NAME
; 3/ USER'S BP
;RETURNS: +1 T3/ UPDATED USER'S BP
NTRNAM: TLC T3,-1
TLCN T3,-1 ;WANT DEFAULT?
HRLI T3,(<POINT 7,>) ;USE. DO IT
ACVAR <W1> ;GET A WORK REG
MOVEI W1,6 ;MAX. OF 6 CHARS IN NAME
NTRHN1: ILDB T4,T2 ;GET A BYTE
JUMPE T4,R ;IF NULL, DONE
ADDI T4,40 ;CONVERT FROM 6-BIT TO 7-BIT
XCTBU [IDPB T4,T3] ;GIVE IT TO USER
SOJG W1,NTRHN1 ;IF MORE, GO GET NEXT
RET ;DONE
ENDAV.
;WORKER ROUTINE TO COPY AN ASCII STRING TO THE USER.
;ACCEPTS: 2/ ADDRESS OF STRING
;RETURNS: +1
;
;PRESERVES T1
NTACPY: UMOVE T3,3 ;GET USER'S STRING POINTER
TLC T3,-1
TLCN T3,-1 ;WANT DEFAULT?
HRLI T3,(<POINT 7,>) ;USE. DO IT
ACVAR <W1> ;GET A WORK REG
MOVE W1,[POINT 7,0(T2)] ;POINT TO SOURCE
NTCPY1: ILDB T4,W1 ;GET A BYTE
JUMPE T4,NTCPY2 ;IF NULL, ALL DONE
XCTBU [IDPB T4,T3] ;STORE BYTE
JRST NTCPY1 ;DO THEM ALL
NTCPY2: UMOVEM T3,3 ;RETURN BYTE POINTER
XCTBU [IDPB T4,T3] ;APPEND A NULL
RET ;AND DONE
ENDAV. ;END ACVAR
;MTOPR FUNCTIONS CONTINUED...
;RDSTS - GET LINK STATUS
;
;ACCEPTS IN T1/ ADDRESS OF LOGICAL LINK BLOCK (ASSUMED LOCKED)
; CALL RDSTS
;RETURNS: +1 ALWAYS, WITH T3/ LINK STATUS
RDSTS:: LOAD T3,LLRSN,(T1) ;GET REASON IN CASE NOW DISCONNECTED
TMNE LLFOB,(T1) ;IS THIS AN OBJECT?
TXO T3,MO%SRV ;YES
LOAD T2,LLSTA,(T1) ;GET CURRENT STATE
CAIN T2,LLSRUN ;RUNNING?
TXO T3,MO%CON ;YES. ALL CONNECTED
CAIN T2,LLSLIS ;LISTENING?
TXO T3,MO%WFC ;YES. WAITING FOR INCOMING CONNECT
CAIN T2,LLSCIS ;CI SENT?
TXO T3,MO%WCC ;YES, WAITING FOR CONNECTION TO COMPLETE
CAIN T2,LLSCCS ;CC SENT?
TXO T3,MO%WCC ;YES, WAITING FOR CONNECTION TO COMPLETE
CAIN T2,LLSCIR ;CI RECEIVED?
TXO T3,MO%WCC ;YES, WAITING FOR CONNECT TO COMPLETE
CAIE T2,LLSDIR ;DI RECEIVED?
CAIN T2,LLSABT ;OR ABORTED?
JRST [ TXO T3,MO%ABT ;YES. ASSUME ABORTED
JE LLFDI,(T1),.+1
TXC T3,MO%ABT!MO%SYN ;NO. SWITCH TO SYNCH DI
JRST .+1] ;AND PROCEED
TMNE LLFIM,(T1) ;HAVE WHOLE MESSAGE IN BUFFER?
TXO T3,MO%EOM ;YES
SKIPE LLMSI(T1) ;HAVE ANY INTERRUPT MESSAGES?
TXO T3,MO%INT ;YES. SAY SO
JN LLLWC,(T1),[TXO T3,MO%LWC ;IF LINK WAS CONNECTED, SO NOTE
JRST .+1] ;CONTINUE
RET ;DONE, RETURN
;MTOPR FUNCTION TO RETURN OBJECT USED TO CONNECT TO THE SERVER
NTRCN:: JE LLFOB,(T1),[CALL BLKULK ;FREE BLOCK
RETBAD (DESX9)] ;AND RETURN ERROR
LOAD T2,LLSTA,(T1) ;GET CURRENT STATE
CAIN T2,LLSLIS ;LISTENING?
JRST [ MOVEI T1,DCNX11 ;YES. NOT CONNECTED
JRST SQOBAD] ;GO CLEAN UP AND GIVE ERROR
LOAD T2,LLSOB,(T1) ;GET OBJECT USED TO CONNECT
UMOVEM T2,3 ;RETURN TO USER
MTDON: CALL BLKULK ;FREE BLOCK
RETSKP ;AND DONE
;MORE MTOPR ROUTINES...
;READ USER NAME
NTRUS:: CALL MTOBJ ;MAKE SURE IS RUNNING OBJECT
JRST SQOBAD ;NOT
LOAD T2,LLUSR,(T1) ;GET BLOCK ADDRESS
CALLRET NTCPY ;GO DO IT
;READ ACCOUNT STRING
NTRAC:: CALL MTOBJ ;MAKE SURE IS RUNNING OBJECT
JRST SQOBAD ;NOT
LOAD T2,LLACT,(T1) ;GET BLOCK
CALLRET NTCPY ;AND GO DO IT
;COMMON ROUTINE TO VERIFY OBJECT
MTOBJ: JE LLFOB,(T1),MTOBJ1 ;MAKE SURE IS OBJECT
MTRDCK: LOAD T2,LLSTA,(T1) ;IT IS. GET CURRENT STATE
CAIE T2,LLSCIR ;IN CIR STATE?
CAIN T2,LLSCCS ; OR CC SENT?
RETSKP ;YES. IS GOOD THEN
MTRNCK::LOAD T2,LLSTA,(T1) ;GET STATE
CAIN T2,LLSRUN ;RUNNING?
RETSKP ;YES.
MTOBJ1: RETBAD (DCNX8) ;NOT A RUNNING OBJECT
;READ PASSWORD
NTRPW:: CALL MTOBJ ;MAKE SURE IS RUNNING OBJECT
JRST SQOBAD ;NOT
LOAD T2,LLPSW,(T1) ;GET BLOCK ADDRESS
LOAD T3,LLPCT,(T1) ;AND THE COUNT
NTCPYB: UMOVEM T3,4 ;RETURN COUNT
ACVAR <W1,W2> ;GET WORK REGS
MOVE W2,T3 ;SAVE COUNT
MOVE W1,[POINT 8,0(T2)] ;GET POINTER TO DATA
UMOVE T3,3 ;GET USER SP
TLC T3,-1
TLCN T3,-1
HRLI T3,(<POINT 7,>) ;FORM DEFAULT
JRST NTCP11 ;GO MAKE SURE IS AT LEAST ONE
NTCP1: ILDB T4,W1 ;GET NEXT BYTE
XCTBU [IDPB T4,T3] ;STORE IT
NTCP11: SOJGE W2,NTCP1 ;AND DO THEM ALL
UMOVEM T3,3 ;RETURN BYTE POINTER
NTMTGD: CALL BLKULK ;FREE THE BLOCK
RETSKP ;AND DONE
ENDAV. ;END ACVAR
;READ OPT DATA
NTRDA:: LOAD T2,LLOPT,(T1) ;GET OPTIONAL DATA BLOCK
LOAD T3,LLUCT,(T1) ;GET COUNT
CALLRET NTCPYB ;AND GO DO IT
;SET CONNECT DONE INTERRUPT CHANNEL
MTSETC::CALL CHKCHL ;VERIFY CHANNEL
RET ;BAD
JUMPL T2,RSKP ;IF NO CHANGE, DONE
STOR T2,LLPIC,(T1) ;SAVE CHANNEL
LOAD T3,LLSTA,(T1) ;GET STATE OF LINK
CAIL T3,LLSCIR ;NEED INTERRUPT NOW?
CALL CONINT ;YES. GIVE IT
RETSKP ;AND DONE
;SET INTERRUPT MESSAGE CHANNEL
MTSETI::CALL CHKCHL ;CHECK CHANNEL
RET ;BAD
JUMPL T2,RSKP ;IF NO CHANGE, ALL DONE
STOR T2,LLPII,(T1) ;SAVE CHANNEL
SKIPE LLMSI(T1) ;HAVE ANY INT MESSAGES
CALL INTINT ;YES. DO INTERRUPT NOW THEN
RETSKP ;AND DONE
;SET DATA ARRIVED INT CHANNEL
MTSETD::CALL CHKCHL ;VERIFY CHANNEL
RET
JUMPL T2,RSKP ;IF NO CHANGE, RETURN
STOR T2,LLDRC,(T1) ;SAVE CHANNEL
SKIPE LLOMSG(T1) ;ANY MESSAGES?
CALL DATINR ;YES. GIVE INT THEN
RETSKP ;DONE
;ROUTINE TO VERIFY CHANNEL #
; T2/ CHANNEL
;RETURNS: +1 BAD CHANNEL
; +2 VALID CHANNEL
CHKCHL: CAIN T2,.MOCIA ;CLEAR?
JRST [ SETZM T2 ;IF SO. UNSETTING
RETSKP] ;SO, RETURN A ZERO
CAIN T2,.MONCI ;NO CHANGE?
JRST [ SETOM T2 ;YES
RETSKP] ;SO SAY SO
CAIL T2,44 ;WITHIN RANGE?
JRST CHKILL ;NO
CAILE T2,5 ;WITHIN RANGE 0-5?
CAIL T2,^D23 ;OR WITHIN RANGE 23-35
AOSA T2 ;YES. A GOOD CHANNEL
JRST CHKILL ;NO. ILLEGAL
RETSKP ;RETURN GOOD VALUE
CHKILL: RETBAD (ARGX13) ;INVALID CHANNEL
;COMMON ROUTINE TO GENERATE INTERRUPT RECEIVED INTERRUPT
INTINT: SAVET ;SAVE REGS
CALL TELINT ;GO NOTIFY DRIVER IF THIS IS AN INTERNAL LINK
LOAD T2,LLFRK,(T1) ;GET FORK TO INT
OPSTR <SKIPN T1,>,LLPII,(T1) ;HAVE AN INT CHANNEL?
RET ;NO
SOS T1 ;YES
CALLRET PSIRQ ;GO DO THE INTERRUPT
;TELINT - ROUTINE TO NOTIFY THE DRIVER WHEN AN INTERRUPT MSG IS RECEIVED
; FOR AN INTERNAL LOGICAL LINK
;
;ACCEPTS IN T1/ ADDRESS OF LOGICAL LINK BLOCK
; CALL TELINT
;RETURNS: +1 ALWAYS, WITH DRIVER NOTIFIED
TELINT: JE LLINT,(T1),R ;IF NOT AN INTERNAL LINK, THEN DONE
SAVET ;PRESERVE TEMPORARY AC'S
LOAD T4,LLVEC,(T1) ;GET DRIVER VECTOR ADDRESS
LOAD T1,LLDRV,(T1) ;GET DRIVER CORRELATION CODE
CALLRET @.NSINT(T4) ;NOTIFY DRIVER AND RETURN
;MORE MTORP FUNCTIONS...
;RECEIVE INTERRUPT MESSAGE
MTRDIN::MOVE T2,[IFIW![ XCTBUU [IDPB T2,3] ;ROUTINE TO RETURN BYTE
RET ]] ; AND DONE
UMOVE T3,3 ;GET USER'S DESTINATION POINTER
CALL RDINT ;GO READ AN INTERRUPT MESSAGE
JRST [ JUMPE T2,SQOBAD ;FAILED, RETURN ERROR
JRST ULKRET ] ; OR BLOCK IF NEEDED
UMOVEM T3,4 ;RETURN BYTE POINTER
UMOVEM T4,3 ;RETURN COUNT TO USER
PUSH P,T2 ;STASH MESSAGE ADDRESS
CALL BLKULK ;DONE WITH BLOCK
POP P,T1 ;RETRIEVE MESSAGE ADDRESS
CALL RELRES ;RELEASE MESSAGE
RETSKP ;AND DONE
;ULKRET - ROUTINE TO UNLOCK LOGICAL LINK BLOCK AND GIVE BLOCK-NEEDED RETURN
;
;ACCEPTS IN JFN/ ADDRESS OF JFN BLOCK
; JRST ULKRET
;RETURNS TO CALLER WITH BLKF SET
ULKRET: TQO <BLKF> ;NOTE BLOCK IS NEEDED
EXCH T1,FILLLB(JFN) ;SAVE ERROR. GET BLOCK ADDRESS
CALL BLKULK ;FREE BLOCK
IFN NSPSW,<
CALL CHKLLB
>
EXCH T1,FILLLB(JFN) ;GET BACK ERROR
RETBAD () ;AND DONE
;RDINT - ROUTINE TO READ AN INTERRUPT MESSAGE
;
;ACCEPTS IN T1/ ADDRESS OF LOGICAL LINK BLOCK
; T2/ ADDRESS OF ROUTINE TO STORE BYTES
; (SHOULD ASSUME BYTE POINTER IS IN T3)
; T3/ DESTINATION BYTE POINTER
; CALL RDINT
;RETURNS: +1 FAILED, T2/ 0 => DO NOT BLOCK, T2/ -1 => BLOCK
; +2 SUCCESS, INTERRUPT MESSAGE DELIVERED, WITH
; T2/ ADDRESS OF MESSAGE
; T3/ UPDATED COUNT
; T4/ UPDATED POINTER
RDINT:: ACVAR <W1>
STKVAR <RDICNT,RDIPTR,RDIRTN>
MOVEM T1,W1 ;SAVE LL BLOCK ADDRESS
MOVEM T2,RDIRTN ;SAVE ROUTINE TO STORE BYTES
MOVEM T3,RDIPTR ;SAVE DESTINATION BYTE POINTER
RDINT1: CALL MTRNCK ;CHECK STATE
JRST RDINX ;FAIL, NOT IN RUN STATE
SKIPN T2,LLMSI(T1) ;HAVE AN INT MESSAGE?
JRST [ MOVX T1,DCNX15 ;NO INTERRUPT MESSAGE AVAILABLE
JRST RDINX ] ;RETURN ERROR
MOVEI T2,1 ;ASK FOR ONE MORE
MOVEI T3,MSLSI ; INTERRUPT MESSAGE
CALL SNDLS ;SEND MESSAGE
JRST [ MDISMS ;CAN'T, WAIT A BIT
MOVE T1,W1 ;RETRIEVE THE LL BLOCK ADDRESS
JRST RDINT1] ;TRY IT AGAIN
MOVE T2,LLMSI(T1) ;GET BACK MESSAGE
LOAD T4,MSDTC,(T2) ;GET COUNT
MOVEM T4,RDICNT ;SAVE COUNT
MOVEM T4,W1 ;AND SAVE AS LOOP VARIABLE
MOVE T3,RDIPTR ;GET DESTINATION POINTER SUPPLIED
TLC T3,-1
TLCN T3,-1
HRLI T3,(<POINT 7,>) ;GET DEFAULT
MOVEM T3,RDIPTR ;SAVE POINTER
MOVE T4,MSBPTR(T2) ;GET POINTER TO MESSAGE DATA
JRST MTRDI2 ;GO MOVE DATA
MTRDI1: ILDB T2,T4 ;GET NEXT BYTE
CALL @RDIRTN ;STORE A BYTE
MTRDI2: SOJGE W1,MTRDI1 ;DO THEM ALL
MOVE T2,LLMSI(T1) ;GET BACK MESSAGE
SETZM LLMSI(T1) ;NONE NOW
MOVE T3,RDICNT ;RESTORE COUNT
MOVE T4,RDIPTR ;RESTORE POINTER
RETSKP ;DONE, RETURN SUCCESS
; HERE ON AN ERROR
RDINX: TDZA T2,T2 ;NOTE BLOCK NOT WANTED
RDINB: SETOM T2 ;BLOCK NEEDED
RET ;FAIL
ENDAV. ;END ACVAR
;MORE MTOPR'S.... SEND INTERRUPT MESSAGE
MTSNIN::UMOVE T4,4 ;GET COUNT
UMOVE T3,3 ;GET BP
;**;[2929]REMOVE 1 LINE AT MTSNIN: + 2L DSC 22-MAR-83
MOVE T2,[IFIW![ XCTBUU [ILDB T2,3]
RET]] ;ROUTINE TO GET BYTES
CALL SNINT ;SEND THE INTERRUPT MESSAGE
JRST SQOBAD ;FAILED, RETURN ERROR
UMOVEM T3,3 ;STORE UPDATED BYTE POINTER
MOVE T1,FILLLB(JFN) ;GET BACK BLOCK ADDRESS
CALL BLKULK ;UNLOCK THE LOGICAL LINK BLOCK
RETSKP ;DONE, RETURN SUCCESS
;SNINT - ROUTINE TO SEND AN INTERRUPT MESSAGE
;
;ACCEPTS IN T1/ ADDRESS OF LOGICAL LINK BLOCK
; T2/ ADDRESS OF ROUTINE TO GET BYTES
; (PLACES BYTE IN T2, ASSUMES PTR IN T3)
; T3/ BYTE POINTER FOR GETTING BYTES
; T4/ COUNT OF BYTES TO SEND
; CALL SNINT
;RETURNS: +1 FAILED, ERROR CODE IN T1
; +2 SUCCESS, WITH T3/ UPDATED BYTE POINTER
SNINT:: ACVAR <W1> ;CAN SEND IT
STKVAR <SIMLLB,SIMRTN,SIMPTR,SIMCNT>
MOVEM T2,SIMRTN ;SAVE ROUTINE ADDRESS
MOVEM T3,SIMPTR ;SAVE POINTER FOR GETTING BYTES
MOVEM T4,SIMCNT ;SAVE COUNT OF BYTES TO SEND
CALL MTRNCK ;MAKE SURE IS RUNNING
RET ;NOT IN RUN STATE, FAIL
MOVE T4,SIMCNT ;GET COUNT
CAILE T4,MAXINT ;WITHIN RANGE?
JRST [ MOVEI T1,DCNX12 ;ARG TOO LARGE
RET ] ;RETURN ERROR
JE LLMIC,(T1),[ MOVEI T1,DCNX14 ;ANY QUOTA?
RET ] ;NO, FAIL
MOVEI T1,INTLEN+MSHDR ;LENGTH
CALL GETRES ;GET SOME SPACE
RET ;NO SPACE, FAIL
MOVE W1,T1 ;SAVE BLOCK ADDRESS
MOVEI T2,MSHDR(T1) ;GET TO DATA PART
HRLI T2,(<POINT 8,>)
MOVE T1,FILLLB(JFN) ;GET LL BLOCK
MOVEM T2,LLBPTR(T1) ;THE POINTER
SETZM LLBPCT(T1) ;INIT COUNT
MOVEI T2,DATMFL+DATFLI+DATINT ;FLAGS
STOR T2,MSMFL,(W1) ;SAVE IN MESSAGE
CALL RTHDCI ;PUT ON ROUTE HEADER AND FLAGS
CALL PUTLLA ;PUT IN LL ADDRESSES
LOAD T2,LLISN,(T1) ;GET SEG #
AOS T2 ;NEXT ONE
ANDI T2,7777 ;MOD 4096
STOR T2,MSSEG,(W1) ;SAVE IN MESSAGE
STOR T2,LLISN,(T1) ;LAST SEG SENT
CALL TWOBYT ;PUT IN DATA PART
DECR LLMIC,(T1) ;ONE LESS PIECE OF QUOTA
MOVE T4,SIMCNT ;GET COUNT
MOVE T3,SIMPTR ;GET POINTER
TLC T3,-1
TLCN T3,-1
HRLI T3,(<POINT 7,>) ;FORM DEFAULT
MOVEM T3,SIMPTR ;SAVE UPDATED POINTER
JRST MSTSN2 ;GO SEND THEM
MSTSN1: CALL @SIMRTN ;GET NEXT BYTE
CALL ONEBYT ;STORE IN MESSAGE
MSTSN2: SOJGE T4,MSTSN1 ;DO THEM ALL
LOAD T2,LLLNK,(T1) ;GET LINK ADDRESS
STOR T2,MSLLA,(W1) ;SAVE IN MESSAGE
MOVEI T2,MSLSI ;GET TYPE OF THIS MESSAGE
STOR T2,MSTOM,(W1) ;SAVE IN MESSAGE
MOVE T2,W1 ;GET MESSAGE
CALL SNDSEG ;SEND IT
MOVE T3,SIMPTR ;RETURN UPDATED POINTER
RETSKP ;DONE, RETURN SUCCESS
ENDAV. ;END ACVAR
;MTOPR ROUTINE TO RETURN OBJECT-DESCRIPTOR.
;RETURNS OBJECT-DESCRIPTOR IN STRING POINTED TO BY USER AC3
;RETURNS USER,GROUP CODE IN AC4 (OR A ZERO IN AC4 IF NONE).
NTRCOB::JE LLFOB,(T1),NTRCB1 ;MAKE SURE IT IS AN OBJECT
LOAD T2,LLSTA,(T1) ;GET STATE
CAIE T2,LLSCIR ;RECIEVED A CI?
CAIN T2,LLSRUN ;OR RUNNING?
SKIPA ;YES
NTRCB1: JRST [ CALL BLKULK ;NO. UNLOCK BLOCK
JRST MTOBJ1] ;AND DONE
MOVE T2,LLUSGP(T1) ;GET USER,GROUP
UMOVEM T2,4 ;RETURN IT
LOAD T2,LLFNM,(T1) ;GET OBJ NUMBER USED IN CI
MOVE T3,[-OBJENT,,OBJPRO+1] ;SET UP FOR SEARCH
NTRCB2: HRRZ T4,0(T3) ;GET OBJECT NUMBER
CAIN T4,0(T2) ;THIS THE ONE?
JRST [ HLRZ T2,0(T3) ;YES. GET POINTER TO NAME
JRST NTRCB3] ;AND PROCEED
AOBJN T3,NTRCB2 ;NO. LOOK AT NEXT
STKVAR <NTRCBN> ;NOT FOUND
MOVEI T3,12 ;CONVERT OBJECT NUMBER TO TEXT
HRROI T1,NTRCBN
NOUT
JFCL
MOVE T1,FILLLB(JFN) ;GET BACK LL BLOCK
MOVEI T2,NTRCBN ;GET POINTER TO NUMBER
NTRCB3: CALL NTACPY ;PUT OBJECT STRING IN USER SPACE
LOAD T3,LLFDS,(T1) ;GET DESCRIPTOR
SKIPN 0(T3) ;HAVE ONE?
JRST MTDON ;NO. ALL DONE THEN
MOVEI T2,[ASCIZ /-/] ;YES. PUT IN PUNCTUATION
CALL NTACPY
LOAD T2,LLFDS,(T1) ;GET BACK DESCRIPTOR STRING
CALLRET NTCPY ;AND DONE
ENDSV.
;MTOPR FUNCTION TO REFUSE A CONNECTION
;*************** NOTE *******************
;THIS CODE HAS A RACE IN THAT THE LINK IS IMMEDIATELY CONVERTED
;INTO A "LISTENER". THEREFORE, WHEN THE DC ARRIVES, THERE
;IS POTENTIAL CONFUSION OVER THE OWNER. THE
;PROBABILITY OF FAILURE IS <1/(HOSTS*2**16)> WHERE,
;"HOSTS" = # OF HOSTS ON THE NET.
NTRJCT: CALL NTRFCI ;SEND DI
JRST SQOBAD ;NEED TO BLOCK
CALL FLUSH ;KILL OF BUFFERS (IF ANY)
CALL CLRBLK ;RESET LL BLOCK
JRST SQOBAD ;FAILED
MOVEI T2,LLSLIS ;GET NEW STATE
STOR T2,LLSTA,(T1) ;SET IT BACK TO LISTENING
CALLRET NTMTGD ;AND DONE
;MTOPR FUNCTION TO CLOSE A CONNECTION
NTMTCZ::LOAD T2,LLSTA,(T1) ;GET CURRENT STATE
CAIN T2,LLSCIR ;REALLY REJECTING A CONNECTION?
CALLRET NTRJCT ;YES. GO DO IT
CAIN T2,LLSDIQ ;DI QUEUED?
JRST NTMCZ0 ;YES. GO ON THEN
CAIE T2,LLSCCS ;CONNECT SENT?
CAIN T2,LLSRUN ;OR RUNNING?
SKIPA ;YES, GO
JRST NTRCB1 ;NO. CAN'T DISCONNECT THEN
UMOVE T2,2 ;GET REASON,,.MOCLZ
HLRZS T2 ;GET TYPE OF CLOSE
SKIPE T2 ;SYNCHRONOUS DISCONNECT?
JRST [ CALL FLUSH ;NO, ABORT CLOSE. CLEAN OUT MESSAGES
JRST NTMCZ0] ;AND SEND THE MESSAGE
JE LLQOU,(T1),NTMCZ0 ;IF QUEUER EMPTY, GO ON.
; CALL MOVSEG ;PICK UP ACKS
; JRST OUTWAT ;NEED TO BLOCK
MOVEI T2,CHKEMP ;WAIT FOR ALL ACKS
JRST OUTWAT ; AND GO DO IT
;READY TO SEND THE MESSAGE
NTMCZ0: MOVEI T2,LLSDIQ ;SET STATE
STOR T2,LLSTA,(T1) ;""
CALL NTRFCI ;SEND DI
JRST SQOBAD ;MUST WAIT
MOVEI T2,LLSDIS ;NEW STATE
STOR T2,LLSTA,(T1) ;STORE IT
CALLRET NTMTGD ;AND DONE
;ROUTINE TO ACCEPT A CONNECTION
NTACPT::STKVAR <<OPTDAT,4>>
LOAD T2,LLSTA,(T1) ;GET STATE
CAIE T2,LLSCIR ;PROPER STATE
JRST NTRCB1 ;NO. ERROR
MOVEI T3,OPTDAT ;MOVE OPTDATA IF ANY
UMOVE T2,4 ;GET COUNT
UMOVE T4,3 ;GET USER'S POINTER
CALL NTMVOP ;GET OPTDATA ARG
JRST SQOBAD ;TOO LONG
CALL CNFCOM ;GO CONFIRM IT
JRST SQOBAD ;NEED TO WAIT
CALLRET NTMTGD ;DONE
;MTOPR TO RETURN MAX SEGMENT SIZE FOR THE LINK
MTGSS:: CALL MTRNCK ;MUST BE RUNNING
JRST SQOBAD ;NOT
LOAD T2,LLSWG,(T1) ;GET MAX SEG SIZE
UMOVEM T2,3 ;RETURN TO USER
CALLRET NTMTGD ;AND DONE
;COMMON ROUTINE USED TO SET UP FOR CALL TO SNDDI TO DISCONNECT
;OR REFUSE A CONNECTION.
NTRFCI: STKVAR <<OPTDAT,4>> ;GET SOME SPACE TO HOLD USER DATA
MOVEI T3,OPTDAT ;WHERE TO MOVE OPTDATA TO
UMOVE T2,4 ;GET COUNT
UMOVE T4,3 ;GET USER'S POINTER
CALL NTMVOP ;DO IT
RETBAD() ;TOO LONG
XCTU [HLRZ T2,2] ;GET REASON
MOVEI T4,CNMRFL+CNMDI ;GET PROPER FLAGS
CALL SNDDI ;SEND THE DI
JRST [ TQO <BLKF> ;SCHED TEST ALREADY IN T1, NOTE BLOCK NEEDED
RET ] ;COME BACK AGAIN LATER
CALL SNDCTL ;SEND THE MESSAGE
RETSKP ;AND DONE
;ROUTINE TO COPY OPTDATA TO A BUFFER AND RETURN PROPER OPTDATA
;ARG
; T2/ INPUT BYTE COUNT
; T3/ BUFFER ADDRESS
; T4/ INPUT POINTER
;RETURNS: +1 TOO LONG
; +2 DONE
NTMVOP::ACVAR <W1,W2,W3>
STKVAR <NMVCNT,NMVPTR>
TLC T4,-1 ;CHECK FOR SPECIAL POINTER
TLCN T4,-1 ;IS IT?
HRLI T4,(<POINT 7,>) ;YES. CONVERT IT THEN
MOVEM T4,NMVPTR ;SAVE POINTER TO INPUT
MOVEM T2,NMVCNT ;SAVE COUNT OF BYTES
MOVE W3,T3 ;SAVE BUFFER ADDRESS
SETZM T3 ;ASSUME NO DATA
MOVE T4,NMVCNT ;GET COUNT
JUMPE T4,RSKP ;IF NONE, NO ARG
SKIPL T4 ;COUNT MUST BE POSITIVE
CAILE T4,MAXOPT ;WITHING LIMITS
RETBAD (DCNX12) ;NO. TOO LONG
STOR T4,CNTFLD,W3 ;BUILD RETURN ARG
MOVE W2,[POINT 8,0(W3)] ;GET POINTER TO SOURCE
MOVE T3,NMVPTR ;GET USER'S POINTER
NTMVO1: XCTBU [ILDB W1,T3] ;GET BYTE
IDPB W1,W2 ;STASH IT
SOJG T4,NTMVO1 ;COPY THEM ALL
MOVE T3,W3 ;GET ARG
RETSKP ;AND DONE
ENDAV. ;END ACVAR
SUBTTL Routines to CLose a Logical Link
NETCLZ::ACVAR <W1,W2> ;GET SOME WORK REGISTERS
MOVE W2,T1 ;SAVE ENTRY FLAGS
CALL NETUOU ;UNDO OUTPUT
NETCL1: MOVE T1,FILLLB(JFN) ;GET LL BLOCK ADDRESS
CALL BLKLLK ;LOCK THE BLOCK
JRST [ TXNN W2,CZ%ABT ;ABORT?
JRST WATBLK ;NO. CONVENTIONAL WAIT THEN
MDISMS ;YES. WAIT HERE
JRST NETCL1] ;AND TRY AGAIN
; CALL MOVSEG ;PICK UP LATENT ACKS
; MOVE T1,FILLLB(JFN) ;GET BACK LL BLOCK ADDRESS
IFQN. LLTTA,(T1) ;SET HOST IN EFFECT?
CALL TTCLSH ;(T1/) YES, CLEAR IT
ENDIF.
LOAD T2,LLSTA,(T1) ;GET CURRENT STATE
JRST @CLZSTA-1(T2) ;GO DO PROPER THING
;STATE ROUTINES OF NETCLZ
;LINK IN RUN STATE
CLZRUN: TXNE W2,CZ%ABT ;WANT ABORT?
CLZDI: JRST [ MOVEI T2,.DCX9 ;YES. SAY USER ABORT
JRST CLZEMP] ;AND GO SEND DI,ETC...
LOAD T3,LLBSZ,(T1) ;GET BYTE SIZE
CALL MAKPTR ;COMPUTE MAX BYTES IN BUFFER
MOVE T1,FILLLB(JFN) ;GET BACK POINTER
HLRZ T3,FILBCT(JFN) ;SEE IF ANY BYTES
SUBI T2,0(T3) ;COMPUTE BYTES TO BE SENT
;**;[3171] Remove 2 lines CEG 4-OCT-84
TMNN LLFLO,(T1) ;FLOW NOW TO F/S?
;**;[3155] Remove 1 line, add 2 new lines CEG 30-AUG-84
JRST [ JUMPE T3,CLZCMS ;[3155] YES, IF NO MORE BYTES TO SEND, MOVE ON
JRST CLZDI0] ;[3155] GO FORCE OUT REMAINING BYTES
JUMPE T2,CLZCMS ;NO, ANY BYTES TO SEND?
SETONE LLFEM,(T1) ;YES, SAY EOM IN THIS BUFFER
;**;[3155] Add label CEG 30-AUG-84
CLZDI0: CALL OUTRR ;[3155] GO FORCE OUT DATA
;**;[6714] Add 1 line CEG 29-MAR-85
RETBAD () ;COULDN'T. WAIT A WHILE
MOVE T1,FILLLB(JFN) ;RESTORE LL BLOCK ADDRESS
;ALL DATA OUT. WAIT FOR ACKS
CLZCMS: SETZ T2, ;SYNCHRONOUS DI
JE LLQOU,(T1),CLZEMP ;IF ALL ACK'ED, READY TO GO
MOVEI T2,CHKEMP ;WAIT FOR EMPTY
JRST OUTWAT ;AND ARRANGE FOR THE WAIT
CLZEMP: STOR T2,LLRSN,(T1) ;SAVE REASON CODE
CLZDIQ: SETZM T2 ;ASSUME SYNCHRONOUS CLOSE
TXNE W2,CZ%ABT ;ABORT CLOSE ?
SETOM T2 ;YES, NOTE SO
SETZM T3 ;NO OPTIONAL DATA
CALL CLZSDI ;GO SEND DI FOR CLOSE
JRST [ TXNE W2,CZ%ABT ;ABORT?
JRST CLZABT ;YES. GO RELEASE BLOCK THEN
TQO <BLKF> ;COULD NOT SEND DI, MUST TRY AGAIN LATER
JRST SQOBAD ] ;BLOCK AND TRY AGAIN
CLZWDC: TXNE W2,CZ%ABT ;ABORT CLOSE?
JRST [ SETONE LLSDE,(T1) ;YES. DISSOCIATE PROCESS AND LINK
CALL BLKULK ;UNLOCK THE LL BLOCK
JRST CLZDN1] ;AND GO FINISH UP
MOVEI T2,CHKDCR ;WAIT FOR DC TO COME BACK
JRST OUTWAT ;ALSO, REQUEST BLOCK
;MORE CLOSE ROUTINES
;DC HAS ARRIVED. FIND OUT IF IT WHAT WE WANTED
CLZDIR: ;CLOSE IN DI RECEIVED STATE
CLZABT:
REPEAT 0,<
LOAD T2,LLRSN,(T1) ;GET REASON
SKIPE T2 ;NON-SPECIAL ERROR?
CAIN T2,.DCX42 ;OR REPLY TO DI?
JRST CLZDON ;YES. GOOD CODE
TXNN W2,CZ%ABT ;NOT. ARE WE ABORTING?
JRST [ CALL BLKULK ;NO. SYNCH DI DIDN'T WORK
RETBAD (DCNX11)] ;SAY SO
>
CLZDON: CALL FLUSH ;CLEAN UP Q'S
LLLOCK ;LOCK THE TREE
CALL DELNOD ;GET RID OF NODE
LLLULK
OKINT ;MATCH BLKLOK THAT IS NEVER MATCHED
CLZDN1: DECR DCCUR ;GIVING BACK A LINK
HLRZ T1,FILWND(JFN) ;GET OUTPUT WINDOW
SKIPE T1
CALL RELPAG ;RELEASE IT
HRRZ T1,FILWND(JFN) ;GET INPUT WINDOW
SKIPE T1
CALL RELPAG ;RELEASE IT
SETZM FILBFO(JFN)
SETZM FILBFI(JFN)
RETSKP ;AND DONE
ENDAV. ;END ACVAR
;CLZSDI - ROUTINE TO SEND A DI FOR A CLOSE
;
;ACCEPTS IN T1/ LOGICAL LINK BLOCK ADDRESS
; T2/ 0 IF SYNCHRONOUS CLOSE, -1 IF ABORT
; T3/ COUNT OF BYTES IN OPTIONAL DATA (0 IF NONE)
; T4/ ADDRESS OF OPTIONAL DATA BUFFER
; CALL CLZSDI
;RETURNS: +1 FAILED, COULD NOT SEND DI
; +2 SUCCESS, WITH DI SEND
CLZSDI::ASUBR <CDILLB,CDIFLG,CDICNT,CDIBUF>
STKVAR <<CDIOPT,4>>
MOVE T1,CDILLB ;GET LOGICAL LINK BLOCK ADDRESS
MOVEI T2,LLSDIQ ;DI IS NOW QUEUED
STOR T2,LLSTA,(T1) ;MARK STATE CHANGE
SETZM T3 ;START BY ASSUMING NO OPTIONAL DATA
SKIPE CDICNT ;ANY OPTIONAL DATA ?
JRST [ MOVEI T3,CDIOPT ;YES, GET DESTINATION BUFFER ADDRESS
MOVE T2,CDICNT ;GET NUMBER OF BYTES IN OPTIONAL DATA
MOVE T4,CDIBUF ;GET SOURCE BUFFER ADDRESS
HRLI T4,(POINT 8,) ;AND FORM A POINTER TO OPTIONAL DATA
CALL NTMVOP ;CHECK OPTIONAL DATA, SETUP T3 WITH COUNT
RETBAD () ;FAILED, RETURN ERROR TO USER
JRST .+1] ;T3 SET UP, CONTINUE WITH SETUP FOR DI MESSAGE
LOAD T2,LLRSN,(T1) ;GET OUR REASON
MOVEI T4,CNMRFL+CNMDI ;IS A DI
CALL SNDDI ;GO SEND DI
JRST [ SKIPN CDIFLG ;ABORT ?
RETBAD () ;NO. BLOCK THEN
TQZ <BLKF> ;YES. UNDO BLOCK
BUG (CLZDIN)
MOVE T1,CDILLB ;GET BACK LOGICAL LINK BLOCK ADDRESS
RETBAD ()] ;AND DONE
CALL SNDCTL ;SEND THE MESSAGE
CLZDQ1: MOVEI T2,LLSDIS ;SAY DI IS SENT
STOR T2,LLSTA,(T1)
RETSKP ;DONE, RETURN SUCCESS
;ROUTINE TO SEND A DI OR A DC
;ACCEPTS: T1/ LL BLOCK ADDRESS
; T2/ REASON
; T3/ <COUNT>B5+PTR TO USER DATA
; T4/ FLAGS
;RETURNS: +1/ COULDN'T. TEST ROUTINE IN T1
; +2/ ALL SENT
SNDDI: ASUBR <LLBLK,DISRSN,DIUDAT,DIFLGS>
STKVAR <LLMSGB>
MOVX T1,DILEN+MSHDR ;GET A BLOCK FOR THE DI
CALL GETRES ;GET IT
JRST TIMWAT ;FAILED
MOVEM T1,LLMSGB ;SAVE BLOCK ADDRESS
MOVE T1,LLBLK ;RETRIEVE LL BLOCK ADDRESS
LOAD T3,LLLNK,(T1) ;GET LL ID
MOVE T2,LLMSGB ;RETRIEVE MESSAGE ADDRESS
STOR T3,MSLLA,(T2) ;PUT LL ID IN MESSAGE HEADER
MOVE T3,DIFLGS ;GET THE MESSAGE FLAGS
STOR T3,MSMFL,(T2) ;PUT FLAGS IN MESSAGE HEADER
MOVEI T3,MSHDR(T2) ;GET TO START OF DATA PORTION
HRLI T3,(<POINT 8,>) ;MAKE A BYTE POINTER
MOVEM T3,LLBPTR(T1) ;SAVE POINTER IN LL BLOCK
SETZM LLBPCT(T1) ;INIT THE BYTE COUNT
MOVE T2,DIFLGS ;GET FLAGS
CALL RTHDCI ;PUT ON ROUTING HEADER AND FLAGS
CALL PUTLLR ;PUT IN LL ADDRESSES
MOVE T2,DISRSN ;GET REASON
CALL TWOBYT ;PUT IT IN
MOVE T3,DIFLGS ;SEE IF DI OR DC
CAIN T3,CNMRFL+CNMDC ;DC?
JRST SNDDI1 ;YES. NO OPTDATA THEN
MOVE T3,DIUDAT ;GET USER DATA
LOAD T2,CNTFLD,T3 ;YES. GET COUNT
SETZRO CNTFLD,T3 ;CLEAR THOSE BITS
CALL MVBNRY ;PUT IN THE DATA
SNDDI1: MOVE T2,LLMSGB ;GET BACK BLOCK ADDRESS
RETSKP ;AND DONE
;ROUTINES CALLED FROM FILE SYSTEM TO SWITCH THE SENSE OF THE
;JFN. FIRST, ROUTINE TO SWITCH JFN TO INPUT SENSE
NETINP::CALL NETUOU ;GO UNDO OUTPUT IF NECESSARY
CALL NETUIN ;UNDO INPUT
MOVE T1,FILLLB(JFN) ;GET LL BLOCK
CALL BLKLLK ;LOCK IT UP
JRST [ MDISMS ;WAIT FOR LOCK
JRST NETINP] ;AND TRY AGAIN
TQO <FILINP> ;NOW WILL SWITCH TO INPUT
LOAD T3,LLSTA,(T1) ;GET STATE
CAIN T3,LLSDIS ;DID USER TERMINATE LINK ?
JRST [ CALL BLKULK ;YES, UNLOCK LOGICAL LINK BLOCK
SETZM T1 ;NOTE NO MORE INPUT AVAILABLE
RET ] ;AND DONE
CAIE T3,LLSRUN ;RUNNING?
CAIN T3,LLSDIR ;OR STILL AVAILBALE FOR INPUT?
SKIPA ;YES
JRST NETIN2 ;NO. GO ON
HRRZ T3,FILBCT(JFN) ;GET COUNT OF BYTES
TMNE LLFLI,(T1) ;IS FLOW FROM NETWORK?
SKIPN T3 ;NO. NEED BYTES?
CALL NETSET ;YES. GO GET SOME BYTES
MOVE T1,FILLLB(JFN) ;GET BACK LL BLOCK ADDRESS
TQZ <BLKF> ;IGNORE BLOCKING IF SET
NETIN2: CALL BLKULK ;FREE LOCK
MOVE T2,FILBFI(JFN) ;GET INPUT BYTE POINTER
HRRZ T1,FILBCT(JFN) ;GET COUNT
MOVE T3,FILLLB(JFN) ;GET LL BLOCK
TMNE LLFLI,(T3) ;IS INPUT FLOW TO THE F/S?
SKIPE LLMSI(T3) ;YES. FREE OF INT MESSAGES
CALL [ SETZB T1,FILLEN(JFN) ;NO. NO BYTES THEN
TQZ <FILINP> ;AND SAY NO GOOD DATA IN JFN BLOCK
RET] ;DONE
NETSCM: MOVEM T1,FILCNT(JFN) ;TO THE JFN
MOVEM T2,FILBYT(JFN) ;STORE NEW POINTER
SETZM FILBYN(JFN) ;ZERO BYTE NUMBER
JUMPE T1,R ;IF NO COUNT, RETURN NOW
TMNN LLFIM,(T3) ;EOM IN THE INPUT BUFFER?
AOS T1 ;NO. MAKE SINR COME BACK THEN
MOVEM T1,FILLEN(JFN) ;AND MAKE COUNT THE LENGTH
RET ;DONE
;ROUTINE TO SET UP FOR OUTPUT
NETOUP::CALL NETUIN ;UNDO INPUT IF NECESSARY
TQOE <FILOUP> ;NOW DOING OUTPUT?
RET ;YES. ALL DONE
MOVE T2,FILBFO(JFN) ;GET POINTER
HLRZ T1,FILBCT(JFN) ;GET COUNT
MOVE T3,FILLLB(JFN) ;GET LL BLOCK
TMNN LLFLO,(T3) ;IS OUTPUT FLOW FROM THE F/S?
SETZM T1 ;NO.
JRST NETSCM ;AND DONE
SUBTTL Sequential I/O JSYS's
;WORKER ROUTINE TO FORCE OUT ALL DATA.
OUTRR:: STKVAR <MSIZE,MBLOCK,MLODR>
; CALL MOVSEG ;PICK UP ACKS,ETC...
; JRST OUTWAT ;ERROR OCCURRED
CALL NETUOU ;UNDO OUTPUT
MOVE T1,FILLLB(JFN) ;GET LL BLOCK
CALL SKPFLO ;IS FLOW FROM THE FILE-SYSTEM
JRST OUTR0E ;NO. ALL SET TO GO THEN
;FLOW IS FROM THE FILE SYSTEM. COMPUTE BYTES NOW IN OUTPUT BUFFER
;AND SWITCH FLOW TO THE NETWORK
CALL CLRFLO ;SWITCH FLOW TO THE NETWORK
CALL GETBSZ ;GET BYTE SIZE FOR THIS LINK
HLRZ T1,FILWND(JFN) ;GET WINDOW ADDRESS
CALL MAKPTR ;GET MAX BYTES IN BUFFER
MOVEM T1,FILBFO(JFN) ;PUT IN STARTING BYTE POINTER
HLRZ T3,FILBCT(JFN) ;GET REMAINING COUNT
SUBI T2,0(T3) ;COMPUTE BYTES IN THE BUFFER
MOVE T1,FILLLB(JFN) ;get logical link block address
CALL GETBSZ ;GO GET BYTE SIZE FOR THIS LINK
CAIN T3,44 ;WORD MODE?
JRST [ IMULI T2,44 ;YES. COMPUTE TOTAL BITS
ADDI T2,7 ;ROUND UP
LSH T2,-3 ;AND NOW COMPUTE FULL BYTES
JRST .+1] ;AND CONTINUE
MOVE T1,FILLLB(JFN) ;GET LL BLOCK ADDRESS
TMNN LLFEM,(T1) ;EOM?
JUMPE T2,RSKP ;NO, DONE
HRLM T2,FILBCT(JFN) ;STORE COUNT TO SEND
OUTR0E: MOVE T1,FILLLB(JFN) ;GET LL BLOCK ADDRESS
TMNN LLFEM,(T1) ;EOM?
JRST OUTR00 ;NO, GO BACK FOR MORE
JRST OUTRR3 ;YES, CONTINUE OUTPUT PROCESSING
; ..
;OUTRR CONTINUED.... TRY TO MAKE A MESSAGE
OUTR00: MOVE T1,FILLLB(JFN) ;GET BACK LL BLOCK ADDRESS
OUTRR1: HLRZ T2,FILBCT(JFN) ;SEE IF ANY MORE BYTES
JUMPE T2,[CALL SETFLO ;NONE - SWITCH FLOW TO FILE-SYSTEM
CALL GETBSZ ;GET BYTE SIZE
HLRZ T1,FILWND(JFN) ;GET BUFFER PAGE
CALL MAKPTR ;MAKE OUTPUT POINTER
MOVEM T1,FILBFO(JFN) ;SET UP NEW POINTER
HRLM T2,FILBCT(JFN) ;AND COUNT
RETSKP] ;AND DONE
OUTRR3: CALL SNDCHK ;GO SEE IF ANOTHER SEGMENT CAN BE SENT
OUTWAT: JRST [ TQNE <ERRF> ;ERROR?
JRST SQOBAD ;YES. GO AWAY
CALL MAKTST ;MAKE A STANDARD TEST WORD
TQO <BLKF> ;REQUEST BLOCK
CALLRET SQOBAD] ;AND FINISH UP
;CAN SEND SOME DATA
OUTRR2: HLRZ T3,FILBCT(JFN) ;GET # OF BYTES REMAINING
CALL GETMXS ;GO GET MAX SEGMENT SIZE
CAILE T3,0(T4) ;CAN WE SEND IT ALL?
MOVEI T3,0(T4) ;NO. SO SEND MAX AMOUNT
MOVEM T3,MSIZE ;SAVE # OF BYTES TO SEND
MOVEI T1,<<MSHDR+DTMLEN>*4+3>(T3) ;COMPUTE BYTES REQUIRED
LSH T1,-2 ;CONVERT TO WORDS
CALL GETRES ;GET ONE
JRST [ CALL GENWAT ;GET A WAIT
CALLRET SQOBAD] ;AND DONE
; ..
;OUTRR CONTINUED... ADJUST COUNTS IN JFN BLOCK
MOVEM T1,MBLOCK ;SAVE BLOCK ADDRESS
MOVEI T2,MSHDR(T1) ;GET BEGINNING OF DATA STORAGE
HRLI T2,(<POINT 8,>) ;FORM BYTE POINTER
MOVE T1,FILLLB(JFN) ;GET BACK LL BLOCK
MOVEM T2,LLBPTR(T1) ;SAVE WORK POINTER
SETZM LLBPCT(T1) ;INIT COUNT
MOVE T3,MSIZE ;GET # OF BYTES TO GO
HLRZ T2,FILBCT(JFN) ;GET # NOW IN BUFFER
SUBI T2,0(T3) ;COMPUTE # LEFT
HRLM T2,FILBCT(JFN) ;SAVE FOR NEXT ROUND
CALL MAKFLG ;GO MAKE FLAGS FOR THIS MESSAGE
MOVE T3,MBLOCK ;GET MESSAGE BLOCK ADDRESS
MOVE T4,MSIZE ;GET MESSAGE COUNT
CALL MAKMSG ;GO ASSEMBLE NON-DATA PARTS OF MESSAGE
LOAD T2,LLBSZ,(T1) ;GET BYTE SIZE
CAIN T2,44 ;WORD MODE?
JRST OUTWRD ;YES. GO DO IT
OUTRR5: MOVE T2,LLBPTR(T1) ;GET DESTINATION
MOVE T1,FILBFO(JFN) ;GET SOURCE
MOVE T3,T4 ;COUNT
CALL NETMOV ;MOVE THE BYTES
MOVEM T1,FILBFO(JFN) ;UPDATE SOURCE POINTER
MOVE T1,FILLLB(JFN) ;RESTORE LL BLOCK POINTER
OUTRR7: MOVE T2,MBLOCK ;GET BACK BLOCK
MOVEI T3,MSDAT ;GET TYPE OF THIS MESSAGE
STOR T3,MSTOM,(T2) ;TO THE MESSAGE
MOVE T4,MSIZE ;GET NO. OF DATA BYTES
ADDI T4,2 ;INCLUDE SEGNUM BYTES IN THE COUNT
STOR T4,MSDTC,(T2); ;PUT NO. OF DATA BYTES IN THE MESSAGE
CALL SNDSEG ;GO SEND A SEGMENT. ROUTINE
;PLUGS IN LL ADDRESS AND MESSAGE SIZE
JRST OUTR00 ;AND TRY FOR ANOTHER SEGMENT
;CODE TO MOVE 36 BIT BYTES INTO A NETWORK MESSAGE.
OUTWRD: MOVEM P3,MLODR ;SAVE A WORK REG
OUTWR0: CAIGE T4,11 ;HAVE AT LEAST 2 MORE WORDS?
JRST [ MOVE T2,@FILBFO(JFN) ;NO. GET LAST WORD
AOS FILBFO(JFN)
SETZ T3, ;TO GEN NULLS
MOVEI P3,5 ;5 MORE BYTES TO MOVE
JRST OUTWR1] ;GO DO IT
DMOVE T2,@FILBFO(JFN) ;GET TWO MORE WORDS
MOVEI P3,2 ;THE INCREMENTER
ADDM P3,FILBFO(JFN)
MOVEI P3,11 ;MOVE 9 BYTES
OUTWR1: SUBI T4,11 ;TAKE SOME BYTES
OUTWR2: ROTC T2,10 ;GET NEXT BYTE RIGHT JUSTIFIED
IDPB T3,LLBPTR(T1) ;STORE IT
SOJG P3,OUTWR2 ;DO ALL BYTES
JUMPG T4,OUTWR0 ;GO DO MORE DATA
MOVE P3,MLODR ;RESTORE REG
JRST OUTRR7 ;AND CONTINUE
;MAKMSG - ROUTINE TO ASSEMBLE THE NON-DATA PORTIONS OF A MESSAGE
;
;ACCEPTS IN T1/ LOGICAL LINK BLOCK ADDRESS
; T2/ MESSAGE FLAGS BYTE
; T3/ MESSAGE BLOCK ADDRESS
; T4/ MESSAGE SIZE
; CALL MAKMSG
;RETURNS: +1 ALWAYS, WITH NON-DATA PORTIONS OF MESSAGE ASSEMBLED
;
; PRESERVES LOGICAL LINK BLOCK ADDRESS IN T1
RESCD
MAKMSG::STKVAR <MBLOCK>
MOVEM T3,MBLOCK ;LOCAL STORAGE FOR LL BLOCK ADDRESS
STOR T2,MSMFL,(T3) ;SAVE MESSAGE FLAGS
CALL RTHDCI ;PUT ON ROUTE HEADER AND FLAGS
CALL PUTLLA ;PUT IN LL ADDRESSES
TMNE LLFNA,(T1) ;THIS LL NEED AN ACK?
CALL MAKACK ;YES, PUT IT IN
MOVE T3,MBLOCK ;GET ADDRESS OF MESSAGE BLOCK
MOVE T2,LLBPTR(T1) ;GET CURRENT BYTE POINTER
MOVEM T2,MSBPTR(T3) ;SAVE IN MESSAGE BLOCK
LOAD T2,LLDSN,(T1) ;GET LAST SEG SENT
AOS T2 ;NEXT ONE
ANDI T2,7777 ;ONLY 12 BITS
STOR T2,LLDSN,(T1) ;PUT IT BACK
STOR T2,MSSEG,(T3) ;SAVE SEG # IN DATA BLOCK
CALL TWOBYT ;PUT IN SEGNUM
ADDM T4,LLBPCT(T1) ;AND COUNT UP MESSAGE SIZE
RET ;DONE, RETURN
;MAKFLG - ROUTINE TO MAKE THE FLAGS BYTE FOR A MESSAGE
;
;ACCEPTS IN T1/ LOGICAL LINK BLOCK ADDRESS
; T2/ NUMBER OF BYTES LEFT TO SEND IN SUBSEQUENT MESSAGES
; CALL MAKFLG
;RETURNS: +1 ALWAYS, WITH T2/ MESSAGE FLAGS BYTE
;
; PRESERVES LOGICAL LINK BLOCK ADDRESS IN T1
MAKFLG::MOVEI T4,DATMFL ;GET BASIC MESSAGE FLAGS
LOAD T3,LLMFC,(T1) ;GET TYPE OF FLOW CONTROL ON THIS LINK
JN LLBOM,(T1),[
SETZRO LLBOM,(T1) ;IS THIS START OF MESSAGE?
TXO T4,DATBOM ;YES. SET BOM THEN
JRST MKFL10] ;KEEP BOM
MKFL10: TMNE LLFEM,(T1) ;WANT EOM?
SKIPE T2 ;IS THIS LAST SEGMENT OF MESSAGE?
JRST [ CAIN T3,2 ;MESSAGE FLOW CONTROL?
JRST MKFL30 ;YES. SKIP FLOW ADJUSTMENT
JRST MKFL20] ;NO. ADJUST FLOW COUNTER
SETZRO LLFEM,(T1) ;YES. TURN OFF EOM
SETONE LLBOM,(T1) ;AND NEXT ONE IS BOM
TXO T4,DATEOM ;AND SET EOM
MKFL20: JUMPE T3,MKFL30 ;IF NO FLOW CONTROL, SKIP ADJUSTMENT
DECR LLMSM,(T1) ;ADJUST FLOW CONTROL
MKFL30: MOVE T2,T4 ;COPY MESSAGE FLAGS
RET
;MAKE THE ACKNUM (PIGGYBACKED ACK) FIELD IN A DATA SEGMENT
;ACCEPTS: T1/ LL BLOCK ADDRESS
;RETURNS: +1
;PRESERVES T1
MAKACK: LOAD T2,LLIDN,(T1) ;GET LAST DATA SEGMENT RECEIVED
TXO T2,ACKIND ;PUT IN ACKNUM INDICATOR
CALL TWOBYT ;PUT ACKNUM FIELD IN MESSAGE
SETZRO <LLFNA,LLFNN>,(T1) ;CLEAR THE "NEED TO ACK/NACK" FLAGS
RET
;SNDCHK - ROUTINE TO SEE IF ANOTHER SEGMENT CAN BE SENT ON A LOGICAL LINK
;
;ACCEPTS IN T1/ LOGICAL LINK BLOCK ADDRESS
; CALL SNDCHK
;RETURNS: +1 FAILED, WITH T2/ ADDRESS OF SCHEDULER TEST ROUTINE
; +2 SUCCESS, ANOTHER SEGMENT CAN BE SENT
;
SNDCHK::JN LLBRP,(T1),[MOVEI T2,CHKBRP ;IF FLOW CONTROL OFF, WAIT
NSBP01: RET] ;FAIL
JN LLQUN,(T1),[
NSBP02: MOVEI T2,CHKSWD ;IF ANY NAK'ED SEGS
RET ] ;FAIL
;**;[3179] Remove 5 lines CEG 5-Nov-84
LOAD T2,LLQOU,(T1) ;GET SEGS NOW IN THE QUEUER
LOAD T3,LLMQO,(T1) ;GET MAX OUTPUT QUEUE LENGTH
NSBP10: CAMLE T2,T3 ;CAN WE PUT ANOTHER ONE IN?
JRST [ MOVEI T2,CHKQTA ;WAIT FOR QUEUER COUNT TO COME DOWN
NSBP03: RET ] ;FAIL
LOAD T3,LLMFC,(T1) ;GET TYPE OF FLOW CONTROL
SKIPN T3 ;IF NO FLOW CONTROL, ALL SET
NSBP04: RETSKP ;NO FLOW CONTROL
LOAD T4,LLMSM,(T1) ;GET CURRENT FLOW COUNT
JUMPE T4,[
NSBP05: MOVEI T2,CHKSCT ;WAIT FOR SOME COUNT TO APPEAR
RET ] ;FAIL
TMNN <LLNLS,LLALS>,(T1) ;NEED TO ACK LS?
IFSKP. ;YES, CAN'T SEND DATA THEN
MOVEI T2,CHKLSA ;RETURN WITH SCHEDULER TEST
RET
ENDIF.
CAIE T3,2 ;MESSAGE FLOW CONTROL?
TRNN T4,200 ;NO. SEGMENT. IS COUNT POSITIVE?
NSBP06: RETSKP ;YES, CAN SEND A SEGMENT NOW.
NSBP07: MOVEI T2,CHKSCP ;WAIT FOR COUNT TO GO POSITIVE
RET ;RETURN SCHED TEST
;ROUTINE TO MAKE A STANDARD TEST WORD
MAKTST::LOAD T1,LLLNK,(T1) ;GET LL ADDRESS
HRLS T1 ;TO THE LH
HRRI T1,0(T2) ;TEST ROUTINE
RET ;DONE
;ROUTINE TO ARRANGE FOR A TIMED WAIT OF 1/2 SEC. THIS IS USED
;WHEN FREE SPACE IS EXHAUSTED.
GENWAT: TQO <BLKF> ;NEED TO BLOCK
TIMWAT::MOVE T2,TODCLK ;GET NOW
ANDI T2,377777
ADDI T2,^D500 ;WAIT 1/2 SEC FOR FREE SPACE
MOVSI T1,0(T2) ;TIME TO THE LH
HRRI T1,BLOCKM ;WAIT THIS LONG
RET ;AND GO BLOCK
SWAPCD
;ROUTINES OF NETSQO GOTTEN TO BY STATE TRANSITION TABLE
;SET UP BLOCK UNTIL LINK IS CONNECTED
SQOLIS: MOVEI T2,CHKCON ;WAIT UNTIL CONNECTED
JRST OUTWAT ;AND GO ARRANGE FOR THE BLOCK
;IMPLICIT CONFIRM
SQOCNF: SETZM T3 ;NO OPTDATA
CALL CNFCOM ;GO CONFORM CONNECTION
JRST SQOBAD ;FAILED
JRST NETSQ1 ;AND COMPLETE OUTPUT REQUEST
;LINK HAS BEEN CLOSED BY PROCESS OR NSP. GIVE ERROR
SQOABT: SKIPA T1,[DCNX11] ;NSP ABORT
SQODIS: MOVEI T1,DCNX8 ;ILLEGAL USER OPERATION
TQO <ERRF> ;SAY HAVE AN ERROR
JRST SQOBAD ;DONE
;FOREIGN HOST HAS DISCONNECTED
SQODIR: TQO <ERRF> ;USER ERROR
MOVEI T1,DCNX11 ;GIVE ERROR
JRST SQOBAD ;AND DONE
SQOEOF: TQO <EOFF> ;NO. SAY EOF
JRST SQOBAD ;DONE
;ROUTINE TO BUILD BASIC CC MESSAGE
; T1/ LL BLOCK ADDRESS
; T3/ <COUNT>B5+OPTDATA STRING
;RETURNS +1 NO FREE SPACE. NEED TO BLOCK
; +2 READY. T2/ BLOCK ADDRESS
SNDCC: ASUBR <SAVLL,SAVBLK,SAVOPT>
MOVEI T1,MSHDR+CCLEN ;GET ENOUGH SPACE
CALL GETRES ;GET IT
RET ;FAILED. WAIT FOR A WHILE
MOVEM T1,SAVBLK
MOVE T1,SAVLL ;RETRIEVE LL BLOCK ADDRESS
LOAD T3,LLLNK,(T1) ;GET LL ID
MOVE T2,SAVBLK ;RETRIEVE MESSAGE ADDRESS
STOR T3,MSLLA,(T2) ;PUT LL ID IN MESSAGE HEADER
MOVEI T3,CNMRFL+CNMCF ;GET CC FLAGS
STOR T3,MSMFL,(T2) ;PUT FLAGS IN MESSAGE HEADER
MOVEI T3,MSHDR(T2) ;GET START OF DATA
HRLI T3,(<POINT 8,>) ;MAKE A BYTE POINTER
MOVEM T3,LLBPTR(T1) ;PUT IT IN LL BLOCK
SETZM LLBPCT(T1) ;INIT THE BYTE COUNT
MOVEI T2,CNMRFL+CNMCF ;GET CC FLAGS
CALL RTHDCI ;PUT IN ROUTE HEADER AND FLAGS
CALL DOSRVS ;PUT IN LL ADDRESSES AND STANDARD SERVICES
MOVE T3,SAVOPT ;GET OPTDATA ARG
LOAD T2,CNTFLD,T3 ;GET COUNT
SETZRO CNTFLD,T3 ;CLEAR OUT COUNT BITS
CALL MVBNRY ;PUT IN THE DATA
MOVE T2,SAVBLK ;GET BLOCK
RETSKP ;AND DONE
;COMMON ERROR RETURN
SQOBAD: EXCH T1,FILLLB(JFN) ;SAVE ERROR. GET BLOCK ADDRESS
CALL BLKULK ;FREE BLOCK
IFN NSPSW,<
CALL CHKLLB
>
EXCH T1,FILLLB(JFN) ;GET BACK ERROR
RETBAD ;AND DONE
;IMPLICIT CONFIRM FROM SOUTR
SQOCN2: SETZM T3 ;NO OPTDATA
CALL CNFCOM ;GO CONFIRM IT
JRST SQOBAD ;FAILED
JRST NETSR1 ;AND GO ON
;ROUTINE TO DO IMPLICIT CONFIRM
CNFCOM: STKVAR <CNFLNK>
MOVEM T1,CNFLNK ;SAVE LINK BLOCK ADDRESS
JN LLTRN,(T1),SQOCN1 ;IF ONLY NEED LS, GO DO IT
CALL SNDCC ;GO BUILD CONNECT CONFIRM
JRST GENWAT ;BLOCK UNTIL FREE SPACE
CALL SNDCTL ;SEND IT
TMNE LLLOC,(T1) ;IS THIS A LOCAL LINK?
JRST SQOCN1 ;YES, "CC SENT" DOESN'T EXIST FOR LOCALS
LOAD T2,LLLKP,(T1) ;GET NODE'S VERSION
CAIN T2,.NSP31 ;IS IT NSP 3.1?
JRST SQOCN1 ;YES, MOVE ON
MOVEI T2,LLSCCS ;STATE IS NOW
STOR T2,LLSTA,(T1) ; CC SENT
RETSKP ;WAIT FOR RESPONSE TO CC
SQOCN1: CALL TURNON ;TRY TO SEND IT
JRST [ EXCH T1,CNFLNK ;SAVE SCHED TEST, GET LINK BLOCK ADR
SETONE LLTRN,(T1) ;SAY STILL NEED LS
MOVE T1,CNFLNK ;RESTORE SCHED TEST
JRST GENWAT] ;AND GO WAIT AWHILE
SETZRO LLTRN,(T1) ;DON'T NEED LS ANYMORE
MOVEI T2,LLSRUN ;NOW IN RUN STATE
STOR T2,LLSTA,(T1) ;SAY SO
MOVEI T2,1 ;INITIAL LS/INT REQ COUNT
STOR T2,LLMIC,(T1) ;STORE IT
RETSKP ;DONE
;COLLECTION OF SCHEDULER TEST ROUTINES USED BY NETSQO AND OTHERS
RESCD ;MUST ALL BE RESIDENT
;BLOCK UNTIL CONNECTED
CHKCON: SETOM T2 ;ANY MATCH
CALL LLLKUP ;GO FIND LL BLOCK
JRST 1(4) ;THIS SHOULDN'T HAPPEN
LOAD T2,LLSTA,(T1) ;GET CURRENT STATE
CAIN T2,LLSLIS ;LISTENING?
JRST 0(T4) ;YES, NOT CONNECTED
CAIN T2,LLSCIS ;CI SENT?
JRST 0(T4) ;YES, NOT CONNETCED
CAIN T2,LLSCCS ;CC SENT?
JRST 0(T4) ;YES, NOT CONNECTED
JRST 1(T4) ;MUST BE CONNECTED
;WAIT UNTIL BLOCK LOCK IS FREE
CHKLOK: SETOM T2 ;ANY MATCH
CALL LLLKUP ;FIND LL BLOCK
JRST 1(4) ;CAN'T HAPPEN
JN LLRCT,(T1),0(4) ;IF STILL NON-ZERO, MUST WAIT
JRST 1(4) ;IS FREE
;WAIT UNITL QUEUER WILL TAKE SOME MORE MESSAGES
CHKQTA: CALL CHKSET ;GET LL BLOCK, MAKE SURE STILL RUNNING
JRST 1(4) ;SOMETHING WRONG WITH LINK
LOAD T2,LLQOU,(T1) ;GET QUEUER COUNT
LOAD T3,LLMQO,(T1) ;GET MAX QUEUE LENGTH
CAMLE T2,T3 ;CAN TAKE SOME MORE?
JRST 0(4) ;NO. WAIT SOME MORE
JRST 1(4) ;YES.
;WAIT UNTIL SOME ACKS COME IN
;**;[2927]REPLACE 4 LINES WITH 8 LINES AT CHKSCT: DSC 22-MAR-83
CHKSCT: SETOM T2 ;[2927]ANY REMOTE LINK FOR NOW
CALL LLLKUP ;[2927]GET LL BLOCK ADDRESS
JRST 1(T4) ;[2927]NOT THERE ANYMORE, WAKE
LOAD T2,LLSTA,(T1) ;[2927]GET STATE OF LL
CAIE T2,LLSRUN ;[2927]RUNNING?
JRST 1(4) ;[2927]NO, WAKE
JN LLMSM,(T1),1(4) ;[2927]YES, IF SOME ACKS, WAKE UP
JRST 0(4) ;[2927]STILL NO ACKS. WAIT SOME MORE
;WAIT UNTIL SEG ACK COUNT IS POSITIVE
CHKSCP: CALL CHKSET ;VERIFY LINK STATE
JRST 1(4) ;LINK CHANGED STATE
LOAD T2,LLMSM,(T1) ;GET SEG COUNT
TRNE T2,177 ;IS IT ZERO?
TRNE T2,200 ;NO. IS IT NEGATIVE?
JRST 0(4) ;YES. MUST WAIT SOME MORE
JRST 1(4) ;NO. CAN SEND SOME MORE DATA
;ROUTINE TO WAIT FOR MESSAGES TO ARRIVE
CHKRAW: CALL CHKSET ;FORCE WAKE?
JRST 1(4) ;YES.
TMNN LLFLI,(T1) ;ANYTHING IN FILE SYSTEM BUFFER?
SKIPE LLOMSG(T1) ;ANYTHING ON ORDERED Q?
JRST 1(4) ;YES. WAKE UP THEN
JRST 0(4) ;NOTHING TO DO YET
;COMMON ROUTINE TO FIND LL BLOCK AND VERIFY THAT LL IS RUNNING
CHKSET: SETOM T2 ;ANY LINK
CALL LLLKUP ;GO FIND BLOCK
RET ;NOT THERE. SOMETHING TERRIBLE HAPPENED
LOAD T2,LLSTA,(T1) ;GET STATE
SKIPN LLOMSG(T1) ;MESSAGES ON QUEUE?
CAIE T2,LLSRUN ;IS IT RUNNING?
RET ;WAKE UP
RETSKP ;YES. ALL FINE
;CHECK IF RESENDS ARE ALL DONE
CHKSWD: CALL CHKSET ;GO VERIFY LINK STATE
JRST 1(4) ;CHANGED. WAKE UP
JE LLQUN,(T1),1(4) ;ALL NAK'ED SEGS NOW SENT?
JRST 0(4) ;STILL RESENDS. WAIT
;TESTS FOR CLOSF
CHKDCR::SETOM T2 ;ANY MATCH
CALL LLLKUP ;FIND LL BLOCK
JRST 1(4) ;IF NO MORE LINK, THAT'S GOOD ENOUGH
LOAD T2,LLSTA,(T1) ;GET STATE
CAIE T2,LLSABT ;DC RECEIVED?
CAIN T2,LLSDIR ;OR DI RECEIVED?
JRST 1(4) ;YES. AWAKE
JRST 0(4) ;NO. KEEP WAITING
CHKEMP::CALL CHKSET ;MAKE SURE ALL IS SET
JRST 1(4) ;NOT. A STATE CHANGE OCCURRED
JE LLQOU,(T1),1(4) ;HAVE ALL ACKS ARRIVED?
JRST 0(4) ;NO
;WAIT FOR BACK-PRESSURE
CHKBRP: CALL CHKSET ;MAKE SURE ALL IS SET
JRST 1(4) ;NO. AWAKE
JE LLBRP,(T1),1(4) ;IF NOW ON, AWAKE
JRST 0(4) ;NO YET ON
;**;[3179] Remove routine NETRES CEG 5-Nov-84
;WAIT UNTIL ACKING OF LS MESSAGES IS NO LONGER NECESSARY
CHKLSA: SETOM T2 ;ANY MATCH
CALL LLLKUP ;FIND LL BLOCK
JRST 1(4) ;BADNESS, WAKE UP
TMNN <LLNLS,LLALS>,(T1) ;NEED LS ACK?
JRST 1(4) ;NO, WAKE UP
JRST 0(4) ;YES, KEEP WAITING
;ROUTINES FOR SEQUENTIAL INPUT
;ROUTINE TO TAKE SEGMENTS OFF OF THE RAW DATA QUEUE AND
;PUT THEM ON THE ORDERED DATA QUEUE
REPEAT 0,<
MOVSEG::ACVAR <W1,W2,W3>
STKVAR <MSGLLB>
MOVEM T1,MSGLLB ;SAVE LOGICAL LINK BLOCK ADDRESS
TMNE LLFNN,(T1) ;NEED A NACK?
CALL MOVNAK ;YES. SEND NACK
MOVSE1: SKIPN T2,LLMSG(T1) ;HAVE ANY?
RETSKP ;NO. MUST BE DONE THEN
NOSKD1 ;PREVENT SCHEDULING
MOVE T2,LLMSG(T1) ;GET HEADER AGAIN IN CASE IT CHANGED
LOAD T3,MSLNK,(T2) ;GET LINK
MOVEM T3,LLMSG(T1) ;NEW LINK
OKSKD1 ;AND ALLOW SCHEDULING
LOAD T3,MSMFL,(T2) ;GET FLAGS
TXNE T3,ACKFLM ;IS IT AN ACK?
JRST [ CALL MOVACK ;YES. GO DO THE ACK THEN
RETBAD() ;ERROR OCCURRED
JRST MOVSE1] ;AND DONE
DECR LLDRW,(T1) ;ONE LESS DATA SEG ON Q
MOVEI T3,MSDAT ;IS A DATA SEGMENT
CALL VERSEG ;GO VERIFY CORRECTNESS OF MESSAGE
JRST [ MOVE W1,T3 ;SAVE FLAG FROM VERSEG
DECR LLDMT,(T1) ;ONE LESS DATA SEGMENT
MOVE T1,T2 ;GET SEGMENT ADDRESS
CALL RELRES ;FREE IT UP
MOVE T1,MSGLLB ;GET BACK LL BLOCK
JUMPE W1,BADSEG ;IF PROTOCOL ERROR, GO SHUT LINK
LOAD T2,LLIDN,(T1) ;GET LAST ACKED SEG
MOVEI T3,MSDAT ;ON THE DATA CHANNEL
CALL SNDACK ;ACK IT AGAIN
NOP ; IGNORE ERROR
MOVE T1,MSGLLB ;RESTORE ADDRESS
JRST MOVSE1] ;AND PROCEED
; ..
; ..
;MESSAGE IS GOOD. PUT IT ON THE ORDERED QUEUE
LOAD T4,LLMQI,(T1) ;GET MAXIMUM INPUT QUEUE LENGTH
CAMLE T3,T4 ;SEE IF REASONABLE TO KEEP IT?
JRST [ DECR LLDMT,(T1) ;NO. REMOVE SEG
JE LLIMS,(T1),BADSEG ;IF NOT MESSAGE CONTROL, ERROR
MOVE T1,T2 ;NO. IS BEYOND QUOTA
CALL RELRES ;FREE THE BLOCK
MOVE T1,MSGLLB ;GET BACK LL BLOCK
CALL MOVNAK ;AND SEND THE NACK
JRST MOVSE1] ;DONE
SKIPN T3,LLOMSG(T1) ;ANYTHING ON THE QUEUE?
JRST [ MOVEM T2,LLOMSG(T1) ;NO. MAKE THIS THE QUEUE
SETZRO MSLNK,(T2) ;TIE IT OFF
JRST MOVSE1] ;AND DONE
SETZ W1, ;AT THE TOP
LOAD W2,MSSEG,(T2) ;GET SEG NUMBER
; ..
;MOVSEG CONTINUED...
MOVSEL: LOAD T4,MSSEG,(T3) ;GET THIS ONE'S NUMBER
CAIN W2,0(T4) ;SAME?
JRST [ MOVE T1,T2 ;YES
CALL RELRES ;THROW IT AWAY
MOVE T1,MSGLLB ;GET LL BLOCK ADDRESS
JRST MOVSE1] ;AND GO AGAIN
SUBI T4,0(W2) ;COMPUTE THE DIFFERENCE
MOVM W3,T4 ;GET MAGNITUDE OF DIFFERENCE
CAILE W3,MAXDIF ;IS GREATER THAN MAX DIFFERENCE?
TLC T4,(1B0) ;YES. FLIP SIGN THEN
JUMPL T4,[MOVE W1,T3 ;IF LESS, INSERT AFTER
LOAD T3,MSLNK,(T3) ;GET LINK
JUMPN T3,MOVSEL ;AND GO LOOK SOME MORE
JRST MOVSE2] ;AND GO INSERT IT
JUMPE W1,[MOVE T4,LLOMSG(T1) ;GET OLD HEAD
MOVEM T2,LLOMSG(T1) ;NEW HEAD
STOR T4,MSLNK,(T2) ;AND FINISH LINK
JRST MOVSE1] ;DONE
MOVSE2: LOAD T4,MSLNK,(W1) ;GET OLD LINK
STOR T2,MSLNK,(W1) ;INSERT IT
STOR T4,MSLNK,(T2) ;FINISH UP
JRST MOVSE1 ;AND DONE
;ROUTINE TO SEND A NACK FOR THE LINK
MOVNAK: STKVAR <MVNLLB>
MOVEM T1,MVNLLB ;SAVE LOGICAL LINK BLOCK ADDRESS
LOAD T2,LLIDN,(T1) ;GET SEG NUMBER
TXO T2,ACKBIT ;MAKE IT A NACK
MOVEI T3,MSDAT ;ON THE DATA CHANNEL
CALL SNDACK ;SEND THE NACK
JRST [ MOVE T1,MVNLLB ;GET BACK LL BLOCK ADDRESS
CALLRET DATINR] ;BUT MAKE IT RETRY SOON
SETZRO <LLFNN,LLFNA>,(T1) ;CLEAR FLAGS
RET ;AND DONE
ENDAV. ;END ACVAR
;LOCAL ROUTINE TO HANDLE AN ACK FOUND ON LLOMSG QUEUE
; T1/ LL BLOCK ADDRESS
; T2/ MESSAGE BLOCK ADDRESS
MOVACK: TRVAR <MSGCNT,MSGBYP,MSGBLK,MSGLL>
MOVEM T1,MSGLL ;SAVE LL BLOCK
MOVEM T2,MSGBLK ;SAVE DATA BLOCK
LOAD T3,MSDTC,(T2) ;GET DATA COUNT
MOVEM T3,MSGCNT
MOVE T3,MSBPTR(T2) ;GET POINTER TO DATA
MOVEM T3,MSGBYP ;SET UP POINTER
LOAD T2,MSMFL,(T2) ;GET FLAGS
CALL ACKDO ;GO DO THA ACTUAL ACK
JRST BADSEG ;BADLY FORMED SEGMENT ENCOUNTERED
MOVE T1,MSGBLK ;GET BLOCK ADDRESS
CALL RELRES ;FREE IT UP
MOVE T1,MSGLL ;GET LL ADDRESS
RETSKP ;AND DONE
> ;END REPEAT 0 AT MOVSEG
;WORKER ROUTINE TO DO ACK. CALLED FROM BOTH PROCESS CONTEXT AND FROM
;NSPTSK.
; T1/ LL BLOCK ADDRESS
; T2/ MESSAGE FLAGS
ACKDO: MOVE T4,T2 ;SAVE FLAGS
CALL GETTWO ;GET ACKNUM
RET ;BAD
MOVEI T3,MSDAT ;IS A DATA ACK
TRNE T4,ACKLSI ;ACKING DATA?
MOVEI T3,MSLSI ;NO.
CALL ACKCHN ;GO DO IT
RETSKP ;AND DONE
;A BADLY FORMED SEGMENT WAS ENCOUNTERED
BADSEG: MOVEI T2,LLSDIQ ;CHANGE LINK STATE
STOR T2,LLSTA,(T1)
CALL FLUSH ;RELEASE ALL PENDING MESSAGES
MOVEI T2,.DCX40 ;DATA LOSE ERROR
STOR T2,LLRSN,(T1) ;THE ABORT REASON
CALL DATINR ;GIVE INT
SETZM T3 ;NO USER DATA
MOVEI T4,CNMRFL+CNMDI ;A DI
CALL SNDDI ;GO SEND IT
CALLRET GENWAT ;NO FREE SPACE
CALL SNDCTL ;SEND CONTROL MESSAGE
MOVEI T2,LLSDIS ;NEW STATE
STOR T2,LLSTA,(T1)
CALLRET SEGERR ;AND GIVE ERROR
SWAPCD
;ROUTINE TO DO SEQUENTIAL INPUT.
NETSQI::MOVE T1,FILLLB(JFN) ;GET LL BLOCK ADDRESS
CALL BLKLLK ;LOCK IT UP
JRST WATBLK ;GO WAIT FOR THE LOCK
LOAD T2,LLSTA,(T1) ;GET STATE
JRST @SQISTA-1(T2) ;GO DO PROPER THING
SQI1: SKIPE LLMSI(T1) ;have pending interrupt message?
JRST [ MOVEI T1,DCNX2 ;yes. illegal to do this input then
TQO <ERRF> ;make it a file sys error
JRST SQOBAD] ;and tell the process
SOSL FILCNT(JFN) ;ANY MORE BYTES?
JRST [ ILDB T2,FILBYT(JFN) ;YES. GET ONE
AOS FILBYN(JFN) ;INDICATE WE TOOK ONE
CALL BLKULK ;FREE THE BLOCK
MOVE T1,T2 ;GET BYTE IN PROPER PLACE
RET] ;AND DONE
JE LLFLI,(T1),SQI11 ;IF FLOW FROM NETWORK...
SETZRO LLFIM,(T1) ;CLEAR FLAG
SQI11: CALL NETUIN ;UNDO INPUT
MOVE T1,FILLLB(JFN) ;GET BACK LL BLOCK POINTER
CALL NETSET ;GO TRY TO GET SOME BYTES
JRST [ TQO <BLKF> ;REQUEST BLOCK
CALLRET SQOBAD] ;AND FINISH UP
CALL BLKULK ;FOUND SOME. FREE THE LOCK
CALL NETINP ;SET UP FOR INPUT
JRST NETSQI ;AND TRY AGAIN
;ROUTINE TO SET BLKF AND RETURN
WATBLK: TQO <BLKF>
RETBAD()
;STATE TRANSITION ROUTINES FOR SEQUENTIAL INPUT
;DI RECEIVED.
SQIDIR: JN LLFDI,(T1),[
SKIPE FILCNT(JFN) ;SYNCHRONOUS?
JRST SQI1 ;GO GET REMAINING BYTES
CALL NETSET ;SEE IF ANY MORE
JRST SQOEOF ;NO. GIVE EOF THEN
JRST SQI1] ;YES. GO GET THEM
CALL FLUSH ;NO . GO FLUSH ALL QUEUES
TQO <ERRF> ;AN ERROR
MOVEI T1,DCNX11 ;ABORT ERROR
JRST SQOBAD ;AND GIVE ERROR TO USER
;NEED IMPLICIT CONFIRM
SQICNF: SETZM T3 ;NO OPTDATA
CALL CNFCOM ;GO DO CONFIRM
JRST SQOBAD ;NEED TO BLOCK
JRST SQI1 ;AND PROCEED
;ROUTINE TO SCAN INPUT QUEUES AND GET BYTES TO DELIVER TO PROGRAM
NETSET: STKVAR <SQICNT>
SETZM SQICNT ;NONE YET
TMNN LLFLI,(T1) ;IS FLOW FROM THE NETWORK?
JRST SQI22 ;YES. ALL SET TO GO THEN
SETZRO LLFIM,(T1) ;NO LONGER EOM
SETZRO LLFLI,(T1) ;NO. SET FLOW FROM THE NETWORK
LOAD T3,LLBSZ,(T1) ;GET BYTE SIZE
HRRZ T1,FILWND(JFN) ;GET WINDOW PAGE
CALL MAKINP ;GO GET INPUT POINTER
MOVEM T1,FILBFI(JFN) ;SAVE BYTE POINTER
SETZM SQICNT ;SAVE CURRENT COUNT
SQI22: MOVE T1,FILLLB(JFN) ;GET ADDRESS OF LOGICAL LINK BLOCK
LOAD T2,LLLSC,(T1) ;GET NO. OF SEGS RECEIVED SINCE LAST LS WAS SENT
CAIGE T2,FLOHLD ;OVER THE THRESHOLD?
IFSKP. ;YES
CALL SQILS ;SEND LS
JRST CHKFRE ;FAILED, WAIT A WHILE
ENDIF.
SQI2: MOVE T2,FILBFI(JFN) ;GET BUFFER ADDRESS
MOVEI T3,4000 ;MAX NUMBER OF BYTES IN JFN BUFFERS
CALL MOVMSG ;GO REMOVE MESSAGES FROM QUEUE AND PUT IN BUFFER
RETBAD () ;FAILED
MOVEM T1,FILBFI(JFN) ;STORE NEW BUFFER POINTER
MOVEM T2,SQICNT ;SAVE COUNT OF BYTES MOVED
MOVE T1,FILLLB(JFN) ;RESTORE LOGICAL LINK BLOCK ADDRESS
SKIPE T2 ;ANY BYTES IN SEGMENT?
JRST SQIEMP ;YES, ONWARD
TMNE LLFIM,(T1) ;NO, EOM?
IFNSK. ;YES, A NULL MESSAGE
SETZRO LLFIM,(T1) ;TURN OFF EOM
TQO <NSPNUL> ;SET THE FILSTS WORD
JRST SQIEM1 ;FINISH PROCESSING THE MESSAGE
ENDIF.
; ..
;NETSQI CONTINUED....
;GOT ALL MESSAGES MOVED.
SQIEMP: SKIPG SQICNT ;GET ANY BYTES?
JRST SQINOB ;NO. NOTHING TO DO
SQIEM1: LOAD T3,LLBSZ,(T1) ;GET BYTE SIZE
HRRZ T1,FILWND(JFN) ;GET WINDOW ADDRESS
CALL MAKPTR ;MAKE A POINTER
MOVEM T1,FILBFI(JFN) ;TO THE BLOCK
MOVE T4,FILLLB(JFN)
LOAD T3,LLBSZ,(T4) ;GET BYTE SIZE
MOVE T2,SQICNT ;GET COUNT WE FOUND
CAIN T3,44 ;WORD MODE?
JRST [ IDIVI T2,11 ;YES. COMPUTE BYTES
LSH T2,1 ;""
JUMPE T3,.+1 ;AN ODD WORD ON THE END?
AOJA T2,.+1] ;YES. COUNT IT
HRRM T2,FILBCT(JFN) ;SAVE IT
MOVE T1,FILLLB(JFN) ;GET ADDRESS OF LOGICAL LINK BLOCK
SETONE LLFLI,(T1) ;FLOW IS NOW TO F/S
RETSKP ;ALL DONE. WITH GOOD DATA
;COULDN'T FIND ANY BYTES
SQINOB: SKIPE LLOMSG(T1) ;HAVE ANY NOW?
JRST SQI2 ;AND TRY AGAIN
MOVEI T2,CHKRAW ;THE BLOCK ROUTINE
CALLRET MAKTST ;GO ARRANGE FOR THE BLOCK
;MOVMSG - ROUTINE TO REMOVE SEGMENTS FROM LLOMSG QUEUE AND PLACE INTO
; THE DESTINATION BUFFER.
;
;ACCEPTS IN T1/ ADDRESS OF LOGICAL LINK BLOCK
; T2/ BUFFER POINTER
; T3/ MAX # OF BYTES TO PUT INTO BUFFER
; CALL MOVMSG
;RETURNS: +1 FAILED
; +2 SUCCESS, WITH T1/ UPDATE BUFFER POINTER
; T2/ COUNT OF BYTES MOVED
; T3/ -1 IF SOME DATA WOULD NOT FIT IN BUFFER
;
; NOTE: TRVAR'S MSGCNT AND MSGBYP ARE USED BY ROUTINES TO EXTRACT FIELDS
; FROM MESSAGES (E.G. GETTWO).
MOVMSG: TRVAR <MSGCNT,MSGBYP>
STKVAR <MVMLLB,MVMBFI,MVMCNT,MVMMAX,MVMFLG>
MOVEM T1,MVMLLB ;SAVE LOGICAL LINK BLOCK ADDRESS
MOVEM T2,MVMBFI ;SAVE BUFFER ADDRESS
MOVEM T3,MVMMAX ;SAVE MAX # OF BYTES TO BE PUT INTO BUFFER
SETZM MVMCNT ;INITIALIZE COUNT
SETZM MVMFLG ;ASSUME ALL DATA WILL FIT
MVM010:
; CALL MOVSEG ;NO INPUT. GET ANY SEGS
; RETBAD() ;ERROR
SKIPN LLOMSG(T1) ;ARE THERE ANY SEGMENTS?
JRST MVMX ;NO, DONE
HRRZ T2,LLOMSG(T1) ;GET THE HEAD SEGMENT
LOAD T3,MSDTC,(T2) ;GET COUNT OF BYTES
MOVEM T3,MSGCNT ;STASH IT
MOVE T3,MSBPTR(T2) ;GET POINTER TO DATA
MOVEM T3,MSGBYP ;SET UP POINTER
CALL GETTWO ;GET NEXT FIELD
JFCL
TXNE T2,ACKIND ;IS THIS ACKNUM?
CALL GETTWO ;YES. SO SKIP SEGNUM NOW
JFCL
; ..
;NOW POSITIONED TO DATA PORTION OF SEGMENT. MOVE DATA INTO
;DESTINATION BUFFER
MOVE T4,MSGCNT ;GET REMAINING COUNT
ADD T4,MVMCNT ;COMPUTE BYTES TO BE IN BUFFER
CAMLE T4,MVMMAX ;WILL THEY FIT?
JRST [ SETOM T3 ;NOTE NOT ALL DATA WOULD FIT
JRST MVMY] ;EXIT
MOVEM T4,MVMCNT ;YES. UPDATE COUNT
HRRZ T2,LLOMSG(T1) ;GET MESSAGE ADDRESS
LOAD T2,MSMFL,(T2) ;GET FLAGS
TXNN T2,DATEOM ;IS THIS THE END-OF-MESSAGE?
JRST SQI3 ;NO
SETONE LLFIM,(T1) ;YES
SQI3: JE LLIMS,(T1),SQI4 ;JUMP IF NOT MESSAGE INTERFACE
TMNN LLFIM,(T1) ;AT EOM?
JRST SQI5 ;YES
SQI4: INCR LLLSC,(T1) ;NEED ANOTHER BUFFER SENT
SQI5: MOVE T4,MSGCNT ;GET BACK THE COUNT
LOAD T2,LLBSZ,(T1) ;GET BYTE SIZE
CAIN T2,44 ;WORD MODE?
JRST [ CALL SQIWRD ;YES, GO MOVE WORDS THEN
JRST SQIMV1 ] ;AND DONE
SQIMOV: MOVE T3,T4 ;GET COUNT
MOVE T1,MSGBYP ;GET SOURCE POINTER
MOVE T2,MVMBFI ;GET DESTINATION
CALL NETMOV ;MOVE THE BYTES
MOVEM T2,MVMBFI ;UPDATE DESTINATION POINTER
MOVE T1,MVMLLB ;RETRIEVE LL BLOCK
SQIMV1: NOSKD1
HRRZ T2,LLOMSG(T1) ;GET EXPENDED MESSAGE
LOAD T3,MSLNK,(T2) ;GET NEXT
SKIPN T3 ;QUEUE NOW EMPTY
HRLM T3,LLOMSG(T1) ;YES
HRRM T3,LLOMSG(T1) ;NEW QUEUE HEAD
OKSKD1
MOVE T1,T2 ;GET BACK MESSAGE
CALL RELRES ;FREE IT
MOVE T1,MVMLLB ;GET BACK LL ADDRESS
DECR LLDMT,(T1) ;ONE LESS MESSAGE ON QUEUE
JE LLFIM,(T1),MVM010 ;HAVE EOM?
MVMX: SETZM T3 ;NO PROBLEM FITTING ALL DATA IN BUFFER
MVMY: MOVE T1,MVMBFI ;NO, GET UPDATED POINTER
MOVE T2,MVMCNT ;AND COUNT
RETSKP ;DONE, RETURN SUCCESS
;ROUTINE TO MOVE WORDS FROM THE NETWORK TO AN INPUT BUFFER
SQIWRD: STKVAR <<MDPTR,2>>
DMOVEM Q1,MDPTR ;SAVE WORK REGS
SQIWR1: SETZB Q1,Q2 ;INIT WORDS
MOVEI T3,11 ;GET MAX BYTE COUNT
CAIGE T4,11 ;ENOUGH FOR FULL 2 WORDS?
MOVE T3,T4 ;NO. GET WHAT IS LEFT THEN
SUBI T4,11 ;TAKE SOME BYTES
SQIWR2: LSHC Q1,10 ;SHIFT BYTES
ILDB T2,MSGBYP ;GET NEXT BYTE FROM NET BUFFER
DPB T2,[POINT 8,Q2,35] ;STASH IT
SOJG T3,SQIWR2 ;DO THEM ALL
JUMPL T4,[LSHC Q1,-4 ;ALIGN ODD WORD
MOVEM Q2,@FILBFI(JFN) ;STORE ODD WORD
AOS FILBFI(JFN) ;MOVE TO NEXT WORD
JRST SQIWR3] ;AND DONE
DMOVEM Q1,@FILBFI(JFN) ;STORE BOTH WORDS
MOVEI Q1,2 ;INCREMENTER
ADDM Q1,FILBFI(JFN)
JUMPG T4,SQIWR1 ;DO MORE
SQIWR3: DMOVE Q1,MDPTR ;RESTORE REGS
RET ;ALL DONE
;ERROR ROUTINE FOR BADLY FORMED SEGMENT ENCOUNTERED
SEGERR: TQO <ERRF> ;SET FILE SYSTEM ERROR
RETBAD (DCNX11) ;AND RETURN WITH ERROR INDICATOR
;ROUTINE TO ANALYZE FAILURE TO SEND ACK OR LS MESSAGE. IF IT IS
;A FREE SPACE FAILURE, THEN A DATA INT IS ISSUED TO INSURE THE PROCESS
;TRIES AGAIN SOON
CHKFRE: TQO <BLKF> ;NOTE BLOCK NEEDED
HRRZ T3,T1 ;GET TEST ROUTINE
CAIE T3,BLOCKM ;A FREE SPACE FAILURE?
RET ;NO. DONE THEN
EXCH T1,FILLLB(JFN) ;YES. GET LL BLOCK
CALL DATINR ;REQEUST DATA INT
IFN NSPSW,<
CALL CHKLLB
>
EXCH T1,FILLLB(JFN) ;RESTORE TEST ROUTINE
RET ;AND DONE
;SQILS - ROUTINE TO SEND ANY LS MESSAGES NEEDED AFTER INPUT HAS BEEN PROCESSED
;
;ACCEPTS IN T1/ ADDRESS OF LOGICAL LINK BLOCK
; CALL SQILS
;RETURNS: +1 FAILED TO SEND LS
; +2 SUCCESS, T1 PRESERVED
RESCD
SQILS:: STKVAR <SQLLLB>
MOVEM T1,SQLLLB ;SAVE BLOCK ADDRESS
LOAD T2,LLLSC,(T1) ;GET SEGS TO REQUEST
JUMPE T2,RSKP ;IF NONE, JUMP OFF
MOVEI T3,MSDAT ;ON THE DATA CHANNEL
SETONE LLLSA,(T1) ;TELL SCHED TRYING FOR LS SEND
CALL SNDLS ;SEND MESSAGE
RET ;FAILED, RETURN FAILURE
MOVE T1,SQLLLB ;RESTORE LINK BLOCK ADDRESS
SETZRO <LLLSC,LLLSA>,(T1) ;CLEAR ALL LS INDICATORS
RETSKP ;DONE, RETURN SUCCESS
;NOW DEFINE STATE TRANSITION TABLES
;FOR SEQUENTIAL OUTPUT
SWAPCD ;ALL OF THESE ARE SWAPPABLE
SQOSTA::IFIW!SQOLIS ;LISTENING - BLOCK UNTIL CONNECTED
IFIW!SQOLIS ;CIS - SAME HERE
IFIW!SQOCNF ;CIR - GO CONFIRM CIR
IFIW!NETSQ1 ;RUN - ALL SET TO GO
IFIW!SQODIS ;DIS - LINK IS CLOSED. GIVE ERROR
IFIW!SQODIS ;DIQ - SAME HERE
IFIW!SQODIR ;DIR - SEE IF ABORT OR CLOSE
IFIW!SQOLIS ;CC SENT - BLOCK UNTIL CONNECTED
IFIW!SQOABT ;ABORTED -
;FOR SOUTR CALL
SQOOTR::IFIW!SQOLIS ;LISTENING - BLOCK UNTIL CONNECTED
IFIW!SQOLIS ;CIS - BLOCK UNTIL CONNECTED
IFIW!SQOCN2 ;CIR - GO CONFIRM
IFIW!NETSR1 ;RUN - NORMAL STUFF
IFIW!SQODIS ;DIS - LINK IS CLOSED
IFIW!SQODIS ;DIQ - ""
IFIW!SQODIR ;DIR -
IFIW!SQOLIS ;CC SENT - BLOCK UNTIL CONNECTED
IFIW!SQOABT ;ABORTED -
;FOR SEQUENTIAL INPUT
SQISTA: IFIW!SQOLIS ;LISTENING - WAIT FOR CONNECT
IFIW!SQOLIS ;CIS - WAIT FOR CONNECT
IFIW!SQICNF ;CIR - CONFIRM CONNECTION
IFIW!SQI1 ;RUN - ALL SET
IFIW!SQODIS ;DIS - GIVE ERROR
IFIW!SQODIS ;DIQ - GIVE ERROR
IFIW!SQIDIR ;DIR -
IFIW!SQOLIS ;CC SENT - BLOCK UNTIL CONNECTED
IFIW!SQOABT ;ABORTED -
;TABLE FOR CC RECEIVED
CCREC: IFIW!CCJECT ;LISTENING - CAN'T CONFIRM A LISTENER
IFIW!CCGUD ;CIS - GOOD CC
IFIW!CCDON ;CIR - IGNORE IT
IFIW!CCDON ;RUN - IGNORE IT
IFIW!CCDON ;DIS - IGNORE IT
IFIW!CCDON ;DIQ - IGNORE IT
IFIW!CCDON ;DIR - IGNORE IT
IFIW!CCDON ;CC SENT - IGNORE IT
IFIW!CCJECT ;ABORTED -
;TABLE FOR DI RECEIVED
DIREC: IFIW!CCJECT ;LISTENING - ILLEGAL ADDRESS
IFIW!CONREJ ;CIS - CONNECT BEING REJECTED
IFIW!CCDON ;CIR - IGNORE
IFIW!DIMSG2 ;RUN - CLOSING DOWN THE LINK
IFIW!DIDIDC ;DIS - CLOSE LINK
IFIW!DIMSG2 ;DIQ - ABORT IT
IFIW!DIMSG2 ;DIR - ABORT IT
IFIW!DIMSG2 ;CC SENT - CONNECT BEING REJECTED
IFIW!CCJECT ;ABORTED -
;TABLE FOR DC RECEIVED
DCREC: IFIW!CCDON ;LISTENING - IGNORE FOR LISTENER
IFIW!CHKIDL ;CIS - CHECK FOR VALID DC
IFIW!CCDON ;CIR - IGNORE
IFIW!DCRUN ;RUN - SHUTTING DOWN
IFIW!DCGUD ;DIS - VALID REPLY TO DI SENT
IFIW!DCABT ;DIQ - ABORT THE LINK
IFIW!DCABT ;DIR - ABORT THE LINK
IFIW!DCABT ;CC SENT - GET RID OF LINK
IFIW!CCDON ;ABORTED - IGNORE IT
;CLOSF
CLZSTA: IFIW!CLZDON ;LISTENING - JUST GET RID OF A LISTENER
IFIW!CLZDON ;CIS - SAME FOR CIS
IFIW!CLZDI ;CIR - NEED TO REFUSE CONNECTION
IFIW!CLZRUN ;RUN - NORMAL STATE
IFIW!CLZWDC ;DIS - WAIT FOR DC
IFIW!CLZDIQ ;DIQ -
IFIW!CLZDIR ;DIR -
IFIW!CLZRUN ;CC SENT -
IFIW!CLZABT ;ABORTED -
;ACK RECEIVED
ACKSTA: IFIW!CCJECT ;LISTENING -
IFIW!ACKCIS ;CIS -
IFIW!CCDON ;CIR -
IFIW!ACKRUN ;RUN -
IFIW!CCDON ;DIS -
IFIW!CCDON ;DIQ -
IFIW!CCDON ;DIR -
IFIW!ACKCCS ;CC SENT -
IFIW!CCDON ;ABORTED -
;DATA,INT OR LS MESSAGE
DATSTA: IFIW!CCJECT ;LISTENING - ERROR
IFIW!CCDON ;CIS - IGNORE
IFIW!CCDON ;CIR - IGNORE
IFIW!DATRUN ;RUN - GOOD MESSAGE
REPEAT 3,<
IFIW!CCDON> ;DIS,DIQ,DIR - IGNORE
IFIW!DATCCS ;CC SENT - OPEN THE LINK
IFIW!CCDON ;ABORTED
SUBTTL NSP Error Code to TOPS20 Error Code Translation
;NSPERR - ROUTINE TO CONVERT AN NSP ERROR CODE INTO A TOPS20 ERROR CODE
;
;ACCEPTS IN T1/ NSP ERROR CODE
; CALL NSPERR
;RETURNS: +1 FAILED, NO SUCH NSP ERROR CODE
; +2 SUCCESS, WITH T1/ TOPS20 ERROR CODE
NSPERR::MOVSI T4,-ERRLEN ;SET UP TO LOOP THRU ERROR TABLE
NSPER1: HLRZ T2,ERRTAB(T4) ;GET AN NSP ERROR CODE
CAMN T2,T1 ;FOUND NSP ERROR CODE TO BE TRANSLATED ?
JRST NSPER2 ;YES, GO GET CORRESPONDING TOPS20 CODE
AOBJN T4,NSPER1 ;NO, LOOP OVER ENTIRE TABLE
RETBAD (MONX03) ;NO SUCH NSP ERROR CODE, RETURN FAILURE
; HERE HAVING FOUND THE NSP ERROR CODE
NSPER2: HRRZ T1,ERRTAB(T4) ;GET CORRESPONDING TOPS20 ERROR CODE
RETSKP ;DONE, RETURN SUCCESS
; TABLE OF NSP/TOPS20 ERROR CODE CORRESPONDENCE
ERRTAB: .DCX0,,NSPX00
.DCX1,,NSPX01
.DCX2,,NSPX02
.DCX3,,NSPX03
.DCX4,,NSPX04
.DCX5,,NSPX05
.DCX6,,NSPX06
.DCX7,,NSPX07
.DCX8,,NSPX08
.DCX9,,NSPX09
.DCX24,,NSPX10
.DCX32,,NSPX11
.DCX33,,NSPX12
.DCX34,,NSPX13
.DCX35,,NSPX14
.DCX36,,NSPX15
.DCX37,,NSPX16
.DCX38,,NSPX17
.DCX39,,NSPX18
.DCX40,,NSPX19
.DCX41,,NSPX20
.DCX42,,NSPX21
.DCX43,,NSPX22
ERRLEN==.-ERRTAB
SUBTTL NSP Background Task - Main Dispatching Loop
;THIS CODE IS THE REQUEST QUEUER AND THE BACKGROUND NSP
;TASK. THE QUEUER IS RESPONSIBLE FOR "ROUTING" ALL MESSAGES
;TO EITHER THE NETWORK (VIA THE DTE OR WHATEVER ELSE CONNECTS
;US TO THE NETWORK) OR TO ANOTHER LOGICAL LINK ON THE SAME HOST.
;ALSO, IT IS RESPONSIBLE FOR RETRANSMITTING ANY NACK'ED MESSAGES.
;THE BACKGORUND PROCESS RUNS AS A FORK OF JOB 0 AND IS RESPONSIBLE
;FOR PARSING ALL CONTROL MESSAGE, COMPLETING ALL CONNECTS, PROCESSING
;ACK AND LINK SERVICE MESSAGES, ACTING AS A SERVICE OF NETSQI FOR
;ACTING ON ACKS THAT ARE PIGGY-BACKED ONTO DATA SEGMENTS, AND FOR
;GENERATING PROCESS INTERRUPTS. ALSO, THIS PROCESS WILL EVOLVE OVER
;TIME TO HANDLE ALL ROUTING STRATEGIES.
SWAPCD ;ALL OF THIS CODE IS SWAPPABLE
TSKINI: MOVX T1,UMODF
MOVEM T1,FFL ;ESTABLISH USUAL JSYS CONTEXT
SETZM FPC ;SET PC
MCENTR ;GET INTO MONITOR CONTEXT
SE1ENT ;MAKE IT RUN IN PROPER SECTION
TRVAR <MSGCNT,MSGBYP,MSGSRC,MSGDST,MSGBLK,MSGLLB,MSGOBJ,<MSGDDC,5>,<MSGHSN,2>,MSGHNC,MSGW1,MSGW2,MSGSOB,<MSGSDC,5>,<MSGDML,LKSIZE>,MSGLCL,MSGLKP>
MOVEI T1,MAXQ ;DON'T ALLOW THIS FORK TO BE "COMPUTE-BOUND"
MOVEM T1,JOBBIT ;BY PREVENTING MAXQ SCHEDULING BEHAVIOR
;TOP OF LOOP
NSPTSK: SKIPE MSGQ ;ANYTHING ON THE QUEUE?
JRST [ CALL DOMSGQ ;YES, DO ONE
JRST NSPTSK] ;TRY AGAIN UNTIL DONE
CALL NSPTMR ;CHECK THE RESEND QUEUE
CALL NSPINA ;CHECK ON INACTIVITY TIMERS
REPEAT 0,<
SKIPE KDPFLG ;DOES KMC11 WANT SERVICE
CALL KDPTSK ;YES SO CHECK IT
CALL OUTCHK ;TIME TO SEND PREVOUSLY BLOCKED OUTPUT ?
CALL OUTSND ;YES, GO SEND REMAINING OUTPUT
NOP ;NOOP FOR PERFORMANCE ANALYSIS
CALL DOATSQ ;HANDLE THE ATS QUEUES IF THERE ARE ANY
>
CALL MCBCQ ;CHECK ANY MCB LINKS TO CLEAN UP
SKIPE NSPMCB ;ANY DEAD MCB'S TO CLEAN UP?
CALL MCBDED ;YES - GO CLEAN THEM UP
MOVEI T1,NSPTST ;REST UNTIL WORK TO DO
;**;[3167]Change one line at NSPTSK + 17L 20-SEP-84 TAB
MDISMS ;[3167]DISMISS, DO NOT STAY IN BALSET
JRST NSPTSK ;AND TRY AGAIN
;SEE IF ANY LL BLOCKS LEFT BY TTY TO CLOSE AND CLEAN UP
MCBCQ: SAVEAC <JFN,STS,DEV,F1>
STKVAR <MCBCLL> ;STORAGE FOR LL BLOCK ADDRESS
SETOM INNSPT ;SET "IN BACKGROUND TASK" INDICATOR
SETZ F1, ;MAKE AOBJN
HRLI F1,-NTTMCB ; WORD
MCBCQ1: SKIPN T1,ULLCZQ(F1) ;A LINK ID HERE?
JRST MCBCQ2 ;NO
LLLOCK ;YES, LOCK THE LL TREE
SETO T2, ;ANY LINK
CALL LLLKUP ;FIND THE LL BLOCK
IFNSK.
LLLULK ;DOESN'T EXIST ANYMORE, GIVE UP TREE LOCK
JRST MCBCQ3 ;ELIMINATE THIS LINK ID
ENDIF.
MOVEM T1,MCBCLL ;STASH THE LL BLOCK ADDRESS
CALL BLKLOK ;GET LL BLOCK LOCK
IFNSK.
LLLULK ;CAN'T RIGHT NOW, GIVE UP LL TREE LOCK
JRST MCBCQ2 ;MOVE ON
ENDIF.
LLLULK ;GIVE UP LL TREE LOCK
MOVEI T2,MLJFN+1
CALL ASGJFR ;ASSIGN DUMMY JFN BLOCK
IFNSK.
MOVE T1,MCBCLL ;RETRIEVE LL BLOCK ADDRESS
CALL BLKULK ;GIVE UP LL BLOCK LOCK
JRST MCBCQ2 ;MOVE ON
ENDIF.
MOVEI JFN,-JFN0+1(T1) ;SETUP JFN, OFFSET SO FILXXX REFERENCES WORK
EXCH T1,MCBCLL ;SAVE ACTUAL BLOCK, GET LL
MOVEM T1,FILLLB(JFN) ;PUT LL IN JFN BLOCK
SETZ STS, ;FAKE STATUS BITS
MOVEI DEV,DCNDTB ;DITTO DEV
SETZM FILWND(JFN) ;NO WINDOWS
CALL CLZDON ;GET RID OF LL
NOP ;+1 RETURN DOES NOT EXIST
NOINT
MOVEI T1,JSBFRE
MOVE T2,MCBCLL ;DUMMY BLOCK
CALL RELFRE ;RELEASE IT
OKINT
MCBCQ3: SETZM ULLCZQ(F1) ;GET RID OF THIS ENTRY
MCBCQ2: AOBJN F1,MCBCQ1 ;MORE TO DO?
SETZM INNSPT ;CLEAR "IN BACKGROUND TASK" INDICATOR
RET ;NO, DONE
;TEST ROUTINE FOR NSPTSK
RESCD
NSPTST::
REPEAT 0,<
CALL CKATSQ ;CHECK THE ATS QUEUES
JRST 1(T4) ;NEED TO DO SOMETHING
SKIPE KDPFLG ;DOES KMC11 WANT SERVICE
JRST 1(4) ;YES
CALL OUTCHK ;CHECK "RETRY BLOCKED OUTPUT" TIMER
JRST 1(4) ;YES, WAKE UP
>
MOVE T1,LSTTMR ;GET LAST TIME RESEND QUEUE WAS CHECKED
ADDI T1,CKNSTM ;ADD CHECKING INTERVAL
CAMG T1,TODCLK ;TIME TO CHECK AGAIN?
JRST 1(4) ;YES
SKIPE MSGQ ;ANY MESSAGES TO DO?
JRST 1(4) ;YES, WAKE UP
REPEAT 0,< ;SHOULDN'T NEED ANY OF THIS
MOVE T1,LSTINT ;GET LAST TIME INACTIVITY TIMERS WERE CHECKED
ADDI T1,CKINTM ;ADD CHECKING INTERVAL
CAMG T1,TODCLK ;TIME TO DO CHECKS AGAIN?
JRST 1(T4) ;YES
SKIPE NSPMCB ;ANY DEAD LINES TO CLEAN UP?
JRST 1(4) ;YES, WAKE UP
SKIPE ULLCZQ ;LL'S TO CLEAN UP?
JRST 1(T4) ;YES
>
JRST 0(4) ;NO, WAIT SOME MORE
SUBTTL NSP Background Task - NSP Message Timer
SWAPCD
NSPTMR: MOVE T1,LSTTMR ;GET LAST TIME QUEUE WAS CHECKED
ADDI T1,CKNSTM ;ADD CHECKING INTERVAL
CAMLE T1,TODCLK ;TIME TO CHECK AGAIN?
RET ;NO
MOVE T1,TODCLK ;YES, GET TIME
MOVEM T1,LSTTMR ;SAVE AS NEXT TIME CHECKING IS NEEDED
SKIPN NSSNTQ ;ANYTHING ON QUEUE?
RET ;NO, DONE
ACVAR <W1,W2,W3> ;W1 = LOOP COUNTER FOR MESSAGES PROCESSED
;W2 = ADDRESS OF NEXT SEGMENT
;W3 = TIMED OUT SEGMENT'S NUMBER
MOVEI W1,4 ;MAX NUMBER OF SEGMENTS TO PROCESS
STKVAR <MSGADR,LLBLK> ;ADDRESS OF MESSAGE
;LL BLOCK ADDRESS
LLLOCK ;USE LL TREE LOCK TO PREVENT RACES
SETOM INNSPT ;WE ARE NOW IN THE TIMER
NSPTM5: SKIPN T2,NSSNTQ ;GET FIRST MESSAGE ON THE SENT QUEUE
;**;[3186] Delete 2 lines, add 1 line CEG 3-Dec-84
JRST NSPTM6 ;[3186] NOTHING THERE, ALL DONE
;**;[3186] Add label CEG 3-Dec-84
NSPTM1: MOVEM T2,MSGADR ;[3186] STASH THE MESSAGE ADDRESS
LOAD T1,MSLLA,(T2) ;GET THE LL ID
SETOM T2 ;ANY MATCH
CALL LLLKUP ;GET THE LL BLOCK ADDRESS
JRST [
; BUG (NSPGON)
MOVE T1,MSGADR ;LINK GONE, GET BACK MESSAGE ADDRESS
CALL UNQTIM ;REMOVE IT FROM TIMER QUEUE
CALL RELRES ;DONE WITH IT
JRST NSPTM3] ;MOVE ON
MOVEM T1,LLBLK ;SAVE THE LL BLOCK ADDRESS
CALL BLKLOK ;LOCK THE LL BLOCK
;**;[3186] Delete 2 lines, add 1 line CEG 3-Dec-84
JRST NSPTM4 ;[3186] CAN'T GET LOCK NOW
LOAD T3,LLLKP,(T1) ;GET NODE'S VERSION
CAIN T3,.NSP31 ;IS IT NSP 3.1?
JRST NSPTM7 ;YES, DON'T TIME IT
;**;[2963] Add 1 line after NSPTM5:+19 DML 19-MAY-83
MOVE T2,MSGADR ;[2963] RETRIEVE THE MESSAGE ADDRESS
TMNN LLBRP,(T1) ;NO, IS FLOW TURNED OFF?
IFSKP. ;YES
LOAD T4,MSTOM,(T2) ;GET TYPE OF MSG
CAIE T4,MSDAT ;IS IT NORMAL DATA?
;**;[3186] Delete 1 line, add 6 lines CEG 3-Dec-84
ANSKP. ;[3186]
CALL BLKULK ;[3186] YES, CAN'T SEND IT NOW. RELEASE BLOCK LOCK
NSPTM4: SOSL W1 ;[3186] DONE ENOUGH?
SKIPN T2,MSNXT(T2) ;[3186] NO, GET NEXT MSG
JRST NSPTM6 ;[3186] NO MORE, QUIT
JRST NSPTM1 ;[3186] ONWARD
ENDIF.
MOVE T3,LLTIMO(T1) ;GET TIME OUT VALUE FOR LINK
IMUL T3,NSLDFS ;SCALE IT BY
IDIVI T3,^D16 ; LOCAL DELAY FACTOR
;**;[2963] Delete 1 line at NSPTM5:+29 DML 19-MAY-83
ADD T3,MSTIM(T2) ;ADD TIME STAMP OF THE MESSAGE
CAMG T3,TODCLK ;TIMED OUT ?
JRST NSPTMO ;YES
CALL BLKULK ;NO, UNLOCK THE LL BLOCK
;**;[3186] Delete 2 lines, add 1 line CEG 3-Dec-84
JRST NSPTM6 ;[3186] DONE
;**;[3189] Delete 1 line at NSPTMO CEG 21-Dec-84
NSPTMO: LOAD T4,LLHSN,(T1) ;GET THE REMOTE NODE NUMBER
ADD T4,[NSTIMO] ;OFFSET INTO COUNTER TABLE
AOS (T4) ;INCR THE COUNT
LOAD T4,MSTRY,(T2) ;GET NUMBER OF TIMES ALREADY RETRIED DUE TO TIME OUT
CAMGE T4,NSTRYS ;ALREADY TRIED ENOUGH TIMES?
JRST NSPTM2 ;NO, DO IT AGAIN
MOVEI T2,.DCX38 ;REASON IS TIMED OUT
STOR T2,LLRSN,(T1) ;SAVE IT
MOVEI T2,LLSABT ;YES, SAY LINK ABORTED
STOR T2,LLSTA,(T1) ; IS ABORTED
LOAD T4,LLHSN,(T1) ;GET THE REMOTE NODE NUMBER
BUG (NSPLAT,<<T4,NODE>>)
CALL CHKLLT ;CHECK FOR TTY ON THIS LINK
CALL FLUSH ;GET RID OF THE LINK'S MESSAGES
TMNN LLSDE,(T1) ;LINK DISASSOCIATED?
JRST NSPTM7 ;NO, GO TRY FOR MORE
OKINT ;YES, MATCH THE NOINT IN BLKLOK
CALL DELNOD ;GET RID OF THE LL BLOCK
JRST NSPTM3 ;MOVE ON
NSPTM2: INCR MSTRY,(T2) ;ANOTHER TRY
LOAD W3,MSSEG,(T2) ;SAVE SEGMENT # OF TIMED OUT MESSAGE
LOAD W2,MSLNK,(T2) ;GET ADDRESS OF NEXT SEGMENT
NSPTM8: SETZ T3, ;NO PREVIOUS MESSAGE
MOVEI T4,LLSEGQ(T1) ;GET HEAD OF LL'S QUEUE
CALL UNQSEG ;REMOVE CURRENT MESSAGE FROM QUEUE
LLLULK ;GIVE UP LOCK WHILE TRYING TO SEND MESSAGE
CALL SNDSE0 ;AND SEND IT AGAIN
LLLOCK ;GET LOCK AGAIN
MOVE T1,LLBLK ;RETRIEVE THE LL BLOCK ADDR
SKIPE W2 ;ANY MORE TO RESEND?
IFNSK. ;YES
MOVE T2,W2 ;GET ADDRESS OF NEXT SEGMENT
LOAD W2,MSSEG,(T2) ;GET ITS SEGMENT NUMBER
CAMG W2,W3 ;DONE THEM ALL YET?
JRST NSPTM7 ;YES, MOVE ON
LOAD W2,MSLNK,(T2) ;NO, GET NEXT MESSAGE
JRST NSPTM8 ;GO DO IT
ENDIF.
NSPTM7: CALL BLKULK ;UNLOCK THE LL BLOCK
;**;[3186] Change 1 line CEG 3-Dec-84
NSPTM3: SOSL W1 ;[3186] HAVE WE DONE OUR QUOTA?
;**;[3186] Delete 2 lines CEG 3-Dec-84
JRST NSPTM5 ;NO, GO DO SOME MORE
NSPTM6: SETZM INNSPT ;NO LONGER IN TIMER
CALLRET ULOKLL ;GIVE UP TREE LOCK
ENDSV.
ENDAV.
SUBTTL NSP BACKGROUND TASK - INACTIVITY TIMER CHECK
NSPINA: MOVE T1,LSTINT ;GET LAST TIME INACTIVITY TIMERS WERE CHECKED
ADDI T1,CKINTM ;ADD CHECKING INTERVAL
CAMLE T1,TODCLK ;TIME TO DO CHECKS AGAIN?
RET ;NO
MOVE T1,TODCLK ;YES, GET TIME
MOVEM T1,LSTINT ;SAY WE ARE CHECKING NOW
SKIPN LLHEAD ;ANY LINKS?
RET ;NO, NOTHING TO DO
LLLOCK ;LOCK THE LL TREE
SETOM INNSPI ;NOW IN INACTIVITY TIMER
MOVE T1,[INACOR] ;GET ADDRESS OF COROUTINE
SETO T2, ;ALL LINKS
CALL OBJSRC ;SEARCH THE LL TREE
JFCL ;DONE THEM ALL
SETZM INNSPI ;NO LONGER IN INACTIVITY TIMER
CALLRET ULOKLL ;UNLOCK THE LL TREE AND RETURN
;**;[2933]REORDER CODE AT INACOR: DSC 22-MAR-83
INACOR: SAVET
STKVAR <INALLB> ;LL BLOCK ADDRESS
MOVEM T1,INALLB ;SAVE THE LL BLOCK ADDRESS
CALL BLKLOK ;LOCK THE LL BLOCK
RET ;CAN'T, BETTER LUCK NEXT TIME
LOAD T2,LLSTA,(T1) ;GET STATE OF LINK
CAIE T2,LLSRUN ;RUNNING?
JRST INACOD ;NO
LOAD T2,LLLKP,(T1) ;GET NSP VERSION
CAIE T2,.NSP31 ;NSP 3.1?
SKIPN T2,LLINAC(T1) ;NO, INACTIVITY TIMER ON?
JRST INACOD ;NO
CAMLE T2,TODCLK ;YES, TIMED OUT?
JRST INACOD ;NO
SETZ T2, ;NO NEW PERMISSIONS
MOVEI T3,MSDAT ;ON THE DATA CHANNEL
CALL SNDLS ;FIRE OFF A LS MSG TO SEE IF THE OTHER
JRST [MOVE T1,INALLB ;COULDN'T SEND IT
CALLRET BLKULK] ;DONE WITH THIS LL
MOVE T1,INALLB ;RETRIEVE THE LL BLOCK ADDRESS
SETZM LLINAC(T1) ;OK, TURN OFF INACTIVITY TIMER
SETZRO <LLLSA>,(T1) ;CLEAR THE LS INDICATORS
INACOD: CALLRET BLKULK ;DONE WITH THIS LL
ENDSV.
SUBTTL NSP Background Task - Node Counters Bookkeeping
RESCD
;ROUTINE TO DO NSP INPUT BOOKKEEPING - UPDATES THE FOLLOWING NSP COUNTERS
; MESSAGES RECEIVED
; BYTES RECEIVED
;ACCEPTS: 1/ LL BLOCK ADDRESS
; 2/ MESSAGE ADDRESS
;RETURNS: +1
;
;PRESERVES T1,T2
NSINBK: SAVEAC <T1,T2>
LOAD T3,LLHSN,(T1) ;GET NODE NUMBER
ADD T3,[NSMSGR] ;OFFSET INTO "MESSAGES RECEIVED" TABLE
AOS (T3) ;INCR THE COUNT
LOAD T3,LLHSN,(T1) ;GET NODE NUMBER
ADD T3,[NSBYTR] ;OFFSET INTO "BYTES RECEIVED" TABLE
LOAD T4,MSCNT,(T2) ;GET NUMBER OF BYTES IN MESSAGE
ADDM T4,(T3) ;UPDATE THE COUNT
RET
;ROUTINE TO DO NSP OUTPUT BOOKKEEPING - UPDATES THE FOLLOWING COUNTERS
; MESSAGES SENT
; BYTES SENT
;ACCEPTS: 1/ LL BLOCK ADDRESS
;RETURNS: +1
;
;PRESERVES T1,T2
NSOUBK: SAVEAC <T1,T2>
LOAD T2,LLHSN,(T1) ;GET THE NODE NUMBER
ADD T2,[NSMSGS] ;OFFSET INTO "SENT MESSAGES" TABLE
AOS (T2) ;INCR THE COUNTER
LOAD T2,LLHSN,(T1) ;GET THE NODE NUMBER
ADD T2,[NSBYTS] ;OFFSET INTO "SENT BYTES" TABLE
MOVE T4,LLBPCT(T1) ;GET THE NUMBER OF BYTES IN MESSAGE
ADDM T4,(T2) ;UPDATE THE COUNTER
RET
SUBTTL NSP Background Task
;OUTCHK - ROUTINE TO DETERMINE IF PREVIOUSLY BLOCKED OUTPUT SHOULD BE
; RETRIED.
;
;CALL: CALL OUTCHK
;RETURNS: +1 TIME TO CHECK THE "OUTPUT REMAINING" QUEUE
; +2 NOT TIME TO RETRY YET
REPEAT 0,<
OUTCHK: SKIPN OUTTIM ;ANY TIMER SET ?
RETSKP ;NO
SAVET
MOVE T1,OUTTIM ;GET NEXT TIME TO WAKE UP
CAMG T1,TODCLK ;TIMER EXPIRE ?
RET ;YES, INDICATE SO
RETSKP ;NO, NOTE NOT TIME YET
>
SUBTTL NSP Background Task - MSGQ Processing
SWAPCD
DOMSGQ: NOSKD1 ;GET SET TO PULL A MESSAGE OFF
CHNOFF DLSCHN ;TURN OFF DTE
HRRZ T1,MSGQ ;GET TOP MOST ENTRY
LOAD T2,MSLNK,(T1) ;GET LINK
HRRM T2,MSGQ ;STASH IT
SKIPN T2 ;WAS A MESSAGE THERE?
SETZM MSGQ ;NO. CLEAR ENTIRE HEADER
CHNON DLSCHN ;TURN ON DTE
OKSKD1 ;AND ALLOW SCHEDULING
SETZM MSGLCL ;ASSUME LOCAL IN TRVAR
TMNN MSLCL,(T1) ;DID IT COME FROM DRIVER?
JRST [SKIPL T3,NSPLPB ;YES, IS THERE A LOOPBACK LINE RUNNING?
JRST DOMSG1 ;NO
HRRZS T3 ;GET RID OF LOOPBACK FLAGS
LOAD T4,MSPRT,(T1);GET PORT OF MESSAGE
CAME T3,T4 ;IS IT THE LOOPER?
JRST DOMSG1 ;NO
SETONE MSLCL,(T1) ;YES, SAY LOCAL IN THE MESSAGE BLOCK
JRST .+1]
SETOM MSGLCL ;SAY LOCAL IN TRVAR
DOMSG1: MOVEM T1,MSGBLK ;SAVE BLOCK ADDRESS
LOAD T2,MSCNT,(T1) ;GET BYTE COUNT OF THE MESSAGE
MOVEM T2,MSGCNT ;SAVE IT
ADDI T1,MSHDR ;GET TO START OF DATA
HRLI T1,(<POINT 8,>) ;FORM BYTE POINTER
MOVEM T1,MSGBYP ;AND SET UP BYTE POINTER
; ..
;MESSAGE ALL SET UP. GET MESSAGE FLAGS
;HAVE A MESSAGE. SEE WHAT IT IS
SETZM MSGHSN ;ASSUME NO HOST NAME
GETBYM (MSGCNT,MSGBYP,BADMSG) ;GET BYTE. IF BADLY FORMED, REJECT MSG
TRNE T2,1 ;IS THIS A PHASE III TRANSPORT MSG?
JRST TOSMSG ;YES, IGNORE IT
TRNN T2,2 ;IS THIS A ROUTING HEADER?
JRST DOMSG ;NO. GO HANDLE MESSAGE THEN
TRNE T2,100 ;MUST BE ASCII NAME
TRNE T2,60 ;VALID ROUTING HEADER?
JRST INVHDR ;NO.
CALL SKPFLD ;SKIP OUR NAME
JRST BADMSG ;BADLY FORMED
MOVEI T3,MSGHSN ;GET LOCATION OF REMOTE HOST NAME
MOVEI T4,MAXHST ;MAXIMUM NUMBER OF CHARS. IN NAME
CALL GTASCI ;AND GET ASCII FIELD
JRST BADMSG ;BADLY FORMED MESSAGE
MOVEM T2,MSGHNC ;SAVE NO. OF CHARS. IN HOST NAME
GETBYM (MSGCNT,MSGBYP,BADMSG) ;BADLY FORMED
DOMSG: MOVE T3,MSGBLK ;GET MESSAGE BLOCK
STOR T2,MSMFL,(T3) ;SAVE FLAGS
;**;[3108] Add 2 lines at DOMSG:+2L (W.Nichols edit) DEE 15-MAY-84
CAIN T2,RCIMFL ;[3108] IS THIS A PHASE IV RETRANSMITTED CI?
JRST TOSMSG ;[3108] YES, IGNORE IT QUIETLY
LDB T4,[POINT 3,T2,31] ;EXTRACT SUBTYPE
LDB T3,[POINT 2,T2,33] ;EXTRACT TYPE OF MESSAGE
JRST @MSGTYP(T3) ;GO DO MESSAGE
MSGTYP: IFIW!DATMSG ;DATA MESSAGE
IFIW!ACKMSG ;AN ACK MESSAGE
IFIW!CTLMSG ;A CONTROL MESSAGE
IFIW!BADMSG ;BADLY FORMED MESSAGE
CTLMSG: JRST @.+1(T4) ;GET TO PROPER TYPE OF MESSAGE
IFIW!TOSMSG ;A NOOP. IGNORE IT
IFIW!CIMSG ;CONNECT-INITIATE
IFIW!CCMSG ;CONNECT-CONFIRM
IFIW!DIMSG ;DI MESSAGE
IFIW!DCMSG ;DC MESSAGE
IFIW!STRMSG ;A STARTUP MESSAGE
IFIW!BADMSG ;BADLY FORMED MESSAGE
IFIW!BADMSG ;BADLY FORMED MESSAGE
;RECEIVED A MESSAGE WITH AN INVALID ROUTING HEADER.
INVHDR: MOVE T1,MSGBLK ;GET MESSAGE
LOAD T1,MSPRT,(T1) ;GET PORT I.D.
BUG (NSPRTH,<<T1,LINE>,<T2,BADBYT>>)
JRST TOSMSG ;DONE
;RECEIVED AN UNINTELLIGIBLE MESSAGE
BADMSG: BUG (NSPBAD)
TOSMSG: MOVE T1,MSGBLK ;GET MESSAGE ADDRESS
CALLRET RELRES ;GIVE BACK SPACE
;GOT A STARTUP MESSAGE
STRMSG: SKIPE MSGHSN ;ALREADY PARSED A NODE NAME?
JRST BADNOD ;YES, UNREADABLE MESSAGE. THROW IT AWAY
SETZM Q2 ;INITIALIZE "VERIFICATION REQUESTED" FLAG
MOVE T2,MSGBLK ;POINT TO MSG BLOCK AGAIN
LOAD Q1,MSPRT,(T2) ;GET PORT MESSAGE CAME FROM
JN INIRCV,MCBDTE(Q1),BADSTR ;IF ALREADY RUNNING, ERROR
GETBYM (MSGCNT,MSGBYP,BADSTR) ;GET STARUP TYPE
CAIE T2,STRTYP ;THE EXPECTED ONE?
JRST BADSTR ;NO
CALL GETEXT ;GET NODE NUMBER
JRST BADSTR
MOVEM T2,ITSNUM(Q1) ;SAVE NODE NUMBER
MOVEI T3,(Q1) ;GET PORT
ADDI T3,ITSNAM(Q1) ;POINT TO NAME FOR NEIGHBOR(2 WDS / PORT)
MOVEI T4,MAXHST
CALL GTASCI ;GET IT
JRST BADSTR ;BAD
STOR T2,NAMCN,MCBDTE(Q1) ;STORE COUNT OF BYTES IN NAME
GETBYM (MSGCNT,MSGBYP,BADSTR) ;GET SUPPORTED FUNCTIONS
TRC T2,OURNED
MOVX T1,NOTMCB ;NEIGHBOR IS NOT AN MCB
ANDCAM T1,MCBDTE(Q1) ;ASSUME NEIGHBOR IS AN MCB
TRNE T2,OURNED ;DOES IT SUPPORT ALL REQUIRED FUNCTIONS?
IORM T1,MCBDTE(Q1) ;REMEMBER NOT AN MCB
GETBYM (MSGCNT,MSGBYP,BADSTR) ;GET ITS REQUIRED FUNCS
TXNE T2,VERIF ;WANT SECURITY MESSAGE?
SETOM Q2 ;NOTE VERIFICATION REQUESTED
CALL GETTWO ;GET MAX BLOCK SIZE
JRST BADSTR ;BAD
MOVEM T2,MSGW1 ;SAVE IT
CALL GETTWO ;GET NSP MAX
JRST BADSTR
CAMLE T2,MSGW1 ;VALID?
JRST BADSTR ;NO
SUBI T2,NSPOVR ;YES. ACCOUNT FOR NSP OVERHEAD BYTES
MOVEM T2,NSPMAX(Q1) ;SET UP NSPMAX (MAX USER BYTES IN A SEGMENT)
MOVEI T4,10 ;BYTES TO IGNORE
STRMS1: GETBYM (MSGCNT,MSGBYP,BADSTR) ;GET A BYTE
SOJG T4,STRMS1 ;SKIP BYTES
MOVE T3,Q1 ;GET PORT
IMULI T3,^D9 ;ITSID IS 9 WORDS/PORT
ADDI T3,ITSID ;WHERE TO PUT IS ID
MOVEI T4,^D36
CALL GTASCI ;GET IT
JRST BADSTR
HRRM Q1,MCBDTE(Q1) ;SAVE PORT WE INITED ON
LOAD T1,NAMCN,MCBDTE(Q1) ;GET LENGTH OF ITS NAME
CAME T1,OURCNT ;SAME LENGTH AS OURS ?
JRST STRMS6 ;NAMES ARE NOT THE SAME
MOVEI T1,(Q1) ;COPY PORT NUMBER
ADDI T1,ITSNAM(Q1) ;POINT TO PORTS NAME
MOVEI T2,OURNAM ;POINT TO OUR NAME
CALL CMPSTR ;SEE IF SAME NAME
JRST STRMS6 ;NAMES ARE NOT THE SAME
SKIPE T1,NSPLPB ;GET PORT FOR LOOPBACK
CAIE Q1,(T1) ;IS THIS PORT INTENDED FOR LOOPBACK ?
JRST BADSTR ;NOT SUPPOSED TO BE IN LOOPBACK
SETONE ND%LPR,NSPLPB ;LOOPBACK NOW RUNNING
JRST STRMS7 ;WE ARE NOW IN LOOPBACK MODE
STRMS6: SKIPN T1,NSPLPB ;GET PORT FOR LOOPBACK
JRST STRMS7 ;NO PORT SCHEDULED FOR LOOPBACK
CAIN Q1,(T1) ;IS THIS PORT SCHEDULED FOR LOOPBACK ?
JRST BADSTR ;FLUSH THE PORT
STRMS7: SETONE INIRCV,MCBDTE(Q1) ;NOTE INIT MSG RECEIVED
JUMPN Q2,[
JE INISNT,MCBDTE(Q1),[
SETONE REQVER,MCBDTE(Q1)
JRST .+1]
MOVE T1,Q1 ;VERIFICATION WANTED, GET PORT NUMBER
CALL NODVER ;SEND VERIFICATION MESSAGE
JRST .+1 ] ;DONE, CONTINUE
MOVE T1,ITSNUM(Q1) ;GET PORT'S NODE NUMBER
MOVX T2,.NDSON ;SAY IT'S REACHABLE
MOVEI T3,3 ;IT'S PHASE III
CALL ADDNOD
BUG(NSPSTR)
JRST TOSMSG ;AND GO TO IT
BADSTR: CALL PROOFF ;TURN OFF FE
BUG (ILLSTR,<<Q1,DTE>>)
JRST BADMSG ;DON'T INIT
;ROUTINE USED BY STRMSG TO TURN OFF AN MCB IF NODE INIT
;FAILS
PROOFF: MOVE T1,MSGBLK ;GET MESSAGE
LOAD T3,MSPRT,(T1) ;GET PORT I.D.
MOVEI T2,T3 ;POINT TO ARG BLOCK
MOVEI T1,.BTTPR ;TURN OFF PROTOCOL
BOOT ;DO IT
ERJMP .+1 ;?
RET ;DONE
;ROUTINE USED TO SHUT ALL LINKS TO AN MCB THAT HAS DIED.
;ACCEPTS: T1/ PORT NUMBER
DEDMCB::SKIPL MCBDTE(T1) ;WAS THAT OURS
RET ;NO
SKIPL T1 ;IS PORT NUMBER OUT OF RANGE
CAIL T1,DCN
JRST [ BUG (NSPBPN,<<T1,BADDTE>>)
RET]
MOVE T1,BITS(T1) ;GET THE PROPER BIT NUMBER
IORM T1,NSPMCB ;AND SET IT. THIS WILL WAKE NSP BCKGRND TASK
RET
;ROUTINE TO CLOSE ALL LINKS ON ALL DEAD MCB'S
MCBDED: TRVAR <WAITER,DEDPRT,<DEDDUM,15>,MSGW1> ;MONUMENT TO HACKERY
MCBDE1: SKIPE T1,NSPMCB ;GET VECTOR OF DEAD MCB'S
JFFO T1,GOTMCB ;IS THERE ANY MORE WORK
RET ;NO - ALL DONE
GOTMCB: MOVE T1,BITS(T2) ;CLEAR BIT WE'RE WORKING ON
ANDCAM T1,NSPMCB ;AND SAVE
MOVEM T2,DEDPRT ;SAVE PORT
SETZRO <INISNT,INIRCV,REQVER>,MCBDTE(T2)
IFN DN20SW,< ;CHECK FOR MULTIPLE MCBS
CAIE T2,1 ;WAS IT THE PRIMARY MCB?
JRST DEDMC3 ;NO
>
;RESET TOPOLOGY
SETZM NODTBL ;CLEAR
HRLI T1,NODTBL ; REACHABLE
HRRI T1,NODTBL+1 ; NODES
MOVEI T2,NODTSZ ; TABLE
BLT T1,NODTBL(T2) ;
MOVE T1,OURNUM ;GET OUR NODE NUMBER
MOVE T2,[POINT 2,NODTBL] ;POINT TO BEGINNING OF TABLE
ADJBP T1,T2 ;OFFSET TO US
MOVEI T2,2 ;WE'RE PHASE II
DPB T2,T1 ;SAY SO
;
DEDMC3: MOVE T2,DEDPRT ;GET PORT NUMBER
IFN DN20SW,< ;CHECK FOR OTHER MCBS
CAIE T2,1 ;WAS IT THE PRIMARY MCB?
JRST DEDMC4 ;NO
SKIPL MCBDTE(T2) ;IS ANOTHER MCB RUNNING?
JRST DEDMC4 ;NO
MOVE T1,[440200,,NODTBL] ;BP TO REACH TABLE
MOVE T3,ITSNUM(T2) ;GET NODE NUMBER
ADJBP T3,T1 ;OFFSET INTO REACH
MOVEI T1,3 ;SAY PHASE III
DPB T1,T3 ;UPDATE TABLE
>
DEDMC4: MOVE T1,ITSNUM(T2) ;GET ITS NODE NUMBER
SETZM ITSNUM(T2) ;CLEAR IT
MOVEI T2,.NDSOF ;NODE IS OFF
CALL ADDNOD ;REMOVE IT
JFCL
MOVE T2,DEDPRT ;GET BACK PORT NUMBER
IMULI T2,2 ;POINT AT RIGHT PLACE
SETZM ITSNAM(T2) ;CLEAR NAME
SETZM ITSNAM+1(T2) ; ENTRY
MOVEI T2,.DCX39 ;GET ERROR
MOVEM T2,MSGW1 ;SAVE REASON
DEDMC1: LLLOCK ;LOCK TREE
MOVE T1,[DEDCOR] ;COROUTINE
SETOM T2 ;ALL LINKS
CALL OBJSRC
JRST [ LLLULK ;UNLOCK THE TREE
JRST MCBDE1] ;SEE IF ANY MORE MCB'S
SKIPN T1,WAITER ;IS WAIT TEST IS ZERO THEN WE AREN'T DONE
JRST DEDMC1 ;YES - START AT TOP OF TREE AGAIN
MDISMS ;NO - WAIT FOR LINK
JRST DEDMC1 ;AND PROCEED
;COROUTINE TO DO THE WORK FOR MCBDED
DEDCOR: SAVET
LOAD T2,LLSTA,(T1) ;GET THE LINK'S STATE
CAIG T2,LLSLIS ;IS IT LISTENING?
RET ;YES, NO CLEANUP NEEDED
JN LLLOC,(T1),R ;IF LOCAL, NOTHING TO DO
JN LLDED,(T1),R ;IF ALREADY PROCESSED, NOTHING TO DO
LOAD T2,LLPRT,(T1) ;GET THE LNK'S PORT NUMBER
CAME T2,DEDPRT ;THE DEAD ONE?
RET ;NO, ALL DONE
CALL BLKLOK ;YES. LOCK THE LL BLOCK
JRST [ LLLULK ;CAN'T. UNLOCK TREE
MOVEM T1,WAITER ;STORE WAIT
RETSKP] ;AND STOP NOW
LLLULK ;UNLOCK THE TREE
LOAD T2,LLSTA,(T1) ;GET STATE AGAIN
SETONE LLDED,(T1) ;INDICATE THIS BLOCK PROCESSED FOR DEAD MCB
CAIG T2,LLSCCS ;NEED TO CHANGE STATE?
XCT [ CALL RJECT ;YES. FOR CIS
CALL RJECT1 ;FOR CIR
CALL SHUTLK ;FOR RUNNING
CALL RJECT1 ;FOR DI SENT
CALL RJECT1 ;FOR QUEUED
CALL RJECT1 ;FOR DI REC
CALL RJECT1]-2(T2) ;AND, FINALLY, FOR CC SENT
SETZM WAITER ;FLAG INDICATES "CONTINUE AT TOP OF TREE"
JN LLSDE,(T1),[ OKINT ;IF DISASSOCIATED
CALL FLUSH ;GET RID OF ALL MESSAGES
LLLOCK ;LOCK UP THE LL TREE
CALL DELNOD ;RELEASE NODE
LLLULK ;GIVE UP THE TREE LOCK
RETSKP] ;NEED TO START AT TOP OF TREE
DEDMC2: CALL BLKULK ;RELEASE BLOCK AND RETURN
RETSKP ;NEED TO START AT TOP OF TREE
;ROUTINES TO HANDLE CONTROL MESSAGES
;PROCESS A CONNECT-INITIATE
;**;[2932]RE-DO CIMSG: LOGIC DSC 22-MAR-83
CIMSG: STKVAR <NDNUM> ;TEMP STORAGE FOR NODE NUMBER
CALL GETLLA ;GET LL ADDRESSES
JRST BADMSG ;BADLY FORMED
SKIPE MSGDST ;IS DEST ADDR 0?
JRST [ MOVEI T2,.DCX21 ;ILLEGAL DEST ADDR
JRST CIDC] ;AND GO BOMB IT OUT
CALL CIPSRV ;GO DO OTHER FIELDS
JRST [ MOVEI T2,.DCX35
JRST CIDC] ;AND BOMB IT OUT
GETBYM (MSGCNT,MSGBYP,INVPRC) ;GET FORMAT OF DEST OBJECT
CAILE T2,OBJTWO ;IS IT A FORMAT WE UNDERSTAND?
INVPRC: JRST [ MOVEI T2,.DCX5
JRST CIDC] ;AND ERROR
MOVE T4,T2 ;SAVE OBJECT TYPE
GETBYM (MSGCNT,MSGBYP,INVPRC) ;GET OBJECT NUMBER
MOVEM T2,MSGOBJ ;SAVE OBJECT #
SETZM MSGDDC ;ASSUME NO DESCRIPTOR
CAIN T4,OBJZRO ;ANY MORE?
JRST DSCNO ;NO
CAIE T4,OBJONE ;A GROUP CODE INCLUDED?
JRST [ CALL GETTWO ;YES. GET GOUP
JRST INVPRC ;INVALID
CALL GETTWO ;GET USER CODE
JRST INVPRC ;INVALID
JRST .+1] ;ALL READY TO GO
MOVEI T3,MSGDDC ;DESCRIPTOR BLOCK
MOVEI T4,MAXDSC
CALL GTASCI ;MOVE DESCRIPTOR STRING
JRST INVPRC
DSCNO: GETBYM (MSGCNT,MSGBYP,INVPRC) ;GET SOURCE OBJECT TYPE
CAILE T2,OBJTWO ;VALID?
JRST INVPRC
MOVE T4,T2 ;SAVE IT
GETBYM (MSGCNT,MSGBYP,INVPRC) ;GET OBJECT #
MOVEM T2,MSGSOB ;SAVE SOURCE OBJECT #
SETZM MSGSDC ;ASSUME NO DESCRIPTOR
SETZM MSGDML ;ASSUME NO GROUP,USER
CAIN T4,OBJTWO ;DOES IT INCLUDE A GROUP?
JRST [ CALL GETTWO ;YES. GET GROUP
JRST INVPRC ;BAD
HRLM T2,MSGDML ;SAVE IT
CALL GETTWO ;GET USER
JRST INVPRC
HRRM T2,MSGDML ;SAVE IT
JRST .+1] ;AND PROCEED
CAIGE T4,OBJONE ;HAVE A DESCRIPTOR?
JRST DSCNO1 ;NO. GO FIND MATCH
MOVEI T3,MSGSDC ;MOVE DESCRIPTOR
MOVEI T4,MAXDSC
CALL GTASCI ;GET IT
JRST INVPRC
; ..
;CIMSG CONTINUED .....
DSCNO1: MOVE T2,MSGBLK ;POINT TO MSG BLOCK AGAIN
LOAD T2,MSPRT,(T2) ;GET PORT MESSAGE CAME FROM
TMNE NTSHUT,MCBDTE(T2) ;SHUTTING DOWN?
SKIPE MSGLCL ;YES. IS THIS A FOREIGN HOST?
JRST DSCNO2 ;NO. ALLOW IT.
MOVEI T2,.DCX3 ;"NODE SHUTTING DOWN"
JRST CIDC ;AND REJECT THE CONNECT
DSCNO2: SKIPN MSGLCL ;LOCAL CONNECTION?
IFSKP.
MOVE T2,OURNUM ;YES
ELSE.
CALL NAMNUM ;NUMERIC NODE NAME?
IFNSK.
CALL DSCCNV ;NO, CONVERT NAME TO NUMBER
JRST BADNOD ;COULDN'T
JRST DSCNO4 ;MOVE ON
ENDIF.
MOVEI T1,MSGHSN ;CONVERT
HRROS T1 ; HOST STRING
MOVEI T3,^D10 ; TO A
NIN ; NUMBER
JRST BADNOD ;MUST BE FUNNY
;**;[2985]Add 2 lines at DSCNO2: +15L RWW 5-JUL-83
CAILE T2,BIGNOD ;[2985]Is this a legit node?
JRST BADNOD ;[2985]No,
ENDIF.
DSCNO4: MOVEM T2,NDNUM ;STASH NODE NUMBER
ADD T2,[NSCONR] ;OFFSET INTO "CONNECTS RECEIVED" TABLE
AOS (T2) ;INCR THE COUNT
MOVE T2,NDNUM ;RETRIEVE NODE NUMBER
ADD T2,[NSMSGR] ;GET "MESSAGES RECEIVED" TABLE
AOS (T2) ;COUNT THIS ONE
MOVE T2,NDNUM ;RETRIEVE NODE NUMBER
ADD T2,[NSBYTR] ;GET "BYTES RECEIVED" TABLE
MOVE T3,MSGBLK ;RETRIEVE MESSAGE ADDR
LOAD T3,MSCNT,(T3) ;GET NUMBER OF BYTES IN MESSAGE
ADDM T3,(T2) ;ADD THEM IN
DSCNO5: MOVEI T1,CICOR ;COROUTINE ADDRESS
MOVEI T2,1 ;LOOK FOR LISTENING OBJECT ONLY
LLLOCK ;LOCK THE TREE
CALL OBJSRC ;GO LOOK FOR AVAILABLE OBJECT
JRST [ CAIE T2,.DCX4 ;OBJECT EXIST?
IFSKP.
MOVE T3,NDNUM ;NO, RETRIEVE NODE NUMBER
ADD T3,[NSRCNE] ;GET "CONNECT RESOURCE ERROR" TABLE
AOS (T3) ;COUNT IT
ENDIF.
LLLULK ;RELEASE TREE
JRST CIDC]
CALL BLKLOK ;LOCK THE BLOCK
JRST [ LLLULK ;COULDN'T.
MDISMS ;WAIT HERE
JRST DSCNO5] ;AND TRY AGAIN
LLLULK ;AND FREE THE TREE
MOVEI T2,LLSCIR ;HAVE A CONNECT-INITIATE
STOR T2,LLSTA,(T1) ;NOTE STATE CHANGE
MOVEM T1,MSGLLB ;SAVE BLOCK
MOVE T2,MSGOBJ ;GET OBJECT USED IN CONNECT
STOR T2,LLSOB,(T1) ;SAVE IT
MOVE T2,MSGDML ;GET GROUP,USER
MOVEM T2,LLUSGP(T1) ;SAVE IN LL BLOCK
SKIPN MSGLCL ;LOCAL CONNECTION?
IFSKP.
SETONE LLLOC,(T1) ;YES, NOTE THIS IS A LOCAL LINK
MOVE T2,OURNUM ;GET OUR NODE NUMBER
STOR T2,LLHSN,(T1) ;PUT IT IN LL BLOCK
ELSE.
MOVE T2,NDNUM ;RETRIEVE NODE NUMBER
MOVE T1,MSGLLB ;GET LL BLOCK ADDRESS
STOR T2,LLHSN,(T1) ;PUT NODE NUMBER IN LL BLOCK
LOAD T1,LLHST,(T1) ;PLACE TO PUT HOST'S NAME STRING
HRROS T1 ;MAKE A BP TO IT
MOVEI T3,^D10 ;IN DECIMAL
NOUT
JFCL
MOVE T1,MSGLLB ;GET BACK BLOCK ADDRESS
MOVE T2,MSGBLK ;GET MESSAGE
LOAD T2,MSPRT,(T2) ;GET PORT #
STOR T2,LLPRT,(T1) ;SAVE IN LL BLOCK
ENDIF.
CALL FILLIN ;GO FILL IN COMMON QUANTITIES
MOVE T2,MSGSOB ;GET SOURCE OBJECT
STOR T2,LLFNM,(T1) ;SAVE IT
LOAD T1,LLFDS,(T1) ;GET DESCRIPTOR STRING
SKIPN T2,MSGSDC ;HAVE A DESCRIPTOR?
JRST [ CALL RELBLK ;FREE THE BLOCK
MOVE T1,MSGLLB ;GET BACK LL BLOCK
SETZRO LLFDS,(T1) ;CLEAR IT
JRST DSCMOV]
SETOM T3 ;UNTIL A NULL
MOVEI T2,MSGSDC ;GET POINTER TO STRING
CALL MOVSTR ;MOVE IT
MOVE T1,MSGLLB ;GET BACK BLOCK ADDRESS
; ..
;CIMSG CONTINUED. FOUND BLOCK. GET OPTIONAL ACCESS CONTROL STUFF
DSCMOV: GETBYM (MSGCNT,MSGBYP,NODATA) ;GET MENU BYTE
MOVEM T2,MSGW1 ;SAVE MENU
TRNN T2,1 ;HAVE ACCESS CONTROL?
JRST NOUSER ;NO. CHECK FOR OPDATA
LOAD T3,LLUSR,(T1) ;WHERE TO PUT USER DATA
MOVEI T4,MAXUAP ;MAX SIZE OF USERID
CALL GTASCI ;GET IT
JRST BADUDT ;BADLY FORMED
LOAD T3,LLPSW,(T1) ;WHERE TO PUT PASSWORD
MOVEI T4,MAXUAP ;MAX SIZE OF PASSWORD
CALL GTBNRY ;GET OCTETS
JRST BADUDT ;BADLY FORMED
STOR T2,LLPCT,(T1) ;SAVE COUNT
LOAD T3,LLACT,(T1) ;GET ACCOUNT DATA
MOVEI T4,MAXUAP ;MAX SIZE OF ACCOUNT
CALL GTASCI ;GET IT
JRST BADUDT ;BADLY FORMED
NOUSER: MOVE T2,MSGW1 ;GET BACK MENU
TRNN T2,2 ;HAVE OPTDATA?
JRST NODATA ;NO. ALL DONE
LOAD T3,LLOPT,(T1) ;WHERE TO PUT IT
MOVEI T4,MAXOPT
CALL GTBNRY ;GET OCTETS
JRST BADUDT ;BADLY FORMED
STOR T2,LLUCT,(T1) ;SAVE COUNT
NODATA: CALL INTTST ;GO SEE IF THIS IS CONNECTED TO AN INTERNAL LINK
DSCMV1: CALL CONINT ;GIVE INTERRUPT
CALL BLKULK ;RELEASE THE BLOCK
MOVE T1,MSGBLK ;GET BACK MESSAGE BLOCK
CALL RELRES ;FREE THE BLOCK
RET ;RETURN TO BACKGROUND TASK DISPATCHER
ENDSV.
;RECEIVED A MESSAGE FROM A NODE WHOSE NAME WE DON'T RECOGNIZE
;**;[2932]REPLACE 8 LINES WITH 3 LINES AT BADNOD: DSC 22-MAR-83
BADNOD: BUG (NSPNOD) ;[2932]BUGINF
MOVEI T2,.DCX7 ;[2932]UNSPECIFIED ERROR
JRST CIDC ;[2932]GO SEND DC
;TRY TO CONVERT THE NODE NAME TO A NODE NUMBER
;USES TRVAR MSGHSN,MSGHNC,MSGLLB
;RETURNS +1 NO NAME ASSIGNED TO NODE NUMBER
; +2 T2/ NODE NUMBER
DSCCNV: SAVEQ
MOVNI Q3,BIGNOD ;MAKE
HRLS Q3 ; AOBJN
HRRI Q3,1 ; WORD
SETZB T3,Q2 ;PERMANENT VALUES THROUGH EXTEND LOOP
DSCCN1: MOVE T1,[POINT 7,MSGHSN] ;BP TO HOST NAME IN MSG
MOVE T2,[POINT 6,] ;BP TO ENTRY
HRRI T2,NODMAP(Q3) ; IN NODE NAME MAPPING TABLE
MOVE T3,MSGHNC ;GET NUMBER OF CHARS. IN HOST NODE NAME
TLO T3,400000 ;SPECIAL CALL TO COMPAR
MOVNI T4,40 ;COMPARE ASCII TO SIXBIT
CALL COMPAR ;DO THEY MATCH?
IFSKP.
HRRZ T2,Q3 ;YES, POSITION NODE NUMBER
RETSKP
ENDIF.
AOBJN Q3,DSCCN1 ;NO, TRY ANOTHER
RET ;DIDN'T FIND IT
;SEE IF IT'S A NODE NAME OR A NUMERIC NAME
;RETURNS: +1 NOT NUMERIC
; +2 NUMERIC
NAMNUM: MOVE T1,[440700,,MSGHSN] ;BP TO NAME IN MSG
MOVE T2,MSGHNC ;GET NUMBER OF CHARS. IN NAME
NAMNU1: ILDB T3,T1 ;GET A CHAR.
CAIL T3,"0" ;IS IT
CAILE T3,"9" ; NUMERIC?
RET ;NO
SOJG T2,NAMNU1 ;YES, ANY MORE TO CHECK
RETSKP ;NO, NAME IS NUMERIC
;COROUTINE OF CIMSG TO FIND THE PROPER LISTENING OBJECT
CICOR: SAVET ;SAVE ALL TEMPS
SKIPN T2,MSGOBJ ;WANT TASK NAME MATCH?
JRST [ LOAD T2,LLTSK,(T1) ;YES. PICK UP STRING
JRST CICOR1] ;AND GO TRY
OPSTR <CAME T2,>,LLNAM,(T1) ;IS THIS THE CORRECT OBJECT?
RET ;NO.
LOAD T2,LLDSC,(T1) ;YES. CHECK DESCRIPTOR STRINGS
CICOR1: MOVEI T1,MSGDDC ;GET REQUESTED DESCRIPTOR
CALL CMPSTR ;GO COMPARE STRINGS
RET ;NOT THE ONE
RETSKP ;FOUND IT!!!!
;COMMON ROUTINE TO FETCH LL ADDRESSES FROM MESSAGES AND STORE IN
;PROPER TRVAR'S
RESCD ;USED BY INT LEVEL
GETLLA: CALL GETTWO ;GET DEST LL
RET ;BADLY FORMED
MOVEM T2,MSGDST ;SAVE IT
CALL GETTWO ;GET SOURCE
RET ;BADLY FORMED
MOVEM T2,MSGSRC
RETSKP ;GO THEM
;COMMON ROUTINE TO FILL IN LL BLOCK AFTER SUCCESSFUL CONNECTION
SWAPCD ;IS SWAPPABLE
FILLIN: MOVE T2,MSGLKP ;GET LINK PRIORITY
STOR T2,LLLKP,(T1) ;SAVE IT IN LL BLOCK
MOVE T2,MSGW1 ;GET FC OPTION
STOR T2,LLMFC,(T1) ;SAVE IT IN LL BLOCK
MOVE T2,MSGW2 ;GET SEGSIZE
MOVE T3,MSGBLK ;GET MESSAGE ADDRESS
LOAD T3,MSMFL,(T3) ;GET MESSAGE FLAGS
CAIE T3,CIMMFL ;A CI?
JRST [ LOAD T4,LLSWG,(T1) ;NO, A CC. GET SEGSIZ OF CI
CAMLE T2,T4 ;OUR'S LESS?
MOVE T2,T4 ;NO, USE SEGSIZ OF CI
TMNE LLLOC,(T1) ;LOCAL CONNECTION?
JRST FILLI2 ;YES, NO FURTHER CHECK NEEDED
LOAD T4,LLPRT,(T1) ;GET PORT NUMBER
CAMLE T2,NSPMAX(T4) ;OUR'S LESS THAN PORT'S?
MOVE T2,NSPMAX(T4) ;NO, USE PORT'S SEGSIZ
JRST FILLI2]
FILLI2: LOAD T3,LLBSZ,(T1) ;GET BYTE SIZE
CAIE T3,44 ;WORD MODE?
JRST FILLI1 ;NO.
IDIVI T2,11 ;YES. MAKE IT EVEN # OF WORDS THEN
IMULI T2,11 ;""
FILLI1: STOR T2,LLSWG,(T1) ;SAVE IT
MOVE T2,MSGSRC ;GET FOREIGN LINK I.D.
STOR T2,LLHLK,(T1) ;SAVE IT
RET ;AND DONE
;COMMON ROUTINE TO GEN CONNECT INTERRUPT
CONINT: SAVET ;SAVE TEMPS
STKVAR <CNTLLB,CNTSTS>
MOVEM T1,CNTLLB ;SAVE LOGICAL LINK BLOCK ADDRESS
JN LLINT,(T1),CONIN1 ;IF INTERNAL LINK GO NOTIFY DRIVER OF CONNECT
LOAD T2,LLFRK,(T1) ;GET OWNING FORK
OPSTR <SKIPN T1,>,LLPIC,(T1) ;HAVE A CONNECT PI?
RET ;NONE TO DO
SOS T1 ;GET PROPER CHANNEL
CALLRET PSIRQ ;GEN INTERRUPT
; HERE FOR INTERNAL LINKS
CONIN1: CALL RDSTS ;GO GET LINK STATUS
MOVEM T3,CNTSTS ;SAVE STATUS
HRRZ T1,CNTSTS ;GET NSP ERROR CODE
CALL NSPERR ;CONVERT TO TOPS20 ERROR CODE
JFCL ;USE TRANSLATION ROUTINE'S ERROR CODE
HRR T2,T1 ;GET TOPS20 ERROR CODE
HLL T2,CNTSTS ;GET STATUS FLAGS
MOVE T1,CNTLLB ;RESTORE LOGICAL LINK BLOCK ADDRESS
LOAD T4,LLVEC,(T1) ;GET ADDRESS OF DRIVER FUNCTION VECTOR
LOAD T1,LLDRV,(T1) ;GET DRIVER CORRELATION CODE
CALL @.NSCND(T4) ;NOTIFY DRIVER OF CONNECTION
RET ;DONE, RETURN
;INTTST - ROUTINE TO DETERMINE IF CONNECTED TO AN INTERNAL LINK
;
;ACCEPTS IN TRVARS MSGLCL/ LOCAL-FOREIGN FLAG
; MSGSRC/ LINK ID OF SOURCE OF CI MESSAGE
; MSGLLB/ LOGICAL LINK BLOCK ADDRESS OF DESTINATION LINK
; CALL INTTST
;RETURNS: +1 ALWAYS, WITH LLCIL SET IF CONNECTED TO AN INTERNAL LINK
INTTST: ACVAR <W1>
SAVET ;PRESERVE LOCAL AC'S
SKIPN MSGLCL ;LOCAL CONNECTION ?
RET ;NO, DONE
; LOCK SOURCE LOGICAL LINK BLOCK AND SEE IF IT IS AN INTERNAL LINK
INTT10: LLLOCK ;LOCK LOGICAL LINK TREE
MOVE T1,MSGSRC ;GET SOURCE LINK ID
SETOM T2 ;NO SPECIAL CRITERIA
CALL LLLKUP ;FIND THE LINK ADDRESS
JRST [ LLLULK ;FAILED, UNLOCK THE TREE
RET ] ;RETURN, LINK MUST HAVE DISAPPEARED
MOVEM T1,W1 ;SAVE LOGICAL LINK BLOCK ADDRESS OF SOURCE
CALL BLKLOK ;LOCK THE SOURCE LINK BLOCK
JRST [ LLLULK ;CANNOT LOCK IT, UNLOCK THE TREE
MDISMS ;WAIT UNTIL AVAILABLE
JRST INTT10 ] ;GO TRY TO LOCK BLOCK AGAIN
LLLULK ;UNLOCK LOGICAL LINK TREE
JE LLINT,(W1),INTT20 ;IF SOURCE IS NOT AN INTERNAL LINK, WE ARE DONE
MOVE T4,MSGLLB ;GET LOGICAL LINK BLOCK ADDRESS OF DESTINATION
SETONE LLCIL,(T4) ;NOTE CONNECTED TO AN INTERNAL LINK
; HERE WHEN DONE, UNLOCK BLOCK AND RETURN
INTT20: MOVE T1,W1 ;RESTORE LOGICAL LINK BLOCK ADDRESS
CALL BLKULK ;UNLOCK THE BLOCK
RET ;DONE, RETURN
ENDAV. ;END ACVAR
;PROCESS A CONNECT-CONFIRM
CCMSG: CALL GETLLA ;GET LINK ADDRESSES
JRST BADMSG ;BADLY FORMED
SETZM MSGSOB ;ASSUME WE LIKE SERVICES
CALL CIPSRV ;GET SERVICES INFO
SETOM MSGSOB ;DIDN'T LIKE IT. REMEMBER THIS
CCMSG1: MOVE T1,MSGDST ;GET OUR ALLEGED NAME
SETOM T2 ;ANY MATCH
LLLOCK ;LOCK THE TREE
CALL LLLKUP ;AND LOOK UP THE BLOCK
JRST [ LLLULK ;FREE THE TREE
MOVEI T2,.DCX41 ;NO MATCH
JRST CIDC] ;GO DC THE LINK
MOVEM T1,MSGLLB ;SAVE LINK BLOCK ADR
CALL BLKLOK ;LOCK BLOCK LOCK
JRST [ LLLULK ;FREE TREE LOCK
MDISMS ;WAIT HERE A WHILE
JRST CCMSG1] ;AND TRY AGAIN
LLLULK ;FREE THE TREE
MOVE T2,MSGBLK ;GET MESSAGE ADDRESS
CALL NSINBK ;DO BOOKKEEPING
JN LLFOB,(T1),CCJECT ;CAN'T BE AN OBJECT
LOAD T2,LLSTA,(T1) ;GET STATE
JRST @CCREC-1(T2) ;GO DO RIGHT THING
;EXPECTING A CC.
CCGUD: SKIPN MSGSOB ;DID WE LIKE SERVICES?
JRST CCGUD1 ;YES
MOVEI T2,LLSABT ;NEED TO CLOSE LINK
STOR T2,LLSTA,(T1) ;SAY LINK IS DEAD
CALL CONINT ;GET AN INTERRUPT
MOVEI T2,.DCX35 ;SERVICES MISMATCH
JRST CCJEC1 ;AND SEND A DC
CCGUD1: SKIPG MSGSRC ;A VALID SOURCE I.D.?
JRST [ SETZM MSGW1 ;NO.
CALL RJECT ;SHUT DOWN LINK
JRST CCDON] ;AND GIVE UP
CALL FILLIN ;FILL IN NECESSARY INFORMATION
CALL TURNON ;GO SEND INTIAL LS MESSAGE
JRST [ EXCH T1,MSGLLB ;SAVE SCHED TEST, GET LINK BLOCK ADR
CALL BLKULK ;FREE THIS BLOCK
MOVE T1,MSGLLB ;RESTORE SCHED TEST
CALL GENWAT ;WAIT HERE FOR A WHILE
MDISMS ;UNTIL FREE SPACE IS AVAILABLE
JRST CCMSG1] ;AND DO IT AGAIN
MOVEI T2,LLSRUN ;NOW WE ARE RUNNING
STOR T2,LLSTA,(T1) ;SAY SO
SETONE LLLWC,(T1) ;NOTE THAT A GOOD CC WAS RECEIVED
LOAD T3,LLOPT,(T1) ;SEE IF ANY OPTDATA
MOVEI T4,MAXOPT
CALL GTBNRY
JRST [ JUMPE T2,CCGUD2 ;IF NO OPTDATA, OK
JRST BADUDT] ;BAD MESSAGE
STOR T2,LLUCT,(T1) ;YES. SAVE COUNT
CCGUD2: MOVEI T2,1 ;INITIAL COUNT FOR LS/INT
STOR T2,LLMIC,(T1) ;STASH IT
JRST DSCMV1 ;AND GO INTERRUPT, ETC.
;CCMSG CONTINUED...
;DON'T LIKE IT
CCJECT: MOVEI T2,.DCX41 ;ILLEGAL DEST ADDRESS
CCJEC1: CALL BLKULK ;FREE THE BLOCK
JRST CIDC ;AND SEND DC
CCDON: CALL BLKULK ;FREE THE BLOCK
JRST TOSMSG ;IGNORE THE MESSAGE
;ROUTINES TO SEND DC'S FOR CONNECT ERRORS
CIDC: SKIPE MSGLCL ;IS IT LOCAL?
JRST [SKIPL NSPLPB ;YES, IS THERE A RUNNING LOOPBACK LINE?
JRST CIDCLC ;NO
JRST .+1] ;YES
MOVEM T2,MSGW1 ;SAVE CODE
CIDCT: MOVEI T1,MSGDML ;USE DUMMY LINK BLOCK
MOVEI T3,CNMRFL+CNMDC ;FLAGS
MOVE T2,MSGW1 ;GET REASON
CALL SNDDC ;BUILD THE DC MESSAGE
JRST [ MDISMS ;WAIT A WHILE
JRST CIDCT] ;AND TRY AGAIN
CALL SNDCTL ;SEND IT
JRST TOSMSG ;AND DONE
CIDCLC: MOVE T1,MSGDST
EXCH T1,MSGSRC ;EXCHANGE SOURCE AND DEST
MOVEM T1,MSGDST ;""
JRST DCMSG4 ;AND GO DO DC
;ROUTINE TO HANDLE ACCESS INFORMATION ERRORS
BADUDT: CALL CONINT ;INT PROCESS
MOVEI T2,.DCX43 ;SAY BAD OPTDATA
STOR T2,LLRSN,(T1) ;AND STASH IT
MOVEI T3,LLSABT ;NEW STATE
STOR T3,LLSTA,(T1)
CALL BLKULK ;FREE BLOCK
JRST CIDC ;AND SEND DC
;ROUTINE TO BUILD A DI OR DC MESSAGE FOR NSPTSK
;ACCEPTS: T1/ ADDRESS OF DUMMY LL BLOCK
; T2/ REASON
; T3/ FLAGS
;RETURNS: +1 FAILED. NEED TO BLOCK
; +2 ALL SENT
SNDDC: SKIPE T4,MSGHSN ;ANY HOST NAME ?
MOVEI T4,MSGHSN ;YES, GET ADDRESS OF HOST NAME
STOR T4,LLHST,(T1) ;STORE IT
MOVE T4,MSGSRC ;GET SOURCE NAME
STOR T4,LLHLK,(T1) ;SAVE AS REMOTE NAME
MOVE T4,MSGDST ;GET OUR NAME
STOR T4,LLLNK,(T1) ;SAVE IT
MOVE T4,T3 ;MOVE FLAGS
MOVE T3,MSGBLK ;GET MESSAGE
LOAD T3,MSPRT,(T3) ;GET PORT
STOR T3,LLPRT,(T1) ;SAVE IN LL BLOCK
SETZM T3 ;NO USER DATA
CALL SNDDI ;BUILD THE MESSAGE
JRST [ TQO <BLKF> ;NOTE BLOCK NEEDED
RET ] ;AND RETURN
RETSKP ;DONE, RETURN SUCCESS
;RECEIVED AN ACK
ACKMSG: CAIL T4,2 ;VALID SUBTYPE?
JRST TOSMSG ;NO, IGNORE IT
CALL GETLLA ;GET LINK ADDRESSES
JRST BADMSG ;BADLY FORMED
MOVE T1,MSGBLK ;GET BLOCK ADDRESS
MOVE T3,MSGBYP ;GET CURRENT POINTER
MOVEM T3,MSBPTR(T1) ;SAVE POINTER
MOVE T3,MSGCNT ;GET CURRENT COUNT
STOR T3,MSDTC,(T1) ;SAVE IT
ACKMS1: LLLOCK ;LOCK THE TREE
MOVE T1,MSGDST ;GET OUR NAME
MOVE T2,MSGSRC
CALL LLLKUP ;LOOK UP THE NAME
JRST [ LLLULK ;NOT FOUND
MOVEI T2,.DCX41 ;INVALID ADDRESS
JRST CIDC] ;SEND A DC TO SHUT OFF THIS NOISE
CALL BLKLOK ;FOUND IT. LOCK IT
JRST [ LLLULK ;CAN'T
MDISMS ;WAIT A WHILE
JRST ACKMS1] ;AND TRY AGAIN
LLLULK
MOVEM T1,MSGLLB ;SAVE LOGICAL LINK BLOCK ADDRESS
MOVE T2,MSGBLK ;GET MESSAGE ADDRESS
CALL NSINBK ;DO BOOKKEEPING
LOAD T2,LLSTA,(T1) ;GET CURRENT STATE
JRST @ACKSTA-1(T2) ;GO HANDLE IT
;IN CIS STATE
ACKCIS: CALL GETTWO ;GET ACK VALUE
JRST ACKINV ;NOT VALID
TXNE T2,ACKBIT ;ACK OR NACK?
JRST CCDON ;A NACK. IGNORE IT
JUMPN T2,ACKINV ;AN ACK. MUST BE FOR SEG # 0
MOVE T2,MSGBLK ;GET FLAGS
LOAD T2,MSMFL,(T2) ;""
SKIPN MSGSRC ;MUST NOT HAVE A SOURCE NAME YET
TXNE T2,ACKLSI ;AND MUST BE FOR DATA SUBCHANNEL
JRST ACKINV ;NOT
JRST CCDON ;A VALID ACK. IGNORE IT HOWEVER
ACKINV: MOVEI T2,.DCX41 ;INVALID.
MOVEM T2,MSGW1 ;SET UP ERROR CODE
CALL RJECT ;ABORT THE LINK
JRST CCJEC1 ;SEND THE DC
;IN CC SENT STATE
ACKCCS: STKVAR <LLBLK> ;TEMP STORAGE FOR LL BLOCK ADDRESS
MOVEM T1,LLBLK ;SAVE IT
ACKCC4: CALL TURNON ;TRY TO SEND INITIAL LS MESSAGE
JRST[ PUSH P,T1 ;SAVE SCHEDULER TEST
MOVE T1,LLBLK ;RETRIEVE LL BLOCK ADDRESS
SETONE LLTRN,(T1) ;STILL NEED LS
CALL BLKULK ;UNLOCK THE LL BLOCK
POP P,T1 ;RETRIEVE SCHEDULER TEST
CALL GENWAT ;AND WAIT HERE
MDISMS ;UNTIL FREE SPACE IS AVAILABLE
ACKCC5: MOVE T1,LLBLK ;GET LL BLOCK ADDRESS
CALL BLKLLK ;LOCK THE BLOCK
JRST [MDISMS ;CAN'T, WAIT
JRST ACKCC5] ;AND TRY TO LOCK AGAIN
JRST ACKCC4] ;TRY TO SEND MESSAGE AGAIN
SETZRO LLTRN,(T1) ;DON'T NEED LS ANYMORE
MOVEI T2,LLSRUN ;NOW IN
STOR T2,LLSTA,(T1) ; RUN STATE
MOVEI T2,1 ;SET INITIAL LS/INT
STOR T2,LLMIC,(T1) ; REQUEST COUNT
ACKCC3: HRRZ T2,LLSEGQ(T1) ;GET ADDRESS OF FIRST MESSAGE ON LINK'S QUEUE
JUMPE T2,ACKRUN ;IF NONE, ALL SET
SETZ T3, ;NO PREVIOUS MESSAGE YET
ACKCC1: LOAD T4,MSMFL,(T2) ;GET MESSAGE TYPE
CAIN T4,CNMRFL+CNMCF ;IS IT A CC?
JRST ACKCC2 ;YES, GO REMOVE IT FROM THE QUEUE
MOVE T3,T2 ;MAKE THIS ONE PREVIOUS
OPSTR <SKIPE T2,>,MSLNK,(T2) ;GET ADDRESS OF NEXT
JRST ACKCC1 ;GO TRY IT
JRST ACKRUN ;NO MORE TO TRY
ACKCC2: MOVEI T4,LLSEGQ(T1) ;GET ADDRESS OF LINK'S SEGMENT QUEUE
CALL UNQSEG ;REMOVE THE CC FROM THE SENT QUEUE
MOVE T1,T2 ;GET MESSAGE ADDRESS IN NECESSARY PLACE
CALL RELRES ;GIVE BACK THE SPACE
MOVE T1,LLBLK ;GET BACK THE LL BLOCK ADDRESS
;IN RUN STATE
;**;[2931]REWRITE ACKRUN LOGIC DSC 22-MAR-83
ACKRUN: MOVE T2,MSGBLK ;GET MESSAGE
LOAD T2,MSMFL,(T2) ;GET FLAGS
CALL ACKDO ;GO DO THE ACTUAL ACK
JRST ABTMSG ;BADLY FORMED MESSAGE
JN LLINT,(T1),[
CALL SQILS ;INTERNAL LINK, TRY LS SEND AGAIN
MOVE T1,MSGLLB ;FAILED, RESTORE LINK BLOCK ADDRESS
JRST CCDON]
TMNE LLLSA,(T1) ;WANT TO RETRY A LS SEND?
CALL DATINR ;YES. MAKE PROCESS WAKE NOW THEN
JRST CCDON ;AND DONE
ENDSV.
DIMSG: CALL GETLLA ;GET LINK ADDRESSES
JRST BADMSG ;BAD MESSAGE
CALL GETTWO ;GET REASON CODE
SETOM T2 ;BADLY FORMED MESSAGE
MOVEM T2,MSGW1 ;SAVE REASON CODE
DIMSG1: MOVE T1,MSGDST ;GET OUR NAME
SETOM T2 ;MATCH ANY LINK
MOVEI T3,MSGHSN ;GET HOST NAME
LLLOCK ;LOCK THE TREE
CALL LLLKUP ;FIND THE LINK
JRST [ LLLULK ;FREE THE TREE
MOVEI T2,.DCX41 ;INVALID LINK I.D.
JRST CIDC] ;AND SEND A DC
MOVEM T1,MSGLLB ;SAVE BLOCK ADDRESS
CALL BLKLOK ;LOCK THE BLOCK
JRST [ LLLULK ;FREE THE TREE
MDISMS ;WAIT HERE FOR A WHILE
JRST DIMSG1] ;AND TRY AGAIN
LLLULK ;FREE THE TREE
MOVE T2,MSGBLK ;GET MESSAGE ADDRESS
CALL NSINBK ;DO BOOKKEEPING
LOAD T3,LLOPT,(T1) ;GET OPTDATA, IF ANY
MOVEI T4,MAXOPT
CALL GTBNRY ;GO GET IT
SETZM T2 ;NONE THERE.
STOR T2,LLUCT,(T1) ;SAVE COUNT OF DATA
LOAD T2,LLSTA,(T1) ;GET CURRENT STATE
JRST @DIREC-1(T2) ;GO DO STATE ACTION
;DI RECIEVED WHEN IN CI SENT STATE
CONREJ: CALL RJECT ;SET STATE OF LINK
JRST DCDCS ;SEND DC
;HERE FOR DI RECEIVED WHEN IN DIS STATE
DIDIDC: TMNE LLLOC,(T1) ;LOCAL MESSAGES AREN'T
JRST DIMSG2 ; ON SENT QUEUE
HRRZ T2,LLSEGQ(T1) ;GET ADDRESS OF FIRST MESSAGE IN QUEUE
SETZ T3, ;NO PREVIOUS MESSAGE YET
DIDID1: LOAD T4,MSMFL,(T2) ;GET MESSAGE TYPE
CAIN T4,CNMRFL+CNMDI ;IS IT A DI?
JRST DIDID2 ;YES
MOVE T3,T2 ;NO, MAKE THIS MESSAGE PREVIOUS
LOAD T2,MSLNK,(T2) ;GET ADDRESS OF NEXT MESSAGE
JRST DIDID1 ;GO TRY THIS ONE
DIDID2: MOVEI T4,LLSEGQ(T1) ;GET ADDRESS OF SEGMENT QUEUE HEAD
CALL UNQSEG ;REMOVE SEGMENT FROM QUEUE
MOVE T1,T2 ;GET ADDRESS OF OLD DI
CALL RELRES ;GIVE BACK THE SPACE
MOVE T1,MSGLLB ;RETRIEVE LL BLOCK ADDRESS
;DI RECEIVED IN RUN, DIQ, DIR, OR CCS
DIMSG2: CALL CHKFRN ;SOURCE ADDR MUST MATCH
JRST CCJECT ;DOESN'T, SEND DC
CALL SHUTLK ;SHUT DOWN LINK
;COMMON POINT FOR DI RECEIVED - RESPONSE IS ALWAYS REASON CODE 42
DCDCS: STKVAR <DILLB>
MOVEM T1,DILLB ;PRESERVE LL BLOCK ADDRESS
MOVEI T2,.DCX42 ;SAY REPLY TO DI
CALL CIDC ;SEND DC
;**;[2940]CHANGE 1 LINE AT DCDCS: + 4L DSC 29-MAR-83
MOVE T1,DILLB ;[2940]GET BACK LL BLOCK ADDRESS
TMNE LLSDE,(T1) ;DISASSOCIATED?
IFSKP.
CALL BLKULK ;NO, UNLOCK LL
RET ;DONE
ENDIF.
CALL FLUSH ;YES, GET RID OF ALL MESSAGES
LLLOCK ;LOCK THE LL TREE
CALL DELNOD ;GET RID OF THIS LL
LLLULK ;UNLOCK THE TREE
;**;[2930]ADD 1 LINE AT DCDCS: + 8L DSC 22-MAR-83
OKINT ;[2930]MATCH THE NOINT DONE IN BLKLOK
DECR DCCUR ;GIVE BACK A LINK
RET
ENDSV.
;ROUTINES TO CHANGE LINK STATE WHEN DI OR DC IS RECIEVED
;FOR DI OR DC RECEIVED IN CIS STATE
RJECT: MOVEI T2,LLSABT ;CONNECTION IS ABORTED
STOR T2,LLSTA,(T1) ;SAY SO
MOVE T2,MSGW1 ;GET REASON CODE
STOR T2,LLRSN,(T1) ;SAVE IN THE LL BLOCK
CALLRET CONINT ;GIVE CONNECTION INTERRUPT
;FOR DI OR DC RECIEVED IN NON-RUN STATE
RJECT1: MOVEI T2,LLSABT ;SAY LINK NOW ABORTED
STOR T2,LLSTA,(T1)
MOVE T2,MSGW1 ;GET REASON
STOR T2,LLRSN,(T1) ;STORE IN BLOCK
CALL FLUSH ;CLEAR OUT LINK'S QUEUES
CALL CHKLLT ;CHECK FOR TTY ON THIS LINK
CALLRET TELDIS ;NOTIFY DRIVER IF THIS IS AN INTERNAL LINK
;FOR DI OR DC RECEIVED IN RUN STATE
SHTLK1: SKIPA T3,[LLSDIS] ;NEW STATE
SHUTLK: MOVEI T3,LLSDIR ;NEW STATE
MOVE T2,MSGW1 ;GET REASON
STOR T2,LLRSN,(T1) ;SAVE IT
STOR T3,LLSTA,(T1) ;SAVE NEW STATE
CALL DATINR ;GIVE INT IF NECESSARY
SKIPE MSGW1 ;SYNCHRONOUS DI?
JRST [ SETZRO LLFDI,(T1) ;NO. CLEAR THIS JUST IN CASE
CALL FLUSH ;AND CLEAN UP LINK
JRST SHUT10] ;GO NOTIFY DRIVER IF INTERNAL LINK
SETONE LLFDI,(T1) ;YES. SAY SO
SHUT10: CALL CHKLLT ;CHECK FOR TTY ON THIS LL
CALLRET TELDIS ;NOTIFY DRIVER IF AN INTERNAL LINK
;ROUTINE USED BY DIMSG TO VERIFY SOURCE ADDR
; T1/ LINK ADDRESS
;RETURNS: +1 NOT A MATCH
; +2 A MATCH
CHKFRN: LOAD T2,LLHLK,(T1) ;GET FOREIGN HOST I.D.
CAME T2,MSGSRC ;IS THIS WHO SENT IT?
RET ;NO
RETSKP ;YES
;TELDIS - ROUTINE TO NOTIFY A DRIVER OF A DISCONNECT ON AN INTERNAL LINK
;
;ACCEPTS IN T1/ ADDRESS OF LOGICAL LINK BLOCK
; CALL TELDIS
;RETURNS: +1 ALWAYS, WITH DRIVER NOTIFIED
TELDIS: SAVET
STKVAR <TDSLLB,TDSSTS>
MOVEM T1,TDSLLB ;SAVE LOGICAL LINK BLOCK ADDRESS
JE LLINT,(T1),R ;DONE IF NOT AN INTERNAL LINK
JN LLSDE,(T1),R ;DONE IF LINK DISSOCIATED FROM PROCESS
CALL RDSTS ;GO GET LINK STATUS
MOVEM T3,TDSSTS ;SAVE STATUS
HRRZ T1,TDSSTS ;GET NSP ERROR CODE
CALL NSPERR ;CONVERT TO TOPS20 ERROR CODE
JFCL ;FAILED, USE ERROR CODE FROM TRANSLATION ROUTINE
HRR T2,T1 ;GET TOPS20 ERROR CODE
HLL T2,TDSSTS ;GET STATUS BITS
MOVE T1,TDSLLB ;RESTORE LOGICAL LINK BLOCK ADDRESS
LOAD T4,LLVEC,(T1) ;GET ADDRESS OF DRIVER FUNCTION VECTOR
LOAD T1,LLDRV,(T1) ;GET DRIVER CORRELATION CODE
CALLRET @.NSDIS(T4) ;NOTIFY DRIVER OF DISCONNECT
;RECEIVED A DC MESSAGE
DCMSG: CALL GETLLA ;GET LINK ADDRESSES
JRST BADMSG ;BADLY FORMED
CALL GETTWO ;GET REASON
SETOM T2 ;NONE THERE
DCMSG4: MOVEM T2,MSGW1 ;SAVE IT
DCMSG1: MOVE T1,MSGDST ;GET OUR NAME
MOVE T2,MSGSRC ;GET SOURCE ADDRESS
LLLOCK ;LOCK THE TREE
CALL LLLKUP ;FIND THE LINK
JRST [ LLLULK ;FREE THE TREE
JRST TOSMSG] ;IGNORE THE MESSAGE
MOVEM T1,MSGLLB ;SAVE THE LL BLOCK ADDRESS
CALL BLKLOK ;LOCK THE BLOCK
JRST [ LLLULK ;CAN'T. FREE TREE
MDISMS ;WAIT HERE
JRST DCMSG1] ;AND TRY AGAIN
LLLULK ;FREE TREE
LOAD T2,LLSTA,(T1) ;GET STATE
JRST @DCREC-1(T2) ;AND GO DO RIGHT THING
CHKIDL: SKIPN MSGSRC ;SOURCE NODE FIELD MBZ, IS IT?
CALL RJECT ;YES, GO SET PROPER LINK STATE
JRST CCDON ;AND DONE
;RECEIVED DC IN DIS STATE - MUST REMOVE THE DI FROM THE SENT QUEUE
;BEFORE CLOSING THE LINK
DCGUD: TMNE LLLOC,(T1) ;LOCAL MESSAGES AREN'T
JRST DCABT ; ON SENT QUEUE
HRRZ T2,LLSEGQ(T1) ;GET ADDRESS OF FIRST MESSAGE IN QUEUE
SETZ T3, ;NO PREVIOUS MESSAGE YET
DCGUD1: LOAD T4,MSMFL,(T2) ;GET MESSAGE TYPE
CAIN T4,CNMRFL+CNMDI ;IS IT A DI?
JRST DCGUD2 ;YES
MOVE T3,T2 ;NO, MAKE THIS MESSAGE PREVIOUS
LOAD T2,MSLNK,(T2) ;GET ADDRESS OF NEXT MESSAGE
JRST DCGUD1 ;GO TRY THIS ONE
DCGUD2: MOVEI T4,LLSEGQ(T1) ;GET ADDRESS OF SEGMENT QUEUE HEAD
CALL UNQSEG ;REMOVE SEGMENT FROM QUEUE
MOVE T1,T2 ;GET ADDRESS OF OLD DI
CALL RELRES ;GIVE BACK THE SPACE
MOVE T1,MSGLLB ;RETRIEVE THE LL BLOCK ADDRESS
;RECEIVED DC IN NON-RUN STATE
DCABT: JN LLSDE,(T1),[
CALL RELLNK ;IF DISASSOCIATED
JRST TOSMSG] ;JUST GIVE UP QUIETLY
CALL RJECT1 ;SET PROPER LINK STATE
JRST CCDON ;AND DONE
;DC RECEIVED IN RUN STATE
DCRUN: SKIPN T2,MSGW1 ;AN ABORT?
MOVEI T2,.DCX9 ;NO. MAKE IT ONE THEN
MOVEM T2,MSGW1
CALL SHUTLK ;BEGIN LINK SHUT DOWN
JRST CCDON ;AND DONE
;UTILITY ROUTINE TO RELEASE A DISASSOCIATED NODE
RELLNK: OKINT ;DO THE OKINT TO MATCH THE NOINT IN BLKLOK
CALL FLUSH ;GET RID OF ALL MESSAGES
LLLOCK ;LOCK UP THE TREE
CALL DELNOD ;FREE LL BLOCK
LLLULK ;GIVE UP THE LOCK
RET ;DONE
;DATA MESSAGE RECEIVED
DATMSG: CAIE T4,5 ;VALID
CAIN T4,7 ; SUBTYPE?
JRST BADMSG ;NO, IGNORE IT
MOVEM T4,MSGW1 ;SAVE SUBTYPE
CALL GETLLA ;GET LINK ADDRESSES
JRST BADMSG ;BADLY FORMED
DATMS1: LLLOCK ;LOCK TREE
MOVE T1,MSGDST ;GET OUR NAME
MOVE T2,MSGSRC ;GET REMOTE'S NAME
CALL LLLKUP ;LOOK IT UP
JRST [ LLLULK ;FREE TREE
MOVEI T2,.DCX41 ;INVALID ADDRESS
JRST CIDC] ;SEND A DC
CALL BLKLOK ;LOCK UP THE BLOCK
JRST [ LLLULK ;FREE TREE
MDISMS ;WAIT FOR BLOCK
JRST DATMS1] ;AND TRY AGAIN
LLLULK ;HAVE THE BLOCK
MOVEM T1,MSGLLB ;SAVE LL BLOCK
MOVE T2,MSGBLK ;GET MESSAGE ADDRESS
CALL NSINBK ;DO BOOKKEEPING
LOAD T2,LLSTA,(T1) ;GET STATE
JRST @DATSTA-1(T2) ;GO DO IT
;IN CC SENT STATE
DATCCS: STKVAR <LLBLK> ;TEMP STORAGE FOR LL BLOCK ADDRESS
MOVEM T1,LLBLK ;SAVE IT
DATCC4: CALL TURNON ;TRY TO SEND LS MESSAGE
JRST [ PUSH P,T1 ;SAVE SCHEDULER TEST
MOVE T1,LLBLK ;RETRIEVE LL BLOCK ADDRESS
SETONE LLTRN,(T1) ;STILL NEED LS
CALL BLKULK ;UNLOCK THE LL BLOCK
POP P,T1 ;RETRIEVE SCHEDULER TEST
CALL GENWAT ;AND WAIT HERE
MDISMS ;UNTIL FREE SPACE IS AVAILABLE
DATCC6: MOVE T1,LLBLK ;GET LL BLOCK ADDRESS
CALL BLKLLK ;LOCK THE BLOCK
JRST [MDISMS ;CAN'T, WAIT
JRST DATCC6] ;AND TRY TO LOCK AGAIN
JRST DATCC4] ;TRY TO SEND MESSAGE AGAIN
SETZRO LLTRN,(T1) ;DON'T NEED LS ANYMORE
MOVEI T2,LLSRUN ;NOW IN
STOR T2,LLSTA,(T1) ; RUN STATE
MOVEI T2,1 ;SET INITIAL LS/INT
STOR T2,LLMIC,(T1) ; REQUEST COUNT
DATCC5: HRRZ T2,LLSEGQ(T1) ;GET ADDRESS OF FIRST MESSAGE ON LINK'S QUEUE
JUMPE T2,DATCC3 ;IF NONE, ALL SET
SETZ T3, ;NO PREVIOUS MESSAGE YET
DATCC1: LOAD T4,MSMFL,(T2) ;GET MESSAGE TYPE
CAIN T4,CNMRFL+CNMCF ;IS IT A CC?
JRST DATCC2 ;YES, GO REMOVE IT FROM THE QUEUE
MOVE T3,T2 ;MAKE THIS ONE PREVIOUS
OPSTR <SKIPE T2,>,MSLNK,(T2) ;GET ADDRESS OF NEXT
JRST DATCC1 ;GO TRY IT
JRST DATCC3 ;NO MORE TO TRY
DATCC2: MOVEI T4,LLSEGQ(T1) ;GET ADDRESS OF LINK'S SEGMENT QUEUE
CALL UNQSEG ;REMOVE THE CC FROM THE SENT QUEUE
MOVE T1,T2 ;GET MESSAGE ADDRESS IN NECESSARY PLACE
CALL RELRES ;GIVE UP THE SPACE
MOVE T1,LLBLK ;GET BACK LL BLOCK ADDRESS
DATCC3: MOVE T2,MSGBLK ;RETRIEVE ADDRESS OF INCOMING DATA MESSAGE
; AND PROCEED WITH LINK RUNNING
;IN RUN STATE
;**;[2931]REWRITE DATRUN DSC 22-MAR-83
DATRUN: MOVE T4,MSGW1 ;GET BACK SUBTYPE
TXNE T4,1 ;DATA MESSAGE?
JRST INTLS ;NO.
CALL SETCNT ;SET COUNTS IN MESSAGE HEADER
MOVE T2,MSGBLK ;GET MESSAGE BLOCK
CALL ONRAWQ ;PUT IT ON THE Q
DATDON: JN LLINT,(T1),INTRUN ;IF THIS IS AN INTERNAL LINK, GO ASSEMBLE DATA
CALL BLKULK ;NOT INTERNAL, FREE BLOCK
RET ;RETURN TO BACKGROUND TASK DISPATCHER
ENDSV.
; HERE FOR INTERNAL LINKS - ASSEMBLE DATA INTO DRIVER'S BUFFER
INTRUN: CALL INTSET ;GO DO INPUT FOR INTERNAL LINK
JFCL ;FAILED, IGNORE FAILURE FOR NOW
CALL BLKULK ;UNLOCK THE LOGICAL LINK BLOCK
RET ;AND RETURN TO BACKGROUND TASK'S DISPATCHER
; NOT A DATA MESSAGE - MUST BE INTERRUPT OR LINK SERVICES MESSAGE
RESCD
;**;[2933]DELETE 3 LINES AT INTLS: DSC 22-MAR-83
INTLS: CALL GETTWO ;GET ACK NUMBER
JRST LSIDON ;NO GOOD
TXZE T2,ACKIND ;AN ACK?
JRST [ MOVEI T3,MSLSI ;GET PROPER CHANNEL
CALL ACKCHN ;DO ACK
CALL GETTWO ;GET SEGNUM
JRST LSIDON ;BADLY FORMED
JRST .+1]
MOVE T3,MSGBLK ;GET BLOCK ADDRESS
STOR T2,MSSEG,(T3) ;SAVE SEG #
LOAD T3,LLIIN,(T1) ;GET EXPECTED NUMBER
AOS T3
ANDI T3,7777 ;COMPUTE IT
SUBI T3,0(T2) ;COMPUTE DIFFERENCE
ANDI T3,7777
JUMPE T3,LSINT1 ;IF EXACT ONE, MOVE ON
SKIPL T3 ;NOT THE ONE, OLD OR TOO NEW?
IFSKP. ;TOO NEW
LOAD T3,LLLKP,(T1) ;GET NODE'S VERSION
CAIE T3,.NSP31 ;NSP 3.1?
JRST LSIDON ;NO, FORGET IT
SETONE LLNLS,(T1) ;SAY NEED A NAK IN LL BLOCK
SETZRO LLALS,(T1) ;NOT AN ACK
ELSE.
SETONE LLALS,(T1) ;NEED AN ACK
ENDIF.
CALL ONSRVQ ;PUT LL ON "NEEDS SERVICE" QUEUE
JRST LSIDON ;AND DONE
;HAVE A GOOD INT OR LS MESSAGE
LSINT1: STOR T2,LLIIN,(T1) ;STORE SEG #
MOVE T4,MSGBLK ;GET BACK MESSAGE ADDRESS
LOAD T4,MSMFL,(T4) ;GET MESSAGE FLAGS
CAIE T4,DATFLI+DATINT ;INT OR LS?
JRST LSMSG ;LS
SKIPE LLMSI(T1) ;INT, ALREADY HAVE AN INTERRUPT MESSAGE?
JRST LSIDON ;YES, CAN'T HAVE THAT
CALL SETCNT ;GO SET COUNTS IN BLOCK
MOVE T2,MSGBLK ;GET BLOCK
SETZRO MSLNK,(T2) ;CLEAR LINK WORD
MOVEM T2,LLMSI(T1) ;STORE IT
CALL INTINT ;GO INTERRUPT PROCESS
SETONE LLALS,(T1) ;NEED AN ACK
SKIPN INSKED ;IN SCHEDULER?
IFSKP. ;
CALL ONSRVQ ;YES, PUT LL ON "NEEDS SERVICE" QUEUE
RET ;DONE
ENDIF.
CALLRET BLKULK ;NO, UNLOCK LL AND RETURN
;HAVE A LS MESSAGE
LSMSG: SETONE LLALS,(T1) ;NEED AN ACK
CALL ONSRVQ ;PUT LL ON "NEEDS SERVICE" QUEUE
GETBYM (MSGCNT,MSGBYP,LSIDON) ;GET LSFLAGS BYTE
TXNN T2,3 ;CHANGING BACK-PRESSURE?
JRST LSMSG1 ;NO
TRNE T2,1 ;STOPPING?
JRST [ SETONE LLBRP,(T1) ;YES. SAY SO
JRST LSMSG1] ;AND PROCEED
SETZRO LLBRP,(T1) ;NO. START IT UP
LSMSG1: MOVE T3,T2 ;SAVE FIELD
GETBYM (MSGCNT,MSGBYP,LSIDON) ;GET NEXT
TXNE T3,4 ;DATA COUNTS?
JRST [ OPSTR <ADD T2,>,LLMIC,(T1) ;NO. COMPUTE NEW VALUE
TXNE T2,200 ;WITHIN RANGE?
JRST LSIDON ;NO
STOR T2,LLMIC,(T1) ;YES. STORE IT
JRST LSIDON] ;AND DONE
LOAD T3,LLMFC,(T1) ;GET FLOW CONTROL TYPE
JUMPE T3,LSIDN1 ;IF NONE, GO ON
TRNE T2,200 ;IS THE COUNT NEGATIVE?
CAIE T3,2 ;YES. IS FLOW CONTROL MESSAGE TYPE?
SKIPA ;NO. IS GOOD THEN
JRST LSIDON ;YES. LINK ERROR
OPSTR <ADD T2,>,LLMSM,(T1) ;ADD IN THE NUMBER
STOR T2,LLMSM,(T1) ;SAVE NEW VALUE
TXNN T2,200 ;IS THE COUNT NEGATIVE?
JUMPN T2,[MOVEI T2,CHKSCT ;NO. HAVE SOME COUNT MORE
PUSH P,T1 ;SAVE LL BLOCK
LOAD T1,LLFRK,(T1) ;GET FORK NUMBER
CALL NETWKF ;WAKE UP THE PROCESS
POP P,T1 ;GET BACK LL BLOCK
JRST .+1] ;AND PROCEED
LSIDN1: CALL RESEND ;SEE IF CAN RESEND ANYTHING
LSIDON: CALL CHKLLT ;CHECK FOR TTY ON THIS LL
; JN LLINT,(T1),[
; CALL INTOUT ;IF INTERNAL LINK SEND ANY OUTPUT STILL LEFT
; JFCL ;IGNORE FAILURE HERE
; JRST .+1] ;CONTINUE
SKIPN INSKED ;IN SCHEDULER?
IFSKP. ;YES
MOVE T2,MSGBLK ;GET MESSAGE ADDRESS
SETONE MSSKD,(T2) ;SET THE RELEASE INDICATOR
RET ;DONE
ENDIF.
CALL BLKULK ;NO, FREE THE LL LOCK
JRST TOSMSG ;AND DONE
;INTSET - ROUTINE TO DO INPUT ON INTERNAL LINKS
;
;ACCEPTS IN T1/ ADDRESS OF LOGICAL LINK BLOCK
; CALL INTSET
;RETURNS: +1 FAILED
; +2 SUCCESS
SWAPCD
INTSET::SAVET
STKVAR <INSLLB,INSCNT,INSFLG>
MOVEM T1,INSLLB ;SAVE LOGICAL LINK BLOCK ADDRESS
SETZM INSFLG ;INITIALIZE "ALL DATA FIT IN BUFFER" FLAG
; SET UP INPUT BUFFER IF NOT ALREADY SET UP, AND PUT SEGMENTS ON ORDERED QUEUE
INS010: MOVE T1,INSLLB ;GET LOGICAL LINK BLOCK ADDRESS
SETZRO LLFIM,(T1) ;START BY ASSUMING NOT END OF MESSAGE
; CALL MOVSEG ;PLACE SEGMENTS ON ORDERED MESSAGE QUEUE
; RET ;FAILED, RETURN ERROR
MOVE T1,INSLLB ;RESTORE LOGICAL LINK BLOCK
SKIPN LLOMSG(T1) ;ANY MESSAGES TO PROCESS ?
RETSKP ;NO, DONE.
MOVE T1,INSLLB ;GET LOGICAL LINK BLOCK ADDRESS
CALL SETIBF ;SET UP BUFFER IF REQUIRED
RETSKP ;FAILED, WAIT FOR BUFFER FROM DRIVER
; IF TRUNCATING CURRENT NSP MESSAGE, DISCARD THIS SEGMENT
MOVE T1,INSLLB ;GET ADDRESS OF LOGICAL LINK BLOCK
JN LLTRM,(T1),[
CALL TRNMSG ;GO DISCARD THIS SEGMENT
RET ;FAILED
JRST INS030] ;GO SEND ANY ACK'S OR LS MESSAGES NEEDED
; COPY DATA IN RECEIVED SEGMENTS INTO DRIVER'S BUFFER
MOVE T1,INSLLB ;GET LOGICAL LINK BLOCK ADDRESS
LOAD T2,LLBPI,(T1) ;GET CURRENT BUFFER POINTER
LOAD T3,LLICT,(T1) ;GET MAX NUMBER OF CHARACTERS IN INPUT BUFFER
CALL MOVMSG ;GO COPY DATA INTO DRIVER'S BUFFER
RET ;FAILED, RETURN ERROR
MOVE T4,INSLLB ;RESTORE LOGICAL LINK BLOCK ADDRESS
MOVEM T2,INSCNT ;SAVE NUMBER OF BYTES THAT WERE INPUT
MOVEM T3,INSFLG ;SAVE FLAG NOTING WHETHER ALL DATA FIT IN BUFFER
STOR T1,LLBPI,(T4) ;STORE NEW BUFFER POINTER
SKIPG INSCNT ;ANY BYTES INPUT ?
JRST INS020 ;NO, DO NOT UPDATE COUNT
LOAD T3,LLICT,(T4) ;GET PREVIOUS COUNT
SUB T3,T2 ;COMPUTE NUMBER OF BYTES LEFT IN BUFFER
STOR T3,LLICT,(T4) ;UPDATE NUMBER OF BYTES REMAINING
; ..
; ..
; IF SEGMENT DID NOT FIT IN BUFFER, SEE IF DRIVER WANTED TO TRUNCATE
INS020: MOVE T2,INSFLG ;GET FLAG INDICATING IF ALL DATA FIT IN BUFFER
CAMN T2,[-1] ;DID LAST SEGMENT FIT IN THE BUFFER ?
JRST [ JE LLTRC,(T4),.+1 ;NO. JUST CONTINUE IF NOT TRUNCATING MESSAGES
SETONE LLTRM,(T4) ;REMAINDER OF THIS MESSAGE NOT NEEDED
JRST .+1] ;AND CONTINUE
; CALL DRIVER IF EITHER BUFFER WAS FILLED OR A COMPLETE MESSAGE WAS RECEIVED
MOVE T1,INSLLB ;GET ADDRESS OF LOGICAL LINK BLOCK
MOVE T2,INSCNT ;GET NUMBER OF BYTES INPUT
MOVE T3,INSFLG ;GET FLAG NOTING IF ALL DATA FIT IN BUFFER
CALL TELDAT ;NOTIFY DRIVER THAT DATA HAS ARRIVED
; IF NO BYTES WERE INPUT, ALL DONE. RETURN TO DISPATCHER
SKIPN INSCNT ;WERE ANY BYTES INPUT ?
RETSKP ;NO, ALL DONE THEN
; SEND ANY ACK MESSAGES OR LINK SERVICES MESSAGES NEEDED
INS030: MOVE T1,INSLLB ;GET ADDRESS OF LOGICAL LINK BLOCK
CALL SQIACK ;SEND ANY ACK'S NEEDED
RET ;FAILED, RETURN ERROR
MOVE T1,INSLLB ;GET ADDRESS OF LOGICAL LINK BLOCK AGAIN
CALL SQILS ;SEND ANY LINK SERVICES MESSAGES NEEDED
JFCL ;IGNORE FAILURE, ACK'S WILL CAUSE RETRY
JRST INS010 ;GO SEE IF THERE ARE MORE MESSAGES TO PROCESS
;TELDAT - ROUTINE TO ADVISE THE DRIVER IF A COMPLETE MESSAGE HAS ARRIVED
;
;ACCEPTS IN T1/ ADDRESS OF LOGICAL LINK BLOCK
; T2/ NUMBER OF BYTES INPUT, -1 IF NOT ENOUGH ROOM IN BUFFER
; CALL TELDAT
;RETURNS: +1 ALWAYS, WITH DRIVER NOTIFIED IF NEEDED
TELDAT: STKVAR <TLDLLB,TLDCNT,TLDFLG>
MOVEM T1,TLDLLB ;SAVE LOGICAL LINK BLOCK ADDRESS
MOVEM T2,TLDCNT ;SAVE COUNT OF BYTES INPUT
MOVEM T3,TLDFLG ;SAVE FLAG NOTING IF ALL DATA FIT IN BUFFER
; DETERMINE IF DRIVER MUST BE NOTIFIED
MOVE T4,TLDLLB ;GET LOGICAL LINK BLOCK ADDRESS
LOAD T3,LLICT,(T4) ;GET # OF BYTES LEFT IN BUFFER
JUMPE T3,TLDT10 ;IF NONE, BETTER TELL DRIVER !
MOVE T2,TLDFLG ;GET FLAG
CAME T2,[-1] ;INSUFFICIENT ROOM IN BUFFER FOR THIS MSG ?
JRST [ JE LLFIM,(T1),R ;NO, RETURN UNLESS A COMPLETE MESSAGE RECEIVED
JRST TLDT10 ] ;...
; COMPUTE NUMBER OF BYTES IN BUFFER AND NOTIFY DRIVER OF DATA ARRIVAL
TLDT10: LOAD T4,LLVEC,(T1) ;GET ADDRESS OF DRIVER FUNCTION VECTOR
LOAD T3,LLIIC,(T1) ;YES, GET INITIAL COUNT OF BYTES IN BUFFER
LOAD T2,LLICT,(T1) ;GET CURRENT COUNT OF BYTES LEFT FOR INPUT
SUB T3,T2 ;COMPUTE NUMBER OF BYTES ALREADY INPUT
JN LLFIM,(T1),[TXO T3,NS%MSG ;BUFFER BEING RETURNED BECAUSE EOM SEEN
JRST .+1] ;...
LOAD T2,LLBFI,(T1) ;GET ADDRESS OF DRIVER'S BUFFER
LOAD T1,LLDRV,(T1) ;GET DRIVER CORRELATION CODE
CALL @.NSDAT(T4) ;ADVISE DRIVER THAT INPUT HAS ARRIVED
MOVE T4,TLDLLB ;RESTORE LOGICAL LINK BLOCK ADDRESS
JUMPN T1,[JN LLFIM,(T4),.+1 ;ONLY SET TRUNCATE IF NOT FULL MSG
SETONE LLTRM,(T4) ;NOTE TRUNCATION IF DRIVER REQUESTED IT
JRST .+1] ;...
; UPDATE APPROPRIATE COUNTS AND RETURN
MOVE T1,TLDLLB ;RESTORE LOGICAL LINK BLOCK ADDRESS
SETZRO <LLICT,LLIIC>,(T1) ;CLEAR BYTE COUNTS
SETZRO LLBFI,(T1) ;NOTE WE NO LONGER HAVE AN INPUT BUFFER
RET ;DONE, RETURN
;TRNMSG - ROUTINE TO DISCARD A SEGMENT BECAUSE MESSAGE IS BEING TRUNCATED
;
;ACCEPTS IN T1/ ADDRESS OF LOGICAL LINK BLOCK
; CALL TRNMSG
;RETURNS: +1 FAILED
; +2 SUCCESS, SEGMENT THROWN AWAY
TRNMSG: STKVAR <TMSLLB>
MOVEM T1,TMSLLB ;SAVE LOGICAL LINK BLOCK ADDRESS
TRNM10: MOVE T1,TMSLLB ;GET LOGICAL LINK BLOCK ADDRESS
MOVE T2,[POINT 0,0,2] ;GET NUL POINTER (THROW BYTES AWAY)
MOVX T3,.INFIN ;NO LIMIT ON NUMBER TO DISCARD
CALL MOVMSG ;DISCARD THE DATA
RET ;FAILED
MOVE T1,TMSLLB ;RESTORE LOGICAL LINK BLOCK ADDRESS
JE LLFIM,(T1),RSKP ;IF STILL DON'T HAVE ENTIRE MESSAGE THEN DONE
SETZRO LLTRM,(T1) ;MESSAGE ENTIRELY DISCARDED, STOP TRUNCATING
RETSKP ;DONE, RETURN SUCCESS
;SETIBF - ROUTINE TO SET UP AN INPUT BUFFER FOR AN INTERNAL LINK
;
;ACCEPTS IN T1/ LOGICAL LINK BLOCK ADDRESS (LINK ASSUMED LOCKED)
; CALL SETIBF
;RETURNS: +1 FAILED, COULD NOT SET UP BUFFER NOW
; +2 SUCCESS, WITH BUFFER INFO STORED IN LINK BLOCK
SETIBF: JN LLBFI,(T1),RSKP ;IF ALREADY HAVE A BUFFER THEN DONE
JN LLDRB,(T1),R ;FAIL IFDRIVER ALREADY REFUSED TO PROVIDE BFR
ASUBR <SBFLLB>
LOAD T4,LLVEC,(T1) ;GET DRIVER FUNCTION VECTOR ADDRESS
LOAD T1,LLDRV,(T1) ;GET DRIVER CORRELATION CODE FOR THIS LINK
CALL @.NSBFR(T4) ;REQUEST DRIVER TO SUPPLY A BUFFER
JRST [ MOVE T1,SBFLLB ;RESTORE LOGICAL LINK BLOCK ADDRESS
SETONE LLDRB,(T1) ;NOTE THAT DRIVER REFUSED TO PROVIDE BUFFER
RET ] ;AND DONE
MOVE T4,SBFLLB ;RESTORE LOGICAL LINK BLOCK ADDRESS
STOR T1,LLBFI,(T4) ;STORE BUFFER ADDRESS
STOR T2,LLICT,(T4) ;STORE COUNT OF BYTES CURRENTLY LEFT IN BUFFER
STOR T2,LLIIC,(T4) ;ALSO STORE AS INITIAL COUNT OF BYTES IN BUFFER
HRLI T1,(POINT 8,) ;FORM POINTER TO FIRST BYTE IN THIS BUFFER
STOR T1,LLBPI,(T4) ;SAVE AS POINTER TO NEXT BYTE TO BE INPUT
TXNE T2,NS%TRN ;DRIVER WANT MESSAGES TRUNCATED IF TOO LONG ?
JRST [ SETONE LLTRC,(T4) ;YES, NOTE TRUNCATION DESIRED
JRST .+1 ] ;AND CONTINUE
RETSKP ;DONE, RETURN WITH BUFFER INFO IN LINK BLOCK
;ROUTINES USED BY DATMSG.....
;KILL OFF LINK AFTER PROTOCOL ERROR.
ABTMSG: MOVEI T2,.DCX40 ;DATA LOSS
MOVEM T2,MSGW1 ;SAVE CODE
CALL SHTLK1 ;SHUT IT OFF
MOVEM T1,MSGLLB ;SAVE LL BLOCK
MOVEI T4,CNMRFL+CNMDI ;SEND A DI
SETZM T3 ;NO OPTDATA
CALL SNDDI ;GO DO IT
JRST [ TQO <BLKF> ;NOTE BLOCK NEEDED
MOVE T1,MSGLLB ;RESTORE BLOCK ADDRESS
MOVEI T2,LLSDIQ ;NEW STATE
STOR T2,LLSTA,(T1)
JRST LSIDON] ;AND DONE
CALL SNDCTL ;SEND THE MESSAGE
JRST LSIDON ;DONE
;ROUTINE TO FILL IN MESSAGE COUNTS IN MESSAGE BLOCK
SETCNT: MOVE T3,MSGBLK ;GET BLOCK ADDRESS
MOVE T4,MSGBYP ;GET CURRENT BYTE POINTER
MOVEM T4,MSBPTR(T3) ;SAVE IT
MOVE T4,MSGCNT ;GET CURRENT COUNT
STOR T4,MSDTC,(T3) ;SAVE IT
RET ;AND DONE
;ROUTINE TO SEND INTIAL LS MESSAGE TO OTHER END OF THE LINK.
;ACCEPTS: T1/ LL BLOCK ADDRESS
;RETURNS: +1 FAILED. MESSAGES NOT SENT
; T1/ SCHEDULER TEST WORD
; +2 SUCCESS. MESSAGES SENT
; T1/ LL BLOCK ADDRESS (UNCHANGED)
TURNON:
;**;[3059] Remove 1 Line at TURNON: +0L CRJ 19-Dec-83
; JE LLOPI,(T1),RSKP ;IF NOT OPEN FOR READ, DON'T SEND LS
MOVEI T3,MSDAT ;ON THE DATA SUBCHANNEL
LOAD T2,LLMQI,(T1) ;GET MAX QUEUE VALUE
;**;[3059] Add 4 Lines at TURNON: +3L CRJ 19-Dec-83
JE LLOPI,(T1),[ ;Write-only?
JN LLFOB,(T1),RSKP ;Yes, if also SRV: then forget it
CLEAR T2, ;Otherwise, WO DCN: send an LS so other side
CALLRET SNDLS ] ; will give one back, set flow to 0 and send it
TMNE LLIMS,(T1) ;MESSAGE?
MOVEI T2,1 ;YES. ONE MESSAGE THEN
CALLRET SNDLS ;SEND IT OFF
;COLLECTION OF ROUTINES TO GET FIELDS FROM A MESSAGE
;MOST ARE RESIDENT BECAUSE THEY ARE USED BY THE CHANNEL 7 CODE
RESCD ;CALLED FROM SCHEDULER
;GET TWO BYTE FIELD
;CLOBBERS T3, PRESERVES T4
GETTWO: GETBYM (MSGCNT,MSGBYP,R) ;GET A BYTE, RETURN IF NONE
LSHC T2,-10 ;SAVE LOW ORDER BYTE
GETBYM (MSGCNT,MSGBYP,R) ;GET NEXT ONE
LSHC T2,10 ;COMBINE BYTES
RETSKP ;AND DONE
;COPY ASCII STRING
; T3/ POINTER TO COPY TO
; T4/ MAX COUNT OF STRING
;RETURNS:
; +1 FAILURE. BAD MESSAGE
; +2 SUCCESS. T2/ COUNT OF BYTES COPIED
GTBNRY: SKIPA T2,[POINT 8,0(T3)] ;ENTRY FOR OCTET COPY
GTASCI: MOVE T2,[POINT 7,0(T3)] ;ENTRY FOR ASCII COPY
GTASC0: ACVAR <W1,W2> ;ENTRY FOR SKPFLD
MOVE W1,T2 ;SAVE POINTER
GETBYM (MSGCNT,MSGBYP,[SETZM T2 ;GET COUNT FIELD
RET]) ;DONE
CAMLE T2,T4 ;WITHIN RANGE?
RET ;NO.
MOVE W2,T2 ;SAVE COUNT
SKIPN T4,T2 ;SAVE COUNT
JRST GTASCD ;NO COUNT
GTASC1: GETBYM (MSGCNT,MSGBYP,R)
IDPB T2,W1 ;SAVE IT
SOJG T4,GTASC1 ;DO ALLOF THEM
GTASCD: SETZ T2, ;GET A NULL
IDPB T2,W1 ;TIE OFF STRING
MOVE T2,W2 ;RETURN COUNT
RETSKP ;AND DONE
ENDAV. ;END ACVAR
;MORE BYTE MANIPULATION ROUTINES
;SKIP AN IMAGE FIELD
SKPFLD: GETBYM (MSGCNT,MSGBYP,R) ;GET IMAGE COUNT
JUMPE T2,RSKP ;IF NO BYTES, DONE
MOVN T4,T2 ;GET NEG OF COUNT
ADDB T4,MSGCNT ;COMPUTE RESIDUE
JUMPL T4,R ;IF MESSAGE TOO SMALL, ERROR
ADJBP T2,MSGBYP ;MODIFY BYTE POINTER
MOVEM T2,MSGBYP ;AND UPDATE IT
RETSKP ;DONE
;GET AN EXTENSIBLE FIELD
GETEXT: SETZB T3,T4 ;INIT ACCUMULATOR AND COUNTER
GETEX1: GETBYM (MSGCNT,MSGBYP,R) ;GET NEXT BYTE
AOS T4 ;GOT ANOTHER ONE
LSHC T2,-7 ;PUT DATA PART IN ACCUMULATOR
TXZE T2,1 ;WAS IT EXTENDED?
JRST GETEX1 ;YES. GET NEXT THEN
IMULI T4,7 ;COMPUTE GOOD BITS IN ACCUMULATOR
LSHC T2,0(T4) ;PUT FIELD IN T2
RETSKP ;AND DONE
;MAKE AN EXTENSIBLE FIELD
;ACCEPTS: T1/ LL BLOCK ADDRESS
; T3/ THE VALUE
;RETURNS: +1
;PRESERVES T1
MAKEXT: MOVEI T2,177 ;GET EXTENSIBLE FIELD MASK
AND T2,T3 ;GET A BYTE'S WORTH
LSH T3,-7 ;ADJUST THE REMAINING QUANTITY
SKIPE T3 ;MORE BYTES TO COME?
TXO T2,NSPEXT ;YES, PUT IN EXTENSIBLE FLAG BIT
CALL ONEBYT ;PUT BYTE IN MESSAGE
JUMPN T3,MAKEXT ;IF MORE, GO DO IT
RET ;DONE
;ROUTINE USED BY CI AND CC TO PROCESS COMMON FIELDS
SWAPCD ;SWAPPABLE
CIPSRV: GETBYM (MSGCNT,MSGBYP,R) ;GET SERVICES
TXC T2,1
TRNE T2,363 ;MUST BE NORMAL LINK AND NO MSG ACK
RET ;NO. CAN'T HAVE IT
LSH T2,-2 ;GET FCOPT FIELD
CAIN T2,3 ;A VALID FLOW CONTROL?
RET ;NO.
MOVEM T2,MSGW1 ;YES. SAVE IT
GETBYM (MSGCNT,MSGBYP,R) ;GET LINK PRI
MOVEM T2,MSGLKP ;SAVE IT
CALL GETTWO ;GET SEGSIZE
RET ;BAD
MOVEM T2,MSGW2 ;SAVE IT
RETSKP ;ALL GOOD
;REQUEST QUEUER ROUTINES
;SEND CONTROL MESSAGE
;ACCEPTS: T1/ LL BLOCK ADDRESS
; T2/ MESSAGE BLOCK
;RETURNS: +1 ALWAYS
RESCD
SNDCTL: SAVET ;SAVE ALL REGISTERS
ASUBR <SAVLL,SAVMSG> ;SAVE ARGS
MOVE T3,LLBPCT(T1) ;GET MESSAGE COUNT
STOR T3,MSCNT,(T2) ;STORE IN THE BLOCK
TMNE LLLOC,(T1) ;LOCAL?
JRST CTLLCL ;YES. GO HANDLE IT
SNDSG0: CALL NSOUBK ;DO NSP OUTPUT BOOKKEEPING
LOAD T4,MSMFL,(T2) ;GET MESSAGE TYPE
TRNN T4,ACKFLM ;IS IT AN ACK?
IFSKP.
MOVEI T4,ACKPST ;YES, GET POSTING ROUTINE
CALL SNDRDY ;GET READY FOR DRVIER
JRST SNDMSG ;GO
ENDIF.
CAIE T4,CNMRFL+CNMDI ;IS IT A DI?
IFSKP.
CALL ONSEGQ ;YES, PUT IT ON RESEND QUEUE
MOVEI T4,SEGPST ;GET POSTING ROUTINE
CALL SNDRDY ;GET READY FOR DRIVER
JRST SNDMSG ;GO
ENDIF.
CAIE T4,CNMRFL+CNMCF ;IS IT A CC?
IFSKP.
LOAD T4,LLLKP,(T1) ;YES, GET NSP VERSION
CAIN T4,.NSP31 ;NSP 3.1?
IFSKP.
CALL ONSEGQ ;NO, PUT IT ON RESEND QUEUE
MOVEI T4,SEGPST ;GET POSTING ROUTINE
CALL SNDRDY ;GET READY FOR DRIVER
JRST SNDMSG ;GO
ENDIF.
MOVEI T4,RELRES ;YES, PHASE II - GET POSTING ROUTINE
CALL SNDRDY ;GET READY FOR DRVIER
JRST SNDMSG ;GO
ENDIF.
LOAD T3,MSCNT,(T2) ;GET BYTE COUNT
LOAD T1,LLPRT,(T1) ;GET PORT NUMBER
; HRLI T1,MSGPST ;POSTING ADDRESS
SNDSG1: HRLI T1,RELRES ;MAKE DRIVER RELEASE THE BLOCK
SNDMSG: STKVAR <SAVPST,SAVFF>
MOVEM F,SAVFF ;SAVE F
MOVE F,T2 ;UNIQUE CODE FOR POST
TMNE MSMS1,(T2) ;SENT THIS MESSAGE ONCE YET?
TXO T3,1B0 ;YES. TELL DRIVER OF THIS THEN
SETONE MSMS1,(T2) ;SAY SENT IT ONCE
MOVEI T2,MSHDR(T2) ;GET DATA PORTION OF MESSAGE
HRLI T2,(<POINT 8,>) ;MAKE A BYTE POINTER
HLRZM T1,SAVPST ;SAVE POSTING ADDRESS
CALL DCNMSO ;SEND THE MESSAGE
JRST [ MOVE T1,F ;FAILED. PORT MUST BE TURNED OFF.
;SET UP FOR POST IF ANY
SKIPE T2,SAVPST ;WANT A POST ON DONE?
CALL 0(T2) ;YES. DO IT THEN
JRST .+1] ;AND GO FINISH UP
MOVE F,SAVFF ;RESTORE F
RET ;AND DONE
ENDSV.
;CONNECTION IS TO A TASK ON THIS NODE
CTLLCL: SETONE MSLCL,(T2) ;REMEMBER IS LOCAL
SKIPGE T4,NSPLPB ;IS THERE A RUNNING LOOPBACK LINE?
JRST [STOR T4,LLPRT,(T1);YES, SAY WHICH PORT
JRST SNDSG0] ;GIVE "LOCAL MESSAGE" TO DRIVER FOR LOOPBACK
CALL NSOUBK ;DO NSP BOOKKEEPING
CALLRET ONMSQ ;AND GO DO IT
;GET ACS READY FOR CALL TO DRVIER
;ACCEPTS: T1/ LL BLOCK ADDRESS
; T2/ MESSAGE ADDRESS
; T4/ POSTING ROUTINE ADDRESS
;RETURNS +1 T1/ POSTING ROUTINE ADDRESS ,, PORT NUMBER
; T2/ MESSAGE ADDRESS
; T3/ BYTE COUNT
SNDRDY: LOAD T3,MSCNT,(T2) ;GET BYTE COUNT OF MESSAGE
LOAD T1,LLPRT,(T1) ;GET PORT NUMBER
HRLI T1,(T4) ;INSERT POSTING ROUTINE
RET
;VARIOUS QUEUENING ROUTINES USED BY INT, SCHED, AND PROCESS LEVELS
;ROUTINE TO PUT A MESSGE ON NSPTSK'S QUEUE
ONMSGQ: MOVEI T3,MSGQ ;GET QUEUE HEAD
CALLRET PUTONQ ;PUT DATA ON
;ROUTINE TO QUEUE UP EXPENDED MESSAGE BLOCKS FROM DTESRV
REPEAT 0,< ;NOT USED PRESETNLY
MSGPST: MOVE T2,RMSGQ ;GET OLD HEAD
MOVEM T1,RMSGQ ;MAKE NEW HEAD
STOR T2,MSLNK,(T1) ;LINK IN
RET ;AND DONE
> ;END OF REPEAT 0
;ROUTINE CALLED FROM INTERRUPT LEVEL TO PUT A MESSAGE ON THE SCHEDULER'S
;QUEUE
; T2/ DATA ADDRESS
NSPQ:: MOVEI T2,-MSHDR(T2) ;GET POINTER TO HEADER
MOVE T4,TODCLK ;GET TOD
MOVEM T4,MSTIM(T2) ;PUT IT IN MESSAGE HEADER
SKIPE T4,SMSGQ ;QUEUE NOW EMPTY?
IFSKP. ;
HRRM T2,SMSGQ ;YES, MAKE US FIRST
HRLM T2,SMSGQ ;AND LAST
RET
ENDIF.
HLRZS T4 ;GET LAST MSG ON QUEUE
MOVEM T2,MSNXT(T4) ;MAKE LAST MSG POINT AHEAD TO US
MOVEM T4,MSPRV(T2) ;MAKE US POINT BACK TO IT
HRLM T2,SMSGQ ;MAKE QUEUE HEAD POINT TO US
RET
;ROUTINE TO LINK A MESSAGE INTO NSSNTQ (THE TIMER) QUEUE
;
;CALL: T2/ ADDRESS OF MESSAGE
ONTIMQ: SAVET
SKIPE INSKED ;IN SCHEDULER?
JRST ONTMQ3 ;YES
SKIPN INNSPT ;IN RETRANSMISSION TIMER
SKIPE INNSPI ; OR INACTIVITY TIMER?
SKIPA ;YES, THEN ALREADY HAVE THE TREE LOCK
LLLOCK ;NO, THEN USE TREE LOCK TO PREVENT RACES
ONTMQ3: SKIPE T4,NSSNTQ ;TIMER QUEUE EMPTY?
IFSKP. ;YES
MOVEM T2,NSSNTQ ;MAKE THIS MSG FIRST ON Q
;**;[3179] Change 1 line CEG 5-Nov-84
JRST UNQTM1 ;[3179] DONE
ENDIF.
SETZM T3 ;NO, SAY NO PREVIOUS MSG YET
ONTMQ1: MOVE T1,MSTIM(T4) ;GET TIME STAMP OF NEXT MSG
CAMG T1,MSTIM(T2) ;OLDER THAN US?
JRST ONTMQ2 ;YES
SKIPE T3 ;NO, ARE WE AT BEGINNING OF QUEUE?
IFSKP. ;YES
MOVEM T2,NSSNTQ ;PUT US AT HEAD OF THE QUEUE
ELSE. ;NO
MOVEM T2,MSNXT(T3) ;LINK US TO
MOVEM T3,MSPRV(T2) ; PREVIOUS ENTRY
ENDIF.
MOVEM T4,MSNXT(T2) ;LINK US TO
MOVEM T2,MSPRV(T4) ; NEXT ENTRY
;**;[3179] Change 1 line CEG 5-Nov-84
JRST UNQTM1 ;[3179] DONE
ONTMQ2: SKIPN T1,MSNXT(T4) ;ARE WE AT END OF QUEUE?
IFSKP. ;NO
MOVE T3,T4 ;MAKE NEXT PREVIOUS
MOVE T4,MSNXT(T4) ;AND GET THE NEXT
JRST ONTMQ1 ;TRY AGAIN
ENDIF.
MOVEM T2,MSNXT(T4) ;YES, PUT US ON
MOVEM T4,MSPRV(T2) ; END OF QUEUE
JRST UNQTM1 ;FINISH
;**;[3179] Remove 7 lines CEG 5-Nov-84
;ROUTINE TO REMOVE A MESSAGE FROM NSSNTQ (THE "SENT" QUEUE)
;ACCEPTS: T1/ ADDRESS OF MESSAGE
;RETURNS: +1
UNQTIM: SAVET
;**;[3179] Remove 1 line CEG 5-Nov-84
SKIPE INSKED ;IN SHCEDULER?
JRST UNQTM2 ;YES
SKIPN INNSPT ;IN RETRANSMISSION TIMER
SKIPE INNSPI ; OR INACTIVITY TIMER?
SKIPA ;YES, THEN ALREADY HAVE THE TREE LOCK
LLLOCK ;NO, THEN USE TREE LOCK TO PREVENT RACES
;**;[3179] Remove 1 line CEG 5-Nov-84
UNQTM2: SKIPE T2,MSPRV(T1) ;ARE WE FIRST ON THE QUEUE?
IFSKP. ;YES
SKIPE T3,MSNXT(T1) ;ARE WE ALSO LAST ON THE QUEUE?
IFSKP. ;YES
SETZM NSSNTQ ;RESET THE QUEUE HEADER
ELSE.
SETZM MSPRV(T3) ;NO, MAKE NEXT THE HEAD
SETZM MSNXT(T1) ;NO NEXT (IN CASE MESSAGE IN REQUEUED)
MOVEM T3,NSSNTQ ;MAKE QUEUE HEAD POINT TO US
ENDIF.
JRST UNQTM1 ;DONE
ENDIF.
SKIPE T3,MSNXT(T1) ;NO, ARE WE LAST ON THE QUEUE?
IFSKP. ;YES
SETZM MSNXT(T2) ;THEN PREVIOUS NO LONGER HAS NEXT
;**;[3179] Remove 1 line CEG 5-Nov-84
ELSE.
MOVEM T3,MSNXT(T2) ;NO, MAKE PREVIOUS POINT TO NEXT
MOVEM T2,MSPRV(T3) ;AND NEXT POINT TO PREVIOUS
;**;[3179] Remove 1 line CEG 5-Nov-84
SETZM MSNXT(T1) ;WE HAVE NO MORE NEXT (IN CASE OF REQUEUE)
ENDIF.
;**;[3179] Add 1 line CEG 5-Nov-84
SETZM MSPRV(T1) ;[3179] WE HAVE NO MORE PREVIOUS (IN CASE OF REQUEUE)
UNQTM1: SKIPE INSKED ;IN SCHEDULER?
RET ;RET
SKIPN INNSPT ;IN RETRANSMISSION TIMER OR
SKIPE INNSPI ; OR INACTIVITY TIMER?
SKIPA ;YES, DON'T GIVE UP LOCK HERE
LLLULK ;NO, GIVE UP TREE LOCK
RET ;DONE
;ROUTINE TO SEND A DATA,LS, OR INT MESSAGE
;ACCEPTS: T1/ LL BLOCK
; T2/ MESSAGE BLOCK
SNDSEG::ASUBR <SNLBLK,SNMSG>
MOVE T3,LLBPCT(T1) ;GET BYTE COUNT
STOR T3,MSCNT,(T2) ;TO THE MESSAGE
LOAD T3,LLLNK,(T1) ;GET LINK I.D.
STOR T3,MSLLA,(T2) ;TO THE MESSAGE
TMNE LLLOC,(T1) ;LOCAL?
JRST SNDLCL ;YES.
LPBSEG: CALL ONSEGQ ;PUT IT ON THE SEG QUEUE
SNDSE2: CALL NSOUBK ;DO NSP BOOKKEEPING
LOAD T3,MSCNT,(T2) ;GET COUNT
LOAD T1,LLPRT,(T1) ;PORT I.D.
HRLI T1,SEGPST ;POSTING ADDRESS
SETONE MSPST,(T2) ;SAY WAITING FOR POST
CALL SNDMSG ;SEND IT
SNDSE1: MOVE T1,SNLBLK ;GET BLOCK ADDRESS
RET ;AND DONE
ENDAS.
;ROUTINE TO PUT A DATA,LS, OR INT SEGEMENT ON THE SEND Q
;ACCEPTS: T1/ LL BLOCK ADDRESS
; T2/ MESSAGE BLOCK
;RETURNS: +1
ONSEGQ: INCR LLQOU,(T1) ;ONE MORE ON Q
MOVE T3,TODCLK ;GET THE TIME
MOVEM T3,MSTIM(T2) ;PUT TIME STAMP IN MESSAGE HEADER
MOVEI T3,LLSEGQ(T1) ;GET HEADER
LOAD T4,LLLKP,(T1) ;GET NODE'S VERSION
CAIN T4,.NSP31 ;NSP 3.1?
JRST ONSEG0 ;YES
SKIPN (T3) ;NO, QUEUE CURRENTLY EMPTY?
CALL ONTIMQ ;YES, TIE IN TO TIMER QUEUE
ONSEG0: CALLRET PUTONQ ;PUT SEG ON THE Q
;LOCAL ROUTINE TO PUT MESSAGE ON INPUT QUEUE
ONMSQ: NOSKD1 ;NO SCHEDULING
CALL ONMSGQ ;PUT MESSAGE ON THE QUEUE
OKSKD1 ;AND SCHEDULING
RET ;AND DONE
;ENTRY USED TO RESEND A NACKED OR TIMED OUT MESSAGE
SNDSE0: ASUBR <SNLBLK,SNMSG>
CALLRET LPBSEG ;SEND IT
;SNDSEG CONTINUED...
;ROUTINE TO SEND SEGMENT TO A LOCAL CONNECTION
SNDLCL: STKVAR <SRCLLB,DESLLB>
MOVEM T1,SRCLLB ;SAVE THE SOURCE LL BLOCK ADDRESS
SETONE MSLCL,(T2) ;SAY IS LOCAL
SKIPGE T4,NSPLPB ;IS THERE A RUNNING LOOPBACK LINE?
JRST [STOR T4,LLPRT,(T1);YES, SAY WHICH PORT
JRST LPBSEG] ;GIVE "LOCAL MESSAGE" TO DRIVER FOR LOOPING
LOAD T3,MSMFL,(T2) ;GET FLAGS
TXNE T3,DATFLI ;IS THIS AN INTERRUPT MESSAGE?
JRST SNDBAD ;YES. GO HANDLE VIA NSPTSK
LOAD T2,LLLNK,(T1) ;GET OUR I.D.
LOAD T1,LLHLK,(T1) ;GET I.D. OF OTHER PROCESS
LLLOCK ;LOCK UP THE TREE
CALL LLLKUP ;GO FIND ENTRY
JRST [ LLLULK ;RELEASE THE TREE
JRST SNDBAD ] ;NOT THERE
LLLULK ;RELEASE THE TREE
MOVEM T1,DESLLB ;SAVE DESTINATION LL BLOCK ADDRESS
MOVE T2,SNMSG ;GET MESSAGE BLOCK
NOSKD1 ;PROTECT LINK STATE
JN LLINT,(T1),SNDBA1 ;IF INTERNAL LINK, PUT ON BACKGOUND TASK'S QUEUE
LOAD T3,LLSTA,(T1) ;GET STATE OF THE LINK
CAIE T3,LLSRUN ;RUNNING?
JRST SNDBA1 ;NO.
MOVE T1,SRCLLB ;RETRIEVE SOURCE LL BLOCK ADDRESS
CALL NSOUBK ;DO NSP OUTPUT BOOKKEEPING
MOVE T1,DESLLB ;RETRIEVE DESTINATION LL BLOCK ADDRESS
CALL NSINBK ;DO NSP INPUT BOOKKEEPING
CALL ONRAWQ ;GO PUT ON THE QUEUE
OKSKD1 ;ALL DONE
JRST SNDSE1 ;GO Q IT UP ON SEG Q
;ERROR ROUTINES
SNDBA1: OKSKD1
SNDBAD: MOVE T2,SNMSG ;GET MESSAGE ADDRESS
CALL ONMSQ ;PUT DATA MESSAGE ON NSPTSK'S Q
JRST SNDSE1 ;AND DONE FOR NOW
;ROUTINE TO HANDLE ACK OR NACK FOR A SUBCHANNEL.
;ACCEPTS: T1/ LL BLOCK ADDRESS
; T2/ ACK OR NACK #
; T3/ SUBCHANNEL OF THE ACK/NACK
;RETURNS: +1 ALWAYS. ALL REGS PRESERVED
ACKCHN: TMNE LLLOC,(T1) ;LOCAL?
JRST [SKIPL NSPLPB ;YES, IS THERE A RUNNING LOOPBACK LINE?
JRST ACKDON ;NO
JRST .+1] ;YES, MESSAGE MUST BE QUEUED AS REMOTE
SAVET ;SAVE ALL REGS
ACVAR <W1,W2,W3> ;GET WORK REGS
STKVAR <LLBLK,ACKNO,ACKCHL,LNKADR>
MOVEM T1,LLBLK ;SAVE LL BLOCK
MOVEM T3,ACKCHL ;SAVE CHANNEL
MOVEM T2,ACKNO
TRZN T2,ACKBIT ;IS IT A NACK?
IFSKP. ;YES
CALL ACKCHN ;DO THE ACK PROCESSING
LOAD T3,LLLKP,(T1) ;GET NODE'S VERSION
CAIE T3,.NSP31 ;NSP 3.1?
RET ;NO
JRST DONACK ;YES, PHASE II LINK, SEE IF RESENDS ARE NEEDED
ENDIF.
ANDI T2,7777 ;GET SEG NUMBER ONLY
MOVEM T2,ACKNO ;SAVE ACK NUMBER
ACKLP1: SKIPN W1,LLSEGQ(T1) ;HAVE ANY SEGS?
JRST ACKDON ;NO. ALL DONE THEN
SETZ W2, ;NO PREVIOUS
HRRZS W1 ;GET TOP SEG
; ..
;ACKCHN CONTINUED...
;LOOP TO PROCESS QUEUE
ACKLOP: LOAD T3,MSTOM,(W1) ;GET TYPE
CAME T3,ACKCHL ;IS THIS THE PROPER SUBCHANLEL?
JRST ACKNXT ;NO. GO ON
LOAD T3,MSSEG,(W1) ;GET SEGMENT #
SUB T3,ACKNO ;COMPUTE "AGE"
ANDI T3,7777 ;MOD 4096
SKIPE T3 ;IS IT THE VERY ONE WE ARE DOING?
CAILE T3,MAXDIF ;NO. IS IT ACKABLE ANYWAY?
SKIPA ;YES. ACK IT THEN
JRST ACKNXT ;NO.
PUSH P,T2 ;TEMPORARILY STASH
PUSH P,T3 ; SOME ACS
MOVE T2,TODCLK ;GET CURRENT TIME
SUB T2,MSTIM(W1) ;CALC ROUND TRIP TIME OF MESSAGE
MOVE T4,LLTIMO(T1) ;GET OLD TIME
SUB T2,T4 ;GET DIFFERENCE
IDIV T2,NSLDWS ;WEIGHT THE DIFFERENCE
ADD T2,T4 ;MAKE THE NEW TIME
CAIG T2,^D1000 ;IS IT REAL SMALL?
MOVEI T2,^D1000 ;YES, IMPOSE THE MINIMUM
MOVEM T2,LLTIMO(T1) ;SAVE THE NEW TIME OUT VALUE
MOVEI T4,LLSEGQ(T1) ;THE Q ADDRESS
DMOVE T2,W1 ;GET ARGUMENTS IN PROPER ACS FOR CALL
CALL UNQSEG ;REMOVE SEGEMENT
POP P,T3 ;RETRIEVE THE
POP P,T2 ; STASHED ACS
EXCH T1,W1 ;GET BACK MESSAGE ADDRESS
CALL RELRES ;FREE IT
MOVE T1,W1
JUMPE W2,ACKLP1 ;IF AT THE HEAD, START OVER
LOAD W1,MSLNK,(W2) ;GET THE ONE TO DO NEXT
JUMPN W1,ACKLOP ;DO IT IF ONE THERE
JRST ACKDON ;ALL DONE
ACKNXT: MOVE W2,W1 ;SAVE PREVIOUS
LOAD W1,MSLNK,(W1) ;GET NEXT
JUMPN W1,ACKLOP ;DO ALL
ACKDON: CALL CHKLLT ;CHECK FOR TTY ON THIS LL
; JN LLINT,(T1),[
; CALL INTOUT ;IF INTERNAL LINK SEND ANY OUTPUT STILL LEFT
; JFCL ;IGNORE FAILURE HERE
; JRST .+1] ;CONTINUE
RET ;AND DONE
;ROUTINE TO PROCESS A NACK
; T1/ BLOCK ADDRESS
; NACK NUMBER IN THE STKVAR "ACKNO"
DONACK: AOS T2,ACKNO ;GET THE ACK #
ANDI T2,7777 ;AND GET MODULO 4096
MOVEM T2,ACKNO ;SAVE IT
SETZ W2, ;NO HEAD
DONAC2: SKIPN W1,LLSEGQ(T1) ;HAVE ANY SEGS?
RET ;NO. ALL DONE
HRRZS W1 ;GET FIRST MESSAGE
DONAC1: LOAD T3,MSTOM,(W1) ;GET MESSAGE TYPE
CAME T3,ACKCHL ;THE CORRECT CHANNEL?
JRST DONNXT ;NO
LOAD T3,MSSEG,(W1) ;GET SEG #
SUB T3,ACKNO ;COMPUTE "AGE"
ANDI T3,7777 ;""
CAILE T3,MAXDIF ;IS IT ONE BEING NACKED?
JRST DONNXT ;NO
AOS NAKCNT ;COUNT THIS SEGMENT
MOVE T3,ACKCHL ;YES. GET CHANNEL
CAIE T3,MSDAT ;DATA?
JRST DONRES ;NO. RESEND NOW
LOAD T3,LLMFC,(T1) ;GET FLOW CONTROL TYPE
CAIN T3,1 ;SEGMENT?
JRST [ INCR LLMSM,(T1) ;YES. ACCOUNT FOR THE MACK
JRST .+1]
JN LLBRP,(T1),[
CAIE T3,2 ;MESSAGE FLOW CONTROL?
JRST DONRQ ;NO. GO ARRANGE FOR REQUEUE
LOAD T3,MSMFL,(W1) ;YES. GET MESSAGE FLAGS
JXE T3,DATEOM,DONRQ ;IS THIS THE EOM?
INCR LLMSM,(T1) ;YES. INCREMENT REQUEST COUNT
JRST DONRQ] ;AND REQUEUE IT
CAIE T3,1 ;YES. SEGMENT?
JRST DONRES ;NO. RESEND NOW
LOAD T3,LLMSM,(T1) ;GET SEG COUNT TO SEND
SKIPE T3 ;ANY THERE?
TXNE T3,200 ;AND IS IT POSITIVE?
JRST DONRQ ;NO.
DECR LLMSM,(T1) ;YES. COUNT DOWN
DONRES: PUSH P,T2 ; TEMPORARILY STASH
PUSH P,T3 ; ACS
MOVEI T4,LLSEGQ(T1) ;GET THE SEG Q HEAD
DMOVE T2,W1 ;GET ARGUMENTS IN PROPER ACS FOR CALL
CALL UNQSEG ;REMOVE SEG FROM QUEUE
POP P,T3 ;RETRIEVE
POP P,T2 ; STASHED ACS
MOVE T2,W1 ;GET SEG
SETZRO MSTRY,(T2) ;RESET THE TIME OUT RETRY COUNT
CALL SNDSE0 ;RESEND IT NOW
DONNXT: MOVE W2,W1 ;NEW HEAD
LOAD W1,MSLNK,(W2) ;GET NEXT
JUMPN W1,DONAC1 ;IF MORE, DO IT
RET ;DONE
DONRQ: SETONE MSNAK,(W1) ;REMEMBER IS NAKED
INCR LLQUN,(T1) ;AND ACCOUNT FOR IT
JRST DONNXT ;AND CONTINUE DOWN Q
ENDAV. ;END ACVAR
;ROUTINE TO TAKE A SEGMENT OFF OF A SEGMENT Q
;
;ACCEPTS: T1/ ADDRESS OF LL BLOCK
; T2/ ADDRESS OF MESSAGE
; T3/ ADDRESS OF PREVIOUS MESSAGE ON SEGMENT QUEUE
; T4/ ADDRESS OF LINK'S SEGMENT QUEUE HEAD
;RETURNS: +1
UNQSEG: SAVET
ACVAR <LLB> ;AC FOR LL BLOCK ADDRESS
MOVEM T1,LLB ;SAVE IT
DECR LLQOU,(LLB) ;ONE LESS ON SEG Q
LOAD T1,MSLNK,(T2) ;GET ADDRESS OF NEXT SEG
JUMPE T3,UNQSG1 ;IF AT HEAD OF QUEUE, NO BACKWARD LINKING
STOR T1,MSLNK,(T3) ;MAKE PREVIOUS POINT TO NEXT
SKIPN T1 ;IS THERE A NEXT?
HRLM T3,(T4) ;NO, MAKE THIS TAIL OF QUEUE
RET
UNQSG1: HRRM T1,(T4) ;SET NEXT SEGMENT TO BE QUEUE HEAD
EXCH T1,T2 ;T1/ SEG TO BE ELIMINATED; T2/ NEXT SEG
LOAD T3,LLLKP,(LLB) ;GET NODE'S VERSION
CAIE T3,.NSP31 ;NSP 3.1?
CALL UNQTIM ;NO, REMOVE MESSAGE FROM NSSNTQ QUEUE
SKIPE T2 ;IS THERE A NEXT?
IFSKP. ;NO
SETZM (T4) ;RESET QUEUE HEADER
RET ;DONE
ENDIF.
CAIE T3,.NSP31 ;NSP 3.1?
CALL ONTIMQ ;NO, GO PUT IT ON NSSNTQ
RET
ENDAV.
;ROUTINE TO PUT A DATA MESSAGE ON A SEGMENT Q
; T2/ THE MESSAGE
; T3/ THE QUEUE ADDRESS
;PRESERVES T1,T2,T4
PUTONQ: SAVEAC <T4>
SKIPN T4,0(T3) ;HAVE A QUEUE?
JRST [ HRRM T2,0(T3) ;NO MAKE ONE
HRLM T2,0(T3)
JRST PUTOND] ;DONE
HLRZS T4 ;GET TAIL
STOR T2,MSLNK,(T4) ;LINK THIS IN
HRLM T2,0(T3) ;AND MAKE IT THE TAIL
PUTOND: SETZRO MSLNK,(T2) ;TIE IT OFF
RET ;AND DONE
;ROUTINE TO RESEND NACK'ED SEGMENTS
;ACCEPTS: T1/ BLOCK ADDRESS
; BLOCK MUST BE LOCKED
RESEND: JE LLQUN,(T1),R ;ANY NAKED SEGS?
JN LLBRP,(T1),R ;YES. IS FLOW ON?
JE LLMFC,(T1),RSEND0 ;IF NO FLOW CONTROL, GO RESEND NOW
LOAD T3,LLMSM,(T1) ;GET COUNT
SKIPE T3 ;IF ZERO
TXNE T3,200 ;OR IF NEG
RET ;CAN'T RESEND
RSEND0: HRRZ T2,LLSEGQ(T1) ;GET HEAD OF Q
RSEND1: SKIPE T2 ;ANYTHING THERE?
IFSKP. ;
BUG (NSPRSN) ;NO, SHOULDN'T HAPPEN! TELL THE WORLD
RET ;GO AWAY
ENDIF.
TMNN MSNAK,(T2) ;IS THIS A NAKED SEG?
JRST [ LOAD T2,MSLNK,(T2) ;NO. GET NEXT
JRST RSEND1] ;AND PROCEED
DECR LLQUN,(T1) ;ONE LESS NAKED SEG
LOAD T3,LLMFC,(T1) ;GET TYPE OF FLOW CONTROL
JUMPE T3,RSEND3 ;IF NO FLOW CONTROL, SEND IT NOW
CAIE T3,2 ;MESSAGE FLOW CONTROL?
JRST RSEND2 ;NO. SEND IT NOW THEN
LOAD T3,MSMFL,(T2) ;GET MESSAGE FLAGS
JXE T3,DATEOM,RSEND3 ;IS THIS EOM?
RSEND2: DECR LLMSM,(T1) ;YES. DOWNCOUNT REQUEST COUNT
RSEND3: SETZRO MSNAK,(T2) ;NO LONGER A NACKED SEG
CALL SNDSE0 ;AND RESEND IT
JRST RESEND ;AND DO IT AGAIN
;ROUTINE TO FLUSH ALL QUEUES FOR A LL
;FLUSHES: SEGQ,RSEGQ,LLOMSG,LLOMSG
; T1/ LL BLOCK - MUST BE LOCKED
;RETURNS +1 ALWAYS
FLUSH:: SETZRO <LLQUN,LLQOU>,(T1) ;CLEAR COUNTS
MOVEI T2,LLOMSG(T1) ;GET ORDERED QUEUE
CALL PRUNE ;KILL IT
MOVEI T2,LLMSI(T1) ;INT MESSAGES
CALL PRUNE ;KILL THIS AS WELL
SKIPN T2,LLSEGQ(T1) ;GET FIRST MSG ON LL'S QUEUE
RET ;QUEUE IS EMPTY, DONE
LOAD T3,LLLKP,(T1) ;GET NODE'S VERSION
CAIN T3,.NSP31 ;NSP 3.1?
JRST FLUSH1 ;YES, THEN NOT ON TIMER'S Q
PUSH P,T1 ;SAVE ADDRESS OF LL BLOCK
HRRZ T1,T2 ;GET ADDRESS OF MESSAGE
CALL UNQTIM ;TAKE MSG OF TIMER'S QUEUE
POP P,T1 ;RETRIEVE ADDRESS OF LL BLOCK
FLUSH1: MOVEI T2,LLSEGQ(T1) ;GET SENT Q
CALLRET PRUNE ;GET RID OF THEM
;WORKER ROUTINE TO FLUSH A LINK Q
PRUNE: SAVET ;SAVE ALL REGS
HRRZ T1,0(T2) ;GET HEAD
SETZM 0(T2) ;CLEAR Q
PRUNE1: JUMPE T1,R ;IF AT THE END, DONE
LOAD T2,MSLNK,(T1) ;GET NEXT
PUSH P,T2 ;SAVE IT
JN MSPST,(T1),CHKPST ;IF POSTING ON, GO CHECK OUT MESSAGE
PRUNE2: CALL RELRES ;RELEASE NODE
PRUNE3: POP P,T1 ;GET BACK NEXT
JRST PRUNE1 ;AND DO IT
;MESSAGE NEEDS TO BE PRUNED BUT POSTING IS STILL OUTSTANDING.
CHKPST: PIOFF ;OWN MACHINE WHILE CHECKING MESSAGE
JE MSPST,(T1),CHKPS1 ;IF NO LONGER NEEDED, GO ON
SETONE MSRLS,(T1) ;IS STILL NEEDED. REQUEST RELEASE WHENEVER
PION ;ALLOW INTS AGAIN
JRST PRUNE3 ;DON'T RELEASE IT
CHKPS1: PION ;ALLOW INTS
JRST PRUNE2 ;AND RELEASE IT
;ROUTINE TO SEND AN ACK MESSAGE.
; T1/ LL BLOCK
; T2/ SEGMENT # TO ACK
; T3/ SUBCHANNEL TO ACK
;RETURNS: +1 FAILED
; +2 SUCCESS
;ALL REGS PRESERVED
SNDACK: ASUBR <LLBLK,ACKNO,ACKTYP>
NSBP09: TMNE LLLOC,(T1) ;LOCAL?
JRST [ SKIPGE NSPLPB ;YES, IS THERE A RUNNING LOOPBACK LINE?
JRST ACKRMT ;YES, GIVE MESSAGE TO DRIVER
JE LLCIL,(T1),RSKP ;NO, DONE IF NOT CONNECTED TO INTERNAL LINK
; CALL SKDOUT ;INTERNAL LINK, SCHEDULE OUTPUT
RETSKP ] ;DONE, RETURN
JRST ACKRMT ;NEED TO SEND A MESSAGE
;ROUTINE TO ACK THE LS/INT CHANNEL
ACKLI: LOAD T2,LLIIN,(T1) ;GET SEG TO ACK/NAK
TMNN LLALS,(T1) ;NEED AN ACK?
TXO T2,ACKBIT ;NO, TURN ON NAK BIT IN MESSAGE
MOVEI T3,MSLSI ;THE CHANNEL I.D.
CALL SNDACK ;SEND ACK
RET ;FAILED
SETZRO <LLNLS,LLALS>,(T1) ;DON'T NEED ACK OR NACK ANYMORE
CALL CHKLLT ;CHECK FOR NVT LINK
RETSKP ;OK
;SNDACK CONTINUED.....
;SEND ACK TO REMOTE NODE.
ACKRMT: STKVAR <MSGBL> ;PLACE TO SAVE MESSAGE BLOCK
MOVEI T3,AKLSTL-1 ;GET LENGTH OF ACK LIST
ACKRM1: SKIPE T2,ACKLST(T3) ;GET THE ENTRY
IFSKP. ;NONE THERE
SOJGE T3,ACKRM1 ;END OF LIST?
CALLRET TIMWAT ;YES, RETURN TEST ROUTINE
ENDIF.
JN MSACK,(T2),[SOJGE T3,ACKRM1 ;IF BUFFER IN USE, ARE THERE MORE?
CALLRET TIMWAT] ;NO, RETURN TEST ROUTINE
SETONE MSACK,(T2) ;BLOCK NOW BEING USED
MOVEM T2,MSGBL ;SAVE THE BUFFER ADDRESS
MOVE T1,LLBLK ;GET BACK LL BLOCK ADDRESS
SETZM LLBPCT(T1) ;INIT MESSAGE COUNT
ADDI T2,MSHDR ;GET TO DATA PART
HRLI T2,(<POINT 8,>)
MOVEM T2,LLBPTR(T1) ;INIT POINTER
MOVEI T2,ACKFLM ;BASIC ACK MESSAGE
MOVE T3,ACKTYP ;GET SUBCHANNEL
CAIN T3,MSLSI ;LS/INT SUBCHANNEL?
ADDI T2,ACKLSI ;YES.
MOVE T3,MSGBL ;RETRIEVE MESSAGE ADDRESS
STOR T2,MSMFL,(T3) ;SAVE MESSAGE FLAGS IN MESSAGE HEADER
CALL RTHDCI ;PUT ON ROUTING HEADER AND FLAGS
CALL PUTLLA ;PUT IN LL ADDRESSES
MOVE T2,ACKNO ;GET SEG TO ACK
TXO T2,ACKIND ;SET ACK INDICATOR
CALL TWOBYT ;PUT IT IN
MOVE T2,MSGBL ;GET MESSAGE
REPEAT 0,<
HRRZ T3,LLBPTR(T1) ;GET BYTE PTR
CAIL T3,0(T2) ;WITHIN RANGE OF MSG BLOCK?
CAILE T3,ACKLEN+MSHDR(T2)
JSR BUGHLT
>;END REPEAT 0
CALL SNDCTL ;SEND IT
RETSKP ;AND DONE
;ROUTINE TO BUILD AND SEND A NODE INIT
; T1/ PORT I.D.
NODINI::TRVAR <<LLDUM,LKSIZE>,NODMSG,NODPRT>
MOVEM T1,NODPRT ;SAVE PORT I.D.
MOVEI T1,NDISIZ+MSHDR ;REQUIRES BLOCK SIZE
CALL GETRES ;GET A BLOCK
RETBAD ;COULDN'T
MOVEM T1,NODMSG ;SAVE BLOCK
MOVEI T2,MSHDR(T1) ;POINT TO DATA PART
HRLI T2,(<POINT 8,>)
MOVEI T1,LLDUM ;DUMMY LL BLOCK
SETZM LLBPCT(T1) ;INIT COUNT
MOVEM T2,LLBPTR(T1) ;SET UP BYTE POINTER
MOVEI T2,CNMRFL+NDIFLG ;MESSAGE FLAGS
CALL ONEBYT
MOVEI T2,STRTYP ;NOD INIT MESSAGE
CALL ONEBYT
MOVE T3,OURNUM ;GET LOCAL NUMBER
CALL MAKEXT ;PUT IT IN MESSAGE
MOVEI T3,OURNAM ;OUR NAME
CALL ASCIIZ ;PUT IT IN
MOVEI T2,OURCAP ;SUPPORTED CAPS
CALL ONEBYT
MOVEI T2,OURREQ ;REQUIRED CAPS
CALL ONEBYT
MOVEI T2,BLKSIZ ;GET OUR DLL BLOCK SIZE
CALL TWOBYT
MOVE T2,SEGSZ ;OUR NSP SEGMENT SIZE
CALL TWOBYT
MOVEI T2,MAXLNK ;MAX LINKS
CALL TWOBYT
MOVEI T2,ROUVER ;ROUTING VERSION
CALL ONEBYT
MOVEI T2,ROUECO ;ROUTING ECO LEVEL
CALL ONEBYT
MOVEI T2,ROUCST ;CUSTOMER MODS
CALL ONEBYT
MOVEI T2,COMVER ;NSP VERSION
CALL ONEBYT
MOVEI T2,COMECO ;NSP ECO LEVEL
CALL ONEBYT
MOVEI T2,COMCST ;CUST MODS TO NSP
CALL ONEBYT
SETZ T2, ;NO TEXT YET
CALL ONEBYT
MOVE T2,NODMSG ;MESSAGE BLOCK
MOVE T3,NODPRT ;GET PORT I.D.
STOR T3,LLPRT,(T1) ;SAVE IN LL BLOCK
MOVE T3,LLBPCT(T1) ;COUNT
MOVE T1,NODPRT ;GET PORT NUMBER
CALL SNDSG1 ;SEND NODE INIT MESSAGE
MOVE T1,NODPRT ;GET PORT NUMBER AGAIN
SETONE INISNT,MCBDTE(T1) ;SAY NOTE INIT MSG SENT
JE REQVER,MCBDTE(T1),RSKP ;DONE IF NO VERIFICATION MSG NEEDED
CALL NODVER ;SEND VERIFICATION MSG
MOVE T1,NODPRT ;RESTORE PORT ID
SETZRO REQVER,MCBDTE(T1) ;NOTE VERIFICATION NO LONGER NEEDED
RETSKP ;DONE, RETURN
;NODVER - ROUTINE TO ASSEMBLE AND SEND A NODE VERIFICATION MESSAGE
;
;ACCEPTS IN T1/ PORT ID
; CALL NODVER
;RETURNS: +1 ALWAYS
NODVER: TRVAR <<LLDUM,LKSIZE>,NODMSG,NODPRT>
MOVEM T1,NODPRT ;SAVE PORT I.D.
; INITIALIZE MESSAGE BLOCK
MOVEI T1,NDISIZ+MSHDR ;REQUIRES BLOCK SIZE
CALL GETRES ;GET A BLOCK
RETBAD ;COULDN'T
MOVEM T1,NODMSG ;SAVE BLOCK
MOVEI T2,MSHDR(T1) ;POINT TO DATA PART
HRLI T2,(<POINT 8,>)
MOVEI T1,LLDUM ;DUMMY LL BLOCK
SETZM LLBPCT(T1) ;INIT COUNT
MOVEM T2,LLBPTR(T1) ;SET UP BYTE POINTER
; ASSEMBLE MESSAGE FLAGS AND STARTTYPE FIELDS
MOVEI T2,CNMRFL+NDIFLG ;MESSAGE FLAGS
CALL ONEBYT
MOVEI T2,VERTYP ;NOD VERIFICATION MESSAGE
CALL ONEBYT
; ADD PASSWORD TO MESSAGE
MOVSI T4,-10 ;8 BYTES
MOVE T3,[POINT 7,[ASCII/DECNET20/]]
NDVER1: ILDB T2,T3 ;GET NEXT BYTE
CALL ONEBYT ;ADD TO MESSAGE
AOBJN T4,NDVER1 ;DO ALL 8 BYTES
; SEND THE MESSAGE
MOVE T2,NODMSG ;MESSAGE BLOCK
MOVE T3,NODPRT ;GET PORT I.D.
STOR T3,LLPRT,(T1) ;SAVE IN LL BLOCK
MOVE T3,LLBPCT(T1) ;COUNT
MOVE T1,NODPRT ;GET PORT NUMBER AGAIN
CALLRET SNDSG1 ;SEND IT
;ROUTINE TO SEND AN LS MESSAGE
;ACCEPTS:
; T1/ LL BLOCK ADDRESS
; T2/ COUNT OF SEGS TO REQUEST
; T3/ SUBCHANNEL
; CALL SNDLS
;RETURNS +1: FAILURE
; T1/ SCHEDULER TEST WORD
; +2: SUCCESS
; T1/ LL BLOCK ADDRESS (UNCHANGED)
SNDLS:: ASUBR <SNDLBL,SNDLCT,SNDLTP,SNDLMS>
TMNE LLLOC,(T1) ;LOCAL?
JRST [SKIPL NSPLPB ;YES, IS THERE A RUNNING LOOPBACK LINE?
JRST SNDLSL ;NO
JRST .+1] ;YES, MESSAGE MUST GO TO DRIVER
LOAD T2,LLQOU,(T1) ;GET SEGS IN QUEUER
LOAD T3,LLMQO,(T1) ;GET MAXIMUM OUTPUT QUEUE LENGTH
CAILE T2,1(T3) ;ROOM FOR THIS ONE?
JRST [ MOVEI T2,CHKQTA ;NO. MUST WAIT UNTIL THERE IS
CALLRET MAKTST] ;""
MOVEI T1,MSHDR+LSLEN ;GET FREE SPACE
CALL GETRES ;GET SOME
JRST TIMWAT ;NONE.
MOVEM T1,SNDLMS ;SAVE BLOCK ADDRESS
MOVEI T2,MSHDR(T1) ;POINT TO DATA PORTION
HRLI T2,(<POINT 8,>)
MOVE T1,SNDLBL ;GET BACK LL BLOCK
MOVEM T2,LLBPTR(T1)
SETZM LLBPCT(T1)
MOVEI T2,DATFLI ;GET FLAGS
CALL RTHDCI ;PUT ON ROUTE HEADER AND FLAGS
CALL PUTLLA ;PUT IN ADDRESSES
TMNE LLALS,(T1) ;THIS LINK NEED AN ACK?
CALL MAKLSA ;YES, PUT IT IN
LOAD T2,LLISN,(T1) ;GET SEG #
AOS T2 ;NEXT ONE
ANDI T2,SEGMSK
STOR T2,LLISN,(T1)
MOVE T4,SNDLMS ;GET MESSAGE ADDRESS
STOR T2,MSSEG,(T4) ;SAVE SEG #
STOR T1,MSLLA,(T4) ;SAVE LINK ADDRESS
MOVEI T3,MSLSI ;SAY THIS IS A LS MSG
STOR T3,MSTOM,(T4) ;""
MOVEI T3,DATFLI ;GET LS MESSAGE TYPE
STOR T3,MSMFL,(T4) ;PUT IT IN HEADER OF MESSAGE
CALL TWOBYT ;PUT IN SEG #
SETZM T2 ;ASSUME DATA CHANNEL
MOVE T3,SNDLTP ;GET SUBCHANNEL
CAIE T3,MSDAT ;DATA?
MOVEI T2,4 ;NO. LS/INT
CALL ONEBYT
MOVE T2,SNDLCT ;GET COUNT
CALL ONEBYT
MOVE T2,SNDLMS ;GET MESSAGE
CALL SNDSEG ;SEND THE DATA
RETSKP ;AND DONE
;MAKE THE ACKNUM (PIGGYBACKED ACK) FIELD IN A LS MESSAGE
;ACCEPTS: T1/ LL BLOCK ADDRESS
;RETURNS: +1
;PRESERVES T1
MAKLSA: LOAD T2,LLIIN,(T1) ;GET LAST LS MESSAGE RECEIVED
TXO T2,ACKIND ;PUT IN ACKNUM INDICATOR
CALL TWOBYT ;PUT ACKNUM FIELD IN MESSAGE
SETZRO <LLALS,LLNLS>,(T1) ;CLEAR THE "NEED TO ACK/NACK" FLAGS
CALL CHKLLT ;CHECK FOR NVT LINK
RET
;SNDLS CONTINUED...
;SEND ON A LOCAL CONNECTION
SNDLSL: SAVEAC <T1> ;SAVE LL BLOCK
SETOM T2 ;ANY MATCH IS OKAY
LOAD T1,LLHLK,(T1) ;GET OTHER ADDRESS
LLLOCK
CALL LLLKUP ;GET BLOCK ADDRESS
JRST [ LLLULK ;?
RETSKP] ;OTHER ONE WENT AWAY
MOVE T2,SNDLCT ;GET COUNT
MOVE T3,SNDLTP ;GET SUBCHANNEL
NOSKD1
CAIE T3,MSDAT ;DATA
JRST [ OPSTRM <ADDM T2,>,LLMIC,(T1) ;NO
JRST SNDLS1] ;GO WRAP UP
OPSTRM <ADDM T2,>,LLMSM,(T1) ;YES
SNDLS1: CALL CHKLLT ;CHECK FOR TTY ON THIS LL
OKSKD1
LLLULK ;FREE TREE
JE LLINT,(T1),RSKP ;SENDER OF LS CONNECTED TO AN INTERNAL LINK ?
; CALL SKDOUT ;YES, NOTE CAN SEND MORE NOW
RETSKP ;DONE
;ROUTINES CALLED FROM INT LEVEL TO GET AND QUEUE UP BUFFERS
;GET A BUFFER
; T1/ PORT # (E.G. DTE#)
; T2/ # OF BYTES REQUIRED
;RETURNS:
; +1 COULDN'T GET BLOCK
; +2 T1=BLOCK ADDRESS.
NSPSPC::ASUBR <PRTNO,PRTCNT>
;**;[3179] Remove 4 lines CEG 5-Nov-84
MOVEI T1,MSHDR*4+3(T2) ;GET # OF BYTES
LSH T1,-2 ;CONVERT TO WORDS
HRLI T1,.RESP1 ;PRIORITY 1
MOVE T2,[RS%SE0+.RESNP] ;FROM THE NET POOL
CALL ASGRES ;GET THE SPACE
RETBAD ;COULDN'T
MOVE T2,PRTNO ;GET PORT I.D.
STOR T2,MSPRT,(T1) ;SAVE IT
MOVE T2,PRTCNT ;GET COUNT OF BYTES IN MESSAGE
STOR T2,MSCNT,(T1) ;SAVE IT
ADDI T1,MSHDR ;POINT TO DATA PORTION
RETSKP ;AND RETURN WITH BLOCK
SUBTTL NSP Background Task - Output on Internal Links
;OUTSND - ROUTINE TO CHECK "OUTPUT REMAINING" QUEUE AND SEND ANY REMAINING DATA
;
; CALLED PERIODICALLY FROM NSP BACKGROUND TASK DISPATCHER (NSPTSK)
REPEAT 0,<
SWAPCD
OUTSND: SAVEPQ
SETZM OUTTIM ;RESET TIME AT WHICH TASK SHOULD AWAKEN
LOCK OUTLOK ;LOCK THE QUEUE WHILE PROCESSING ENTRIES
HRRZ Q1,OUTQUE ;GET ADR OF FIRST LINK BLOCK TO PROCESS
MOVEI Q2,0 ;INITIALIZE "PREVIOUS BLOCK" ADDRESS
; LOCK THE LOGICAL LINK BLOCK AND SEND REMAINING OUTPUT
OUTCK0: JUMPE Q1,[UNLOCK OUTLOK ;IF END OF QUEUE, UNLOCK THE QUEUE
RET] ; AND RETURN
MOVE T1,Q1 ;GET ADR OF CURRENT LOGICAL LINK BLOCK
CALL BLKLLK ;GO LOCK THE LOGICAL LINK
JRST [ CALL SKDOUT ;FAILED, SCHEDULE OUTPUT FOR LATER
MOVE Q2,Q1 ;MAKE PREVIOUS BLOCK THE CURRENT
LOAD Q1,LLOUT,(Q1) ;MAKE CURRENT BLOCK THE NEXT ONE
JRST OUTCK0 ] ;GO DO OUTPUT FOR NEXT LOGICAL LINK
MOVE T1,Q1 ;GET ADR OF CURRENT LOGICAL LINK BLOCK
CALL INTOUT ;DO REMAINING OUTPUT FOR THIS LINK
JRST [ CALL SKDOUT ;FAILED, SCHEDULE OUTPUT FOR LATER
JRST OUTCK1 ] ;GO DO OUTPUT FOR NEXT LOGICAL LINK
JN LLOCT,(Q1),[ CALL SKDOUT ;IF MORE OUTPUT, SCHEDULE FOR LATER
JRST OUTCK1] ;GO HANDLE NEXT BLOCK ON QUEUE
; ALL REMAINING OUTPUT SENT, REMOVE THE BLOCK FROM THE QUEUE
SETZRO LLQUE,(Q1) ;NOTE BLOCK NO LONGER ON QUEUE
HLRZ T4,OUTQUE ;GET POINTER TO TAIL OF QUEUE
CAMN T4,Q1 ;PROCESSING TAIL OF QUEUE ?
HRLM Q2,OUTQUE ;YES, SAVE PREVIOUS BLOCK AS NEW TAIL
LOAD T4,LLOUT,(Q1) ;GET ADDRESS OF NEXT BLOCK ON QUEUE
SETZRO LLOUT,(Q1) ;CLEAR ADR OF NEXT BLOCK ON QUEUE
SKIPN Q2 ;PROCESSING HEAD OF QUEUE ?
JRST [ HRRM T4,OUTQUE ;YES, SAVE NEXT BLOCK AS NEW HEAD
JRST OUTCK1 ] ; AND GO DO OUTPUT FOR NEXT LOGICAL LINK
STOR T4,LLOUT,(Q2) ;NO, SAVE ADR OF NEXT BLOCK IN PREVIOUS
OUTCK1: MOVE Q2,Q1 ;MAKE CURRENT BLOCK THE PREVIOUS
MOVE T1,Q1 ;GET ADDRESS OF CURRENT LINK BLOCK
LOAD Q1,LLOUT,(T1) ;GET ADDRESS OF NEXT BLOCK ON QUEUE
CALL BLKULK ;UNLOCK THE CURRENT BLOCK
JRST OUTCK0 ;GO PROCESS NEXT BLOCK ON QUEUE
;SKDOUT - ROUTINE TO SCHEDULE OUTPUT FOR AN INTERNAL LINK
;
;CALL: CALL SKDOUT
;RETURNS: +1 ALWAYS, WITH ALL AC'S PRESERVED
RESCD
SKDOUT::SAVET
MOVE T4,TODCLK ;GET CURRENT TIME
ADD T4,OUTIVL ;GET TIME INTERVAL TO WAIT BEFORE TRYING AGAIN
MOVEM T4,OUTTIM ;SCHEDULE WAKEUP AT LATER TIME
RET ;DONE, RETURN
;INTOUT - ROUTINE TO PERFORM OUTPUT FOR AN INTERNAL LINK
;
;ACCEPTS IN T1/ ADDRESS OF LOGICAL LINK BLOCK
; CALL INTOUT
;RETURNS: +1 FAILED, MORE OUTPUT WILL HAVE TO BE DONE LATER
; +2 SUCCESS, ALL REMAINING OUTPUT HAS BEEN SENT
;
; ASSUMES LOGICAL LINK BLOCK IS LOCKED. PRESERVES LINK BLOCK ADR IN T1
INTOUT: ASUBR <INOLLB>
; PROCESS ANY OUTSTANDING ACK'S FOR THIS LINK
MOVE T1,INOLLB ;GET LOGICAL LINK BLOCK ADDRESS
; CALL MOVSEG ;PROCESS OUTSTANDING ACK'S
; RET ;FAILED, TRY AGAIN LATER
MOVE T1,INOLLB ;GET LOGICAL LINK BLOCK ADDRESS
JE LLOCT,(T1),RSKP ;IF NO DATA LEFT, ALL DONE
; CHECK TO SEE IF THERE IS ANY MORE OUTPUT TO SEND
INO020: MOVE T1,INOLLB ;GET ADDRESS OF LOGICAL LINK BLOCK
JN LLOCT,(T1),INO025 ;IF DATA LEFT, GO TRY TO SEND IT
MOVE T1,INOLLB ;GET LOGICAL LINK BLOCK ADDRESS
CALL TELOBE ;GO TELL DRIVER THAT OUTPUT BUFFER NOW EMPTY
MOVE T1,INOLLB ;GET ADDRESS OF LOGICAL LINK BLOCK
CALL TELOOK ;GO ADVISE DRIVER OUTPUT CAN BE DONE
MOVE T1,INOLLB ;RESTORE LOGICAL LINK BLOCK ADDRESS
RETSKP ;DONE, RETURN
;CHECK TO SEE IF ANY SEGMENTS CAN BE SENT NOW
INO025: MOVE T1,INOLLB ;GET LOGICAL LINK BLOCK ADDRESS
CALL SNDCHK ;CAN ANY SEGMENTS BE SENT ?
RET ;NO, TRY AGAIN LATER
MOVE T1,INOLLB ;YES, GET LOGICAL LINK BLOCK ADDRESS
; CALL OUTSEG ;SEND THE SEGMENT
RET ;FAILED, TRY AGAIN LATER
JRST INO020 ;CHECK TO SEE IF ANOTHER SEGMENT CAN BE SENT
;TELOOK - ROUTINE TO CHECK TO SEE IF NECESSARY TO NOTIFY DRIVER THAT
; OUTPUT MAY NOW BE SENT
;
;ACCEPTS IN T1/ ADDRESS OF LOGICAL LINK BLOCK
; CALL TELOOK
;RETURNS: +1 ALWAYS, DRIVER NOTIFIED THRU FUNCTION VECTOR IF NEEDED
TELOOK: JE LLNDO,(T1),R ;RETURN IF DRIVER DOES NOT NEED NOTIFICATION
SETZRO LLNDO,(T1) ;NO LONGER NEED NOTIFICATION FLAG LIT
LOAD T4,LLVEC,(T1) ;GET DRIVER FUNCTION VECTOR ADDRESS
MOVX T2,.NSOMO ;GET "OUTPUT CAN BE SENT" TYPE CODE
LOAD T1,LLDRV,(T1) ;GET DRIVER'S CORRELATION CODE
CALLRET @.NSOOK(T4) ;NOTIFY DRIVER AND RETURN
;TELOBE - ROUTINE TO NOTIFY THE DRIVER THAT AN OUTPUT BUFFER IS NOW EMPTY
;
;ACCEPTS IN T1/ ADDRESS OF LOGICAL LINK BLOCK
; CALL TELOBE
;RETURNS: +1 ALWAYS, WITH DRIVER NOTIFIED THRU ITS FUNCTION VECTOR
TELOBE::ASUBR <OBELLB>
LOAD T4,LLVEC,(T1) ;DATA SENT, GET DRIVER FCN VECTOR ADR
LOAD T2,LLBFO,(T1) ;GET DRIVER'S BUFFER ADDRESS
LOAD T1,LLDRV,(T1) ;GET DRIVER CORRELATION CODE
CALL @.NSOBE(T4) ;TELL DRIVER IT CAN HAVE BUFFER BACK
MOVE T1,OBELLB ;GET LOGICAL LINK BLOCK ADDRESS
SETZRO LLBFO,(T1) ;NOTE THAT BUFFER IS NOW GONE
RET ;DONE, RETURN.
>
SUBTTL Routine Needed by TTYSRV
;GET THE NEXT SEGMENT ON THE INCOMING MESSAGE QUEUE
;ACCEPTS: T1/ LL BLOCK
;RETURNS: +1 - NO SEGMENT AVAILABLE
; +2 - T2/ SEGMENT ADDRESS
;PRESERVES T1
RESCD
TTGETS::SKIPN T2,LLOMSG(T1) ;ANY SEGMENTS?
RET ;NO, DONE
HRRZS T2 ;YES, JUST THE HEAD SEGMENT
RETSKP
;REMOVE A SEGMENT FROM THE INCOMING MESSAGE QUEUE
;ACCEPTS: T1/ LL BLOCK
; T2/ SEGMENT ADDRESS
;RETURNS: +1 ALWAYS
TTREMS::LOAD T3,MSLNK,(T2) ;GET NEXT SEGMENT ON QUEUE
SKIPN T3 ;ANY MORE?
HRLM T3,LLOMSG(T1) ;NO, MAKE IT THE TAIL
HRRM T3,LLOMSG(T1) ;MAKE IT THE HEAD
RET
SUBTTL Scheduler Interface
;ROUTINE CALLED BY THE SCHEDULER EVERY 20 MS TO PROCESS MESSAGES
;ARRIVED FROM THE NETWORK
NSPCH7::ACVAR <W1> ;GET A WORK REG
STKVAR <MB> ;MESSAGE ADDRESS
;**;[3179] Add 4 lines CEG 5-Nov-84
SETZM RESNET ;[3179] ASSUME WE HAVE LOTS OF SPACE
MOVE T1,RESUTB+.RESNP ;[3179] GET AMOUNT CURENTLY IN USE
CAIG T1,RESHLD ;[3179] ABOVE THE THRESHOLD?
SETOM RESNET ;[3179] NO, INDICATE WE'RE LOW ON SPACE
MOVEI W1,15 ;DO A LIMITED # PER PASS
SKIPL LLLLCK ;LL TREE LOCK AVAILABLE
RET ;NO
SKIPN T1,SMSGQ ;ANY MSGS ON Q?
JRST LLSRVR ;NO, GO SEE IF ANY LINKS NEED SERVICE
HRRZS T1 ;YES, GET FIRST MSG
NSPCH0: MOVEM T1,MB ;SAVE MESSAGE ADDRESS
CALL NSPMSG ;GO PROCESS THE MSG
IFNSK. ;COULDN'T, WE'LL DO IT LATER
MOVE T1,MB ;RETRIEVE MESSAGE ADDRESS
CALL NSPNXT ;ANY MORE MSGS?
JRST LLSRVR ;NO
JRST NSPCH0 ;YES
ENDIF.
MOVE T1,MB ;RETRIEVE MESSAGE ADDRESS
CALL NSPREM ;REMOVE THIS MSG FROM Q
JRST LLSRVR ;NO MORE TO DO
SOJGE W1,NSPCH0 ;GO DO MORE
JRST LLSRVR
ENDSV.
ENDAV. ;END ACVAR
;Get the next message on SMSGQ
;
;ACCEPTS: T1/ Address of current message
;RETURNS: +1 No more messages
; +2 T1/ Address of next message
NSPNXT: CHNOFF DLSCHN ;TURN OFF NET
MOVE T1,MSNXT(T1) ;GET NEXT MSG
CHNON DLSCHN ;TURN ON NET
JUMPE T1,R ;RETURN NO NEXT MSG
RETSKP ;THERE IS ANOTHER MSG
;Remove a message from SMSGQ and get the next message on the queue
;
;ACCEPTS: T1/ Address of message to be removed
;RETURNS: +1 Message removed, no more messages on queue
; +2 Message removed, T1/ Address of next message
NSPREM: ASUBR <MSG,NXT>
CHNOFF DLSCHN ;TURN OFF NET
SKIPN T2,MSPRV(T1) ;ARE WE FIRST ON Q?
IFNSK. ;YES
SKIPN T3,MSNXT(T1) ;ARE WE ALSO LAST ON Q?
IFNSK. ;YES
SETZM SMSGQ ;INIT THE Q HEADER
SETZM NXT ;NO NEXT MESSAGE
JRST NSPRE1 ;DONE
ENDIF.
SETZM MSPRV(T3) ;NO, MAKE NEXT MSG THE FIRST
HRRM T3,SMSGQ ;MAKE Q HEADER POINT TO US
MOVEM T3,NXT ;RETURN WITH NEXT
JRST NSPRE1
ENDIF.
SKIPN T3,MSNXT(T1) ;NO, WE ARE NOT FIRST. ARE WE LAST?
IFNSK. ;YES
SETZM MSNXT(T2) ;PREVIOUS NO LONGER HAS NEXT
HRLM T2,SMSGQ ;MAKE Q HEADER POINT TO PREVIOUS
SETZM NXT ;NO NEXT MESSAGE
JRST NSPRE1 ;DONE
ENDIF.
MOVEM T3,MSNXT(T2) ;NO, NOT FIRST OR LAST. MAKE PREVIOUS POINT AHEAD TO NEXT
MOVEM T2,MSPRV(T3) ;MAKE NEXT POINT BACK TO PREVIOUS
MOVEM T3,NXT ;RETURN NEXT MSG
NSPRE1: MOVE T1,MSG ;RETRIEVE MESSAGE ADDRESS
JE MSSKD,(T1),NSPRE2 ;NEED TO RELEASE IT?
CALL RELRES ;YES
NSPRE2: CHNON DLSCHN ;TURN ON NET
;**;[3179] Change 2 lines CEG 5-Nov-84
SKIPN T1,NXT ;[3179] GET NEXT MESSAGE
RET ;[3179] NO MORE
RETSKP ;THERE IS ANOTHER MSG
ENDAS.
;ROUTINE TO QUEUE UP A RECEIVED MESSAGE.
;ACCEPTS: T1/ MESSAGE BLOCK ADDRESS
;RETURNS: +1 UNABLE TO PROCESS MESSAGE
; +2 MESSAGE SUCCESSFULLY PROCESSED
;**;[3179] Add MSGLLB to TRVAR CEG 5-Nov-84
NSPMSG::TRVAR <MSGCNT,MSGBYP,MSGSRC,MSGDST,MSGBLK,MSGLLB,<NSPDUM,11>,MSGW1>
;**;[3179] Remove 1 line CEG 5-Nov-84
MOVEI T2,MSHDR(T1) ;GET TO DATA PORTION
MOVEM T1,MSGBLK ;SAVE BLOCK ADDRESS
HRLI T2,(<POINT 8,>) ;MAKE BP
MOVEM T2,MSGBYP ;SAVE BYTE POINTER
LOAD T1,MSCNT,(T1) ;GET BYTE COUNT
MOVEM T1,MSGCNT ;SET UP COUNT
GETBYM (MSGCNT,MSGBYP,NSPMS4) ;GET FIRST BYTE
TRNE T2,201 ;A ROUTE HEADER?
;**;[3179] Change 1 line CEG 5-Nov-84
JRST NSPMS4 ;[3179] YES, BUT IN ERROR
TRNN T2,2 ;IS THIS FLAGS OR ROUTE HEADER?
JRST NSPMS1 ;FLAGS, GO DO MESSAGE
TRNE T2,100
TRNE T2,60 ;VALID HEADER?
;**;[3179] Change 1 line CEG 5-Nov-84
JRST NSPMS4 ;[3179] NO
CALL SKPFLD ;SKIP HOST NAME
;**;[3179] Change 1 line CEG 5-Nov-84
JRST NSPMS4 ;[3179] SOMETHING WRONG
CALL SKPFLD ;SKIP OTHER HOST NAME
;**;[3179] Change 1 line CEG 5-Nov-84
JRST NSPMS4 ;[3179] SOMETHING WRONG
;**;[3179] Change 1 line CEG 5-Nov-84
GETBYM (MSGCNT,MSGBYP,NSPMS4) ;[3179] GET FLAGS
NSPMS1: MOVE T1,MSGBLK ;GET MESSAGE ADDRESS
STOR T2,MSMFL,(T1) ;SAVE MESSAGE FLAGS
TRNE T2,CNMRFL ;IS IT A CONTROL MESSAGE?
;**;[3179] Add comment CEG 5-Nov-84
;Control message
;**;[3179] Change 1 line CEG 5-Nov-84
JRST NSPMS4 ;[3179] YES, GIVE IT TO BACKGROUND TASK
CALL GETLLA ;( ) GET LINK NUMBERS
;**;[3179] Change 1 line CEG 5-Nov-84
JRST NSPMS4 ;[3179] BAD MESSAGE
; ..
; ..
; MESSAGE PARSED - PLACE MESSAGE ON APPROPRIATE QUEUE FOR LATER HANDLING
MOVE T1,MSGDST ;GET OUR NAME
MOVE T2,MSGSRC ;GET ITS NAME
LOCK LLLLCK ;GET LL TREE LOCK
CALL LLLKUP ;(T1,T2) FIND THE LINK
IFNSK. ;COULDN'T
;**;[3179] Add comment CEG 5-Nov-84
;Logical link doesn't exist
UNLOCK LLLLCK ;GIVE UP TREE LOCK
;**;[3179] Change 1 line CEG 5-Nov-84
JRST NSPMS4 ;[3179] GIVE MSG TO BACKGROUND TASK
ENDIF.
TMNN LLDED,(T1) ;HAS DN20 CRASHED?
IFSKP.
;**;[3179] Add comment CEG 5-Nov-84
;DN20 has crashed
UNLOCK LLLLCK ;YES, GIVE BACK THE BIG LOCK
MOVE T2,MSGBLK ;GET BACK MESSAGE ADDRESS
SETONE MSSKD,(T2) ;TELL SCHEDULER TO TOSS THE NESSAGE
RETSKP ;DONE
ENDIF.
CALL BLKLOK ;(T1) GET LL LOCK
IFNSK. ;COULDN'T
;**;[3179] Add comment CEG 5-Nov-84
;Can't get interlock now, must try again later
UNLOCK LLLLCK ;GIVE UP TREE LOCK
RET
ENDIF.
UNLOCK LLLLCK ;GIVE UP TREE LOCK
LOAD T2,LLSTA,(T1) ;GET STATE OF LL
CAIE T2,LLSRUN ;RUNNING?
;**;[3179] Add comment CEG 5-Nov-84
;Logical link not in run state
;**;[3179] Remove 4 lines, add 1 line CEG 5-Nov-84
JRST NSPMS5 ;[3179] NO, GIVE MESSAGE TO BACKGROUND TASK
;**;[3179] Add comment CEG 5-Nov-84
;Logical link is in run state
MOVE T2,TODCLK ;YES, GET THE TIME
ADD T2,NSINAC ;ADD INACTIVITY TIMEOUT VALUE
MOVEM T2,LLINAC(T1) ;PUT NEW TIME IN LL BLOCK
MOVE T2,MSGBLK ;RETRIEVE ADDRESS OF MESSAGE
MOVE T3,MSGCNT ;GET REMAINING COUNT
STOR T3,MSDTC,(T2) ;SAVE RESIDUAL COUNT
MOVE T3,MSGBYP
MOVEM T3,MSBPTR(T2) ;SAVE RESIDUAL BYTE POINTER
;**;[3179] Change 1 line CEG 5-Nov-84
MOVEM T1,MSGLLB ;[3179] SAVE LL BLOCK
LOAD T4,MSMFL,(T2) ;GET MESSAGE FLAGS
; ..
; ..
TRNN T4,ACKFLM ;AN ACK?
IFSKP.
;**;[3179] Add comment CEG 5-Nov-84
;Ack message
CALL GETTWO ;(/T2) YES, GET THE ACK NUMBER
;**;[3179] Change 1 line CEG 5-Nov-84
JRST NSPMS5 ;[3179] COULDN'T
CAIE T4,ACKFLM ;A DATA ACK?
IFSKP. ;YES
MOVEI T3,MSDAT ;GET ITS INDICATOR
ELSE. ;NO, MUST BE LS/INT ACK
MOVEI T3,MSLSI ;GET ITS INDICATOR
ENDIF.
CALL ACKCHN ;(T1,T2,T3) PROCESS THE ACK
MOVE T2,MSGBLK ;RETRIEVE MESSAGE ADDRESS
SETONE MSSKD,(T2) ;SET THE RELEASE INDICATOR
;**;[3179] Change 1 line CEG 5-Nov-84
JRST NSPMS6 ;DONE
ENDIF.
TRNN T4,DATFLI ;IS IT LS OR INT MESSAGE?
IFSKP.
;**;[3179] Add comment CEG 5-Nov-84
;Link service or interrupt message
;**;[3179] Add 6 lines CEG 5-Nov-84
SKIPN RESNET ;[3179] YES, LOTS OF SPACE?
IFSKP. ;[3179]
SETONE MSSKD,(T2) ;[3179] NO, HAVE IT TOSSED
MOVE T1,MSGLLB ;[3179] RETRIEVE LL BLOCK
JRST NSPMS6 ;[3179] DONE
ENDIF. ;[3179]
CALL INTLS ;( ) YES, PROCESS IT
ELSE. ;NO, MUST BE A DATA SEGMENT
;**;[3179] Add comment CEG 5-Nov-84
;Data segment
CALL NSINBK ;(T1,T2) DO BOOKKEEPING
CALL ONRAWQ ;(T1,T2) PROCESS IT
ENDIF.
;**;[3179] Remove 1 line CEG 5-Nov-84
NSPMS6: CALL BLKULK ;(T1) UNLOCK IT
RETSKP
;**;[3179] Add comment CEG 5-Nov-84
;Message is for background task
;**;[3179] Remove 5 lines, add 9 CEG 5-Nov-84
NSPMS5: CALL BLKULK ;[3179] (T1) FREE THE LL BLOCK
NSPMS4: MOVE T2,MSGBLK ;[3179] GET MESSAGE ADDRESS
SKIPN RESNET ;[3179] LOTS OF SPACE?
IFSKP. ;[3179]
SETONE MSSKD,(T2) ;[3179] NO, HAVE IT TOSSED
ELSE. ;[3179]
CALL ONMSGQ ;[3179] (T2) YES, PUT IN ON THE TASK'S Q
ENDIF. ;[3179]
RETSKP ;[3179] FINISHED WITH MSG
;**;[3179] Remove 1 line CEG 5-Nov-84
ENDTV.
;PUT A DATA SEGMENT MESSAGE ON A LINK'S INCOMING QUEUE
;ACCEPTS: T1/ LL BLOCK ADDRESS
; T2/ MESSAGE ADDRESS
;RETURNS: +1
;**;[3179] This routine is now a combination of what used to be ONRAWQ and
;**;[3179] and VERSEG. CEG 5-Nov-84
ONRAWQ: NOSKD1 ;[3179] HOLD OFF SCHEDULER
TRVAR <MSGCNT,MSGBYP,MSGSRC,MSGDST,MSGBLK> ;[3179]
MOVE T3,MSBPTR(T2) ;[3179] GET POINTER TO DATA
MOVEM T3,MSGBYP ;[3179] TO THE POINTER
LOAD T3,MSDTC,(T2) ;[3179] GET COUNT
MOVEM T3,MSGCNT ;[3179] SAVE COUNT
MOVEM T2,MSGBLK ;[3179] SAVE MESSAGE BLOCK
CALL GETTWO ;[3179] (MSGCNT,MSGBYP/T2) GET ACKNUM
JRST ONRAW1 ;[3179] COULDN'T
TRZN T2,ACKIND ;[3179] IS THIS AN ACKNUM?
IFSKP. ;[3179]
;Piggy-backed Ack
;******************************************************************************
;The ACK must be processed before the RESNET check is made. When we're low on
;space we want to process only ACKs. When a piggy-backed ACK is found we
;process the ACK and then throw away the data segment in which it was imbedded.
;******************************************************************************
MOVEI T3,MSDAT ;[3179] YES, DATA MESSAGE
CALL ACKCHN ;[3179] (T1,T2,T3) GO HANDLE THE ACK
CALL GETTWO ;[3179] (MSGCNT,MSGBYP/T2) GET SEGNUM
JRST ONRAW1 ;[3179] COULDN'T
ENDIF. ;[3179]
LOAD T3,LLDMT,(T1) ;[3179] GET NUMBER OF SEGMENTS CURRENTLY IN INCOMING Q
AOS T3 ;[3179] ADD THE ONE WE'RE LOOKING AT
LOAD T4,LLMQI,(T1) ;[3179] GET MAXIMUM INPUT QUEUE LENGTH
CAMG T3,T4 ;[3179] WOULD THIS ONE MAKE TOO MANY?
IFSKP. ;[3179]
;The link's incoming queue is full (its quota has been reached)
LOAD T3,LLLKP,(T1) ;[3179] YES, GET NODE'S VERSION
CAIE T3,.NSP31 ;[3179] NSP 3.1?
JRST ONRAW1 ;[3179] NO, DONE
SETONE LLFNN,(T1) ;[3179] PHASE II, SAY THIS LL NEEDS A NACK
SETZRO LLFNA,(T1) ;[3179] NOT AN ACK
CALL ONSRVQ ;[3179] (T1) PUT LL ON "NEEDS SERVICE" QUEUE
JRST ONRAW1 ;[3179] DONE
ENDIF. ;[3179]
;The link has room in its queue to accept this segment
SKIPE RESNET ;[3179] LOTS OF SPACE?
; ..
; ..
;Low on free space
JRST ONRAW1 ;[3179] NO
;Lots of free space
MOVE T3,T2 ;[3179] YES, POSITION SEGMENT #
LOAD T4,LLIDN,(T1) ;[3179] GET LAST SEG RECEIVED
AOS T4 ;[3179] MAKE NEXT EXPECTED
ANDI T4,7777 ;[3179] 12 BITS ONLY (BE SURE TO CATCH WRAP AROUND)
CAMN T3,T4 ;[3179] THIS THE RIGHT ONE?
IFSKP. ;[3179]
;Out-of-order segment
CAML T3,T4 ;[3179] NO, TOO NEW?
IFSKP. ;[3179]
SETONE LLFNA,(T1) ;[3179] OLD, SAY THIS LL NEEDS AN ACK
ELSE. ;[3179]
LOAD T4,LLLKP,(T1) ;[3179] TOO NEW, GET NODE'S VERSION
CAIE T4,.NSP31 ;[3179] NSP 3.1?
JRST ONRAW1 ;[3179] NO, FORGET IT
SETONE LLFNN,(T1) ;[3179] PHASE II, SAY LL NEEDS TO NAK
SETZRO LLFNA,(T1) ;[3179] NOT AN ACK
ENDIF. ;[3179]
CALL ONSRVQ ;[3179] (T1) PUT LL ON NEEDS SERVICE QUEUE
JRST ONRAW1 ;[3179] DONE
ENDIF. ;[3179]
;The expected segment
STOR T3,LLIDN,(T1) ;[3179] YES, UPDATE SEGMENT NUMBER LL BLOCK
MOVE T2,MSGBLK ;[3179] RETRIEVE MESSAGE ADDRESS
STOR T3,MSSEG,(T2) ;[3179] SAVE SEGMENT NUMBER IN MSG HEADER
SETONE LLFNA,(T1) ;[3179] THIS LL NEEDS AN ACK
INCR LLDMT,(T1) ;[3179] SAY WE HAVE ANOTHER MESSAGE IN QUEUE
LOAD T3,LLDMT,(T1) ;[3179] GET NUMBER OF SEGMENTS ON Q
CAIN T3,1 ;[3179] WAS Q PREVIOUSLY EMPTY?
CALL DATINR ;[3179] (T1) YES, GIVE INT
MOVEI T3,LLOMSG(T1) ;[3179] THE ORDERED MESSAGE QUEUE
CALL PUTONQ ;[3179] (T2,T3) PUT ON NEW SEGMENT
CALL ONSRVQ ;[3179] (T1) PUT LL ON "NEEDS SERVICE" QUEUE
CALL CHKLLT ;[3179] (T1) CHECK FOR TTY ON THIS LL
OKSKD1 ;[3179]
RET ;[3179] AND DONE
ONRAW1: MOVE T2,MSGBLK ;[3179] GET MESSAGE ADDRESS
SETONE MSSKD,(T2) ;[3179] TELL SCHEDULER TO RELEASE THE MESSAGE
CALL DATINR ;[3179] (T1) REQUEST INT
OKSKD1 ;[3179]
RET ;[3179]
ENDTV. ;[3179]
;GIVE DATA INTERUPT
DATINR: SAVEAC <T1,T2> ;SAVE VOLATILE REGS
LOAD T2,LLFRK,(T1) ;GET FORK I.D.
OPSTR <SOSL T1,>,LLDRC,(T1) ;WANT DATA INT?
CALL PSIRQ ;YES. GIVE IT
RET ;AND DONE
;POSTING ADDRESS FOR SEGMENTS. T1= MESSAGE ADDRESS
SEGPST: JN MSRLS,(T1),RELRES ;IF "RELEASED", GO DO IT
SETZRO MSPST,(T1) ;NOT. SAY POSTED
RET ;AND DONE
;POSTING ADDRESS FOR ACKS
;ACCEPTS: T1/ MESSAGE ADDRESS
;RETURNS: +1
ACKPST::SETZM (T1) ;CLEAR
HRL T2,T1 ; OUT
HRRI T2,1(T1) ; THE
BLT T2,ACKLEN+MSHDR-1(T1) ;[3179] BLOCK
RET
;**;[3179] Remove routine VERSEG CEG 5-Nov-84
;PROCESS "LINKS THAT NEED SERVICE" QUEUE
LLSRVR: STKVAR <LLB> ;LL BLOCK ADDRESS
SKIPL LLLLCK ;LL TREE LOCK AVAILABLE?
RET ;NO
MOVE T1,LSTLLS ;GET LAST TIME LINKS WERE SERVICED
ADDI T1,^D200 ;ADD INTERVAL
CAMLE T1,TODCLK ;TIME TO DO IT AGAIN?
RET ;NO, GO AWAY
MOVE T1,TODCLK ;GET CURRENT TIME
MOVEM T1,LSTLLS ;LINKS BEING SERVICED NOW
SKIPN T1,LLSRVQ ;ANYTHING TO DO?
RET ;NO, BYE
HRRZS T1 ;GET FIRST LL BLOCK
LOCK LLLLCK ;GET LOCK ON LL TREE
LLSRV2: MOVEM T1,LLB ;STASH LL BLOCK
CALL BLKLOK ;LOCK THE LL
IFNSK. ;COULDN'T
MOVE T1,LLB ;RETRIEVE LL BLOCK
JRST LLSRV3
ENDIF.
TMNN <LLFNN,LLFNA>,(T1) ;THIS LINK NEED A DATA ACK OR NACK?
IFSKP. ;YES
CALL ACKNSP ;SEND IT
JRST LLSRV6 ;COULDN'T
ENDIF.
TMNN <LLNLS,LLALS>,(T1) ;THIS LINK NEED A LS ACK OR NACK?
JRST LLSRV4 ;NO
CALL ACKLI ;YES, SEND IT
IFNSK. ;COULDN'T
LLSRV6: MOVE T1,LLB ;RETRIEVE LL BLOCK ADDRESS
JRST LLSRV5 ;MOVE ON
ENDIF.
LLSRV4: CALL UNQSRV ;REMOVE LL FROM Q
LLSRV5: CALL BLKULK ;UNLOCK LL
LLSRV3: LOAD T1,LLNSR,(T1) ;GET NEXT LL
SKIPE T1 ;ANY MORE?
JRST LLSRV2 ;YES
UNLOCK LLLLCK ;GIVE UP LL TREE LOCK
RET ;ALL DONE
ENDSV.
;ROUTINE TO PUT AN LL BLOCK ON THE "NEEDS SERVICE" LIST
;ACCEPTS: T1/ LL BLOCK ADDRESS
;RETURNS: +1 ALWAYS
;PRESERVES T1,T2,T3
ONSRVQ: NOSKED ;DON'T LET THE SCHEDULER RUN
TMNE LLISR,(T1) ;ALREADY ON QUEUE?
JRST ONSRV1 ;YES, NOTHING TO DO
SAVEAC <T2,T3>
SETONE LLISR,(T1) ;NO, SAY NOW IN QUEUE
SKIPE T2,LLSRVQ ;QUEUE CURRENTLY EMPTY?
IFSKP. ;YES
HRRM T1,LLSRVQ ;MAKE QUEUE HEAD POINT TO US
HRLM T1,LLSRVQ ;MAKE QUEUE TAIL POINT TO US
SETZRO <LLPSR,LLNSR>,(T1) ;CLEAR ALL POINTERS
JRST ONSRV1 ;DONE
ENDIF.
HLRZ T3,T2 ;NO, GET LAST QUEUE ENTRY
STOR T3,LLPSR,(T1) ;MAKE IT PREVIOUS TO US
SETZRO LLNSR,(T1) ;WE ARE AT THE END
STOR T1,LLNSR,(T3) ;MAKE IT POINT AHEAD TO US
HRLM T1,LLSRVQ ;MAKE US TAIL OF QUEUE
ONSRV1: OKSKED ;ALLOW SCHEDULER TO RUN AGAIN
RET
;ROUTINE TO REMOVE AN LL FROM THE "NEEDS SERVICE" QUEUE
;ACCEPTS: 1/ LL BLOCK ADDRESS
;RETURNS: +1 ALWAYS
;PRESRVES T1,T2,T3
UNQSRV: NOSKED ;DON'T LET SCHEDULER RUN
TMNN LLISR,(T1) ;NOW IN QUEUE?
JRST UNQSR1 ;NO, NOTHING TO DO
SAVEAC <T1,T2,T3>
SETZRO LLISR,(T1) ;YES, SAY NO LONGER IN QUEUE
LOAD T2,LLPSR,(T1) ;GET PREVIOUS LL
SKIPE T2 ;ARE WE THE FIRST?
IFSKP. ;YES
LOAD T3,LLNSR,(T1) ;GET NEXT LL
SKIPE T3 ;ARE WE LAST?
IFSKP. ;YES
SETZM LLSRVQ ;RESET QUEUE HEADER
JRST UNQSR1 ;DONE
ENDIF.
SETZRO LLPSR,(T3) ;NO, MAKE NEXT FIRST
HRRM T3,LLSRVQ ;MAKE Q HEADER POINT TO NEXT
JRST UNQSR1 ;DONE
ENDIF.
LOAD T3,LLNSR,(T1) ;GET NEXT LL
SKIPE T3 ;ARE WE LAST?
IFSKP. ;YES
SETZRO LLNSR,(T2) ;MAKE PREVIOUS LAST
HRLM T2,LLSRVQ ;MAKE Q HEADER POINT TO PREVIOUS
JRST UNQSR1 ;DONE
ENDIF.
STOR T3,LLNSR,(T2) ;MAKE PREVIOUS POINT AHEAD TO NEXT
STOR T2,LLPSR,(T3) ;MAKE NEXT POINT BACK TO PREVIOUS
UNQSR1: OKSKED ;ALLOW SCHEDULER TO RUN AGAIN
RET ;DONE
;ROUTINE TO SEND ANY DATA SEGMENT ACK'S NEEDED
;ACCEPTS: T1/ ADDRESS OF LOGICAL LINK BLOCK
;RETURNS: +1 FAILED, COULD NOT SEND THE ACK
; +2 SUCCESS
ACKNSP: STKVAR <SQASEG>
LOAD T2,LLIDN,(T1) ;GET LAST SEGMENT RECEIVED
MOVEM T2,SQASEG ;STASH SEG NUMBER
MOVEI T3,MSDAT ;ON THE DATA CHANNEL
TMNN LLFNA,(T1) ;NEED AN ACK?
TXO T2,ACKBIT ;NO, TURN ON THE NACK BIT
CALL SNDACK ;SEND IT
RET ;COULDN'T
MOVE T2,SQASEG ;RETRIEVE SEG NUMBER
STOR T2,LLLAK,(T1) ;SAY IT HAS BEEN ACKED
SETZRO <LLFNA,LLFNN>,(T1) ;CLEAR ACK FLAGS
RETSKP ;DONE, RETURN SUCCESS
ENDSV.
;TEMPORARY DUMMY ENTRY POINT FOR TTYSRV
SQIACK::RETSKP
SUBTTL The NODE JSYS
SWAPCD ;IS SWAPPABLE
.NODE:: MCENT ;MONITOR CONTEXT ENTRY
; VALIDATE FUNCTION CODE AND DISPATCH TO PROCESSING ROUTINE
UMOVE T1,1 ;GET FUNCTION CODE FROM USER
CAIL T1,0 ;FUNCTION CODE WITHIN
CAIL T1,NDTLEN ; VALID RANGE ?
ITERR (ARGX02) ;NO, RETURN "INVALID FUNCTION" ERROR
MOVE T4,NODTAB(T1) ;GET ADDRESS OF PROCESSING ROUTINE
CALL (T4) ;DISPATCH TO PROPER ROUTINE
ITERR () ;FAILED, RETURN ERROR CODE
MRETNG ;SUCCESS, DONE.
; TABLE OF NODE JSYS FUNCTIONS
NODTAB: EXP NDSLN ;(0) SET LOCAL NODE NAME
EXP NDGLN ;(1) GET LOCAL NODE NAME
EXP NDSNM ;(2) SET LOCAL NODE NUMBER
EXP NDGNM ;(3) GET LOCAL NODE NUMBER
EXP NDSLP ;(4) SET LOOPBACK PORT
EXP NDCLP ;(5) CLEAR LOOPBACK PORT
EXP NDFLP ;(6) FIND LOOPBACK PORT
EXP NDSNT ;(7) SET NETWORK TOPOLOGY INFO
EXP NDGNT ;(10) GET NETWORK TOPOLOGY INFO
EXP NDSIC ;(11) SET ITERRUPT CHANNEL FOR TOPOLOGY CHANGE
EXP NDCIC ;(12) CLEAR ITERRUPT CHANNEL FOR TOPOLOGY CHANGE
EXP NDGVR ;(13) GET NSP VERSION INFORMATION
EXP NDGLI ;(14) GET LINE INFORMATION
EXP NDVFY ;(15) VERIFY NODE NAME
EXP NDRNM ;(16) RETURN A NODE NAME
NDTLEN==.-NODTAB
;NDSLN - ROUTINE TO SET THE LOCAL NODE NAME
NDSLN: STKVAR <<NODNAM,WPN>>
MOVE T1,CAPENB ;GET CURRENTLY ENABLED CAPABILITIES
TXNN T1,SC%WHL!SC%OPR ;WHEEL OR OPERATOR CAPABILITY REQUIRED
RETBAD (CAPX1) ;NOT ENOUGH CAPABILITY, RETURN ERROR
; COPY THE NODE NAME STRING FROM THE USER ADDRESS SPACE
UMOVE T2,2 ;GET ADDRESS OF USER'S ARGUMENT BLOCK
UMOVE T1,.NDNOD(T2) ;GET POINTER TO STRING IN USER SPACE
MOVEI T2,NODNAM ;WE'LL WRITE PARSED NAME TO "NODNAM"
CALL PARNDU ;MAKE SURE NODE NAME IS KOSHER
RETBAD ;FAILED, TELL CALLER WHY
MOVEM B,OURCNT ;REMEMBER LENGTH OF NAME
DMOVE T1,NODNAM ;GET NODE NAME *** DMOVE IS CHEATING BECAUSE IT ASSUMES WPN=2!
DMOVEM T1,OURNAM ;STORE FOR NSP
;NOW FIX THE NODE NAME MAPPING TABLE
MOVE T2,[MOVSO -40] ;SET UP OPERATOR
MOVEM T2,P3 ; FOR EXTEND
MOVE Q3,OURNUM ;GET OUR NODE NUMBER
NOINT
LOCK NMAPLK ;LOCK THE NODE MAPPING TABLE
SETZM NODMAP(Q3) ;NULLIFY THE CURRENT NODE NAME
MOVE T1,OURCNT ;GET CHAR. COUNT OF NEW NAME
MOVE T2,[440700,,OURNAM] ;BYTE POINTER TO NEW NAME
SETZB T3,Q2 ;SINGLE WORD BYTE POINTERS
MOVE T4,OURCNT ;GET CHAR. COUNT OF NEW NAME
HRLI Q1,440600 ;BYTE POINTER TO NEW
HRRI Q1,NODMAP(Q3) ; NAME'S DESTINATION
EXTEND T1,P3 ;MOVE THE NEW NAME
JFCL
UNLOCK NMAPLK ;UNLOCK THE NODE MAPPING TABLE
OKINT
RETSKP ;SUCCESS RETURN
ENDSV.
;NDGLN - RETURN LOCAL NODE NAME
NDGLN: UMOVE T2,2 ;GET ADDRESS OF USER'S ARGUMENT BLOCK
UMOVE T1,.NDNOD(T2) ;GET BYTE POINTER TO DEPOSIT NODE NAME
MOVE T3,T2 ;KEEP 30-BIT ADDRESS IN T3 FOR RETURNING
; UPDATED BYTE POINTER TO USER
HRROI T2,OURNAM-1 ;GET POINTER TO SOURCE STRING
CALL CPYTU1 ;COPY STRING TO USER SPACE, RETURN POINTER
RETSKP ;DONE, RETURN SUCCESS
;SET LOCAL NODE NUMBER
NDSNM: MOVE T1,CAPENB ;GET CURRENTLY ENABLED CAPABILITIES
TXNN T1,SC%WHL!SC%OPR ;WHEEL OR OPERATOR CAPABILITY REQUIRED
RETBAD (CAPX1) ;NOT ENOUGH CAPABILITY, RETURN ERROR
UMOVE T2,2
UMOVE T2,0(T2) ;GET NUMBER
CAIL T2,1
CAILE T2,BIGNOD ;WITHIN RANGE?
RETBAD (NSPX25) ;NO
MOVE T4,OURNUM ;SAVE THE CURRENT NUMBER
MOVEM T2,OURNUM ;SET THE NEW NODE NUMBER
;NOW FIX THE NODE NAME MAPPING TABLE
MOVE T1,T4 ;RETRIEVE THE CURRENT NUMBER
NOINT
LOCK NMAPLK ;LOCK THE NODE MAPPING TABLE
MOVE T3,NODMAP(T1) ;GET THE CURRENT NODE NAME
SETZM NODMAP(T1) ;NULLIFY IT
MOVEM T3,NODMAP(T2) ;MOVE NAME TO NEW NODE ADDRESS
UNLOCK NMAPLK ;UNLOCK THE NODE MAPPING TABLE
;NOW FIX THE REACHABLE NODES TABLE
LOCK NODLOK ;LOCK THE REACHABLE NODES TABLE
MOVE T3,[POINT 2,NODTBL] ;MAKE BYTE POINTER TO THE TABLE
ADJBP T1,T3 ;POINT TO THE CURRENT
SETZ T4, ; AND
DPB T4,T1 ; SAY NO LONGER REACHABLE
ADJBP T2,T3 ;POINT TO THE NEW
MOVEI T4,2 ;WE ARE PHASE II
DPB T4,T2 ;SAY THE NEW IS REACHABLE
UNLOCK NODLOK ;UNLOCK THE REACHABLE NODES TABLE
OKINT
RETSKP
;GET LOCAL NODE NUMBER
NDGNM: UMOVE T2,2
MOVE T3,OURNUM
UMOVEM T3,0(T2) ;STORE NUMBER
RETSKP ;DONE
;SET LOOPBACK PORT
NDSLP: MOVE T1,CAPENB ;GET CURRENTLY ENABLED CAPABILITIES
TXNN T1,SC%WHL!SC%OPR!SC%MNT ;WHEEL OPERATOR OR MAINTENANCE CAPABILITY REQUIRED
RETBAD (CAPX2) ;WHEEL, OPERATOR, or MAINTENANCE capability required
UMOVE T2,2 ;GET ADDRESS OF USERS ARGUMENT BLOCK
UMOVE T3,.NDPRT(T2) ;GET PORT WANTS TO SET IN LOOPBACK
SKIPE T2,NSPLPB ;IS ANOTHER PORT ALREADY ASSIGNED ?
JRST [ CAIE T3,(T2) ;IS IT SAME PORT ?
RETBAD (NODX03) ;Another line already looped
RETSKP ] ;ALL DONE
MOVEI T1,.BTSTS ;WANT TO GET PORT STATUS
MOVEI T2,T3 ;ADDRESS OF ARGUMENT BLOCK
BOOT ;GET ARGUMENT STATUS
ERJMP [RETBAD (ARGX19)] ;Invalid unit number
CAME T4,[EXP -1] ;IS PORT TURNED OFF
RETBAD (NODX02) ;Line not turned off
HRLI T3,(ND%LPA) ;HAVE A PORT FOR LOOPBACK NOW
MOVEM T3,NSPLPB ;REMEMBER WHICH PORT WILL BE LOOPED
RETSKP
;CLEAR LOOPBACK PORT
NDCLP: MOVE T1,CAPENB ;GET CURRENTLY ENABLED CAPABILITIES
TXNN T1,SC%WHL!SC%OPR!SC%MNT ;WHEEL OPERATOR OR MAINTENANCE CAPABILITY REQUIRED
RETBAD (CAPX2) ;WHEEL, OPERATOR, or MAINTENANCE capability required
SKIPN T1,NSPLPB ;GET LOOPBACK PORT NUMBER
RETSKP ;NONE SO DONE
UMOVE T2,2 ;GET ADDRESS OF USERS ARGUMENT BLOCK
UMOVE T3,.NDPRT(T2) ;GET PORT TO CLEAR LOOPBACK
CAIE T3,(T1) ;SAME PORT AS IS LOOPED BACK ?
RETBAD (ARGX19) ;Invalid unit number
MOVEI T1,.BTTPR ;TERMINATE PROTOCOL
MOVEI T2,T3 ;ADDRESS OF ARGUMENT BLOCK
BOOT ;DISABLE LINE
ERJMP .+1 ;CAN'T TURN OFF ?
SETZM NSPLPB ;NOTHING IS LOOPED BACK NOW
RETSKP
;FIND LOOPBACK PORT
NDFLP: UMOVE T2,2 ;GET ADR OF USERS ARGUMENT BLOCK
MOVE T1,NSPLPB ;GET LOOPED BACK LINE
UMOVEM T1,.NDPRT(T2) ;GIVE ANSWER TO USER
RETSKP
; SET NETWORK TOPOLOGY INFO
NDSNT: STKVAR <NEWTOP,NODES,TMPTOP,USRMSK>
MOVE T1,CAPENB ;GET CURRENTLY ENABLED CAPABILITIES
TXNN T1,SC%WHL!SC%OPR ;WHEEL, OPERATOR CAPABILITY REQUIRED
RETBAD (CAPX1) ;WHEEL OR OPERATOR capability required
UMOVE T2,2 ;GET ADDR OF USER'S ARGUMENT BLOCK
UMOVE T1,.NDNNO(T2) ;GET THE NUMBER OF NODES
CAILE T1,BIGNOD ;CAN WE HANDLE THIS MANY NODES?
RETBAD (NSPX25) ;NO, FAIL
MOVEM T1,NODES ;SAVE THE NUMBER OF NODES BEING REPORTED
UMOVE T1,.NDMSK(T2) ;GET USER'S ADDRESS OF TOPOLOGY MESSAGE
MOVEM T1,USRMSK ;SAVE IT
NOINT ;NO INTERRUPTIONS WHILE GETTING SPACE
MOVEI T1,<BIGNOD+17>/20 ;ENOUGH WORDS FOR TOPOLOGY MESSAGE
CALL GETBLK ;GET SWAPPABLE FREE SPACE
RETBAD (MONX06,<OKINT>) ;ERROR - "NO MORE SWAPPABLE FREE SPACE"
MOVEM T1,TMPTOP ;SAVE THE ADDRESS
MOVEI T1,<BIGNOD+21>/22 ;ENOUGH WORDS FOR TOPOLOGY BIT MASK
CALL GETBLK ;GET SWAPPABLE FREE SPACE
JRST [ MOVE T1,TMPTOP ;GET ADDR
CALL RELBLK ;RELEASE THE SPACE
RETBAD (MONX06,<OKINT>)] ;ERROR - NO MORE SPACE
MOVEM T1,NEWTOP ;SAVE THE ADDR
MOVE T3,TMPTOP ;GET DESTINATION IN CORRECT AC FOR BLT
MOVE T1,NODES ;GET NUMBER OF NODES
ADDI T1,17 ;CALC NUMBER OF
IDIVI T1,20 ; WORDS TO BLT
MOVE T2,USRMSK ;RETRIEVE USER'S ADDRESS
CALL BLTUM1 ;GET USER'S NEW TOPOLOGY BIT MASK
MOVE T1,NODES ;GET NUMBER OF NODES
ADDI T1,3 ;CALC NUMBER OF
IDIVI T1,4 ; 8-BIT BYTES
MOVE T2,TMPTOP ;GET ADDR OF COPIED MESSAGE
HRLI T2,441000 ;MAKE A BP
MOVE T3,NEWTOP ;GET ADDR FOR BIT MASK
HRLI T3,440200 ;MAKE A BP
NDXLT: ILDB T4,T2 ;GET A BYTE FROM THE MESSAGE
MOVEI Q1,4 ;NUMBER OF NODES REPRESENTED IN A MESSAGE BYTE
NDXLT1: IDPB T4,T3 ;MAKE ENTRY IN BIT MASK
SOJLE Q1,NDXLT2 ;ANY MORE IN THIS BYTE?
LSH T4,-2 ;YES
JRST NDXLT1 ;CONTINUE
NDXLT2: SOJG T1,NDXLT ;ANY MORE BYTES IN MESSAGE?
LOCK NODLOK ;LOCK THE REACHABLE NODES TABLE
IFN DN20SW,< ;CHECK FOR OTHER MCBS
MOVEI T4,2 ;NEXT DTE TO CHECK
NDXLT4: SKIPL MCBDTE(T4) ;IS IT UP?
JRST NDXLT3 ;NO
MOVE T2,NEWTOP ;MAKE BP
HRLI T2,440200 ; TO NEW TOPOLOGY
MOVE T1,ITSNUM(T4) ;GET ITS NODE NUMBER
ADJBP T1,T2 ;POINT TO ITS ENTRY IN REACH TABLE
MOVEI T3,3 ;IT'S PHASE 3
DPB T3,T1 ;PUT IT IN
NDXLT3: CAIGE T4,3 ;CHEKCED ALL DTES YET?
IFNSK. ;NO
AOS T4 ;MAKE NEXT DTE
JRST NDXLT4 ;TRY IT
ENDIF.
>
MOVE T1,NEWTOP ;GET THE ADDRESS
HRLI T1,440200 ;MAKE A BYTE POINTER
MOVE T2,[POINT 2,NODTBL] ;BYTE POINTER TO EXISTING TOPOLOGY
MOVE T3,NODES ;NUMBER OF BYTES TO COMPARE
SETZ T4, ;NO OFFSET DURING COMPARISON
CALL COMPAR ;HAS TOPOLOGY CHANGED?
SKIPA ;YES
JRST NDSNTR ;NO, THEN NOTHING TO DO
MOVE T1,NEWTOP ;RETRIEVE ADDRESS OF NEW TOPOLOGY
MOVE T2,NODES ;GET NUMBER OF NODES
ADDI T2,21 ;CALC NUMBER OF
IDIVI T2,22 ; WORDS TO SEARCH
MOVNS T2 ;MAKE
HRLZS T2 ; AOBJN WORD
NDSNTL: MOVE T3,(T1) ;GET A WORD FROM NEW TOPOLOGY
MOVEM T3,NODTBL(T2) ;MOVE IT TO REACHABLE NODES TABLE
AOS T1 ;INCR SOURCE POINTER
AOBJN T2,NDSNTL ;DO THEM ALL
CALL ADDTEL ;INFORM INTERESTED USERS OF NEW TOPOLOGY
JFCL ;NO SUCH RETURN
NDSNTR: MOVE T1,TMPTOP ;GET ADDR
CALL RELBLK ;RELEASE THE SPACE
MOVE T1,NEWTOP ;GET ADDR
CALL RELBLK ;RELEASE THE SPACE
UNLOCK NODLOK ;DONE WITH THE LOCK
OKINT ;
RETSKP ;EVERYTHING OK
ENDSV.
; SET INTERRUPT CHANNEL FOR NETWORK TOPOLOGY CHANGE
NDSIC: UMOVE T3,T2 ;GET USER BLOCK ADDRESS
XCTU [ MOVEI T1,.NDCHN(T3)] ;POINT TO CHANNEL NUMBER WORD
UMOVE T1,(T1) ;GET THE CHANNEL NUMBER
SKIPGE T1 ;VALIDATE CHANNEL NUMBER
RETBAD (ARGX13) ;NEGATIVE CHANNEL NUMBERS ARE ILLEGAL
CAILE T1,^D35 ;CHANNEL NUMBER TOO HIGH
RETBAD (ARGX13) ;NEGATIVE CHANNEL NUMBERS ARE ILLEGAL
CAIL T1,.ICAOV ;SKIP IF GOOD NUMBER
CAILE T1,.ICNXP ;SKIP IF BAD NUMBER
JRST CHANOK ;CHANNEL NUMBER OK.
RETBAD (ARGX13) ;BAD CHANNEL NUMBER
CHANOK: SETZ T4, ;T4 WILL HOLD ADDRESS OF FREE ENTRY
MOVEI T2,NTCTAB ;POINT TO TOP OF TABLE OF WAITING FORKS
;HERE TO DETERMINE IF FORK ALREADY HAS SET THE INTERRUPT ONCE
CHNOK1: SKIPN (T2) ;SKIP IF ENTRY IS BEING USED
JRST [ MOVE T4,T2 ;SAVE FOR FORK NOT CURRENTLY ACTIVATED
JRST CHNOK2] ;TRY NEXT ENTRY
LOAD T3,NTCFRK,(T2) ;GET THE FORK NUMBER
CAMN T3,FORKX ;DOES THIS ENTRY BELONG TO THIS FORK
JRST [ STOR T1,NTCCHN,(T2) ;YES. PUT NEW CHANNEL NUMBER IN
RETSKP]
CHNOK2: CAIE T2,NTCTAB+<NTCMAX-1> ;HAVE WE LOOKED AT WHOLE TABLE
AOJA T2,CHNOK1 ;NO - KEEP LOOKING
SKIPN T4 ;DID WE FIND AN ENTRY?
RETBAD (NSPX26) ;ERROR - TABLE OF TOPOLOGY WATCHERS IS FULL
STOR T1,NTCCHN,(T4) ;SAVE THE CHANNEL NUMBER
MOVE T1,FORKX ;NOW GET THE FORK NUMBER
STOR T1,NTCFRK,(T4) ;AND SAVE
SETONE FKNTC,(T1) ;FLAG IN FORK DATA BASE
RETSKP
;NDCIC - CLEAR INTERRUPT CHANNEL FOR NETWORK TOPOLOGY CHANGE
NDCIC:
NTCOFF::MOVEI T1,NTCTAB ;FIND THE FORK'S ENTRY
NDCIC1: LOAD T2,NTCFRK,(T1) ;GET THE FORK NUMBER FOR THIS ENTRY
CAMN T2,FORKX ;THIS FORKS ENTRY
JRST [ SETZM (T1) ;CLEAR ENTRY
MOVE T1,FORKX ;GET FORK INDEX
SETZRO FKNTC,(T1) ;CLEAR THE ITEM IN FORK DATA BASE
RETSKP]
CAIE T1,NTCTAB+<NTCMAX-1> ;AT END OF TABLE
AOJA T1,NDCIC1 ;NO - KEEP LOOKING
RETSKP ;INDICATE SUCCESS EVEN WHEN NEVER SET
;NDGVR - GET NSP VERSION INVORMATION
NDGVR: UMOVE T3,T2 ;GET THE USER BLOCK POINTER
MOVX T2,2 ;GET NUMBER OF VERSIONS TO RETURN
UMOVEM T2,.NDNVR(T3) ;STORE IN USER ARGUMENT BLOCK
UMOVE T1,.NDCVR(T3) ;GET THE ADDRESS OF THE COMMUNICATION BLOCK
MOVEI T2,COMVER ;COMMUNICATION VERSION NUMBER
UMOVEM T2,.NDVER(T1) ;SAVE IN USER SPACE
MOVEI T2,COMECO ;COMMUNICATION ECO
UMOVEM T2,.NDECO(T1) ;SAVE IN USER SPACE
MOVEI T2,COMCST ;GET THE CUSTOMER CHANGE NUMBER
UMOVEM T2,.NDCST(T1) ;SAVE IN USER SPACE
;NOW GIVE USER THE ROUTING VERSION INFORMATION
UMOVE T1,.NDRVR(T3) ;GET THE ADDRESS OF THE ROUTING BLOCK
MOVEI T2,ROUVER ;ROUTING VERSION NUMBER
UMOVEM T2,.NDVER(T1) ;SAVE IN USER SPACE
MOVEI T2,ROUECO ;ROUTING ECO
UMOVEM T2,.NDECO(T1) ;SAVE IN USER SPACE
MOVEI T2,ROUCST ;GET THE CUSTOMER CHANGE NUMBER
UMOVEM T2,.NDCST(T1) ;SAVE IN USER SPACE
RETSKP ;RETURN
; GET NETWORK TOPOPLOGY INFORMATION
NDGNT: TRVAR <GNTBLK,GNTRET,GNTCNT,GNTPTR,PTRAOB>
; SET UP TO LOOP OVER EACH NODE
UMOVE T4,2 ;GET ADDRESS OF USER'S ARGUMENT BLOCK
MOVEM T4,GNTBLK ;SAVE ADDRESS OF USER'S ARG BLOCK
UMOVE T1,.NDNND(T4) ;GET NUMBER OF WORDS IN BLOCK
ADD T1,T4 ;COMPUTE LAST ADDRESS TO USE
MOVEM T1,GNTCNT ;SAVE LAST ADDRESS IN USER SPACE TO STORE INTO
MOVEI Q1,.NDBK1(T4) ;SET UP ADDRESS OF NEXT POINTER TO USE
SETZ T2, ;INIT THE "NUMBER OF NODES FOUND" COUNTER
MOVNI T1,BIGNOD ;MAKE
MOVSS T1 ; AOBJN
HRRI T1,1 ; WORD
MOVE T3,[POINT 2,NODTBL] ;BYTE POINTER TO REACH TABLE
NOINT ;NO INTERRUPTIONS
LOCK NMAPLK ; WHILE
LOCK NODLOK ; TABLES LOCKED
NDGN02: ILDB Q2,T3 ;GET INFO
SKIPE Q2 ;REACHABLE?
AOS T2 ;YES. COUNT IT
AOBJN T1,NDGN02 ;GET NEXT NODE INFO
;end of list
IFE. T2 ;IF NONE REACHABLE, DONE
UNLOCK NODLOK ;UNLOCK
UNLOCK NMAPLK ; TABLES
OKINT ;ALLOW INTERRUPTS
RETSKP ;DONE.
ENDIF.
;REACHABLE NODES HAVE BEEN COUNTED
MOVE Q2,Q1 ;COPY STARTING ADDRESS OF NODE BLOCK POINTERS
ADD Q2,T2 ;COMPUTE STARTING ADDRESS OF NODE BLOCK AREA
CAMLE Q2,GNTCNT ;ENOUGH ROOM FOR ALL THE NODE BLOCK POINTERS ?
IFNSK. <
MOVX T1,ARGX04 ;GET "ARG BLOCK TOO SMALL"
JRST NDGNXX> ;FAIL
MOVX T1,.NDNBS ;GET SIZE OF A NODE BLOCK
UMOVEM T1,.NDCNT(T4) ;STORE IN USER ARG BLOCK
;LOOP OVER EACH NODE
SETZM GNTRET ;INIT THE "NUMBER RETURNED"
MOVNI T2,BIGNOD ;MAKE
MOVSS T2 ; AOBJN
HRRI T2,1 ; WORD (node number in LH)
MOVE T1,[POINT 2,NODTBL] ;BYTE POINTER TO REACH TABLE
MOVEM T1,GNTPTR ;SAVE POINTER
NDGN10: ILDB Q3,GNTPTR ;GET INFO
SKIPN Q3 ;REACHABLE ?
JRST NDGN20 ;NO.
HRRZ Q3,T2 ;YES. GET NODE NUMBER
SKIPN NODMAP(Q3) ;DOES THIS NODE HAVE A NAME?
JRST NDGN20 ;NO, DON'T RETURN ANYTHING TO USER
UMOVEM Q2,(Q1) ;STORE POINTER TO NODE BLOCK
ERJMP NDGNXX ;FAILED, CLEAN UP AND RETURN ERROR
MOVEI T1,.NDNBS(Q2) ;COMPUTE ADDRESS AFTER THIS NODE BLOCK
CAML T1,GNTCNT ;ENOUGH ROOM FOR THIS NODE BLOCK AND NAME ?
IFNSK. <
MOVX T1,ARGX04 ;NO, GET "ARG BLOCK TOO SMALL"
JRST NDGNXX> ;GO CLEAN UP AND FAIL RETURN
MOVX T1,.NDSON ;GET NODE STATE ("ON" IF IN KNOWN NODE TABLE)
UMOVEM T1,.NDSTA(Q2) ;STORE STATE IN NODE BLOCK IN USER SPACE
HRRI T3,.NDNBS(Q2) ;GET ADDRESS WHERE NAME WILL GO
HRLI T3,(POINT 7,) ;FORM POINTER TO NODE NAME DESTINATION
UMOVEM T3,.NDNAM(Q2) ;STORE POINTER TO NODE NAME IN USER SPACE
MOVEI T1,NODMAP(Q3) ;GET ADDRESS OF NODE NAME
HRLI T1,440600 ;MAKE A BYTE POINTER TO THE SOURCE STRING
MOVEM T2,PTRAOB ;SAVE AOBJN WORD (NUMBER OF NODES NOT YET PROCESSED IN RH)
MOVEI T2,40 ;CONVERT SIXBIT ASCII TO 7-BIT ASCII
MOVEI T4,6 ;MAX OF 6 CHARACTERS TO BE MOVED
CALL STONOD ;STORE NODE NAME STRING IN USER SPACE
JRST NDGNXX ;FAILURE.
MOVE T2,PTRAOB ;RETRIEVE THE AOBJN WORD
ADDI Q1,1 ;INCREMENT ADDRESS OF NEXT NODE BLOCK POINTER
HRRI Q2,1(T3) ;GET ADDRESS OF NEXT NODE BLOCK
AOS GNTRET ;INCR THE "NUMBER RETURNED"
NDGN20: AOBJN T2,NDGN10 ;LOOP OVER EACH NODE
; HERE WHEN ALL INFO RETURNED TO USER SUCCESSFULLY
CALL NDGNRE ;FINISH UP
RETSKP ;DONE, RETURN SUCCESS
; HERE ON AN ERROR
NDGNXX: CALLRET NDGNRE ;FINISH UP WITH FAILURE RETURN
;RETURN NUMBER OF NODES REPORTED AND CLEAN UP LOCKS
;RETURNS: +1
NDGNRE: MOVE T1,GNTRET ;GET NUMBER OF BLOCKS RETURNED
MOVE T2,GNTBLK ;GET ADDR OF USER'S ARG BLOCK
XCTU [HRLM T1,.NDNND(T2)] ;RETURN THE INFO
UNLOCK NODLOK ;UNLOCK REACH TABLE
UNLOCK NMAPLK ;UNLOCK THE MAPPING TABLE
OKINT ;PERMIT INTERRUPTS AGAIN
RET
ENDTV. ;end TRVAR
; GET LINE INFORMATION INFORMATION
NDGLI: STKVAR <LITCNT>
; SET UP TO LOOP OVER EACH NODE
XCTU [HRRZ T2,2] ;GET ADDRESS OF USER'S ARGUMENT BLOCK
XCTU [HRRZ T1,.NDNLN(T2)] ;GET NUMBER OF WORDS IN BLOCK
ADD T1,T2 ;COMPUTE LAST ADDRESS TO USE
MOVEM T1,LITCNT ;SAVE LAST ADDRESS IN USER SPACE TO STORE INTO
MOVEI Q1,.NDNLN+1(T2) ;SET UP ADDRESS OF NEXT POINTER TO USE
MOVEI T3,DCN ;GET MAXIMUM NUMBER OF POSSIBLE LINES
JUMPE T3,[SETZM T4 ;IF NO INFO, RETURN 0
JRST NDLI40 ] ; IN THE USER ARGUMENT BLOCK
UMOVE T4,2 ;GET ADDRESS OF USER'S ARGUMENT BLOCK
XCTU [HRLM T3,.NDNLN(T4)] ;STORE COUNT OF ITEMS RETURNED
MOVE Q2,Q1 ;COPY STARTING ADDRESS OF LINE BLOCK POINTERS
ADD Q2,T3 ;COMPUTE STARTING ADDRESS OF LINE BLOCK AREA
CAMLE Q2,LITCNT ;ENOUGH ROOM FOR ALL THE LINE BLOCK POINTERS ?
RETBAD (ARGX04) ;NO, FAIL
MOVN Q3,T3 ;COMPUTE -NUMBER OF LINES
HRLZ Q3,Q3 ;FORM AOBJN POINTER TO LINE TABLE
; LOOP OVER EACH KNOWN LINE
NDLI10: UMOVEM Q2,(Q1) ;STORE POINTER TO LINE BLOCK
MOVEI T1,.NDLSZ+2(Q2) ;COMPUTE ADDRESS AFTER THIS LINE BLOCK
CAMLE T1,LITCNT ;ENOUGH ROOM FOR THIS LINE BLOCK AND NAME ?
RETBAD(ARGX04) ;NO, FAIL
MOVEI T1,.BTSTS ;USE BOOT JSYS TO GET STATUS OF LINE
MOVEI T2,3 ;HAVE IT PUT DATA IN AC'S
HRRZ T3,Q3 ;GET LINE NUMBER
UMOVEM T3,.NDLNM(Q2) ;SAVE THE PORT NUMBER
BOOT
ERJMP [ MOVE T1,LSTERR ;GET THE LAST ERROR MESSAGE
RETBAD()]
MOVEI T3,.NDLON ;TRANSLATE BOOT CODE TO NODE JSYS CODE
CAIE T4,.VNMCB ;IS IT RUNNING MCB
CAIN T4,.VNDDC ;NO - IS IT RUNNING DDCMP
JRST NDLI11 ;YES - THEN IT IS ON
MOVEI T3,.NDLCN ;IS IT CONTROLLER LOOPBACK?
CAIN T4,.VNCNL ;???
JRST NDLI11 ;YES
MOVEI T3,.NDLCB ;CABLE LOOPBACK?
CAIN T4,.VNCBL ;??
JRST NDLI11 ;YES
MOVEI T3,.NDLOF ;SEE IF IT'S OFF
NDLI11: UMOVEM T3,.NDLST(Q2) ;STORE STATE IN LINE BLOCK IN USER SPACE
HRRI T3,.NDLSZ(Q2) ;GET ADDRESS WHERE NAME WILL GO
HRLI T3,(POINT 7,) ;FORM POINTER TO LINE NAME DESTINATION
UMOVEM T3,.NDLND(Q2) ;STORE POINTER TO LINE NAME IN USER SPACE
HRRZ T1,Q3 ;ITSNAM INDEX IS TWICE THE LINE NUMBER
LSH T1,1
HRRI T1,ITSNAM(T1) ;GET ADDRESS OF LINE NAME STRING
HRLI T1,(POINT 7,) ;FORM POINTER TO LINE NAME
SETZB T2,T4 ;NO OFFSET, STRING ENDS WITH A NULL
CALL STONOD ;STORE LINE NAME STRING IN USER SPACE
JRST NDLI40 ;FAILED
ADDI Q1,1 ;INCREMENT ADDRESS OF NEXT LINE BLOCK POINTER
HRRI Q2,1(T3) ;GET ADDRESS OF NEXT LINE BLOCK
AOBJN Q3,NDLI10 ;LOOP OVER EACH LINE NAME TO BE RETURNED
; HERE WHEN ALL INFO RETURNED TO USER
NDLI40: RETSKP ;DONE, RETURN SUCCESS
ENDSV.
;STONOD - ROUTINE TO STORE NODE NAME STRING IN USER SPACE
;
;ACCEPTS IN T1/ BYTE POINTER TO SOURCE STRING
; T2/ OFFSET TO BE ADDED TO EACH CHARACTER
; T3/ BYTE POINTER TO DESTINATION IN USER SPACE
; T4/ MAX CHAR COUNT IF STRING DOESN'T END WITH NULL
; CALL STONOD
;RETURNS: +1 FAILED
; +2 SUCCESS
STONOD: SAVEAC <P6>
STONO1: ILDB P6,T1 ;GET A BYTE
JUMPE P6,STONO2 ;IF NULL, ALL DONE
SKIPE T2 ;ANY OFFSET?
ADD P6,T2 ;YES
XCTBU [IDPB P6,T3] ;STORE BYTE
ERJMP R ;FAILED, RETURN ERROR
SKIPG T4 ;COUNTING CHARS?
JRST STONO1 ;NO
SOJG T4,STONO1 ;YES - ANY MORE?
SETZ P6, ;NO, MAKE A NULL
STONO2: XCTBU [IDPB P6,T3] ;APPEND A NULL
ERJMP R ;FAILED, RETURN ERROR
RETSKP ;DONE, RETURN SUCCESS
; NDVFY - VERIFY NODE NAME IS IN MONITOR'S DATABASE OF REACHABLE NODES
;NOTE: IT MUST FIRST BE IN THE NODE NAME MAPPING TABLE
NDVFY: SAVEAC (Q1)
STKVAR <<NDVNOD,WPN>,VFYSTR,VFYARG>
; GET NODE NAME FROM USER SPACE
UMOVE Q1,T2 ;GET ADDRESS OF USER ARGUMENT BLOCK
MOVEM Q1,VFYARG ;SAVE IT FOR LATER
UMOVE T1,.NDNAM(Q1) ;GET POINTER TO NODE NAME IN USER SPACE
MOVEI T2,NDVNOD ;GET ADDRESS OF DESTINATION FOR NAME
CALL PARNDU ;GET THE NODE NAME FROM USER SPACE
RETBAD () ;FAILED
; VERIFY THAT THE NODE IS IN NAME MAPPING TABLE
HRRI T1,NDVNOD ;GET ADDRESS OF NODE NAME
HRLI T1,(POINT 7,) ;FORM POINTER TO NODE NAME
MOVEM T1,VFYSTR ;SAVE IT FOR LATER USE
MOVE T3,T2 ;GET NUMBER OF CHARS IN NAME (RETURNED FROM PARNDU)
MOVNI T4,40 ;COMPARING 7-BIT TO SIXBIT ASCII
MOVNI P3,BIGNOD ;MAKE
HRLZS P3 ; AOBJN
HRRI P3,1 ; WORD
NOINT ;NO INTERRUPTIONS
LOCK NMAPLK ; WHILE TABLE LOCKED
NDVFY1: MOVE T1,VFYSTR ;GET BYTE POINTER TO USER'S NAME
HRLI T2,440600 ;MAKE A BYTE POINTER
HRRI T2,NODMAP(P3) ; TO MAPPING TABLE
TLO T3,400000 ;SPECIAL CALL TO COMPAR
CALL COMPAR ;IS THIS IT?
JRST [AOBJN P3,NDVFY1 ;NO, ANY MORE TO TEST?
UNLOCK NMAPLK ;NO, GIVE UP
OKINT ; THE LOCK
SETZ T1, ;TURN OFF THE "FOUND IT" BIT
JRST NDVFY2] ;DONE
;NODE IS IN NODE NAME MAPPING TABLE
UNLOCK NMAPLK ;DONE WITH THE MAPPING TABLE
LOCK NODLOK ;NOW LOCK THE REACH TABLE
MOVE T1,[POINT 2,NODTBL] ;MAKE BYTE POINTER TO BEGINNING OF REACH TABLE
HRRZS P3 ;GET JUST THE NODE NUMBER
ADJBP P3,T1 ;POINT TO APPROPRIATE ENTRY
LDB T1,P3 ;GET THE INFO
SKIPN T1 ;REACHABLE?
JRST [UNLOCK NODLOK ;NO, DONE WITH
OKINT ; THE LOCK
SETZ T1, ;TURN OFF THE "FOUND IT" BIT
JRST NDVFY2] ;DONE
;NODE IS REACHABLE
UNLOCK NODLOK ;DONE WITH
OKINT ; THE LOCK
MOVX T1,ND%EXM ;TURN ON THE "FOUND IT" BIT
;RETURN INFO TO THE USER
NDVFY2: MOVE T2,VFYARG ;RETRIEVE ADDR OF USER'S ARG BLOCK
UMOVEM T1,.NDFLG(T2) ;RETURN THE NEWS TO THE USER
RETSKP
ENDSV.
; NDRNM - GIVEN A NODE NUMBER, RETURN THE NODE NAME
NDRNM: UMOVE T4,.NDNOD(T2) ;GET NODE @MBER
CAIL T4,1 ;IS IT
CAILE T4,BIGNOD ; LEGAL?
RETBAD (NSPX25) ;NO
NOINT ;LOCK THE
LOCK NMAPLK ; NODE NAME MAPPING TABLE
UMOVE T3,.NDCVR(T2) ;GET THE USER'S BP
HRLI T2,440600 ;MAKE A BP
HRRI T2,NODMAP(T4) ; TO THE NAME
CALL NTRNAM ;RETURN THE NODE NAME TO THE USER
UMOVEM T3,.NDCVR(T2) ;RETURN UPDATED BP TO USER
SETZ T4, ;GIVE HIM
XCTBU [IDPB T4,T3] ; THE NULL
UNLOCK NMAPLK ;DONE WITH
OKINT ; THE LOCK
RETSKP
SUBTTL NTMAN% JSYS Functions
;Network Management's interface to the lower layers of DECnet architecture.
;THIS INTERFACE ASSUMES AT ALL TIMES:
;
;Q1/ ADDRESS OF MONITOR'S COPY OF THE USER'S ARGUMENT BLOCK
;Q3/ AMOUNT OF SPACE (IN BYTES) REMAINING IN USER'S RETURN BUFFER
SWAPCD
.NTMAN::MCENT
STKVAR <USRARG,ARGSIZ,MONARG>
MOVE T1,CAPENB ;GET ENABLED CAPABILITIES
TXNN T1,SC%WHL!SC%OPR ;WHEEL OR OPERATOR ENABLED?
ITERR (CAPX1) ;NO. RETURN "NOT ENOUGH CAPABILITIES" ERROR
UMOVE T2,1 ;GET USER'S ARG BLOCK ADDR
MOVEM T2,USRARG ;SAVE IT
UMOVE T1,.NTCNT(T2) ;GET USER'S LENGTH OF ARG BLOCK
CAIE T1,.NTARG ;CORRECT SIZE?
ITERR (ARGX17) ;NO, ERROR RETURN
NOINT
CALL GETBLK ;GET SWAPPABLE FREE SPACE FOR USER'S ARGS
JRST [OKINT ;CAN'T
HRREI T3,NTXRE ;RESOURCE ERROR
MOVE T1,USRARG ;GET USER'S ARG BLOCK ADDRESS
UMOVEM T3,.NTERR(T1) ;UPDATE ERROR RETURN STATUS
ITERR (NTMX1)] ;NETWORK MANAGEMENT GENERIC ERROR
OKINT
MOVEM T1,MONARG ;SAVE IT
MOVEI T1,.NTARG ;GET ARG BLOCK LENGTH
MOVE T2,USRARG ;RETRIEVE USER'S ARG BLOCK ADDR
MOVE T3,MONARG ;RETRIEVE MONITOR'S ARG BLOCK ADR
CALL BLTUM1 ;MOVE ARG BLOCK TO MONITOR
MOVE Q1,MONARG ;SET UP ARG BLOCK ADDR
LDB T1,[POINT 6,.NTBPT(Q1),11] ;GET THE USER'S BYTE SIZE
CAIE T1,^D8 ;MUST BE 8-BIT BYTES
IFNSK. ;NOT SO
CALL NMXMPE ;NETWORK MANAGEMENT PROGRAM ERROR
CALL NTMRET ;CLEAN UP
ITERR (ARGX09) ;JSYS ERROR RETURN - INVALID BYTE SIZE
ENDIF.
MOVE T1,.NTENT(Q1) ;GET ENTITY
MOVE Q3,.NTBYT(Q1) ;GET USER'S BUFFER SIZE
SETZM .NTBYT(Q1) ;INIT THE RETURN COUNT
CAIL T1,0 ;A VALID
CAIL T1,NTENTL ; ENTITY?
JRST [CALL NMXII ;INVALID IDENTIFICATION ERROR
CALL NTMRET ;CLEAN UP
ITERR ( )] ;ERROR RETURN
MOVE T4,NTMENT(T1) ;YES, GET THE DISPATCH ADDRESS
CALL (T4) ;GO DO THE WORK
JRST [CALL NTMRET ;GO FINISH UP
ITERR ( )] ;FAILURE RETURN
MOVEI T2,NTXGUD ;SUCCESSFUL COMPLETION
MOVEM T2,.NTERR(Q1) ;PUT STATUS IN ARG BLOCK
CALL NTMRET ;GO FINISH UP
MRETNG ;SUCCESS
;NTMAN% JSYS CLEAN UP ROUTINE - FILLS IN USER'S ARGUMENT BLOCK
NTMRET: SAVEAC <T1>
MOVEI T1,.NTARG ;GET LENGTH OF ARGUMENT BLOCK
MOVE T2,Q1 ;GET UPDATED ARG BLOCK
UMOVE T3,T1 ;GET USER'S ADDRESS
CALL BLTMU1 ;GIVE IT BACK
MOVE T1,Q1 ;GET ARG BLOCK ADDR
NOINT
CALL RELBLK ;RELEASE IT
OKINT
RET
ENDSV.
;NTMAN% "ENTITY" DISPATCH TABLE
NTMENT: EXP NTNOD ;NODE
EXP NMXUC ;LINE
EXP NMXUC ;LOG
EXP NMXUC ;CIRCUIT
EXP NMXUC ;MODULE
NTENTL==.-NTMENT
;Network Management Error Status Returns
;ROUTINE TO RETURN ERROR -1 (UNRECOGNIZED FUNCTIONS OR OPTION)
NMXUFO: HRREI T1,NTXUFO ;GET THE ERROR CODE
MOVEM T1,.NTERR(Q1) ;PUT IT IN THE ARG BLOCK
RETBAD (NTMX1) ;RETURN GENERIC ERROR CODE ON JSYS FAILURE
;ROUTINE TO RETURN ERROR -5 (MANAGEMENT PROGRAM ERROR)
NMXMPE: HRREI T1,NTXMPE ;GET THE ERROR CODE
MOVEM T1,.NTERR(Q1) ;PUT IT IN THE ARG BLOCK
RETBAD (NTMX1) ;RETURN GENERIC ERROR CODE ON JSYS FAILURE
;ROUTINE TO RETURN ERROR -6 (UNRECOGNIZED PARAMETER TYPE)
NMXUPT: HRREI T1,NTXUPT ;GET THE ERROR CODE
MOVEM T1,.NTERR(Q1) ;PUT IT IN THE ARG BLOCK
RETBAD (NTMX1) ;RETURN GENERIC ERROR CODE ON JSYS FAILURE
;ROUTINE TO RETURN ERROR -8 (UNRECOGNIZED COMPONENT)
NMXUC: HRREI T1,NTXUC ;GET THE ERROR CODE
MOVEM T1,.NTERR(Q1) ;PUT IT IN THE ARG BLOCK
RETBAD (NTMX1) ;RETURN GENERIC ERROR CODE ON JSYS FAILURE
;ROUTINE TO RETURN ERROR -9 (INVALID IDENTIFICATION)
NMXII: HRREI T1,NTXII ;GET THE ERROR CODE
MOVEM T1,.NTERR(Q1) ;PUT IT IN THE ARG BLOCK
RETBAD (NTMX1) ;RETURN GENERIC ERROR CODE ON JSYS FAILURE
;ROUTINE TO RETURN ERROR -10 (LINE COMMUNICATION ERROR)
NMXLCE: HRREI T1,NTXLCE ;GET THE ERROR CODE
MOVEM T1,.NTERR(Q1) ;PUT IT IN THE ARG BLOCK
RETBAD (NTMX1) ;RETURN GENERIC ERROR CODE ON JSYS FAILURE
;ROUTINE TO RETURN ERROR -11 (COMPONENT IN WRONG STATE)
NMXCWS: HRREI T1,NTXCWS ;GET THE ERROR CODE
MOVEM T1,.NTERR(Q1) ;PUT IT IN THE ARG BLOCK
RETBAD (NTMX1) ;RETURN GENERIC ERROR CODE ON JSYS FAILURE
;ROUTINE TO RETURN ERROR -15 (RESOURCE ERROR)
NMXRE: HRREI T1,NTXRE ;GET THE ERROR CODE
MOVEM T1,.NTERR(Q1) ;PUT IT IN THE ARG BLOCK
RETBAD (NTMX1) ;RETURN GENERIC ERROR CODE ON JSYS FAILURE
;ROUTINE TO RETURN ERROR -16 (INVALID PARAMETER VALUE)
NMXIPV: HRREI T1,NTXIPV ;GET THE ERROR CODE
MOVEM T1,.NTERR(Q1) ;PUT IT IN THE ARG BLOCK
RETBAD (NTMX1) ;RETURN GENERIC ERROR CODE ON JSYS FAILURE
;ROUTINE TO RETURN ERROR -22 (PARAMETER NOT APPLICABLE)
NMXPNA: HRREI T1,NTXPNA ;GET THE ERROR CODE
MOVEM T1,.NTERR(Q1) ;PUT IT IN THE ARG BLOCK
RETBAD (NTMX1) ;RETURN GENERIC ERROR CODE ON JSYS FAILURE
;ROUTINE TO RETURN ERROR -25 (OPERATION FAILURE)
NMXOF: HRREI T1,NTXOF ;GET THE ERROR CODE
MOVEM T1,.NTERR(Q1) ;PUT IT IN THE ARG BLOCK
RETBAD (NTMX1) ;RETURN GENERIC ERROR CODE ON JSYS FAILURE
;ROUTINE TO RETURN ERROR -29 (PARAMETER MISSING)
NMXPM: HRREI T1,NTXPM ;GET THE ERROR CODE
MOVEM T1,.NTERR(Q1) ;PUT IT IN THE ARG BLOCK
RETBAD (NTMX1) ;RETURN GENERIC ERROR CODE ON JSYS FAILURE
;LIST OF NODE COUNTER TABLE ADDRESSES
NSNODC: EXP NSBYTR ;BYTES RECEIVED
EXP NSBYTS ;BYTES SENT
EXP NSMSGR ;MESSAGES RECEIVED
EXP NSMSGS ;MESSAGES SENT
EXP NSCONR ;CONNECTS RECEIVED
EXP NSCONS ;CONNECTS SENT
EXP NSTIMO ;RESPONSE TIMEOUTS
EXP NSRCNE ;RECEIVED CONNECT RESOURCE ERRORS
EXP NSALNK ;ACTIVE LOGICAL LINKS
NSNODL==.-NSNODC
;NODE COUNTER INFORMATION - PARALLEL TO NSNODC
;LH/ NUMBER OF BITS IN COUNTER DATA
;RH/ COUNTER NUMBER
NSNWID: .NSW40,,.NSBYR ;BYTES RECEIVED
.NSW40,,.NSBYS ;BYTES SENT
.NSW40,,.NSMGR ;MESSAGES RECEIVED
.NSW40,,.NSMGS ;MESSAGES SENT
.NSW20,,.NSCNR ;CONNECTS RECEIVED
.NSW20,,.NSCNS ;CONNECTS SENT
.NSW20,,.NSRTO ;RESPONSE TIMEOUTS
.NSW20,,.NSRCE ;RECEIVED CONNECT RESOURCE ERRORS
.NSW20,,.NSALL ;ACTIVE LOGICAL LINKS
NSNWDL==.-NSNWID
;NODE PARAMETER ITEMS
NSNPAR: .NDSTT ;NODE STATE
.NDNID ;IDENTIFICATION
.NDNNA ;NODE NAME
.NDCNN ;CIRCUIT FOR NODE NAME
.NDNNU ;NODE NUMBER
.NDITM ;INCOMING TIMER
.NDOTM ;OUTGOING TIMER
.NDALK ;ACTIVE LINKS
.NDDLY ;DELAY
.NDVRS ;VERSION
.NDLML ;LOCAL MAXIMUM LINKS
.NDLDF ;LOCAL DELAY FACTOR
.NDLDW ;LOCAL DELAY WEIGHT
.NDIAT ;INACTIVITY TIMER
.NDRTF ;RETRANSMIT FACTOR
.NDTYP ;TYPE
NSNPRL==.-NSNPAR
;NODE IDENTIFICATION STRING (I-32)
NDIDN: BYTE (8) ^D10,"T","O","P","S","-","2","0"," ","V","5",0
;ENTITY = NODE
;NOW GET THE FUNCTION
;RETURNS: +1 FAILED, T1/ ERROR CODE
; +2 SUCCESS
NTNOD: MOVE T1,.NTFNC(Q1) ;GET FUNCTION REQUESTED
MOVNI T2,LOWFNC ;ADJUST THE FUNCTION CODE
HRRZS T2 ;MAKE IT USEFUL
ADD T1,T2 ; FOR DISPATCHING
CAIL T1,0 ;A VALID
CAIL T1,NTNODL ; FUNCTION?
JRST NMXII ;NO, ERROR RETURN
MOVE T4,NTNODF(T1) ;GET DISPATCH ADDRESS
CALL (T4) ;GO DO THE WORK
RETBAD () ;ERROR
RETSKP ;SUCCESS
NTNODF: EXP NTNMAP ;(-2) MAP NODE NUMBER TO NODE NAME
EXP NTNREX ;(-1) RETURN EXECUTOR NODE ID
EXP NTNSET ;(0) SET PARAMETER
EXP NTNCLR ;(1) CLEAR PARAMETER
EXP NTNZRO ;(2) ZERO ALL COUNTERS
EXP NTNSHO ;(3) SHOW SELECTED ITMES
EXP NTNSZC ;(4) SHOW AND ZERO ALL COUNTERS
EXP NTNRET ;(5) RETURN LIST OF ITEMS
NTNODL==.-NTNODF
;ENTITY = NODE
;FUNCTION = MAP NODE NUMBER TO NODE NAME
;RETURNS: +1 FAILED
; +2 SUCCESS
NTNMAP: STKVAR <BEGIN>
MOVE T2,.NTBPT(Q1) ;GET USER'S BYTE POINTER
MOVEM T2,BEGIN ;PRESERVE IT
MOVEI T1,.NDALN ;GET LENGTH OF NODE NUMBER
ADJBP T1,.NTBPT(Q1) ;SKIP THE NODE NUMBER
XCTBU [ILDB T2,T1] ;GET THE NUMBER OF BYTES IN THE NODE NAME
JUMPN T2,NTNMA1 ;IF SOME THERE, MOVE ON
HRREI T2,-<.NDALN+1> ;BACKUP TO
ADJBP T2,T1 ; NODE NUMBER
MOVEM T2,.NTBPT(Q1) ;RESET THE BYTE POINTER
MOVEI T3,.NTBPT(Q1) ;POINT TO THE NEW POINTER
CALL GETADR ;GET THE NODE NUMBER
JRST NMXUC ;FAILED
CALL FNDNAM ;LOOK UP THE NODE NAME
CALL RETNAM ;RETURN IT TO USER
RETBAD () ;FAILED
RETSKP ;DONE
NTNMA1: SETO T2, ;BACKUP TO
ADJBP T2,T1 ; READ THE NODE NAME
MOVEM T2,.NTBPT(Q1) ;RESET THE BYTE POINTER
MOVEI T3,.NTBPT(Q1) ;POINT TO THE NEW POINTER
CALL GETNAM ;GET THE NODE NAME
RETBAD () ;FAILED
NOINT
LOCK NMAPLK ;LOCK THE NODE NAME MAPPING TABLE
CALL FNDADR ;FIND THE NODE NUMBER
JRST [ UNLOCK NMAPLK ;UNLOCK THE TABLE
OKINT
JRST NMXUC] ;FAILED
UNLOCK NMAPLK ;UNLOCK THE TABLE
OKINT
MOVE T2,BEGIN ;RESET THE USER'S
MOVEM T2,.NTBPT(Q1) ; BYTE POINTER
CALL RETADR ;RETURN THE NODE NUMBER
RETBAD () ;FAILED
RETSKP
ENDSV.
;ENTITY = NODE
;FUNCTION = RETURN EXECUTOR NODE ID
;RETURNS: +1 FAILED
; +2 SUCCESS
NTNREX: MOVE T1,OURNUM ;GET OUR NODE NUMBER
CALL RETADR ;RETURN IT
RETBAD () ;FAILED
CALL FNDNAM ;LOOK UP NODE NAME
CALL RETNAM ;RETURN IT
RETBAD () ;FAILED
RETSKP ;DONE
;ENTITY = NODE
;FUNCTION = SET PARAMETER
;NOW FIND THE PARAMETER
;RETURNS: +1 FAILURE
; +2 SUCCESS
NTNSET: MOVEI T3,.NTBPT(Q1) ;GET USER'S BYTE POINTER
CALL GETPAR ;GET THE PARAMETER NUMBER
CALL FNDPAR ;LOOK IT UP
RETBAD ( )
MOVE T4,NTNSTP(T1) ;GET THE DISPATCH ADDRESS
CALL (T4) ;GO DO THE WORK
RETBAD () ;ERROR
RETSKP ;SUCCESS
NTNSTP: EXP NMXUPT ;LOCAL NODE STATE
EXP NMXUPT ;IDENTIFICATION
EXP SCNSET ;NODE NAME
EXP NMXUPT ;CIRCUIT FOR NODE NAME
EXP NMXUPT ;NODE NUMBER
EXP NMXUPT ;INCOMING TIMER
EXP NMXUPT ;OUTGOING TIMER
EXP NMXUPT ;ACTIVE LINKS
EXP NMXUPT ;DELAY
EXP NMXUPT ;VERSION
EXP NMXUPT ;MAXIMUM LINKS
EXP NSNLDF ;LOCAL DELAY FACTOR
EXP NSNLDW ;LOCAL DELAY WEIGHT
EXP NSNIAT ;INACTIVITY TIMER
EXP NSNTRY ;RETRANSMIT FACTOR
EXP NMXUPT ;TYPE
NTNSTL==.-NTNSTP
;ENTITY = NODE
;FUNCTION = SET PARAMETER
;PARAMETER = NAME
;RETURNS: +1 FAILED
; +2 SUCCESS
SCNSET: STKVAR <ADDR>
MOVEI T3,.NTEID(Q1) ;POINT TO ENTITY ID BYTE POINTER
CALL GETADR ;GET NODE ADDRESS FROM USER
JRST NMXII ;FAILED - "INVALID NODE ADDRESS"
MOVEM T1,ADDR ;STASH THE NODE ADDRESS
MOVEI T3,.NTBPT(Q1) ;POINT TO PARAMETER INFO BYTE POINTER
CALL GETNAM ;GET NODE NAME FROM USER
RETBAD () ;FAILED
MOVE T2,ADDR ;GET ADDRESS IN GOOD PLACE
NOINT
LOCK NMAPLK ;LOCK THE MAPPING TABLE
HRLZI T3,-<BIGNOD+1> ;MAKE AOBJN WORD
SCNSE1: HRRZ T4,T3 ;GET THE OFFSET ONLY
ADD T4,[NODMAP] ;MOVE INTO THE TABLE
CAMN T1,(T4) ;THIS ENTRY MATCH?
JRST [ HRRZ T4,T3 ;YES, GET ITS NUMBER
CAMN T4,T2 ;SAME AS ONE BEING SET?
JRST SCNSE2 ;YES, THAT'S OK
UNLOCK NMAPLK ;UNLOCK THE TABLE
OKINT
JRST NMXCWS] ;FAIL - NAME ALREADY ASSIGNED TO ANOTHER NODE
AOBJN T3,SCNSE1 ;CHECKED THE ENTIRE TABLE?
ADD T2,[NODMAP] ;MOVE INTO THE TABLE
MOVEM T1,(T2) ;PUT NODE NAME INTO TABLE
SCNSE2: UNLOCK NMAPLK ;UNLOCK THE MAPPING TABLE
OKINT
RETSKP ;GOOD RETURN
ENDSV.
;ENTITY = NODE
;FUNCION = SET PARAMETER
;PARAMETER = INACTIVITY TIMER
;RETURNS: +1 FAILURE
; +2 SUCCESS
NSNIAT: MOVEI T3,.NTBPT(Q1) ;GET BP TO USER'S ARG
MOVEI T4,2 ;2 BYTES IN LENGTH
CALL GETNUM ;GET THE VALUE FROM USER
CAIL T2,1 ;A LEGAL
CAILE T2,^D65535 ; VALUE?
JRST NMXIPV ;NO, FAIL
IMULI T2,^D1000 ;CONVERT TO MILLISECONDS
MOVEM T2,NSINAC ;SET THE NEW VALUE
RETSKP ;DONE
;ENTITY = NODE
;FUNCION = SET PARAMETER
;PARAMETER = LOCAL DELAY WEIGHT
;RETURNS: +1 FAILURE
; +2 SUCCESS
NSNLDW: MOVEI T3,.NTBPT(Q1) ;GET BP TO USER'S ARG
MOVEI T4,1 ;1 BYTES IN LENGTH
CALL GETNUM ;GET THE VALUE FROM USER
CAIL T2,1 ;A LEGAL
CAILE T2,^D255 ; VALUE?
JRST NMXIPV ;NO, FAIL
MOVEM T2,NSLDWS ;SET THE NEW VALUE
RETSKP ;DONE
;ENTITY = NODE
;FUNCION = SET PARAMETER
;PARAMETER = LOCAL DELAY FACTOR
;RETURNS: +1 FAILURE
; +2 SUCCESS
NSNLDF: MOVEI T3,.NTBPT(Q1) ;GET BP TO USER'S ARG
MOVEI T4,1 ;1 BYTES IN LENGTH
CALL GETNUM ;GET THE VALUE FROM USER
CAIL T2,1 ;A LEGAL
CAILE T2,^D63 ; VALUE?
JRST NMXIPV ;NO, FAIL
MOVEM T2,NSLDFS ;SET THE NEW VALUE
RETSKP ;DONE
;ENTITY = NODE
;FUNCION = SET PARAMETER
;PARAMETER = RETRANSMIT FACTOR
;RETURNS: +1 FAILURE
; +2 SUCCESS
NSNTRY: MOVEI T3,.NTBPT(Q1) ;GET BP TO USER'S ARG
MOVEI T4,2 ;2 BYTES IN LENGTH
CALL GETNUM ;GET THE VALUE FROM USER
CAIL T2,1 ;A LEGAL
CAILE T2,^D20 ; VALUE?
JRST NMXIPV ;NO, FAIL
MOVEM T2,NSTRYS ;SET THE NEW VALUE
RETSKP ;DONE
;ENTITY = NODE
;FUNCTION = CLEAR PARAMETER
;NOW FIND THE PARAMETER
;RETURNS: +1 FAILURE
; +2 SUCCESS
NTNCLR: SKIPN Q3 ;BYTE COUNT = 0?
JRST NTNCLA ;YES, THAT MEANS CLEAR ALL PARAMETERS
MOVEI T3,.NTBPT(Q1) ;GET ADDRESS OF USER'S POINTER
CALL GETPAR ;GET PARAMETER NUMBER
CALL FNDPAR ;LOOK IT UP
RETBAD ( )
MOVE T4,NTNCLP(T1) ;GET DISPATCH ADDRESS
CALL (T4) ;GO DO THE WORK
RETBAD () ;ERROR
RETSKP ;SUCCESS
NTNCLP: EXP NMXUPT ;LOCAL NODE STATE
EXP NMXUPT ;IDENTIFICATION
EXP SCNCLR ;NODE NAME
EXP NMXUPT ;CIRCUIT FOR NODE NAME
EXP NMXUPT ;NODE NUMBER
EXP NMXUPT ;INCOMING TIMER
EXP NMXUPT ;OUTGOING TIMER
EXP NMXUPT ;ACTIVE LINKS
EXP NMXUPT ;DELAY
EXP NMXUPT ;VERSION
EXP NMXUPT ;MAXIMUM LINKS
EXP NMXUPT ;LOCAL DELAY FACTOR
EXP NMXUPT ;LOCAL DELAY WEIGHT
EXP NMXUPT ;INACTIVITY TIMER
EXP NMXUPT ;RETRANSMIT FACTOR
EXP NMXUPT ;TYPE
NTNCLL==.-NTNCLP
;ENTITY = NODE
;FUNCTION = CLEAR (ALL)
;RETURNS: +1 FAILED
; +2 SUCCESS
NTNCLA: CALL SCNCLR ;DO SESSION CONTROL'S PART
RETBAD () ;FAILED
RETSKP ;DONE
;ENTITY = NODE
;FUNCTION = CLEAR PARAMETER
;PARAMETER = NAME
;RETURNS: +1 FAILED
; +2 SUCCESS
SCNCLR: MOVEI T3,.NTEID(Q1) ;POINT TO ENTITY ID BYTE POINTER
CALL GETADR ;GET USER'S NODE ADDRESS
JRST NMXII ;BAD
NOINT
LOCK NMAPLK ;LOCK THE MAPPING TABLE
ADD T1,[NODMAP] ;MOVE INTO THE TABLE
SETZM (T1) ;NULLIFY CURRENT MAPPING
UNLOCK NMAPLK ;UNLOCK THE MAPPING TABLE
OKINT
RETSKP ;GOOD RETURN
;ENTITY = NODE
;FUNCTION = ZERO COUNTERS
;RETURNS: +1 FAILED
; +2 SUCCESS
NTNZRO: CALL NANUEX ;GET THE NODE NUMBER
RETBAD () ;FAILED
NTNZR2: MOVEI T4,NSNODL-1 ;GET NUMBER OF COUNTERS
NTNZR1: MOVE T3,NSNODC(T4) ;GET THE TABLE
ADD T3,T1 ;GET THE OFFSET
SETZM (T3) ;ZERO THE COUNT
SOJGE T4,NTNZR1 ;MORE TO DO?
RETSKP ;NO, DONE
;ENTITY = NODE
;FUNCTION = SHOW SELECTED ITEMS
;NOW FIND SELECTOR
;RETURNS: +1 FAILED
; +2 SUCCESS
NTNSHO: MOVE T1,.NTSEL(Q1) ;GET THE SELECTOR
CAIL T1,0 ;A VALID
CAIL T1,NTSHOL ; SELECTOR?
JRST NMXII ;NO, FAIL
MOVE T4,NTSHOT(T1) ;GET DISPATCH ADDRESS
CALL (T4) ;GO DO THE WORK
RETBAD () ;FAILED
RETSKP ;SUCCESS
NTSHOT: EXP NTNSUM ;SUMMARY
EXP NTNSTS ;STATUS
EXP NTNSCH ;CHARACTERISTICS
EXP NSNSCO ;COUNTERS
EXP NMXUFO ;EVENTS
NTSHOL==.-NTSHOT
;ENTITY = NODE
;FUNCTION = SUMMARY
;RETURNS: +1 FAILED
; +2 SUCCESS
NTNSUM: STKVAR <NDNUM>
CALL NANUEX ;GET THE NODE NUMBER
RETBAD () ;FAILED
MOVEM T1,NDNUM ;SAVE THE NODE NUMBER
CALL DOSTA ;DO STATE PARAMETER
RETBAD () ;FAILED
MOVE T1,NDNUM ;RETRIEVE THE NODE NUMBER
CALL RETALK ;DO ACTIVE LINK PARAMETER
RETBAD () ;FAILED
MOVE T1,NDNUM ;RETRIEVE NODE NUMBER
CAME T1,OURNUM ;IS IT US?
RETSKP ;NO, DONE
; CALL RETIDN ;RETURN IDENTIFICATION PARAMETER
; RETBAD () ;FAILED
RETSKP ;DONE
ENDSV.
;ENTITY = NODE
;FUNCTION = SHOW SELECTED ITEMS
;SELECTOR = STATUS
;RETURNS: +1 FAILED
; +2 SUCCESS
NTNSTS: STKVAR <NDNUM>
CALL NANUEX ;GET NODE NUMBER
RETBAD () ;FAILED
MOVEM T1,NDNUM ;SAVE NODE NUMBER
CALL SCNSTS ;DO SESSION CONTROL
RETBAD () ;FAILED
MOVE T1,NDNUM ;RETRIEVE NODE NUMBER
CALL NSNSTS ;DO NSP
RETBAD () ;FAILED
RETSKP ;DONE
ENDSV.
;ROUTINE TO DO SESSION CONTROL'S PART OF SHOW NODE STATUS
;ACCEPTS: T1/ NODE NUMBER
;RETURNS: +1 FAILED
; +2 SUCCESS
SCNSTS: CALL DOSTA ;DO STATE PARAMETER
RETBAD () ;FAILED
RETSKP ;DONE
;ROUTINE TO DO NSP'S PART OF SHOW NODE STATUS
;ACCEPTS: T1/ NODE NUMBER
;RETURNS: +1 FAILED
; +2 SUCCESS
NSNSTS: CALL RETALK ;DO ACTIVE LINK PARAMETER
RETBAD () ;FAILED
RETSKP
;ROUTINE TO RETURN THE ACTIVE LINK PARAMETER
;ACCEPTS: T1/ NODE NUMBER
;RETURNS: +1 FAILED
; +2 SUCCESS
RETALK: SAVEAC <P3>
STKVAR <NDNUM>
MOVEM T1,NDNUM ;SAVE THE NODE NUMBER
CALL GTALNK ;GO GET THE NUMBER OF ACTIVE LINKS
MOVE T1,NDNUM ;RETRIEVE THE NODE NUMBER
SETZ Q2, ;INIT THE ARGUMENT
MOVEI T3,NTPAR ;PARAMETER DATA
STOR T3,DIDDA,Q2 ;PUT IT IN
MOVEI T3,.NDALK ;PARAMETER IS ACTIVE LINK
STOR T3,DIDNO,Q2 ;PUT IT IN
CALL NTMDID ;MAKE A DATA ID
RETBAD () ;FAILED
SETZ Q2, ;INIT THE ARGUMENT
MOVEI T1,NTNCD ;NOT CODED
STOR T1,DTYCD,Q2 ;PUT IT IN
MOVEI T1,NTBIN ;BINARY NUMBER
STOR T1,DTYTY,Q2 ;PUT IT IN
MOVEI T1,2 ;2 BYTES
STOR T1,DTYLN,Q2 ;PUT IT IN
MOVEI T1,NTUDN ;UNSIGNED DECIMAL NUMBER
STOR T1,DTYBF,Q2 ;PUT IT IN
CALL NTMDTY ;MAKE A DATA TYPE
RETBAD () ;FAILED
MOVEI T1,2 ;2 BYTES
MOVE T3,[NSALNK] ;ACTIVE LINKS TABLE
ADD T3,NDNUM ;OFFSET INTO TABLE
MOVE P3,(T3) ;GET THE CURRENT VALUE
LSH P3,^D20 ;POSITION IT
MOVE T2,[441000,,P3] ;MAKE A BYTE POINTER
CALL RETNUM ;RETURN IT TO USER
RETBAD () ;FAILED
RETSKP
ENDSV.
;GET NUMBER OF ACTIVE LINKS FOR ALL NODES
;RETURNS: +1 WITH NSALNK TABLE FILLED IN
GTALNK: MOVEI T1,NSALNK ;GET BEGINNING OF TABLE
SETZM (T1) ;ZERO
HRL T2,T1 ; THE
HRRI T2,1(T1) ; ACTIVE LINKS
BLT T2,BIGNOD(T1) ; TABLE
LLLOCK ;LOCK THE LL STRUCTURE
MOVEI T1,GTALCO ;GET ADDRESS OF COROUTINE
SETO T2, ;ALL LINKS
CALL OBJSRC ;GO SEARCH THE LINK STRUCTURE
JFCL ;DOESN'T MATTER MUCH
CALLRET ULOKLL ;UNLOCK THE LL STRUCTURE
GTALCO: SAVET
CALL BLKLOK ;LOCK THIS LL BLOCK
RET ;CAN'T, GO GET NEXT ONE
LOAD T2,LLSTA,(T1) ;GET STATE OF LINK
CAIN T2,LLSLIS ;LISTENING?
JRST GTALCD ;YES, NOT INTERESTING
LOAD T2,LLHSN,(T1) ;GET OTHER HOST'S NUMBER
AOS NSALNK(T2) ;BUMP THE COUNT
GTALCD: CALLRET BLKULK ;UNLOCK THIS LL BLOCK
;ROUTINE TO ASSIST IN RETURNING THE STATE OF A NODE
;ACCEPTS: T1/ NODE NUMBER
;RETURNS: +1/ FAILED
; +2/ SUCCESS
DOSTA: CAME T1,OURNUM ;IS IT US?
JRST DOST1 ;NO
MOVEI T2,.NDON ;YES, SESSION CONTROL IS ON
JRST DOST2 ;MOVE ON
DOST1: MOVE T3,[440200,,NODTBL] ;MAKE BP TO REACHABLE NODES TABLE
ADJBP T1,T3 ;OFFSET TO THE NODE IN QUESTION
LDB T2,T1 ;GET ITS STATE
SKIPE T2 ;IS IT REACHABLE?
JRST [ MOVEI T2,.NDREA ;YES
JRST DOST2] ;MOVE ON
MOVEI T2,.NDUNR ;NO
DOST2: CALL RETSTA ;RETURN THE STATE
RETBAD () ;FAILED
RETSKP
;ROUTINE TO RETURN THE STATE PARAMETER
;ACCEPTS: T2/ STATE
;RETURNS: +1 FAILED
; +2 SUCCESS
RETSTA: SAVEAC <P3>
STKVAR <STATE>
MOVEM T2,STATE ;SAVE THE STATE
SETZ Q2, ;INIT THE ARGUMENT
MOVEI T3,NTPAR ;PARAMETER DATA
STOR T3,DIDDA,Q2 ;PUT IT IN
MOVEI T3,.NDSTT ;PARAMETER IS STATE
STOR T3,DIDNO,Q2 ;PUT IT IN
CALL NTMDID ;MAKE A DATA ID
RETBAD () ;FAILED
SETZ Q2, ;INIT THE ARGUMENT
MOVEI T1,NTCOD ;CODED
STOR T1,DTYCD,Q2 ;PUT IT IN
MOVEI T1,NTSNG ;SINGLE FIELD
STOR T1,DTYTY,Q2 ;PUT IT IN
MOVEI T1,1 ;1 BYTE
STOR T1,DTYCN,Q2 ;PUT IT IN
CALL NTMDTY ;MAKE A DATA TYPE
RETBAD () ;FAILED
MOVEI T1,1 ;1 BYYTE
MOVE P3,STATE ;GET THE STATE
LSH P3,^D28 ;POSITION IT
MOVE T2,[441000,,P3] ;MAKE A BP TO IT
CALL RETNUM ;RETURN IT
RETBAD () ;FAILED
RETSKP
ENDSV.
;ENTITY = NODE
;FUNCTION = SHOW SELECTED ITEMS
;SELECTOR = CHARACTERISTICS
;RETURNS: +1 FAILED, 1/ ERROR CODE
; +2 SUCCESS
NTNSCH: CALL NANUEX ;GET NODE NUMBER
RETBAD () ;FAILED
CAME T1,OURNUM ;IS IT US?
RETSKP ;NO, NOTHING TO RETURN
CALL SCNSCH ;DO SESSION CONTROL
RETBAD () ;FAILED
CALL NSNSCH ;DO NSP
RETBAD () ;FAILED
CALL XPNSCH ;DO TRANSPORT
RETBAD () ;FAILED
RETSKP ;DONE
;SESSION CONTROL'S PART OF SHOW CHARACTERISTICS
;RETURNS: +1 FAILED
; +2 SUCCESS
SCNSCH:
; CALL RETIDN ;RETURN THE IDENTIFICATION
; RETBAD () ;FAILED
RETSKP ;DONE
;NSP'S PART OF SHOW CHARACTERISTICS
;RETURNS: +1 FAILED
; +2 SUCCESS
NSNSCH: SAVEAC <P3>
;DO NSP VERSION
SETZ Q2, ;INIT THE ARGUMENT
MOVEI T2,NTPAR ;PARAMETER DATA
STOR T2,DIDDA,Q2 ;PUT IT IN
MOVEI T2,.NDVRS ;PARAMETER IS NSP VERSION
STOR T2,DIDNO,Q2 ;PUT IT IN
CALL NTMDID ;MAKE A DATA ID
RETBAD () ;FAILED
SETZ Q2, ;INIT THE ARGUMENT
MOVEI T2,NTCOD ;CODED
STOR T2,DTYCD,Q2 ;PUT IT IN
MOVEI T2,NTMUL ;MULTIPLE FIELDS
STOR T2,DTYTY,Q2 ;PUT IT IN
MOVEI T2,3 ;3 FIELDS
STOR T2,DTYCN,Q2 ;PUT IT IN
CALL NTMDTY ;MAKE A DATA TYPE
RETBAD () ;FAILED
MOVEI T1,COMVER ;GET THE VERSION OF NSP
CALL MAKDTY ;DO THE DATA TYPE
RETBAD () ;FAILED
MOVEI T1,COMECO ;GET THE ECO LEVEL OF NSP
CALL MAKDTY ;DO THE DATA TYPE
RETBAD () ;FAILED
MOVEI T1,COMCST ;GET THE CUSTOMER LEVEL OF NSP
CALL MAKDTY ;DO THE DATA TYPE
RETBAD () ;FAILED
;DO NSP LOCAL DELAY FACTOR
SETZ Q2, ;INIT THE ARGUMENT
MOVEI T3,NTPAR ;PARAMETER DATA
STOR T3,DIDDA,Q2 ;PUT IT IN
MOVEI T3,.NDLDF ;PARAMETER IS LOCAL DELAY FACTOR
STOR T3,DIDNO,Q2 ;PUT IT IN
CALL NTMDID ;MAKE A DATA ID
RETBAD () ;FAILED
SETZ Q2, ;INIT THE ARGUMENT
MOVEI T1,NTNCD ;NOT CODED
STOR T1,DTYCD,Q2 ;PUT IT IN
MOVEI T1,NTBIN ;BINARY NUMBER
STOR T1,DTYTY,Q2 ;PUT IT IN
MOVEI T1,1 ;1 BYTE
STOR T1,DTYLN,Q2 ;PUT IT IN
MOVEI T1,NTUDN ;UNSIGNED DECIMAL NUMBER
STOR T1,DTYBF,Q2 ;PUT IT IN
CALL NTMDTY ;MAKE A DATA TYPE
RETBAD () ;FAILED
MOVEI T1,1 ;1 BYTE
MOVE P3,NSLDFS ;GET THE CURRENT VALUE
LSH P3,^D28 ;POSITION IT
MOVE T2,[441000,,P3] ;MAKE A BYTE POINTER
CALL RETNUM ;RETURN IT TO USER
RETBAD () ;FAILED
;DO NSP LOCAL DELAY WEIGHT
SETZ Q2, ;INIT THE ARGUMENT
MOVEI T3,NTPAR ;PARAMETER DATA
STOR T3,DIDDA,Q2 ;PUT IT IN
MOVEI T3,.NDLDW ;PARAMETER IS LOCAL DELAY WEIGHT
STOR T3,DIDNO,Q2 ;PUT IT IN
CALL NTMDID ;MAKE A DATA ID
RETBAD () ;FAILED
SETZ Q2, ;INIT THE ARGUMENT
MOVEI T1,NTNCD ;NOT CODED
STOR T1,DTYCD,Q2 ;PUT IT IN
MOVEI T1,NTBIN ;BINARY NUMBER
STOR T1,DTYTY,Q2 ;PUT IT IN
MOVEI T1,1 ;1 BYTE
STOR T1,DTYLN,Q2 ;PUT IT IN
MOVEI T1,NTUDN ;UNSIGNED DECIMAL NUMBER
STOR T1,DTYBF,Q2 ;PUT IT IN
CALL NTMDTY ;MAKE A DATA TYPE
RETBAD () ;FAILED
MOVEI T1,1 ;1 BYTE
MOVE P3,NSLDWS ;GET THE CURRENT VALUE
LSH P3,^D28 ;POSITION IT
MOVE T2,[441000,,P3] ;MAKE A BYTE POINTER
CALL RETNUM ;RETURN IT TO USER
RETBAD () ;FAILED
;DO NSP INACTIVITY TIMER
SETZ Q2, ;INIT THE ARGUMENT
MOVEI T3,NTPAR ;PARAMETER DATA
STOR T3,DIDDA,Q2 ;PUT IT IN
MOVEI T3,.NDIAT ;PARAMETER IS INACTIVITY TIMER
STOR T3,DIDNO,Q2 ;PUT IT IN
CALL NTMDID ;MAKE A DATA ID
RETBAD () ;FAILED
SETZ Q2, ;INIT THE ARGUMENT
MOVEI T1,NTNCD ;NOT CODED
STOR T1,DTYCD,Q2 ;PUT IT IN
MOVEI T1,NTBIN ;BINARY NUMBER
STOR T1,DTYTY,Q2 ;PUT IT IN
MOVEI T1,2 ;2 BYTES
STOR T1,DTYLN,Q2 ;PUT IT IN
MOVEI T1,NTUDN ;UNSIGNED DECIMAL NUMBER
STOR T1,DTYBF,Q2 ;PUT IT IN
CALL NTMDTY ;MAKE A DATA TYPE
RETBAD () ;FAILED
MOVEI T1,2 ;2 BYTES
MOVE P3,NSINAC ;GET THE CURRENT VALUE
IDIVI P3,^D1000 ;CONVERT TO SECONDS
LSH P3,^D20 ;POSITION IT
MOVE T2,[441000,,P3] ;MAKE A BYTE POINTER
CALL RETNUM ;RETURN IT TO USER
RETBAD () ;FAILED
;DO NSP RETRANSMIT FACTOR
SETZ Q2, ;INIT THE ARGUMENT
MOVEI T3,NTPAR ;PARAMETER DATA
STOR T3,DIDDA,Q2 ;PUT IT IN
MOVEI T3,.NDRTF ;PARAMETER IS LOCAL DELAY WEIGHT
STOR T3,DIDNO,Q2 ;PUT IT IN
CALL NTMDID ;MAKE A DATA ID
RETBAD () ;FAILED
SETZ Q2, ;INIT THE ARGUMENT
MOVEI T1,NTNCD ;NOT CODED
STOR T1,DTYCD,Q2 ;PUT IT IN
MOVEI T1,NTBIN ;BINARY NUMBER
STOR T1,DTYTY,Q2 ;PUT IT IN
MOVEI T1,2 ;2 BYTES
STOR T1,DTYLN,Q2 ;PUT IT IN
MOVEI T1,NTUDN ;UNSIGNED DECIMAL NUMBER
STOR T1,DTYBF,Q2 ;PUT IT IN
CALL NTMDTY ;MAKE A DATA TYPE
RETBAD () ;FAILED
MOVEI T1,2 ;2 BYTES
MOVE P3,NSTRYS ;GET THE CURRENT VALUE
LSH P3,^D20 ;POSITION IT
MOVE T2,[441000,,P3] ;MAKE A BYTE POINTER
CALL RETNUM ;RETURN IT TO USER
RETBAD () ;FAILED
RETSKP ;DONE
;ROUTINE TO RETURN A DATA TYPE
;ACCEPTS: 1/ VALUE TO BE RETURNED
;RETURNS: +1 FAILED
; +2 SUCCESS
MAKDTY: SAVEAC <P3>
STKVAR <VALUE>
MOVEM T1,VALUE ;SAVE THE VALUE
MOVEI T2,NTNCD ;NOT CODED
STOR T2,DTYCD,Q2 ;PUT IT IN
MOVEI T2,NTSNG ;SINGLE FIELD
STOR T2,DTYTY,Q2 ;PUT IT IN
MOVEI T2,1 ;1 BYTE
STOR T2,DTYCN,Q2 ;PUT IT IN
CALL NTMDTY ;MAKE THE DATA TYPE
RETBAD () ;FAILED
MOVEI T1,1 ;1 BYTE
MOVE P3,VALUE ;RETRIEVE THE VALUE
MOVE T2,[101000,,P3] ;MAKE A BYTE POINTER TO IT
CALL RETNUM ;RETURN IT
RETBAD () ;FAILED
RETSKP
ENDSV.
;TRANSPORT'S PART OF SHOW CHARACTERISTICS
;RETURNS: +1 FAILED
; +2 SUCCESS
XPNSCH: SAVEAC <P3>
SETZ Q2, ;ZERO THE ARGUMENT
MOVEI T2,NTPAR ;PARAMETER DATA
STOR T2,DIDDA,Q2 ;PUT IT IN
MOVEI T2,.NDTYP ;PARAMETER IS TYPE
STOR T2,DIDNO,Q2 ;PUT IT IN
CALL NTMDID ;MAKE A DATA ID
RETBAD () ;FAILED
SETZ Q2, ;ZERO THE ARGUMENT
MOVEI T2,NTCOD ;CODED
STOR T2,DTYCD,Q2 ;PUT IT IN
MOVEI T2,NTSNG ;SINGLE FIELD
STOR T2,DTYTY,Q2 ;PUT IT IN
MOVEI T2,1 ;ONE BYTE LONG
STOR T2,DTYCN,Q2 ;PUT IT IN
CALL NTMDTY ;MAKE A DATA TYPE
RETBAD () ;FAILED
MOVEI P3,PHASE2 ;WE ARE PHASE II
LSH P3,^D28 ;POSITION IT
MOVE T2,[441000,,P3] ;MAKE A BYTE POINTER
MOVEI T1,1 ;NUMBER OF BYTES
CALL RETNUM ;RETURN IT
RETBAD () ;FAILED
RETSKP
;ROUTINE TO RETURN THE NODE IDENTIFICATION
;RETURNS: +1 FAILED
; +2 SUCCESS
RETIDN: SETZ Q2, ;ZERO THE ARGUMENT
MOVEI T2,NTPAR ;PARAMETER DATA
STOR T2,DIDDA,Q2 ;PUT IT IN
MOVEI T2,.NDNID ;PARAMETER IS "IDENTIFICATION"
STOR T2,DIDNO,Q2 ;PUT IT IN
CALL NTMDID ;MAKE A DATA ID
RETBAD () ;FAILED
SETZ Q2, ;ZERO THE ARGUMENT
MOVEI T2,NTNCD ;NOT CODED
STOR T2,DTYCD,Q2 ;PUT IT IN
MOVEI T2,NTASC ;ASCII
STOR T2,DTYTY,Q2 ;PUT IT IN
CALL NTMDTY ;MAKE A DATA TYPE
RETBAD () ;FAILED
MOVE T3,[441000,,NDIDN] ;MAKE BYTE POINTER TO STRING
MOVEI T2,.NTBPT(Q1) ;POINT TO USER'S SPACE
RETID1: ILDB T1,T3 ;GET A BYTE
JUMPE T1,RSKP ;IF NULL, DONE
CALL NTMBYT ;UPDATE COUNT
RETBAD () ;FAILED
XCTBU [IDPB T1,(T2)] ;RETURN IT
JRST RETID1 ;GO FOR MORE
;ENTITY = NODE
;FUNCTION = SHOW SELECTED ITEMS
;SELECTOR = COUNTERS
;RETURNS: +1 FAILED, 1/ ERROR CODE
; +2 SUCCESS, 1/ NODE ADDRESS
NSNSCO: SAVEAC <P3>
STKVAR <ADDR>
CALL NANUEX ;GET NODE NUMBER
RETBAD () ;FAILED
MOVEM T1,ADDR ;SAVE THE NODE ADDRESS
MOVSI P3,-NSNODL ;MAKE AOBJN WORD
NSNSC1: HRRZ T4,P3 ;GET THE OFFSET INTO THE COUNTER TABLES
ADD T4,[NSNODC] ;POINT TO THIS TABLE'S ADDRESS
MOVE T3,(T4) ;GET THE TABLE ADDRESS
ADD T3,ADDR ;GET THE NODE'S OFFSET
MOVE T2,(T3) ;GET THE CURRENT VALUE OF THIS COUNTER
MOVE T3,P3 ;RETRIEVE OFFSET INTO COUNTER TABLES
ADD T3,[NSNWID] ;MOVE TO THIS COUNTER'S INFO
HRRZ T1,(T3) ;GET THE COUNTER NUMBER
CALL RETCNT ;RETURN THE INFO TO THE USER
RETBAD () ;FAILED
AOBJN P3,NSNSC1 ;ANY MORE TO DO?
MOVE T1,ADDR ;GET BACK NODE ADDRESS
RETSKP
ENDSV.
;ENTITY = NODE
;FUNCTION = SHOW AND ZERO COUNTERS
;RETURNS: +1 FALIED, 1/ ERROR CODE
; +2 SUCCESS
NTNSZC: CALL NSNSCO ;RETURN THE COUNTERS
RETBAD () ;FAILED
CALL NTNZR2 ;ZERO THE COUNTERS
RETBAD () ;FAIELD
RETSKP
;ENTITY = NODE
;FUNCTION = RETURN LIST OF ITMES
;NOW FIND THE SELECTOR
;RETURNS: +1 FAILED, 1/ ERROR CODE
; +2 SUCCESS
NTNRET: MOVN T1,.NTSEL(Q1) ;GET THE SELECTOR
SOS T1 ;MAKE THE ADJUSTMENT FOR DISPATCHING
CAIL T1,0 ;IS IT
CAIL T1,NTRETL ; VALID?
JRST NMXII ;NO, ERROR RETURN
MOVE T4,NTRETS(T1) ;GET DISPATCH ADDRESS
CALL (T4) ;GO DO THE WORK
RETBAD () ;FAILED
RETSKP ;SUCCESS
NTRETS: EXP NTNRLS ;KNOWN ITEMS
EXP NTNRAC ;ACTIVE ITEMS
EXP NMXII ;LOOPED ITEMS
NTRETL==.-NTRETS
;ENTITY = NODE
;FUNCTION = RETURN LIST OF ITEMS
;SELECTOR = KNOWN
;RETURNS:: +1 FAILED, 1/ ERROR CODE
; +2 SUCCESS
NTNRLS: CALL SCNRET ;GET SESSION CONTROL INFO
RETBAD () ;FAILED, ERROR RETURN
RETSKP ;SUCCESS
;ENTITY = NODE
;FUNCTION = RETURN LIST OF ITEMS
;SELECTOR = KNOWN
;SESSION CONTROL'S PART
;RETURNS: +1 FAILED 1/ ERROR CODE
; +2 SUCCESS
SCNRET: SAVEAC <P3>
NOINT
LOCK NMAPLK ;LOCK THE MAPPING TABLE
HRLI P3,-BIGNOD ;MAKE AOBJN
HRRI P3,1 ; WORD
SCNRE1: MOVE T2,[NODMAP] ;OFFSET INTO
ADDI T2,(P3) ; THE TABLE
MOVE T1,(T2) ;GET THE CURRENT NAME
JUMPE T1,[ MOVE T2,[440200,,NODTBL] ;POINT TO REACH TABLE
HRRZ T3,P3 ;GET NODE NUMBER
ADJBP T3,T2 ;OFFSET TO NODE
LDB T2,T3 ;GET REACH INFO
JUMPE T2,SCNRE2 ;IF NOT REACHABLE, MOVE ON
JRST .+1] ;REACHABLE
HRRZ T1,P3 ;GET NODE ADDRESS
CALL RETADR ;RETURN THE NODE ADDRESS
JRST SCNRE3 ;FAILED
CALL FNDNAM ;LOOK UP THE NODE NAME
CALL RETNAM ;RETURN THE NODE NAME
JRST SCNRE3 ;FAILED
SCNRE2: AOBJN P3,SCNRE1 ;LOOK AT THE ENTIRE TABLE
UNLOCK NMAPLK ;UNLOCK THE MAPPING TABLE
OKINT
RETSKP ;GOOD RETURN
SCNRE3: UNLOCK NMAPLK
OKINT
RETBAD ()
;ENTITY = NODE
;FUNCTION = RETURN LIST OF ITEMS
;SELECTOR = ACTIVE
;RETURNS: +1 FAILED 1/ ERROR CODE
; +2 SUCCESS
NTNRAC: SAVEAC <P3,P6>
NOINT
LOCK NMAPLK
SETZ P3, ;INIT THE NODE NUMBER
MOVE P6,[440200,,NODTBL] ;POINT TO REACH TABLE
NTNRA1: ILDB T1,P6 ;GET THE INFO
AOS P3 ;SET THE NODE NUMBER
JUMPE T1,NTNRA2
MOVE T1,P3 ;GET THE NODE NUMBER IN A GOOD PLACE
CALL RETADR ;RETURN THE NODE NUMBER TO USER
JRST NTNRA3 ;FAILED
CALL FNDNAM ;LOOK UP THE NODE NAME
CALL RETNAM ;RETURN THE NODE NAME TO THE USER
JRST NTNRA3 ;FAILED
NTNRA2: CAIGE P3,BIGNOD ;MORE NODES TO CHECK?
JRST NTNRA1 ;YES
UNLOCK NMAPLK
OKINT
RETSKP
NTNRA3: UNLOCK NMAPLK
OKINT
RETBAD ()
SUBTTL NTMAN% JSYS Support Routines
;ROUTINE TO RETURN A NODE NAME TO THE USER
;ACCEPTS: 2/ ADDRESS OF SIXBIT NODE NAME
; 4/ NUMBER OF BYTES IN NODE NAME
;RETURNS: +1 FAILED 1/ ERROR CODE
; +2 SUCCESS
RETNAM: STKVAR <MONPTR,COUNT>
MOVEM T2,MONPTR ;SAVE
MOVEM T4,COUNT ; ARGUMENTS
MOVE T2,T4 ;GET COUNT IN PROPER AC FOR NOUT
MOVE T1,[POINT 7,T4] ;MAKE BYTE POINTER TO BYTE COUNT
MOVE T3,[1B17+<12>B35] ;1 BYTE, IN DECIMAL
NOUT ;CONVERT IT TO ASCII
JRST NMXMPE ;INTERNAL NETWORK MANAGEMENT ERROR
CALL NTMBYT ;UPDATE THE BYTE COUNT
RETBAD () ;DON'T HAVE ROOM
XCTBU [IDPB T2,.NTBPT(Q1)] ;FILL IN COUNT FIELD
SKIPN T1,COUNT ;GET THE BYTE COUNT
RETSKP ;IT'S ZERO, ALL DONE
MOVE T3,MONPTR ;MAKE BYTE POINTER
MOVE T2,[POINT 6,(T3)] ; TO THE NODE NAME
RETNA1: ILDB T4,T2 ;GET A BYTE
ADDI T4,40 ;CONVERT TO ASCII
CALL NTMBYT ;UPDATE BYTE COUNT
RETBAD () ;DON'T HAVE ROOM
XCTBU [IDPB T4,.NTBPT(Q1)] ;PUT IT IN THE DESTINATION
SOJG T1,RETNA1 ;MORE TO DO?
RETSKP ;NO
ENDSV.
;ROUTINE TO LOOK UP A NODE NAME
;ACCEPTS: 1/ NODE ADDRESS
;RETURNS: +1 WITH 1/ NODE ADDRESS
; 2/ ADDRESS OF SIXBIT NODE NAME
; 4/ NUMBER OF BYTES IN NODE NAME
FNDNAM: SAVEAC <T1>
STKVAR <ADDR>
ADD T1,[NODMAP] ;OFFSET INTO TABLE
MOVEM T1,ADDR ;SAVE IT
MOVE T2,[POINT 6,(T1)] ;MAKE BYTE POINTER TO IT
HRLZI T4,-6 ;MAXIMUM OF SIX BYTES IN NAME
FNDNA1: ILDB T3,T2 ;GET A BYTE
SKIPE T3 ;IF NULL, ALL DONE
AOBJN T4,FNDNA1 ;MORE BYTES TO CHECK?
FNDNA2: HRRZS T4 ;GET NUMBER OF BYTES INTO PROPER AC
MOVE T2,ADDR ;RETRIEVE THE NODE NAME ADDRESS
RET ;ALL DONE
ENDSV.
;ROUTINE TO GET A NODE NAME FROM THE USER AND VERIFY THAT IT IS MADE
;UP OF ALPHANUMERIC CHARACTERS, ONE OF WHICH MUST BE ALPHA.
;ACCEPTS: 3/ ADDRESS OF USER'S BYTE POINTER
;RETURNS: +1 - INVALID, 1/ ERROR CODE
; +2 - O.K. WITH 1/ SIXBIT NODE NAME
; 2/ NUMBER OF BYTES IN NODE NAME
GETNAM: SAVEAC <P3,P6>
STKVAR <COUNT>
SETZB T1,P6 ;ZERO THE DESTINATION WORD AND ALPHA FLAG
MOVE T4,[POINT 6,T1] ;MAKE BYTE POINTER TO DESTINATION
XCTBU [ILDB P3,(T3)] ;GET THE "COUNT" BYTE
CAIL P3,1 ;IS IT WITHIN
CAILE P3,.NDNMX-1 ; RANGE?
JRST NMXII ;NO, INVALID BYTE COUNT FOR NODE NAME
MOVEM P3,COUNT ;SAVE IT
GETNA1: XCTBU [ILDB T2,(T3)] ;GET A BYTE
CALL CHKAL ;IS IT ALPHABETIC?
JRST [CALL CHKNUM ;NO, IS IT NUMERIC?
JRST NMXII ;NO, INVALID FORMAT
JRST .+1] ;YES, MOVE ON
SUBI T2,40 ;MAKE IT SIXBIT
IDPB T2,T4 ;PUT IT IN DESTINATION
SOJG P3,GETNA1 ;MORE TO DO?
SKIPN P6 ;DID WE FIND AN ALPHABETIC CHARACTER?
JRST NMXII ;NO. INVALID
MOVE T2,COUNT ;RETRIEVE THE COUNT
RETSKP
CHKAL: CAIL T2,"A"
CAILE T2,"Z"
RET ;NOT ALPHA
SETOM P6 ;SET THE "FOUND ALPHA" FLAG
RETSKP ;IS ALPHA
CHKNUM: CAIL T2,"0"
CAILE T2,"9"
RET ;NOT NUMERIC
RETSKP ;IS NUMERIC
ENDSV.
;ROUTINE TO FIND A NODE NUMBER BY PARSING THE ENTITY ID FIELD
;RETURNS: +1 ERROR 1/ ERROR CODE
; +2 SUCCESS 1/ NODE NUMBER
NANUEX: MOVEI T1,.NDALN ;GET LENGTH OF NODE NUMBER
ADJBP T1,.NTEID(Q1) ;SKIP THE NODE NUMBER
XCTBU [ILDB T2,T1] ;GET THE NUMBER OF BYTES IN THE NODE NAME
JUMPN T2,NANUE1 ;IF SOME THERE, MOVE ON
HRREI T2,-<.NDALN+1> ;BACKUP TO
ADJBP T2,T1 ; NODE NUMBER
MOVEM T2,.NTEID(Q1) ;RESET THE BYTE POINTER
MOVEI T3,.NTEID(Q1) ;POINT TO THE NEW POINTER
CALL GETADR ;GET THE NODE NUMBER
JRST [ SKIPE T1 ;WAS IT 0?
JRST NMXII ;NO, FAIL
MOVE T1,OURNUM ;YES, THAT MEANS EXECUTOR
RETSKP] ;DONE
RETSKP ;DONE
NANUE1: SETO T2, ;BACKUP TO
ADJBP T2,T1 ; READ THE NODE NAME
MOVEM T2,.NTEID(Q1) ;RESET THE BYTE POINTER
NANUE2: MOVEI T3,.NTEID(Q1) ;POINT TO THE NEW POINTER
CALL GETNAM ;GET THE NODE NAME
RETBAD () ;FAILED
NOINT
LOCK NMAPLK ;LOCK THE NODE NAME MAPPING TABLE
CALL FNDADR ;FIND THE NODE NUMBER
JRST [ UNLOCK NMAPLK ;UNLOCK THE TABLE
OKINT
JRST NMXUC] ;FAILED
UNLOCK NMAPLK ;UNLOCK THE TABLE
OKINT
RETSKP
;ROUTINE TO LOOK UP A NODE ADDRESS
;
;ACCEPTS: 1/ SIXBIT NODE NAME
;
;RETURNS: +1 NOT FOUND
; +2 WITH 1/ NODE ADDRESS
FNDADR: HRLZI T4,-<BIGNOD+1> ;MAKE AOBJN WORD
FNDAD1: HRRZ T3,T4 ;GET OFFSET ONLY
ADD T3,[NODMAP] ;MOVE INTO THE TABLE
CAMN T1,(T3) ;IS THIS A MATCH?
JRST [HRRZ T1,T4 ;YES, GET NODE ADDRESS IN PROPER AC
RETSKP]
AOBJN T4,FNDAD1 ;ANY MORE TO CHECK?
RET ;NO. FAIL RETURN
;ROUTINE TO UPDATE THE "RETURNED BYTE COUNT" IN THE USER'S ARGUMENT BLOCK
;RETURNS: +1 FAIL 1/ ERROR CODE
; +2 SUCCESS
NTMBYT: SOSGE Q3 ;USER HAVE ANY MORE ROOM?
JRST NMXRE ;NO, FAIL
AOS .NTBYT(Q1) ;UPDATE THE RETURN COUNT
RETSKP
;ROUTINE TO RETURN A NODE ADDRESS TO THE USER
;
;ACCEPTS: 1/ NODE ADDRESS
;RETURNS: +1 FAILED 1/ ERROR CODE
; +2 SUCCESS
;PRESERVES T1
RETADR: SAVEAC <T1,P3>
MOVE P3,T1 ;GET ADDRESS IN GOOD PLACE
LSH P3,4 ;POSITION IT
MOVEI T1,.NDALN ;GET NUMBER OF BYTES IN NODE ADDRESS
MOVE T2,T1 ;PRESERVE IT IN T1
MOVNS T2 ;MAKE BYTE
MOVE T4,[041000,,P3] ; POINTER
ADJBP T2,T4 ; TO ADDRESS
CALL RETNUM ;RETURN NODE ADDRESS TO USER
RETBAD () ;FAILED
RETSKP
;RETURN A NUMBER TO THE USER
;ACCEPTS: 1/ NUMBER OF BYTES
; 2/ BYTE POINTER TO NUMBER
;RETURNS: +1 FAILED 1/ ERROR CODE
; +2 SUCCESS
RETNUM: SOS T1 ;FIX IT FOR BYTE POINTER ADJUSTING AND LOOPING
MOVE T3,T1 ;MAKE A COPY
RETNU1: ADJBP T1,T2 ;POINT TO REMAINING RIGHT-MOST BYTE
ILDB T4,T1 ;GET IT
CALL NTMBYT ;UPDATE BYTE COUNT
RETBAD () ;FAILED, USER DOESN'T HAVE ROOM
XCTBU [IDPB T4,.NTBPT(Q1)] ;GIVE BYTE TO USER
SOJL T3,RSKP ;MORE TO DO?
MOVE T1,T3 ;YES, GET NEW BYTE POSITION
JRST RETNU1 ;GO BACK FOR MORE
;ROUTINE TO GET A NODE ADDRESS FROM USER
;AND VERIFY THAT IT IS A LEGITIMATE ADDRESS.
;
;ACCEPTS: 3/ ADDRESS OF USER'S BYTE POINTER
;RETURNS: +1 ERROR 1/ NUMBER FOUND
; +2 WITH 1/ NUMERIC NODE ADDRESS
GETADR: MOVEI T4,.NDALN ;GET NUMBER OF BYTES IN A NODE ADDRESS
CALL GETNUM ;GET THE NUMBER
MOVE T1,T2 ;GET NODE ADDRESS
CAIL T1,1 ;A VALID
CAILE T1,BIGNOD ; NODE ADDRESS?
RET
RETSKP ;GOOD RETURN
;ROUTINE TO GET A PARAMETER NUMBER FROM THE USER
;
;ACCEPTS: 3/ ADDRESS OF USER'S BYTE POINTER
;RETURNS: 2/ PARAMETER NUMBER
GETPAR: MOVEI T4,.NDPLN ;GET NUMBER OF BYTES IN A PARAMETER NUMBER
CALLRET GETNUM ;GET THE NUMBER
;ROUTINE TO GET A NUMBER FROM THE USER
;
;ACCEPTS: 3/ ADDRESS OF USER'S BYTE POINTER
; 4/ NUMBER OF BYTES IN NUMBER
;RETURNS: +1 2/ NUMBER
GETNUM: SAVEAC <P3>
MOVE P3,T4 ;PRESERVE COUNT FOR LOOPING
SETZ T2, ;INIT THE DESTINATION WORD
GETNU1: XCTBU [ILDB T1,(T3)] ;GET BYTE
IORM T1,T2 ;PUT IT IN
ROT T2,-10 ;POSIITON FOR NEXT
SOJG T4,GETNU1 ;MORE TO DO?
ROT T2,10 ;UNWIND
SOJG P3,.-1 ; THE BYTE STRING
RET ;DONE
;ROUTINE TO LOOK UP A PARAMETER NUMBER
;ACCEPTS: 2/ PARAMETER NUMBER
;RETURNS: 1/ OFFSET INTO PARAMETER TABLE
FNDPAR: MOVEI T1,NSNPRL ;GET NUMBER OF ENTRIES IN TABLE
SOS T1 ;FIX FOR OFFSETING
FNDPA1: XMOVEI T3,NSNPAR ;GET TABLE BASE
ADD T3,T1 ;GET OFFSET
CAMN T2,(T3) ;THIS IT?
RETSKP ;YES, DONE
SOJGE T1,FNDPA1 ;ANY MORE TO CHECK?
JRST NMXUPT ;NO, BAD NUMBER
;ROUTINE TO RETURN A NODE ID TO THE USER
;ACCEPTS: T1/ NODE NUMBER
; T2/ PARAMETER NUMBER
;RETURNS: +1 FAILED 1/ ERROR CODE
; +2 SUCCESS
RETNID: ASUBR <NDNUM,PARNUM>
SETZM Q2 ;INIT THE ARGUMENT
MOVEI T1,NTPAR ;PARAMETER DATA
STOR T1,DIDDA,Q2 ;PUT IT IN
STOR T2,DIDNO,Q2 ;PUT IN PARAMETER NUMBER
CALL NTMDID ;MAKE A DATA ID
RETBAD () ;FAILD
SETZM Q2 ;INIT THE ARGUMENT
MOVEI T1,NTCOD ;CODED
STOR T1,DTYCD,Q2 ;PUT IT IN
MOVEI T1,NTMUL ;MULTIPLE FIELDS
STOR T1,DTYTY,Q2 ;PUT IT IN
MOVEI T1,2 ;NUMBER OF FIELDS IN A NODE ID
STOR T1,DTYCN,Q2 ;PUT IT IN
CALL NTMDTY ;MAKE A DATA TYPE
RETBAD () ;FAILED
SETZM Q2 ;INIT THE ARGUMENT
MOVEI T1,NTNCD ;NOT CODED
STOR T1,DTYCD,Q2 ;PUT IT IN
MOVEI T1,NTBIN ;BINARY NUMBER
STOR T1,DTYTY,Q2 ;PUT IT IN
MOVEI T1,NTOCT ;OCTAL NUMBER
STOR T1,DTYBF,Q2 ;PUT IT IN
MOVEI T1,.NDALN ;BYTES IN A NODE ADDRESS
STOR T1,DTYLN,Q2 ;PUT IT IN
CALL NTMDTY ;MAKE A DATA TYPE
RETBAD () ;FAILED
MOVE T1,NDNUM ;GET NODE NUMBER
CALL RETADR ;RETURN THE NODE NUMBER TO USER
RETBAD () ;FAIL
SETZM Q2 ;INIT THE ARGUMENT
MOVEI T1,NTNCD ;NOT CODED
STOR T1,DTYCD,Q2 ;PUT IT IN
MOVEI T1,NTASC ;ASCII IMAGE
STOR T1,DTYTY,Q2 ;PUT IT IN
CALL NTMDTY ;MAKE A DATA TYPE
RETBAD () ;FAILED
MOVE T1,NDNUM ;GET NODE NUMBER
CALL FNDNAM ;GET THE NODE NAME
CALL RETNAM ;RETURN THE NODE NAME TO THE USER
RETBAD () ;FAILED
RETSKP
ENDAS.
;RETURN A COUNTER TO THE USER
;ACCEPTS: T1/ COUNTER NUMBER
; T2/ CURRENT VALUE OF COUNTER
;RETURNS: +1 FAILED 1/ ERROR CODE
; +2 SUCCESS
RETCNT: ASUBR <NUM,VAL,WIDTH>
SAVEAC <P3>
SETZM Q2 ;INIT THE DESTINATION WORD
MOVEI T2,NTCOU ;COUNTER DATA
STOR T2,DIDDA,Q2 ;PUT IT IN
STOR T1,DIDNO,Q2 ;PUT IN THE COUNTER NUMBER
CALL FNDCNT ;FIND THE COUNTER OFFSET
ADD T2,[NSNWID] ;MOVE TO THIS COUNTER'S INFO
HLRZ T1,(T2) ;GET THE COUNTER NUMBER
STOR T1,DIDWD,Q2 ;PUT IT IN
MOVEM T1,WIDTH ;SAVE IT
CALL NTMDID ;MAKE A DATA ID
RETBAD () ;FAILED
MOVE T1,WIDTH ;RETRIEVE THE WIDTH
IDIVI T1,10 ;CONVERT TO BYTES
MOVE T2,T1 ;SAVE IT IN T1
MOVE P3,VAL ;GET THE COUNTER VALUE
LSH P3,4 ;POSITION IT
MOVNS T2 ;MAKE A
MOVE T3,[041000,,P3] ; BYTE POINTER
ADJBP T2,T3 ; TO THE NUMBER
CALL RETNUM ;RETURN THE COUNTER TO USER
RETBAD () ;FAILED
RETSKP ;DONE
ENDAS.
;GET A COUNTER'S OFFSET INTO THE COUNTER TABLES
;ACCEPTS: T1/ COUNTER NUMBER
;RETURNS: +1 T2/ OFFSET INTO COUNTER TABLES
FNDCNT: MOVEI T2,NSNWDL ;GET THE NUMBER
SOS T2 ; OF TABLES
FNDCN1: MOVE T4,T2 ;SAVE T2
ADD T4,[NSNWID] ;OFFSET INTO TABLE
HRRZ T3,(T4) ;GET THE COUNTER NUMBER
CAME T3,T1 ;A MATCH?
SOJGE T2,FNDCN1 ;NO, MORE TO DO?
RET ;YES, DONE
;BUILD A DATA ID
;ACCEPTS: Q2/ DATA ID PARAMETERS
; DEFSTR (DIDDA,0,0,1)
; (DIDWD,0,7,6)
; (DIDNO,0,17,11)
;RETURNS: +1 FAILED 1/ ERROR CODE
; +2 SUCCESS
NTMDID: SAVEAC <P3>
SETZM P3 ;INIT THE DESTINATION
LOAD T2,DIDNO,Q2 ;GET THE PARAMETER OR COUNTER NUMBER
STOR T2,NT%PNM,P3 ;PUT IN NUMBER
LOAD T2,DIDDA,Q2 ;GET THE DATA TYPE
CAIE T2,NTCOU ;COUNTER?
JRST NTMDI1 ;NO, PARAMETER
SETONE NT%DAT,P3 ;SAY COUNTER DATA TYPE
LOAD T3,DIDWD,Q2 ;GET COUNTER WIDTH
LSH T3,-4 ;CONVERT NUMBER OF BYTES
AOS T3 ; INTO PROPER CODE
STOR T3,NT%CWD,P3 ;PUT IN COUNT
NTMDI1: HRLI T2,441000 ;MAKE A BYTE POINTER
HRRI T2,P3 ; TO IT
MOVEI T1,NTMDIL ;GET LENGTH OF DATA ID
CALL RETNUM ;GIVE IT TO USER
RETBAD () ;FAILED
RETSKP
;BUILD A DATA TYPE
;ACCEPTS: Q2/ DATA TYPE PARAMETERS
; DEFSTR (DTYCD,0,0,1)
; (DTYTY,0,1,1)
; (DTYCN,0,7,6)
; (DTYBF,0,3,2)
; (DTYLN,0,7,4)
;RETURNS: +1 FAILED 1/ ERROR CODE
; +2 SUCCESS
NTMDTY: SETZM T4 ;INIT THE DESTINATION
LOAD T2,DTYCD,Q2 ;GET CODE INDICATOR
CAIE T2,NTCOD ;CODED?
JRST NTMDT1 ;NO
SETONE NT%COD,T4 ;CODED, SAY SO
LOAD T2,DTYTY,Q2 ;GET TYPE
SKIPE T2 ;SINGLE FIELD?
SETONE NT%TYP,T4 ;NO, MULTIPLE FIELDS
LOAD T2,DTYCN,Q2 ;GET NUMBER OF FIELDS OR BYTES
STOR T2,NT%CNT,T4 ;PUT IT IN
JRST NTMDT2 ;MOVE ON
NTMDT1: LOAD T2,DTYTY,Q2 ;NOT CODED, GET TYPE
SKIPE T2 ;BINARY?
SETONE NT%TYP,T4 ;NO, ASCII IMAGE
LOAD T2,DTYLN,Q2 ;GET BYTE COUNT
STOR T2,NT%LEN,T4 ;PUT IT IN
LOAD T2,DTYBF,Q2 ;GET FORMAT
STOR T2,NT%FMT,T4 ;PUT IT IN
NTMDT2: HRLI T3,441000 ;MAKE BP
HRRI T3,T4 ; TO DATA TYPE
MOVEI T2,NTMDTL ;GET NUMBER OF BYTES IN DATA TYPE
NTMDT3: ILDB T1,T3 ;GET A BYTE
CALL NTMBYT ;UPDATE BYTE COUNT
RETBAD () ;DON'T HAVE ROOM
XCTBU [IDPB T1,.NTBPT(Q1)] ;RETURN IT TO USER
SOJG T2,NTMDT3 ;MORE TO DO?
RETSKP
TNXEND
END