Trailing-Edge
-
PDP-10 Archives
-
BB-H311D-RM
-
monitor-sources/nspsrv.mac
There are 31 other files named nspsrv.mac in the archive. Click here to see a list.
; UPD ID= 5073, SNARK:<6.MONITOR>NSPSRV.MAC.148, 8-Nov-84 12:31:12 by GRANT
;TCO 6.2277 - In UNQTIM, remove obsolete ASUBR; remove OWGBP stuff and
;references to MSPTP.
; UPD ID= 4861, SNARK:<6.MONITOR>NSPSRV.MAC.147, 20-Sep-84 15:25:20 by TBOYLE
;TCO 6.2223 - Prevent NSPTSK from staying in balance set all the time.
; UPD ID= 4818, SNARK:<6.MONITOR>NSPSRV.MAC.146, 17-Sep-84 10:14:26 by PURRETTA
;Update copyright notice
; UPD ID= 4736, SNARK:<6.MONITOR>NSPSRV.MAC.145, 24-Aug-84 07:06:33 by GRANT
;TCO 6.2198 - In CLZDI, make sure all bytes are sent
; UPD ID= 4622, SNARK:<6.MONITOR>NSPSRV.MAC.144, 28-Jul-84 17:37:07 by GLINDELL
;More TCO 6.2060 - fix typo bug
; UPD ID= 4408, SNARK:<6.MONITOR>NSPSRV.MAC.143, 29-Jun-84 10:24:25 by GRANT
;QAR 706017 - In SRCOPN, add another TRVAR location for the LL block and use
;it in OPNUNQ
; UPD ID= 4355, SNARK:<6.MONITOR>NSPSRV.MAC.142, 18-Jun-84 11:49:06 by GRANT
;In NSPSPC, wrong AC as index register
; UPD ID= 4272, SNARK:<6.MONITOR>NSPSRV.MAC.141, 30-May-84 21:21:01 by MOSER
;TCO 6.2060 - MAKE MTOPRS FASTER
; UPD ID= 4242, SNARK:<6.MONITOR>NSPSRV.MAC.140, 25-May-84 06:15:26 by GRANT
;TCO 6.2068 - try to prevent resident free space deadly embrace
; UPD ID= 4127, SNARK:<6.MONITOR>NSPSRV.MAC.139, 25-Apr-84 11:06:47 by LOMARTIRE
;TCO 6.2046 - Record the job 0 fork number of NSP fork in DNTFRK
; UPD ID= 4033, SNARK:<6.MONITOR>NSPSRV.MAC.138, 31-Mar-84 20:54:07 by GRANT
;Use LLDBUG under NSPSW for debugging LL blocks being clobbered
; UPD ID= 3964, SNARK:<6.MONITOR>NSPSRV.MAC.137, 23-Mar-84 16:40:40 by NICHOLS
;Add TCO number to previous edit.
; UPD ID= 3962, SNARK:<6.MONITOR>NSPSRV.MAC.136, 23-Mar-84 15:50:26 by NICHOLS
;TCO 6.2009 - Ignore Phase IV Retransmitted CI messages quietly rather
;than giving NSPBAD BUGINFs for each one received. Add code to BADMSG
;to keep most recent message which caused NSPBAD BUGINF, pointer in BADMSP.
; UPD ID= 3428, SNARK:<6.MONITOR>NSPSRV.MAC.135, 9-Jan-84 14:53:47 by GRANT
;Turn off NSPSW
; UPD ID= 3391, SNARK:<6.MONITOR>NSPSRV.MAC.134, 30-Dec-83 07:08:08 by GRANT
;In BLKLOK, put lock and context checking under NSPSW debugging switch.
;Replace JSR BUGHLTs with defined BUGHLTs.
;TCO 6.1920 - In debugging mode (NSPSW=1), use LLMSIT instead of LLMSG.
; UPD ID= 3352, SNARK:<6.MONITOR>NSPSRV.MAC.133, 20-Dec-83 15:02:36 by CJOHNSON
;TCO 6.1907 Make TURNON have WRONLY DCN: send 0 xmit alloc
; UPD ID= 3218, SNARK:<6.MONITOR>NSPSRV.MAC.132, 28-Nov-83 09:45:39 by LEACHE
;TCO 6.1641 Move swappable freespace out of section zero
; UPD ID= 2603, SNARK:<6.MONITOR>NSPSRV.MAC.131, 20-Jun-83 15:49:03 by HALL
;TCO 6.1689 - Move fork tables to extended section
; Reference FKJOB via DEFSTR
; UPD ID= 2586, SNARK:<6.MONITOR>NSPSRV.MAC.130, 15-Jun-83 13:25:56 by GRANT
;TCO 6.1687 - In STRMSG, make sure it is a node init
; UPD ID= 2520, SNARK:<6.MONITOR>NSPSRV.MAC.129, 25-May-83 14:03:59 by GRANT
;TCO 6.1667 - use EP. for network management counter references
; UPD ID= 2446, SNARK:<6.MONITOR>NSPSRV.MAC.128, 9-May-83 11:34:12 by GRANT
;TCO 6.1642 - Use SIZ39 in GTSBLK
; UPD ID= 2210, SNARK:<6.MONITOR>NSPSRV.MAC.127, 8-Apr-83 06:48:18 by GRANT
;TCO 6.1605 - make INTINT resident
; UPD ID= 2103, SNARK:<6.MONITOR>NSPSRV.MAC.126, 28-Mar-83 17:44:42 by MURPHY
;TCO 6.1472 - Minor cleanup re. LSTERR
; UPD ID= 2053, SNARK:<6.MONITOR>NSPSRV.MAC.125, 21-Mar-83 18:05:59 by MURPHY
;GET RID OF OBSOLETE SEARCH PROKL
; UPD ID= 2048, SNARK:<6.MONITOR>NSPSRV.MAC.124, 21-Mar-83 14:07:45 by GRANT
;TCO 6.1560 - insert check against BIGNOD in CI message processing
; UPD ID= 2024, SNARK:<6.MONITOR>NSPSRV.MAC.123, 19-Mar-83 06:16:06 by GRANT
;TCO 6.1558 - After ILLSTR BUGINF, go to TOSMSG instead of BADMSG
; UPD ID= 1897, SNARK:<6.MONITOR>NSPSRV.MAC.122, 1-Mar-83 15:40:25 by HALL
;TCO 6.1502 - Allow free space outside of section 0
; At least temporarily, make all callers request section 0
; UPD ID= 1854, SNARK:<6.MONITOR>NSPSRV.MAC.121, 22-Feb-83 12:04:04 by GRANT
;TCO 6.1481 - support for incoming messages in non-PC section
; UPD ID= 1801, SNARK:<6.MONITOR>NSPSRV.MAC.120, 14-Feb-83 15:04:00 by HALL
;TCO 6.1502 - Allow resident free space in non-PC section
; Instead of testing free space availability directly, call routine
; in FREE to do it
; UPD ID= 1787, SNARK:<6.MONITOR>NSPSRV.MAC.119, 10-Feb-83 16:26:30 by COBB
;Add a comment to NTCOFF about is never RETing, only RETSKPing.
; UPD ID= 1738, SNARK:<6.MONITOR>NSPSRV.MAC.118, 2-Feb-83 13:27:18 by GRANT
;TCO 6.1491 - In MTGSS, return segment size in more cases
; UPD ID= 1736, SNARK:<6.MONITOR>NSPSRV.MAC.117, 2-Feb-83 07:26:58 by GRANT
;TCO 6.1486 - Make ONSRVQ and UNQSRV run NOSKED
; UPD ID= 1726, SNARK:<6.MONITOR>NSPSRV.MAC.116, 31-Jan-83 10:07:53 by GRANT
;More of 6.1435 - Change routine BADNOD
; UPD ID= 1724, SNARK:<6.MONITOR>NSPSRV.MAC.115, 31-Jan-83 07:29:06 by GRANT
;Change STKVAR name in previous edit
; UPD ID= 1723, SNARK:<6.MONITOR>NSPSRV.MAC.114, 28-Jan-83 22:20:08 by GRANT
;TCO 6.1483 - In DCDCS, fix management of LL block lock
; UPD ID= 1697, SNARK:<6.MONITOR>NSPSRV.MAC.113, 26-Jan-83 09:42:27 by GRANT
;More TCO 6.1455
; UPD ID= 1685, SNARK:<6.MONITOR>NSPSRV.MAC.112, 20-Jan-83 08:31:26 by GRANT
;TCO 6.1469 - implement node parameter "state"
; UPD ID= 1671, SNARK:<6.MONITOR>NSPSRV.MAC.111, 16-Jan-83 21:50:28 by GRANT
;TCO 6.1454 - Split off NTMAN% into its own module
; UPD ID= 1648, SNARK:<6.MONITOR>NSPSRV.MAC.110, 13-Jan-83 07:18:12 by GRANT
;Fix bug in UPD ID=1256 - in NSPTM5, retrieve message address earlier
; UPD ID= 1647, SNARK:<6.MONITOR>NSPSRV.MAC.109, 13-Jan-83 06:44:45 by GRANT
;TCO 6.1455 - don't assemble internal links code
; UPD ID= 1635, SNARK:<6.MONITOR>NSPSRV.MAC.108, 10-Jan-83 08:09:44 by GRANT
;TCO 6.1442 - don't assemble 2020 loopback code
; UPD ID= 1627, SNARK:<6.MONITOR>NSPSRV.MAC.107, 7-Jan-83 08:30:46 by GRANT
;TCO 6.1443 - In INTLS, remove setting of inactivity timer. In INACOR, reorder
; the tests to make elimination faster.
; UPD ID= 1618, SNARK:<6.MONITOR>NSPSRV.MAC.106, 5-Jan-83 07:02:36 by GRANT
;TCO 6.1435 - rewrite part of incoming CI message processing
; UPD ID= 1588, SNARK:<6.MONITOR>NSPSRV.MAC.105, 28-Dec-82 07:57:25 by GRANT
;TCO 6.1430 - redo the logic in ACKRUN and DATRUN
; UPD ID= 1578, SNARK:<6.MONITOR>NSPSRV.MAC.104, 27-Dec-82 10:56:33 by GRANT
;TCO 6.1429 - add missing OKINT in DCDCS
; UPD ID= 1577, SNARK:<6.MONITOR>NSPSRV.MAC.103, 27-Dec-82 10:45:56 by GRANT
;TCO 6.1428 - remove extraneous instruction in MTSNIN
; UPD ID= 1576, SNARK:<6.MONITOR>NSPSRV.MAC.102, 27-Dec-82 08:52:40 by GRANT
;TCO 6.1427 - add support for "seconds since last zeroed"
; UPD ID= 1528, SNARK:<6.MONITOR>NSPSRV.MAC.101, 10-Dec-82 13:02:05 by GRANT
;TCO 6.1411 - use the table LLIDS to store logical links block addresses
; UPD ID= 1514, SNARK:<6.MONITOR>NSPSRV.MAC.100, 7-Dec-82 13:08:06 by GRANT
;TCO 6.1404 - rewrite CHKSCT
; UPD ID= 1403, SNARK:<6.MONITOR>NSPSRV.MAC.99, 2-Nov-82 11:26:49 by GRANT
;Minor fix to TCO 5.1.1089
; UPD ID= 1396, SNARK:<6.MONITOR>NSPSRV.MAC.98, 1-Nov-82 13:23:43 by GRANT
;TCO 6.1341 - release swappable block in CLRBLK
; UPD ID= 1338, SNARK:<6.MONITOR>NSPSRV.MAC.97, 13-Oct-82 20:58:37 by GRANT
;More of TCO 5.1.1074
; UPD ID= 1333, SNARK:<6.MONITOR>NSPSRV.MAC.96, 13-Oct-82 07:14:41 by GRANT
;More of TCO 5.1.1089 - In MCBCQ, don't need to fake a JFN block anymore
; UPD ID= 1321, SNARK:<6.MONITOR>NSPSRV.MAC.95, 11-Oct-82 10:18:35 by GRANT
;TCO 5.1.1092 - Change a few IFNSK. to IFSKP.
; UPD ID= 1311, SNARK:<6.MONITOR>NSPSRV.MAC.94, 9-Oct-82 10:21:22 by GRANT
;TCO 5.1.1089 - Rewrite MCBCQ, process link IDs rather than LL blocks
; UPD ID= 1299, SNARK:<6.MONITOR>NSPSRV.MAC.93, 8-Oct-82 10:04:25 by GRANT
;TCO 5.1.1087 - Add call to DELNOD in NSPTMO
; UPD ID= 1298, SNARK:<6.MONITOR>NSPSRV.MAC.92, 8-Oct-82 08:58:25 by GRANT
;TCO 5.1.1086 - In RELLNK and DEDMCB, lock LL tree before calling DELNOD
; UPD ID= 1292, SNARK:<6.MONITOR>NSPSRV.MAC.91, 7-Oct-82 13:36:47 by GRANT
;TCO 5.1.1085 - In UNQSEG, stop incorrect removal from the resend queue
; UPD ID= 1280, SNARK:<6.MONITOR>NSPSRV.MAC.90, 6-Oct-82 08:56:30 by GRANT
;TCO 5.1.1074 - Add debugging code for verifying logical link blocks
; UPD ID= 1270, SNARK:<6.MONITOR>NSPSRV.MAC.89, 1-Oct-82 17:56:30 by GRANT
;TCO 5.1.1080 - In NSPMSG, toss messages which have LLDED set
; UPD ID= 1269, SNARK:<6.MONITOR>NSPSRV.MAC.88, 1-Oct-82 14:37:01 by GRANT
;TCO 5.1.1079 - Use MOVE instead of LOAD in NSPNXT
; UPD ID= 1256, SNARK:<6.MONITOR>NSPSRV.MAC.87, 28-Sep-82 19:09:34 by GRANT
;TCO 5.1.1072 - don't retransmit data segments when flow is turned off
; UPD ID= 1220, SNARK:<6.MONITOR>NSPSRV.MAC.86, 23-Sep-82 12:15:29 by GRANT
;TCO 5.1.1067 - Don't send a disconnect when a link times out
; UPD ID= 1218, SNARK:<6.MONITOR>NSPSRV.MAC.85, 23-Sep-82 09:38:18 by GRANT
;TCO 5.1.1066 - If link has been aborted, have synchronous CLOSF return success
; UPD ID= 1216, SNARK:<6.MONITOR>NSPSRV.MAC.84, 22-Sep-82 20:41:49 by CDUNN
;Put back the END (at the end of the source) statement which seems to have
;been lost two edits ago.
; UPD ID= 1206, SNARK:<6.MONITOR>NSPSRV.MAC.83, 21-Sep-82 13:34:53 by GRANT
;TCO 5.1.1063 - In NSNSCH, return characteristics by parameter number
; UPD ID= 1204, SNARK:<6.MONITOR>NSPSRV.MAC.82, 21-Sep-82 11:04:04 by GRANT
;Fix bug in SNDCTL introduced by an incorrect test in TCO 5.1.1057
; UPD ID= 1200, SNARK:<6.MONITOR>NSPSRV.MAC.81, 20-Sep-82 15:57:27 by MCINTEE
;More TCO 6.1251 - clean up NDGNT
; UPD ID= 1147, SNARK:<6.MONITOR>NSPSRV.MAC.80, 7-Sep-82 09:15:06 by MCINTEE
;TCO 6.1251 - Change code in NDGNT not to use so much stack.
; UPD ID= 1121, SNARK:<6.MONITOR>NSPSRV.MAC.79, 30-Aug-82 14:34:32 by MCINTEE
;TCO 5.1.1058 - Change error code at MTOBJ1
; UPD ID= 1116, SNARK:<6.MONITOR>NSPSRV.MAC.78, 27-Aug-82 07:05:35 by GRANT
;TCO 5.1.1057 - make proper check for remote node's NSP version
; UPD ID= 1112, SNARK:<6.MONITOR>NSPSRV.MAC.77, 25-Aug-82 11:55:01 by GRANT
;TCO 5.1.1055 - check for CC sent state in MTRDCK
; UPD ID= 1111, SNARK:<6.MONITOR>NSPSRV.MAC.76, 25-Aug-82 10:13:46 by GRANT
;TCO 5.1.1054 - prevent CLZRUN from wrongly sending 0-length data messages
; UPD ID= 1107, SNARK:<6.MONITOR>NSPSRV.MAC.75, 25-Aug-82 06:05:29 by GRANT
;TCO 6.1236 - change FILBFI to FILBNO
; UPD ID= 1091, SNARK:<6.MONITOR>NSPSRV.MAC.74, 18-Aug-82 09:24:55 by GRANT
;TCO 5.1692 - incorrect test at SQI4
; UPD ID= 1074, SNARK:<6.MONITOR>NSPSRV.MAC.73, 10-Aug-82 12:01:31 by GRANT
;TCO 5.1.1051 - Change RETBAD to JRST SRCFAL in SRCOPN
; UPD ID= 1073, SNARK:<6.MONITOR>NSPSRV.MAC.72, 10-Aug-82 11:30:21 by GRANT
;TCO 5.1.1050 - Change RETERR to RET in DCNOPN's GTOKM
; UPD ID= 1059, SNARK:<6.MONITOR>NSPSRV.MAC.71, 9-Aug-82 15:43:59 by PAETZOLD
;TCO 6.1219 - Extend DCNDTB and SRVDTB for RLJFD
; UPD ID= 993, SNARK:<6.MONITOR>NSPSRV.MAC.70, 18-Jul-82 13:51:26 by MURPHY
;TCO 5.1.1048 - Check LLTTA when closing; keep LL block locked until return
; from TTSETH.
; UPD ID= 987, SNARK:<6.MONITOR>NSPSRV.MAC.69, 15-Jul-82 09:17:51 by GRANT
;TCO 5.1.1045 - In NTSNH, unlock LL block when call to TTYSRV fails
; UPD ID= 974, SNARK:<6.MONITOR>NSPSRV.MAC.68, 6-Jul-82 09:27:02 by GRANT
;TCO 5.1.1042 - Make NSLDWS resident
; UPD ID= 969, SNARK:<6.MONITOR>NSPSRV.MAC.67, 30-Jun-82 08:39:54 by GRANT
;TCO 5.1.1037 - setting local node number requires privileges
; UPD ID= 943, SNARK:<6.MONITOR>NSPSRV.MAC.66, 17-Jun-82 09:46:33 by GRANT
;TCO 5.1.1035 - make interrupt messages work again
; UPD ID= 871, SNARK:<6.MONITOR>NSPSRV.MAC.65, 8-Jun-82 08:23:02 by GRANT
;Rewrite UNQSEG
; UPD ID= 869, SNARK:<6.MONITOR>NSPSRV.MAC.64, 7-Jun-82 16:57:32 by GRANT
;More fixing of TCO 5.1.1022
; UPD ID= 854, SNARK:<6.MONITOR>NSPSRV.MAC.63, 7-Jun-82 08:06:03 by GRANT
;TCO 5.1.1033 - Return proper error message in NANUE2
; UPD ID= 836, SNARK:<6.MONITOR>NSPSRV.MAC.62, 4-Jun-82 21:49:06 by GRANT
;Fix bug in TCO 5.1.1022 change - RESBAZ and RESCHK problems fixed
; UPD ID= 833, SNARK:<6.MONITOR>NSPSRV.MAC.61, 4-Jun-82 16:02:27 by MURPHY
;Now put all BUGs in-line.
; UPD ID= 823, SNARK:<6.MONITOR>NSPSRV.MAC.59, 3-Jun-82 13:31:10 by PAETZOLD
;Fix assembly error due to new and improved bug handling
; UPD ID= 818, SNARK:<6.MONITOR>NSPSRV.MAC.58, 3-Jun-82 07:30:02 by GRANT
;TCO 6.1153 - Fix protocol error of sending data before LS ACK
; UPD ID= 804, SNARK:<6.MONITOR>NSPSRV.MAC.57, 1-Jun-82 11:32:27 by MURPHY
;TCO 6.1147 - Move bug defs from BUGS.MAC to here.
; UPD ID= 703, SNARK:<6.MONITOR>NSPSRV.MAC.56, 9-May-82 11:41:47 by HALL
;TCO 6.1000- Support the 2080
; At TSKINI, establish full word of user flags
; UPD ID= 684, SNARK:<6.MONITOR>NSPSRV.MAC.55, 4-May-82 12:03:37 by GRANT
;TCO 5.1.1032 - turn off LLNLS and LLALS in ACKLI not in SNDACK
; UPD ID= 673, SNARK:<6.MONITOR>NSPSRV.MAC.54, 30-Apr-82 13:27:28 by GRANT
;TCO 5.1.1031 - make NTMAN% set and read retransmit factor
; UPD ID= 666, SNARK:<6.MONITOR>NSPSRV.MAC.53, 28-Apr-82 10:42:22 by GRANT
;TCO 5.1.1029 - Process all incoming, non-control messages at scheduler level
; UPD ID= 656, SNARK:<6.MONITOR>NSPSRV.MAC.52, 22-Apr-82 13:54:26 by GRANT
;TCO 5.1.1028 - apply Local Delay Factor in proper place
; UPD ID= 650, SNARK:<6.MONITOR>NSPSRV.MAC.51, 16-Apr-82 12:26:47 by GRANT
;TCO 5.1.1027 - Unlock LL block when CALL ASMCB fails
; UPD ID= 649, SNARK:<6.MONITOR>NSPSRV.MAC.50, 16-Apr-82 07:45:42 by GRANT
;TCO 5.1.1026 - Let background task wake up whenever it has a message to process
; UPD ID= 641, SNARK:<6.MONITOR>NSPSRV.MAC.49, 14-Apr-82 11:16:11 by GRANT
;Performance improvement to TCO 5.1.1022
; UPD ID= 635, SNARK:<6.MONITOR>NSPSRV.MAC.48, 13-Apr-82 15:18:11 by GRANT
;TCO 5.1.1025 - Make Local Delay Factor and Local Delay Weight settable and
;readable by NTMAN%
; UPD ID= 634, SNARK:<6.MONITOR>NSPSRV.MAC.47, 13-Apr-82 14:29:02 by GRANT
;Slight modification to TCO 5.1.1023 - send LS messgae earlier
; UPD ID= 602, SNARK:<6.MONITOR>NSPSRV.MAC.46, 6-Apr-82 10:52:37 by GRANT
;Undo more debugging code
; UPD ID= 562, SNARK:<6.MONITOR>NSPSRV.MAC.45, 31-Mar-82 14:17:24 by GRANT
;TCO 5.1.1024 - Impose a minimum on the round trip calculation
; UPD ID= 560, SNARK:<6.MONITOR>NSPSRV.MAC.44, 31-Mar-82 14:00:04 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= 548, SNARK:<6.MONITOR>NSPSRV.MAC.43, 23-Mar-82 06:50:05 by GRANT
;Undo previous edit
; UPD ID= 547, SNARK:<6.MONITOR>NSPSRV.MAC.42, 22-Mar-82 11:28:12 by GRANT
;TCO 5.1.1021 - Release message block in DCDCS
; UPD ID= 543, SNARK:<6.MONITOR>NSPSRV.MAC.41, 21-Mar-82 18:24:36 by GRANT
;TCO 5.1.1020 - NAK "too new" segments from Phase II nodes
; UPD ID= 539, SNARK:<6.MONITOR>NSPSRV.MAC.40, 19-Mar-82 17:33:57 by MURPHY
;TCO 5.1.1019 - Make NSPTST wake up less often.
; UPD ID= 518, SNARK:<6.MONITOR>NSPSRV.MAC.39, 17-Mar-82 13:12:31 by GRANT
;TCO 5.1.1018 - Check for CCS state in NTMTCZ
; UPD ID= 509, SNARK:<6.MONITOR>NSPSRV.MAC.38, 16-Mar-82 09:36:51 by GRANT
;TCO 5.1.1017 - Change state transition table for CLOSF in CCS state
; UPD ID= 508, SNARK:<6.MONITOR>NSPSRV.MAC.37, 16-Mar-82 09:16:24 by GRANT
;TCO 5.1.1016 - Remove check for 0 bytes in CLZRUN
; UPD ID= 486, SNARK:<6.MONITOR>NSPSRV.MAC.36, 15-Mar-82 08:59:45 by GRANT
;TCO 5.1.1015 - CALL FLUSH in DCDCS
; UPD ID= 470, SNARK:<6.MONITOR>NSPSRV.MAC.35, 12-Mar-82 08:10:22 by GRANT
;Minor change to UPD 461
; UPD ID= 467, SNARK:<6.MONITOR>NSPSRV.MAC.34, 11-Mar-82 21:35:48 by GRANT
;Fix typo in UPD 450
; UPD ID= 463, SNARK:<6.MONITOR>NSPSRV.MAC.33, 11-Mar-82 16:34:13 by GRANT
;TCO 5.1.1014 - CALL BLKLLK in DATCSS
; UPD ID= 462, SNARK:<6.MONITOR>NSPSRV.MAC.32, 11-Mar-82 16:20:00 by GRANT
;TCO 5.1.1012 - Reset inactivity wake up even if nothing to do
; UPD ID= 461, SNARK:<6.MONITOR>NSPSRV.MAC.31, 11-Mar-82 16:04:23 by GRANT
;TCO 5.1.1013 - Don't turn off inactivity timer unless LS message gets sent
; UPD ID= 460, SNARK:<6.MONITOR>NSPSRV.MAC.30, 11-Mar-82 15:56:40 by GRANT
;TCO 5.1.1011 - Make scheduler send ACKs every 200 milliseconds.
;Previous edit should be TCO 5.1.1010
; UPD ID= 459, SNARK:<6.MONITOR>NSPSRV.MAC.29, 11-Mar-82 15:45:52 by GRANT
;TCO 5.1.1011 - Always go to LLSRVR upon leaving NSPCH7
; UPD ID= 450, SNARK:<6.MONITOR>NSPSRV.MAC.28, 9-Mar-82 14:40:34 by GRANT
;TCO 5.1.1009 - Make .NDGNT function of NODE% return info even on failure
; UPD ID= 449, SNARK:<6.MONITOR>NSPSRV.MAC.27, 9-Mar-82 09:58:50 by GRANT
;Add missing ENDIF. in UPD 445
; UPD ID= 446, SNARK:<6.MONITOR>NSPSRV.MAC.26, 6-Mar-82 21:32:44 by GRANT
;TCO 5.1.1008 - Use BLKSIZ in node init
; UPD ID= 445, SNARK:<6.MONITOR>NSPSRV.MAC.25, 6-Mar-82 21:17:09 by GRANT
;TCO 5.1.1006 - Rewrite ONTIMQ and UNQTIM
; UPD ID= 409, SNARK:<6.MONITOR>NSPSRV.MAC.24, 17-Feb-82 16:07:22 by GRANT
;TCO 5.1.1005 - ACKCCS needs to use CALL BLKLLK instead of CALL BLKLOK
; UPD ID= 398, SNARK:<6.MONITOR>NSPSRV.MAC.23, 12-Feb-82 15:53:44 by GRANT
;TCO 5.1729 - NSPINT no longer loaded, remove calls to OUTSEG
; UPD ID= 388, SNARK:<6.MONITOR>NSPSRV.MAC.22, 6-Feb-82 21:10:53 by GRANT
;Undo duplicated code in NTMAN% - probably caused by REDIT
; UPD ID= 387, SNARK:<6.MONITOR>NSPSRV.MAC.21, 6-Feb-82 14:14:19 by LEACHE
;TCO 5.1721 Make NODE JSYS function .NDGLN use 30-bit addressing
; UPD ID= 381, SNARK:<6.MONITOR>NSPSRV.MAC.20, 5-Feb-82 09:25:35 by GRANT
;TCO 5.1.1004 - put in call to the new code
; UPD ID= 380, SNARK:<6.MONITOR>NSPSRV.MAC.19, 5-Feb-82 08:04:49 by GRANT
;TCO 5.1.1004 - figure out "number of active links" in the NTMAN% JSYS
; UPD ID= 271, SNARK:<6.MONITOR>NSPSRV.MAC.18, 5-Jan-82 08:57:37 by GRANT
;TCO 5.1649 - Add null message handling
; UPD ID= 251, SNARK:<6.MONITOR>NSPSRV.MAC.17, 13-Dec-81 10:55:23 by GRANT
;TCO 5.1636 - use SEGSZ
; UPD ID= 239, SNARK:<6.MONITOR>NSPSRV.MAC.16, 7-Dec-81 12:09:50 by GRANT
;TCO 5.1.1002 - return scheduler test when ACKRMT fails
; UPD ID= 233, SNARK:<6.MONITOR>NSPSRV.MAC.15, 4-Dec-81 14:06:10 by GRANT
;More TCO 5.1503 - make consistent use of symbols
; UPD ID= 231, SNARK:<6.MONITOR>NSPSRV.MAC.14, 4-Dec-81 08:54:48 by GRANT
;TCO 5.1626 - In NODINI, make an extensible field for the node number.
;Another attempt at TCO 5.1510
; UPD ID= 198, SNARK:<6.MONITOR>NSPSRV.MAC.13, 9-Nov-81 11:25:44 by GRANT
;TCO 5.1.1001 - add explicit check for 8-bit bytes in NTMAN%
; UPD ID= 197, SNARK:<6.MONITOR>NSPSRV.MAC.12, 9-Nov-81 10:47:57 by GRANT
;Under DN20SW, enhance checking for multiple MCBs
; UPD ID= 193, SNARK:<6.MONITOR>NSPSRV.MAC.11, 6-Nov-81 13:40:52 by MURPHY
;Make monitor fork start in section 1.
; UPD ID= 182, SNARK:<6.MONITOR>NSPSRV.MAC.10, 4-Nov-81 08:58:45 by GRANT
;TCO 5.1604 - Only do inactivity checking when link is in the run state
; UPD ID= 156, SNARK:<6.MONITOR>NSPSRV.MAC.9, 22-Oct-81 09:01:53 by GRANT
;TCO 5.1593 - Defensive code in RESEND to prevent looping caused by bad counter
; UPD ID= 148, SNARK:<6.MONITOR>NSPSRV.MAC.8, 21-Oct-81 12:07:45 by GRANT
;TCO 5.1594 - Create TTGETS and TTREMS for TTYSRV to use
; UPD ID= 147, SNARK:<6.MONITOR>NSPSRV.MAC.7, 21-Oct-81 10:09:19 by GRANT
;TCO 5.1592 - Fix failure return in LLSRVR
; UPD ID= 126, SNARK:<6.MONITOR>NSPSRV.MAC.6, 19-Oct-81 10:17:14 by GRANT
;TCO 5.1587 - fix segment number wrap around in VERSEG
; UPD ID= 125, SNARK:<6.MONITOR>NSPSRV.MAC.5, 19-Oct-81 10:00:37 by MCINTEE
;Make entry point for monitor in NDVFY (for GTJFN)
; UPD ID= 109, SNARK:<6.MONITOR>NSPSRV.MAC.4, 15-Oct-81 14:18:49 by GRANT
;Fix bug in TCO 5.1534
;<6.MONITOR>NSPSRV.MAC.3, 9-Oct-81 17:43:51, EDIT BY MURPHY
;Change DTB format, eliminate double skips, etc.
;Put source into M60:
; 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 BE USED
;OR COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (C) DIGITAL EQUIPMENT CORPORATION 1976, 1984.
;ALL RIGHTS RESERVED.
SEARCH NSPPAR,PROLOG
TTITLE (NSPSRV,,< - Network Services Protocol Interface to TOPS20 >)
EXTERN ASGDCN,RELDCN
;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==1 ;SWITCH FOR DEBUGGING
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)
SUBTTL Device Dispatch Vectors for SRV: and DCN: Devices
;FOR DEVICE SRV
SWAPCD
SRVDTB::SRVDTL
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
DTBSKP ;RELEASE JFN
SRVDTL==:.-SRVDTB
;FOR THE DCN DEVICE
DCNDTB::DCNDTL
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
DTBSKP ;RELEASE JFN
DCNDTL==:.-DCNDTB
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
TRVAR <NTCNT,NTPNT,NTOBJ,NTDDSC,NTDSS>
CALL SRCNAM ;GO PARSE THE NAME
RETBAD() ;HAD AS ERROR
OKRET: TQNE <UNLKF> ;WANT TO UNLOCK?
RETSKP ;NO. RETURN
OKINT ;YES. GO OKINT THEN
RETSKP ;AND RETURN
;ROUTINE TO DO NAME LOOKUP FOR DCN DEVICE
DCNSET::JUMPE T1,[RETBAD (GJFX18,<OKINT>)] ;CANT'T STEP IT
TRVAR <NTCNT,NTPNT,NTOBJ,NTDSC,NTDSS,NTHST,NTHSC>
CALL DCNNAM ;GO PARSE NAME
RETBAD() ;SOME SORT OF ERROR
JRST OKRET ;AND DONE
;EXTENSION CHECKER
EXTSET::JUMPE T1,[RETBAD (GJFX18,<OKINT>)] ;CANT'T STEP IT
TRVAR <NTCNT,NTPNT>
CALL NETEXT ;CHECK EXTENSION
RETBAD() ;SOME SORT OF ERROR
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
RETSKP ;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,FILBNO(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 FILBNO(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,LLDBUG(T1) ;PUT IT IN BLOCK (LLMSIT IS NOT USED)
>
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,<
RESCD
LLSIGN==101010 ;THE VERIFICATION SYMBOL
CHKLLB: PUSH P,T2 ;PRESERVE T2
MOVE T2,LLDBUG(T1) ;GET THE VERIFICATION WORD
CAIE T2,LLSIGN ;IS IT GOOD?
BUG. (HLT,NSPLLC,NSPSRV,SOFT,<NSPSRV: Logical link block check failed>,<<T1,BADBLK>>,<
Cause: Logical link block verification failed. NSP believes a resident free
space block contains a logical link block but something is wrong.
Most likely, resident free space has been clobbered.
Data: BADBLK - the address of the block
>)
POP P,T2 ;OK, RETRIEVE T2
RET ;YES
SWAPCD
>
;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,FLATL,(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 FILBNO(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
CAIL T2,.MOACN ;TOO SMALL?
CAILE T2,.MOSNH ;OR TOO BIG?
SKIPA ;ILLEGAL RETURN AN ERROR
CALLRET @NTMTTB-.MOACN(T2) ;DO THE FUNCTION
MOVE T1,FILLLB(JFN) ;ILLEGAL, GET LOGICAL LINK BLOCK ADDRESS
CALL BLKULK ;UNLOCK THE BLOCK
RETBAD (MTOX1) ;FAIL
NTMTTB: DTBDSP (MTASGN) ;24 - .MOASN - ASSIGN CONNECT INTERRUPT CHANNEL
DTBDSP (NTSTS) ;25 - .MORLS - READ LINK STATUS
DTBDSP (NTRHN) ;26 - .MORHN - READ FOREIGN HOST NAME
DTBDSP (NTRTN) ;27 - .MORTN - READ LINK TASK NAME
DTBDSP (NTRUS) ;30 - .MORUS - READ USER STRING
DTBDSP (NTRPW) ;31 - .MORPW - READ PASSWORD
DTBDSP (NTRAC) ;32 - .MORAC - READ ACCOUNT STRING
DTBDSP (NTRDA) ;33 - .MORDA - READ OPTIONAL DATA
DTBDSP (NTRCN) ;34 - .MORCN - READ CONNECT OBJECT NUMBER
DTBDSP (MTRDIN) ;35 - .MORIM - READ INT MESSAGE
DTBDSP (MTSNIN) ;36 - .MOSIM - SEND INT MESSAGE
DTBDSP (NTRCOB) ;37 - .MOROD - READ OBJ-DESC OF CONNECT OBJECT
DTBDSP (NTMTCZ) ;40 - .MOCLZ - CLOSE/REJECT A CONNECTION
DTBDSP (NTACPT) ;41 - .MOCC - ACCEPT A CONNECTION
DTBDSP (MTGSS) ;42 - .MORSS - GET LINK SEGMENT SIZE
DTBDSP (NTANT) ;43 - .MOANT - ATTACH NETWORK TERMINAL
DTBDSP (NTSNH) ;44 - .MOSNH - SET NETWORK HOST FOR TERMINAL
;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 FILBNO(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,FILBNO(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.(INF,NDINIT,NSPSRV,SOFT,<NSP - Could not add first entry to node table>,,<
Cause: This BUG is not documented yet.
Action:
Data:
>)
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
SETZM LLNUM ;INIT THE IN-USE LL COUNT
MOVX T1,1B1 ;MAKE FORK HAVE ALL CAPS
SETZ T2,
CFORK ;GET A FORK
BUG.(HLT,NSPFRK,NSPSRV,SOFT,<NSPINI-CFORK FAILED>,<<T1,REASON>>,<
Cause: When the system comes up, a fork is created under JOB 0 in which
the DECnet NSP background task runs. The monitor was unable to
create the fork.
Data: REASON - the reason code returned by the CFORK JSYS when it failed.
>)
MOVE T2,[MSEC1,,TSKINI] ;THE STARTING ADDRESS
MSFRK ;START IT
MOVX T1,.NDOFF ;SAY WE ARE
STOR T1,SCSTA ; OFF - NML MUST TURN US ON
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.(CHK,LLLKBD,NSPSRV,SOFT,<UNLOCK LL LOCK WHEN NOT LOCKED>,,<
Cause: Call to unlock logical link lock when it was not locked.
Action: Continue.
Data: None
>)
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
IFN NSPSW,<
SKIPGE LLLLCK ;ENSURE OUTER LOCK ALREADY SET
BUG. (HLT,NSPLOK,NSPSRV,SOFT,<NSPSRV: Can't lock logical link block>,,<
Cause: An attempt is being made to obtain the lock on a logical link block
without already owning the master lock. This is illegal.
>)
SKIPE INSKED ;MAKE SURE ONLY PROPER SCHEDULER CONTEXT
SKIPGE FORKX
SKIPA
BUG. (HLT,NSPCON,NSPSRV,SOFT,<NSPSRV: Can't lock logical link block>,,<
Cause: An attempt is being made to obtain the lock on a logical link block
but we are in an improper scheduler context. Code calling this routine
from scheduler level should already have realized this.
>)
> ;END IFN NSPSW
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: MOVSI T1,-LLBIT ;GET WORDS IN BIT TABLE
SETOM LLBITS(T1) ;SAY THEY ARE
AOBJN T1,.-1 ; ALL AVAILABLE
MOVSI T1,400000 ; EXCEPT
ANDCAM T1,LLBITS ; LL 0
RET
;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
REPEAT 0,<
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.(CHK,NSPPWA,NSPSRV,HARD,<LOKPIP - Pipe went away>,,<
Cause: This BUG is not documented yet.
Action:
Data:
>)
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.(CHK,NSPPHV,NSPSRV,HARD,<ULKPIP - Pipe has vanished>,,<
Cause: This BUG is not documented yet.
Action:
Data:
>)
RET ] ;UNLOCK THE TREE AND RETURN FAILURE
LLLULK ;UNLOCK THE TREE
CALLRET BLKULK ;UNLOCK PIPE AND RETURN
> ;END OF REPEAT 0 AT LOKPIP
;ROUTINE TO FIND LOGICAL LINK BLOCK
;ACCEPTS: T1/ LOGICAL LINK ID
; T2/ FOREIGN LINK I.D. -1 FOR ANY
;RETURNS: +1 FAILED. LINK NOT FOUND
; +2 SUCCESS. T1/ ADDRESS OF LL BLOCK
;PRESERVES T4
RESCD ;NEEDS TO BE RESIDENT
LLLKUP::MOVE T3,T1 ;PRESERVE LINK ID
ANDI T1,MAXLNK ;GET THE LOCAL PART
SKIPN T1,LLIDS(T1) ;IS THERE AN LL BLOCK?
RET ;NO
OPSTR <CAME T3,>,LLLNK,(T1) ;YES, THE RIGHT ONE?
RET ;NO
SKIPGE T2 ;YES, WANT REMOTE LINK MATCH?
RETSKP ;NO
OPSTR <CAME T2,>,LLHLK,(T1) ;YES, DOES IT MATCH?
RETBAD (NSPX2) ;NO
RETSKP ;YES
;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 ID TABLE. WILL ALSO DO SCAN OF ENTIRE TABLE
;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/ LOGICAL LINK BLOCK ADDRESS
; T2/ LOGICAL LINK I.D.
;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 BLOCK
; ALL OF THE P 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::ACVAR <LUP,TRY,GUD>
SETZB TRY,GUD ;INIT "GOOD OBJECT" FLAG AND NUMBER TRIED COUNT
DMOVE T3,T1 ;SAVE ARGS
SKIPE LLNUM ;ANY LINKS IN USE?
IFSKP.
MOVEI T2,.DCX4 ;NO, GO NO FURTHER
RET
ENDIF.
MOVSI LUP,-MAXLNK ;AOBJN WORD TO SEARCH ID TABLE
AOS LUP ;LINK IDS BEGIN WITH 1
OBJSR1: SKIPN T1,LLIDS(LUP) ;THIS ID IN USE?
JRST OBJSR3 ;NO
AOS TRY ;INCR COUNTER
JUMPL T4,OBJSR2 ;IF ANY MATCH, TRY THIS ONE
JE LLFOB,(T1),OBJSR3 ;MUST BE OBJECT, IF NOT AN OBJECT, MOVE ON
SKIPG T4 ;HAVE TO BE LISTENING?
IFSKP.
LOAD T2,LLSTA,(T1) ;YES, GET THE STATE OF THE LINK
CAIE T2,LLSLIS ;LISTENING?
JRST OBJSR3 ;NO
ENDIF.
OBJSR2: SKIPN T3 ;HAVE A COROUTINE?
IFSKP.
CALL (T3) ;YES, GO DO IT
JRST OBJSR3 ;DON'T WANT THIS ONE
ENDIF.
SETOM GUD ;FOUND A GOOD OBJECT
LOAD T2,LLLNK,(T1) ;GET LINK ID
RETSKP
OBJSR3: CAMGE TRY,LLNUM ;TRIED ALL LINKS IN USE?
AOBJN LUP,OBJSR1 ;NO, DO NEXT LINK ID
MOVEI T2,.DCX4 ;SERVER DOESN'T EXIST
SKIPE GUD ;DID WE FIND THE RIGHT TYPE OF SERVER?
MOVEI T2,.DCX33 ;YES, SAY SERVER IS BUSY
RET
ENDAV.
;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 ASGDCN ;GO GET A BLOCK
RET ;NO MORE SPACE
MOVEM T1,TSKBLK ;SAVE ADDRESS
GETTS1: MOVE T4,T1 ;GET ADDRESS IN T4
HRLZI T1,(<POINT 7,(T4)>) ;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
SETZM LLIDS(T1) ;FREE THE SLOT
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
SOS LLNUM ;ONE LESS LINK IN USE
RET ;AND DONE
;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
GETRES::SKIPE RESNET ;LOW ON SPACE?
RETBAD (MONX07) ;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
RETBAD (MONX07) ;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::LOAD T3,SCSTA ;GET NODE STATE
CAIE T3,.NDOFF ;ARE WE OFF?
CAIN T3,.NDSHT ;OR SHUT?
RETBAD (NSPX27) ;YES, LOCAL NODE SHUT
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
; BECAUSE COROUTINES ACCESS THE VARIABLES.
MOVEM T1,SAVSTR ;SAVE STRING BLOCK ADDRESS
MOVEM T2,SAVBSZ ;SAVE BYTE SIZE
MOVEM T3,SAVERR ;SAVE SIZE OF BLOCK OVER SUBROUTINE CALL
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 ASGDCN ;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 RELDCN ;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 ASGDCN ;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 ASGDCN ;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 RELDCN ;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
LOAD T2,FKJO%,(T2) ;GET FORK'S JOB NUMBER
MOVE T4,FORKX ;GET THIS FORK'S NUMBER
OPSTR <CAMN T2,>,FKJO%,(T4) ;SAME JOB NUMBER?
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 [
REPEAT 0,<
MOVE T2,SAVCAL ;DIDN'T FIND IT, RETRIEVE CALLER'S PC
BUG.(INF,DELNDF,NSPSRV,SOFT,<DELNOD-LLLKUP FAILED>,<<T2,CALLER>>,<
Cause: An attempt to remove a DECnet logical link block from the data
base failed.
ACTION: THIS SHOULD BE EASILY RECOVERED FROM BY THE MONITOR.
IF IT PERSISTS, CHANGE IT TO A BUGHLT AND LOOK AT THE DUMP.
THE ROUTINE MAKING THE CALL TO DELNOD SHOULD BE A VERY GOOD
CLUE AS TO WHY THIS IS OCCURRING.
Data: CALLER - PC of the calling routine
>) > ;END REPEAT 0
RET] ;ALL DONE
LOAD T1,LLLNK,(T1) ;GET ADDRESS
CALL FRELNK ;RELEASE THE LINK #
MOVE T1,SAVBLK ;GET BACK BLOCK ADDRESS
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 RELDCN ;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
REPEAT 0,<
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.(CHK,NSPLNQ,NSPSRV,SOFT,<REMQUE - Link not queued>,,<
Cause: This BUG is not documented yet.
Action:
Data:
>)
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
> ;END REPEAT 0 AT REMQUE
;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 ASGDCN ;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 AND FILL IN LLIDS
;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 T3,T1 ;PRESERVE UNIQUE 7 BITS
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
SKIPE LLIDS(T3) ;IS THERE ONE ALREADY THERE?
BUG.(HLT,ADDONF,NSPSRV,SOFT,<ADDOBJ-LLLKUP FAILED>,,<
Cause: An attempt was made to add a new DECnet logical link to the data
base and it was discovered that the logical link was already there.
Action: Look at the dump. You should be able to tell which routine handed
ADDLNK the bad block number.
>)
MOVEM T1,LLIDS(T3) ;PUT LL BLOCK ADDRESS IN ID TABLE
AOS LLNUM ;ONE MORE LINK ID IN USE
RETSKP ;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,NTLLB>
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
MOVEM W1,NTLLB ;STASH IT FOR OBJSRC AND ITS COROUTINES
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 ASGDCN ;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?
LOAD T2,FKJO%,(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
MOVE T4,NTLLB ;GET LL BLOCK
LOAD T2,LLNAM,(T1) ;GET OBJECT NUMBER
OPSTR <CAME T2,>,LLNAM,(T4) ;SAME AS OURS?
RET ;NO. NO CONFLICT THEN
LOAD T1,LLDSC,(T1) ;GET ITS DESCRIPTOR
LOAD T2,LLDSC,(T4) ;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 USER/PASSWORD/ACCOUNT
GTSBLK: MOVEI T1,SIZ39 ;THE PROPER SIZE
CALL ASGDCN ;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 RELDCN ;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
AOS @[EP. NSCONS(T3)] ;INCR THE CONNECTS SEND 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: SAVEAC <STS,JFN,P3> ;SAVE SOME AC'S
MOVE STS,T1 ;COPY POINTER TO FIRST STRING
MOVE JFN,T2 ;COPY POINTER TO SECOND STRING
HRRZ P3,T3 ;SAVE COUNT
SOS P3 ;FIXUP COUNTER FOR THE LOOP
CMPRLP: ILDB T1,STS ;GET NEXT BYTE
ILDB T2,JFN ;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 P3,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 P3,JFN ;NO, GET THE NEXT BYTE
SKIPE P3 ;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,FLATL,(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
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
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,NTRHN2 ;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
SETZ T4, ;PUT NULL ON END
NTRHN2: UMOVEM T3,3 ;UPDATE BYTE POINTER
XCTBU [IDPB T4,T3] ;GIVE HIM THE NULL
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
RESCD
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
SWAPCD
;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
REPEAT 0,<
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
> ;END REPEAT 0
;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
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
RETBAD () ;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 SEGMENT SIZE FOR THE LINK
MTGSS:: LOAD T2,LLSWG,(T1) ;GET SEG SIZE
SKIPE T2 ;SET UP YET?
IFSKP.
MOVEI T1,DCNX16 ;NO
JRST SQOBAD ;FAIL
ENDIF.
UMOVEM T2,3 ;YES, 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
TMNN LLFLO,(T1) ;FLOW NOW TO F/S?
JRST [ JUMPE T3,CLZCMS ;YES, IF NO MORE BYTES TO SEND, MOVE ON
JRST CLZDI0] ;GO FORCE OUT REMAINING BYTES
JUMPE T2,CLZCMS ;NO, ANY BYTES TO SEND?
SETONE LLFEM,(T1) ;YES, SAY EOM IN THIS BUFFER
CLZDI0: CALL OUTRR ;GO FORCE OUT DATA
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 FILBNO(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.(INF,CLZDIN,NSPSRV,SOFT,<CLZSDI - Could not send DI>,,<
Cause: This BUG is not documented yet.
Action:
Data:
>)
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,FILBNO(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
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
RETBAD () ;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
CHKSCT: SETOM T2 ;ANY REMOTE LINK FOR NOW
CALL LLLKUP ;GET LL BLOCK ADDRESS
JRST 1(T4) ;NOT THERE ANYMORE, WAKE
LOAD T2,LLSTA,(T1) ;GET STATE OF LL
CAIE T2,LLSRUN ;RUNNING?
JRST 1(4) ;NO, WAKE
JN LLMSM,(T1),1(4) ;YES, IF SOME ACKS, WAKE UP
JRST 0(4) ;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
;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,FILBNO(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,FILBNO(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,FILBNO(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,FILBNO(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
MOVE 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
MOVE 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
MOVE T2,LLOMSG(T1) ;GET EXPENDED MESSAGE
LOAD T3,MSLNK,(T2) ;GET NEXT
SKIPN T3 ;QUEUE NOW EMPTY
MOVEM T3,LLOMST(T1) ;YES, RESET THE TAIL
MOVEM 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,@FILBNO(JFN) ;STORE ODD WORD
AOS FILBNO(JFN) ;MOVE TO NEXT WORD
JRST SQIWR3] ;AND DONE
DMOVEM Q1,@FILBNO(JFN) ;STORE BOTH WORDS
MOVEI Q1,2 ;INCREMENTER
ADDM Q1,FILBNO(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
REPEAT 0,<
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
> ;END REPEAT 0
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,USRCTX
MOVEM T1,FFL ;ESTABLISH USUAL JSYS CONTEXT
SETZM FPC ;SET PC
MCENTR ;GET INTO MONITOR CONTEXT
MOVE T1,FORKX ;GET SYSTEM WIDE FORK NUMBER
MOVEM T1,DNTFRK ;RECORD IT
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
MDISMS ;DISMISS, DO NOT STAY IN BALANCE SET
JRST NSPTSK ;AND TRY AGAIN
;SEE IF ANY LL BLOCKS LEFT BY TTY TO CLOSE AND CLEAN UP
MCBCQ: SAVEAC <F1>
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.
CALL BLKLOK ;GET LL BLOCK LOCK
IFNSK.
LLLULK ;CAN'T RIGHT NOW, GIVE UP LL TREE LOCK
JRST MCBCQ2 ;MOVE ON
ENDIF.
CALL FLUSH ;GET RID OF LINK'S MESSAGES
CALL DELNOD ;GET RID OF THE LL BLOCK
LLLULK ;GIVE UP THE LL TREE LOCK
OKINT ;MATCH THE NOINT IN BLKLOK
DECR DCCUR ;ONE LESS LL
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
JRST [ SETZM INNSPT ;NO LONGER IN TIMER
CALLRET ULOKLL] ;GIVE UP TREE LOCK
MOVEM T2,MSGADR ;STASH THE MESSAGE ADDRESS
LOAD T1,MSLLA,(T2) ;GET THE LL ID
SETOM T2 ;ANY MATCH
CALL LLLKUP ;GET THE LL BLOCK ADDRESS
JRST [
REPEAT 0,<
BUG.(INF,NSPGON,NSPSRV,SOFT,<NSP - Logical link look up failed>,,<
Cause: The NSP timer has discovered a message on its resend queue and
the logical link owning the message is no longer in the logical
link data base.
Action:
>) > ;END REPEAT 0
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
JRST [ SETZM INNSPT ;CAN'T, NO LONGER IN TIMER
CALLRET ULOKLL] ;GIVE UP TREE LOCK
LOAD T3,LLLKP,(T1) ;GET NODE'S VERSION
CAIN T3,.NSP31 ;IS IT NSP 3.1?
JRST NSPTM7 ;YES, DON'T TIME IT
MOVE T2,MSGADR ;RETRIEVE THE MESSAGE ADDRESS
TMNN LLBRP,(T1) ;NO, IS FLOW TURNED OFF?
IFSKP. ;YES
LOAD T4,MSTOM,(T2) ;GET TYPE OF MSG
CAIN T4,MSDAT ;IS IT NORMAL DATA?
JRST NSPTM7 ;YES, CAN'T RESEND NORMAL DATA WHEN FLOW IS OFF
ENDIF.
MOVE T3,LLTIMO(T1) ;GET TIME OUT VALUE FOR LINK
IMUL T3,NSLDFS ;SCALE IT BY
IDIVI T3,^D16 ; LOCAL DELAY FACTOR
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
SETZM INNSPT ;NO LONGER IN TIMER
CALLRET ULOKLL ;GIVE UP TREE LOCK
NSPTMO: CALL DATINR ;GIVE INTERRUPT TO USER
LOAD T4,LLHSN,(T1) ;GET THE REMOTE NODE NUMBER
AOS @[EP. NSTIMO(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.(INF,NSPLAT,NSPSRV,SOFT,<NSP response is LATE>,<<T4,NODE>>,<
Cause: NSP has resent a message a number of times and received no response.
Action: Normally this is caused by heavy network traffic or a highly
congested node in the network; the network software should continue
to function without major difficulty. If the condition persists,
check the quality of the communication path to the node that is not
responding.
Data: NODE - the node number(OCTAL) to which we are trying to send
>)
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
NSPTM3: SOSGE W1 ;HAVE WE DONE OUR QUOTA?
JRST NSPTM6 ;YES, ALL DONE
SKIPE NSSNTQ ;NO, ANYTHING ON THE QUEUE?
JRST NSPTM5 ;YES, 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 LLNUM ;ANY LINKS IN USE?
RET ;NO
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
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: LOAD T3,LLHSN,(T1) ;GET NODE NUMBER
AOS @[EP. NSMSGR(T3)] ;INCR THE COUNT
LOAD T4,MSCNT,(T2) ;GET NUMBER OF BYTES IN MESSAGE
ADDM T4,@[EP. NSBYTR(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: LOAD T3,LLHSN,(T1) ;GET THE NODE NUMBER
AOS @[EP. NSMSGS(T3)] ;INCR THE COUNTER
MOVE T4,LLBPCT(T1) ;GET THE NUMBER OF BYTES IN MESSAGE
ADDM T4,@[EP. NSBYTS(T3)] ;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
MOVE T1,MSGQ ;GET FIRST MSG ON Q
LOAD T2,MSLNK,(T1) ;GET NEXT MSG
SKIPN T2 ;WAS A MESSAGE THERE?
MOVEM T2,MSGQ+1 ;NO, RESET THE TAIL
MOVEM T2,MSGQ ;MAKE NEW Q HEAD
CHNON DLSCHN ;TURN ON DTE
OKSKD1 ;AND ALLOW SCHEDULING
SETZM MSGLCL ;ASSUME LOCAL IN TRVAR
TMNE MSLCL,(T1) ;DID IT COME FROM DRIVER?
REPEAT 0,< ;2020 LOOPBACK
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]
> ;END REPEAT 0
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
MOVEI T2,MSHDR(T1) ;GET TO START OF DATA
HRLI T2,(<POINT 8,>) ;MAKE A BP TO IT
MOVEM T2,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) ;TO BADMSG IF BADLY FORMED
DOMSG: MOVE T3,MSGBLK ;GET MESSAGE BLOCK
STOR T2,MSMFL,(T3) ;SAVE FLAGS
CAIN T2,RCIMFL ;IS THIS A PHASE IV RETRANSMITTED CI?
JRST TOSMSG ;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.(CHK,NSPRTH,NSPSRV,SOFT,<NSPTSK- INVALID ROUTING HEADER>,<<T1,LINE>,<T2,BADBYT>>,<
Cause: An invalid routing header has been detected on a DECnet message.
Action: If this BUGCHK happens frequently, inform your network administrator.
Data: LINE - the number of the line which received the invalid message
BADBYT - the invalid byte
>)
JRST TOSMSG ;DONE
;RECEIVED AN UNINTELLIGIBLE MESSAGE
BADMSG: BUG.(INF,NSPBAD,NSPSRV,SOFT,<NSP has received an unintelligible message>,,<
Cause: An DECnet message has been received which was not in proper format.
Action: A pointer to most recent message which caused an NSPBAD BUGINF
is kept in BADMSP. The message block is not freed until another
NSPBAD occurs, so look in that message to find out why NSPSRV
might reject it.
>)
MOVE T1,MSGBLK ;GET MESSAGE ADDRESS
EXCH T1,BADMSP ;SAVE MOST RECENT BAD MESSAGE FOR DEBUG
JUMPE T1,R ;LEAVE IF NO OLD MSG TO FREE
CALLRET RELRES ;FREE OLD BAD MESSAGE
RS BADMSP,1 ;PLACE TO STORE PTR TO MOST RECENT BAD MSG
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 BADMSG ;YES, THROW IT AWAY
SETZM Q2 ;NO, 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
REPEAT 0,< ;2020 LOOPBACK
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:
> ;END REPEAT 0
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.(INF,NSPSTR,NSPSRV,SOFT,<STRMSG - Could not add node to known node table>,,<
Cause: This BUG is not documented yet.
Action:
Data:
>)
JRST TOSMSG ;AND GO TO IT
BADSTR: CALL PROOFF ;TURN OFF FE
BUG.(INF,ILLSTR,NSPSRV,SOFT,<NSPTSK-ILLEGAL INIT MESSAGE>,<<Q1,DTE>>,<
Cause: This BUG is not documented yet.
Action:
Data:
>)
JRST TOSMSG ;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.(CHK,NSPBPN,NSPSRV,SOFT,<BAD NSP PORT NUMBER>,<<T1,BADDTE>>,<
Cause: This BUG is not documented yet.
Action:
Data:
>)
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
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: LOAD T2,SCSTA ;GET OUR NODE STATE
CAIN T2,.NDON ;ARE WE ON?
IFSKP.
MOVEI T2,.DCX3 ;NO, "REMOTE NODE SHUTTING DOWN"
JRST CIDC ;AND REJECT THE CONNECT
ENDIF.
DSCNO2: MOVE T2,MSGBLK ;POINT TO MSG BLOCK AGAIN
LOAD T2,MSPRT,(T2) ;GET PORT MESSAGE CAME FROM
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
CAILE T2,BIGNOD ;THIS A LEGIT NODE?
JRST BADNOD ;NO
ENDIF.
DSCNO4: MOVEM T2,NDNUM ;STASH NODE NUMBER
AOS @[EP. NSCONR(T2)] ;INCR THE CONNECTS RECEIVED COUNT
AOS @[EP. NSMSGR(T2)] ;COUNT THIS MESSAGE
MOVE T3,MSGBLK ;RETRIEVE MESSAGE ADDR
LOAD T3,MSCNT,(T3) ;GET NUMBER OF BYTES IN MESSAGE
ADDM T3,@[EP. NSBYTR(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
AOS @[EP. NSRCNE(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 RELDCN ;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
BADNOD: BUG.(INF,NSPNOD,NSPSRV,SOFT,<NSP got a message from an unknown node>,,<
Cause: An incoming NSP connection attempt was from a node we don't know.
Either, it was a Phase II node and its name is not in our data base
or it was from a Phase III node and we were unable to interpret the
node number.
Action: The first case indicates that there is a node in the network whose
node name has not been assigned through NCP. If you want to
communicate with the node SET NODE number NAME name.
The second case should be filtered by the DN20. If it happens the
DN20 has a bug in Transport.
>)
MOVEI T2,.DCX7 ;UNSPECIFIED ERROR
JRST CIDC ;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
REPEAT 0,<
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
REPEAT 0,<
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: MOVE 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
ACKRUN: MOVE T2,MSGBLK ;GET MESSAGE
LOAD T2,MSMFL,(T2) ;GET FLAGS
CALL ACKDO ;GO DO THE ACTUAL ACK
JRST ABTMSG ;BADLY FORMED MESSAGE
REPEAT 0,<
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
MOVE 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
MOVE T1,DILLB ;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
OKINT ;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
; CALL TELDIS ;NOTIFY DRIVER IF THIS IS AN INTERNAL LINK
RET
;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
; CALL TELDIS ;NOTIFY DRIVER IF AN INTERNAL LINK
RET
;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
REPEAT 0,<
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
MOVE 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: MOVE 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
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
REPEAT 0,<
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
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
REPEAT 0,<
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
REPEAT 0,<
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
> ;END REPEAT 0 AT INTSET
;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: MOVEI T3,MSDAT ;ON THE DATA SUBCHANNEL
LOAD T2,LLMQI,(T1) ;GET MAX QUEUE VALUE
IFQE. LLOPI,(T1) ;Write-only?
JN LLFOB,(T1),RSKP ;Yes, if also SRV: then forget it
CLEAR T2, ;Otherwise, WO DCN: send LS so the other side
CALLRET SNDLS ; will send one back (set flow to zero)
ENDIF.
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 BP TO IT
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
REPEAT 0,< ;2020 LOOPBACK
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
> ;END REPEAT 0
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:: XMOVEI 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. ;
MOVEM T2,SMSGQ ;YES, MAKE US FIRST
MOVEM T2,SMSGQ+1 ;AND LAST
RET
ENDIF.
MOVE T4,SMSGQ+1 ;NO, 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
MOVEM T2,SMSGQ+1 ;MAKE QUEUE TAIL 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
JRST ONTMQ4 ;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
JRST ONTMQ4 ;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
ONTMQ4: SKIPE INSKED ;IN SCHEDULER?
RET ;YES
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 REMOVE A MESSAGE FROM NSSNTQ (THE TIMER) QUEUE
;
;CALL: 1/ ADDRESS OF MESSAGE
UNQTIM: SAVET
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
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
SETZM MSPRV(T1) ;WE HAVE NO MORE PREVIOUS (IN CASE OF REQUEUE)
ELSE.
MOVEM T3,MSNXT(T2) ;NO, MAKE PREVIOUS POINT TO NEXT
MOVEM T2,MSPRV(T3) ;AND NEXT POINT TO PREVIOUS
SETZM MSPRV(T1) ;WE HAVE NO MORE PREVIOUS
SETZM MSNXT(T1) ; NOR NEXT (IN CASE OF REQUEUE)
ENDIF.
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
REPEAT 0,< ;2020 LOOPBACK
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
> ;END REPEAT 0
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
REPEAT 0,<
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?
MOVEM T3,1(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 [ MOVEM T2,0(T3) ;NO, MAKE HEAD
MOVEM T2,1(T3) ; AND TAIL
JRST PUTOND] ;DONE
MOVE T4,1(T3) ;YES, GET TAIL
STOR T2,MSLNK,(T4) ;LINK THIS IN
MOVEM T2,1(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: MOVE T2,LLSEGQ(T1) ;GET HEAD OF Q
RSEND1: SKIPE T2 ;ANYTHING THERE?
IFSKP. ;NO, SHOULDN'T BE HERE
BUG.(CHK,NSPRSN,NSPSRV,SOFT,<NSP - NUMBER OF ENTRIES COUNT AND ACTUAL QUEUE LENGTH DON'T AGREE>,,<
Cause:
Action:
Data:
>)
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
MOVE T1,0(T2) ;GET HEAD
SETZM 0(T2) ;CLEAR Q HEAD
SETZM 1(T2) ; AND TAIL
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?
REPEAT 0,< ;2020 LOOPBACK
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
> ;END REPEAT 0
RETSKP ;YES, DONE
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
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
;CALLED AT INT LEVEL FROM DTESRV TO GET RESIDENT FREE SPACE
;GET A BUFFER
;AACEPTS: T1/ DTE #
; T2/ # OF BYTES REQUIRED
;RETURNS: +1 COULDN'T GET BLOCK
; +2 T1/ BLOCK ADDRESS.
NSPSPC::ASUBR <PRTNO,PRTCNT>
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 #
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)
SWAPCD
REPEAT 0,<
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.
> ;END REPEAT 0 AT OUTSND
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
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?
MOVEM T3,LLOMST(T1) ;NO, RESET THE TAIL
MOVEM T3,LLOMSG(T1) ;MAKE NEW 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
SETZM RESNET ;ASSUME WE HAVE LOTS OF SPACE
MOVEI T1,RESHLD ;GET THRESHOLD VALUE
MOVE T2,[RS%SE0+.RESNP] ;GET DECNET POOL NUMBER
CALL CHKRFS ;IS THIS MUCH LEFT?
SETOM RESNET ;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.
SKIPN T3,MSNXT(T1) ;YES, ARE WE ALSO LAST ON Q?
IFNSK.
SETZM SMSGQ ;YES, INIT THE Q HEAD
SETZM SMSGQ+1 ; AND THE TAIL
SETZM NXT ;NO NEXT MESSAGE
JRST NSPRE1 ;DONE
ENDIF.
SETZM MSPRV(T3) ;NO, MAKE NEXT MSG THE FIRST
MOVEM 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
MOVEM T2,SMSGQ+1 ;MAKE Q TAIL 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
MOVE T1,NXT ;GET NEXT MESSAGE ON Q
JUMPE T1,R ;RETURN NO NEXT MSG
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
NSPMSG::TRVAR <MSGCNT,MSGBYP,MSGSRC,MSGDST,MSGBLK,MSGLLB,<NSPDUM,11>,MSGW1>
MOVEI T2,MSHDR(T1) ;GET TO DATA PORTION
MOVEM T1,MSGBLK ;SAVE BLOCK ADDRESS
HRLI T2,(<POINT 8,>) ;MAKE A BP TO IT
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?
JRST NSPMS4 ;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?
JRST NSPMS4 ;NO
CALL SKPFLD ;SKIP HOST NAME
JRST NSPMS4 ;SOMETHING WRONG
CALL SKPFLD ;SKIP OTHER HOST NAME
JRST NSPMS4 ;SOMETHING WRONG
GETBYM (MSGCNT,MSGBYP,NSPMS4) ;GET FLAGS
NSPMS1: MOVE T1,MSGBLK ;GET MESSAGE ADDRESS
STOR T2,MSMFL,(T1) ;SAVE MESSAGE FLAGS
TRNE T2,CNMRFL ;IS IT A CONTROL MESSAGE?
;Control message
JRST NSPMS4 ;YES, GIVE IT TO BACKGROUND TASK
CALL GETLLA ;( ) GET LINK NUMBERS
JRST NSPMS4 ;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
;Logical link doesn't exist
UNLOCK LLLLCK ;GIVE UP TREE LOCK
JRST NSPMS4 ;GIVE MSG TO BACKGROUND TASK
ENDIF.
TMNN LLDED,(T1) ;HAS DN20 CRASHED?
IFSKP.
;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
;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?
;Logical link not in run state
JRST NSPMS5 ;NO, GIVE MESSAGE TO BACKGROUND TASK
;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
MOVEM T1,MSGLLB ;SAVE LL BLOCK
LOAD T4,MSMFL,(T2) ;GET MESSAGE FLAGS
; ..
; ..
TRNN T4,ACKFLM ;AN ACK?
IFSKP.
;Ack message
CALL GETTWO ;(/T2) YES, GET THE ACK NUMBER
JRST NSPMS5 ;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
JRST NSPMS6 ;DONE
ENDIF.
TRNN T4,DATFLI ;IS IT LS OR INT MESSAGE?
IFSKP.
;Link service or interrupt message
SKIPN RESNET ;YES, LOTS OF SPACE?
IFSKP.
SETONE MSSKD,(T2) ;NO, HAVE IT TOSSED
MOVE T1,MSGLLB ;RETRIEVE LL BLOCK
JRST NSPMS6 ;DONE
ENDIF.
CALL INTLS ;( ) YES, PROCESS IT
ELSE. ;NO, MUST BE A DATA SEGMENT
;Data segment
CALL NSINBK ;(T1,T2) DO BOOKKEEPING
CALL ONRAWQ ;(T1,T2) PROCESS IT
ENDIF.
NSPMS6: CALL BLKULK ;(T1) UNLOCK IT
RETSKP
;Message is for background task
NSPMS5: CALL BLKULK ;(T1) FREE THE LL BLOCK
NSPMS4: MOVE T2,MSGBLK ;GET MESSAGE ADDRESS
SKIPN RESNET ;LOTS OF SPACE?
IFSKP.
SETONE MSSKD,(T2) ;NO, HAVE IT TOSSED
ELSE.
CALL ONMSGQ ;(T2) YES, PUT IN ON THE TASK'S Q
ENDIF.
RETSKP ;FINISHED WITH MSG
ENDSV.
ENDTV.
;PUT A DATA SEGMENT MESSAGE ON A LINK'S INCOMING QUEUE
;ACCEPTS: T1/ LL BLOCK ADDRESS
; T2/ MESSAGE ADDRESS
;RETURNS: +1
ONRAWQ: NOSKD1 ;HOLD OFF SCHEDULER
TRVAR <MSGCNT,MSGBYP,MSGSRC,MSGDST,MSGBLK>
MOVE T3,MSBPTR(T2) ;GET POINTER TO DATA
MOVEM T3,MSGBYP ;TO THE POINTER
LOAD T3,MSDTC,(T2) ;GET COUNT
MOVEM T3,MSGCNT ;SAVE COUNT
MOVEM T2,MSGBLK ;SAVE MESSAGE BLOCK
CALL GETTWO ;(MSGCNT,MSGBYP/T2) GET ACKNUM
JRST ONRAW1 ;COULDN'T
TRZN T2,ACKIND ;IS THIS AN ACKNUM?
IFSKP.
;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 ;YES, DATA MESSAGE
CALL ACKCHN ;(T1,T2,T3) GO HANDLE THE ACK
CALL GETTWO ;(MSGCNT,MSGBYP/T2) GET SEGNUM
JRST ONRAW1 ;COULDN'T
ENDIF.
LOAD T3,LLDMT,(T1) ;GET NUMBER OF SEGMENTS CURRENTLY IN INCOMING Q
AOS T3 ;ADD THE ONE WE'RE LOOKING AT
LOAD T4,LLMQI,(T1) ;GET MAXIMUM INPUT QUEUE LENGTH
CAMG T3,T4 ;WOULD THIS ONE MAKE TOO MANY?
IFSKP.
;The link's incoming queue is full (its quota has been reached)
LOAD T3,LLLKP,(T1) ;YES, GET NODE'S VERSION
CAIE T3,.NSP31 ;NSP 3.1?
JRST ONRAW1 ;NO, DONE
SETONE LLFNN,(T1) ;PHASE II, SAY THIS LL NEEDS A NACK
SETZRO LLFNA,(T1) ;NOT AN ACK
CALL ONSRVQ ;(T1) PUT LL ON "NEEDS SERVICE" QUEUE
JRST ONRAW1 ;DONE
ENDIF.
;The link has room in its queue to accept this segment
SKIPE RESNET ;LOTS OF SPACE?
; ..
; ..
;Low on free space
JRST ONRAW1 ;NO
;Lots of free space
MOVE T3,T2 ;YES, POSITION SEGMENT #
LOAD T4,LLIDN,(T1) ;GET LAST SEG RECEIVED
AOS T4 ;MAKE NEXT EXPECTED
ANDI T4,7777 ;12 BITS ONLY (BE SURE TO CATCH WRAP AROUND)
CAMN T3,T4 ;THIS THE RIGHT ONE?
IFSKP.
;Out-of-order segment
CAML T3,T4 ;NO, TOO NEW?
IFSKP.
SETONE LLFNA,(T1) ;OLD, SAY THIS LL NEEDS AN ACK
ELSE.
LOAD T4,LLLKP,(T1) ;TOO NEW, GET NODE'S VERSION
CAIE T4,.NSP31 ;NSP 3.1?
JRST ONRAW1 ;NO, FORGET IT
SETONE LLFNN,(T1) ;PHASE II, SAY LL NEEDS TO NAK
SETZRO LLFNA,(T1) ;NOT AN ACK
ENDIF.
CALL ONSRVQ ;(T1) PUT LL ON NEEDS SERVICE QUEUE
JRST ONRAW1 ;DONE
ENDIF.
;The expected segment
STOR T3,LLIDN,(T1) ;YES, UPDATE SEGMENT NUMBER LL BLOCK
MOVE T2,MSGBLK ;RETRIEVE MESSAGE ADDRESS
STOR T3,MSSEG,(T2) ;SAVE SEGMENT NUMBER IN MSG HEADER
SETONE LLFNA,(T1) ;THIS LL NEEDS AN ACK
INCR LLDMT,(T1) ;SAY WE HAVE ANOTHER MESSAGE IN QUEUE
LOAD T3,LLDMT,(T1) ;GET NUMBER OF SEGMENTS ON Q
CAIN T3,1 ;WAS Q PREVIOUSLY EMPTY?
CALL DATINR ;(T1) YES, GIVE INT
MOVEI T3,LLOMSG(T1) ;THE ORDERED MESSAGE QUEUE
CALL PUTONQ ;(T2,T3) PUT ON NEW SEGMENT
CALL ONSRVQ ;(T1) PUT LL ON "NEEDS SERVICE" QUEUE
CALL CHKLLT ;(T1) CHECK FOR TTY ON THIS LL
OKSKD1
RET ;AND DONE
ONRAW1: MOVE T2,MSGBLK ;GET MESSAGE ADDRESS
SETONE MSSKD,(T2) ;TELL SCHEDULER TO RELEASE THE MESSAGE
CALL DATINR ;(T1) REQUEST INT
OKSKD1
RET
ENDTV.
;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) ; BLOCK
RET
;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
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.
MOVEM T1,LLSRVQ ;YES, MAKE QUEUE HEAD POINT TO US
MOVEM T1,LLSRVQ+1 ;MAKE QUEUE TAIL POINT TO US
SETZRO <LLPSR,LLNSR>,(T1) ;CLEAR ALL POINTERS
JRST ONSRV1 ;DONE
ENDIF.
MOVE T3,LLSRVQ+1 ;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
MOVEM T1,LLSRVQ+1 ;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 HEAD
SETZM LLSRVQ+1 ; AND TAIL
JRST UNQSR1 ;DONE
ENDIF.
SETZRO LLPSR,(T3) ;NO, MAKE NEXT FIRST
MOVEM T3,LLSRVQ ;MAKE Q HEAD 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
MOVEM T2,LLSRVQ+1 ;MAKE Q TAIL 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
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: RETBAD (NSJX04)
REPEAT 0,< ;2020 LOOPBACK
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
> ;END REPEAT 0
;CLEAR LOOPBACK PORT
NDCLP: RETBAD (NSJX04)
REPEAT 0,< ;2020 LOOPBACK
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
> ;END REPEAT 0
;FIND LOOPBACK PORT
NDFLP: RETBAD (NSJX04)
REPEAT 0,< ;2020 LOOPBACK
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
> ;END REPEAT 0
; 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 ASGDCN ;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 ASGDCN ;GET SWAPPABLE FREE SPACE
JRST [ MOVE T1,TMPTOP ;GET ADDR
CALL RELDCN ;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 Q2,TMPTOP ;GET ADDR OF COPIED MESSAGE
HRLZI T2,(<POINT 8,(Q2)>) ;GET A 8-BIT INDEXED BYTE POINTER
MOVE Q3,NEWTOP ;GET ADDRESS FOR BIT MASK
HRLZI T3,(<POINT 2,(Q3)>) ;GET A 2-BIT INDEXED BYTE POINTER
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 Q2,NEWTOP ;GET ADDRESS FOR BIT MASK
HRLZI T2,(<POINT 2,(Q2)>) ;GET A 2-BIT INDEXED BYTE POINTER
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 Q2,NEWTOP ;GET ADDRESS FOR BIT MASK
HRLZI T1,(<POINT 2,(Q2)>) ;GET A 2-BIT INDEXED 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 RELDCN ;RELEASE THE SPACE
MOVE T1,NEWTOP ;GET ADDR
CALL RELDCN ;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
;THIS ROUTINE O N L Y RETSKPs!!!!!!!!
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
SETZM GNTRET ;INIT THE "NUMBER RETURNED"
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
SOS T1 ; 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 ?
JRST NDGNXX ;NO. FAIL
MOVX T1,.NDNBS ;GET SIZE OF A NODE BLOCK
UMOVEM T1,.NDCNT(T4) ;STORE IN USER ARG BLOCK
;LOOP OVER EACH NODE
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 ?
JRST NDGNXX ;NO. 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: CALL NDGNRE ;FINISH UP
RETBAD (ARGX04) ;RETURN "ARGUMENT BLOCK TOO SMALL"
;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
ERJMPR [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
; USES T1-T4
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
CALL NDVFY1 ;do the work, (length is in T2 from PARNDU)
;RETURN INFO TO THE USER
MOVE T2,VFYARG ;RETRIEVE ADDR OF USER'S ARG BLOCK
UMOVEM T1,.NDFLG(T2) ;RETURN THE NEWS TO THE USER
RETSKP
ENDSV.
;verify that the parsed node name is in the name mapping table and is reachable.
; T1 - byte pointer to parsed node name in monitor space
; T2 - length of that node name
; returns +1 always and OKINT ; flags in T1 (ND%EXM)
; uses T1-T4
; CALL NDVFY1
NDVFY1::SAVEAC (P3)
STKVAR <VFYSTR>
MOVEM T1,VFYSTR ;SAVE IT FOR LATER USE
MOVE T3,T2 ;GET NUMBER OF CHARS IN NAME
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
NDVFY2: 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,NDVFY2 ;NO, ANY MORE TO TEST?
UNLOCK NMAPLK ;NO, GIVE UP
OKINT ; THE LOCK
SETZ T1, ;TURN OFF THE "FOUND IT" BIT
RET] ;DONE
;NODE IS IN NODE NAME MAPPING TABLE, SEE IF IT IS REACHABLE.
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
RET] ;DONE
;NODE IS REACHABLE
UNLOCK NODLOK ;DONE WITH
OKINT ; THE LOCK
MOVX T1,ND%EXM ;TURN ON THE "FOUND IT" BIT
RET
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
UNLOCK NMAPLK ;DONE WITH
OKINT ; THE LOCK
RETSKP
TNXEND
END