Trailing-Edge
-
PDP-10 Archives
-
BB-Y393F-SM
-
monitor-sources/nspsrv.mac
There are 31 other files named nspsrv.mac in the archive. Click here to see a list.
;Edit 3145 to NSPSRV.MAC by EVANS on Mon 6-Aug-84
; Fix bad JRST in Edit 3144; JRST BADMSG, not TOSMSG
;Edit 3144 to NSPSRV.MAC by EVANS on Tue 31-Jul-84, for SPR #19797
; Fix NSPBAD's - (W.Nichols edit) - this is edit number 3108 to
;; Version 5.1
;Edit 3059 to NSPSRV.MAC by CJOHNSON on Mon 19-Dec-83, for SPR #19770
; Make TURNON send a 0 allocation LS, even when write-only
;Edit 2962 to NSPSRV.MAC by LOMARTIRE on Tue 10-May-83, for SPR #19025
; Use SIZ39 in GTSBLK - prevents ILMNRF from clobbered free space
; UPD ID= 183, FARK:<4-1-WORKING-SOURCES.MONITOR>NSPSRV.MAC.7, 29-Sep-82 11:28:41 by DONAHUE
;Edit 2823 - Remove transmit part of 2628
; UPD ID= 131, FARK:<4-1-WORKING-SOURCES.MONITOR>NSPSRV.MAC.5, 13-Aug-82 16:12:52 by DONAHUE
;Edit 2647 - Fix clobberring of node name at GOTMCB
; UPD ID= 104, FARK:<4-1-WORKING-SOURCES.MONITOR>NSPSRV.MAC.4, 21-Jul-82 16:25:13 by BENCE
; UPD ID= 96, FARK:<4-1-WORKING-SOURCES.MONITOR>NSPSRV.MAC.3, 15-Jun-82 14:51:18 by BENCE
; UPD ID= 56, FARK:<4-1-WORKING-SOURCES.MONITOR>NSPSRV.MAC.2, 5-Apr-82 07:48:55 by DONAHUE
;Edit 2607 - Add ENDAV. to all ACVAR's
;<4-1-FIELD-IMAGE.MONITOR>NSPSRV.MAC.2, 25-Feb-82 20:40:36, EDIT BY DONAHUE
;UPDATE COPYRIGHT DATE
; UPD ID= 722, FARK:<4-WORKING-SOURCES.MONITOR>NSPSRV.MAC.3, 19-Aug-81 10:51:39 by ZIMA
;Edit 1925 - put edit 1849 in standard form. No code changes.
; UPD ID= 455, FARK:<4-WORKING-SOURCES.MONITOR>NSPSRV.MAC.2, 15-Apr-81 17:12:55 by DEUFEL
;Edit 1849 - Use correct register when cleaning up links
; UPD ID= 220, SNARK:<4.MONITOR>NSPSRV.MAC.416, 24-Jan-80 15:58:24 by GRANT
;TCO 4.2599 - DEDMCB should not clear the loopback word
;<4.MONITOR>NSPSRV.MAC.415, 3-Jan-80 08:09:53, EDIT BY R.ACE
;UPDATE COPYRIGHT DATE
; UPD ID= 123, SNARK:<4.MONITOR>NSPSRV.MAC.414, 10-Dec-79 15:31:00 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= 84, SNARK:<4.MONITOR>NSPSRV.MAC.412, 3-Dec-79 15:02:17 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
;TCO 4.2575 - Make loopback test work for the 2020
;<4.MONITOR>NSPSRV.MAC.410, 20-Oct-79 14:45:43, EDIT BY MILLER
;FIX TYPEO IN DOSRVS.
;<4.MONITOR>NSPSRV.MAC.409, 18-Oct-79 13:06:43, EDIT BY GRANT
;FIX THE TEST FOR OPTIONAL DATA IN CLZSDI
;<4.MONITOR>NSPSRV.MAC.408, 17-Oct-79 10:06:17, EDIT BY GRANT
;TCO 4.2528 - FIX CC HANDLING TO DO PROPER ADJUSTMENT FOR SEGMENT SIZE
;<4.MONITOR>NSPSRV.MAC.407, 3-Oct-79 12:07:13, EDIT BY GRANT
;ADD ARGUMENT NAMES FOR BUGxxx
;<4.MONITOR>NSPSRV.MAC.406, 1-Oct-79 11:02:43, EDIT BY GRANT
;TCO 4.2503 - ELIMINATE DOUBLE RELEASING OF FREE SPACE BLOCK
;<4.MONITOR>NSPSRV.MAC.405, 26-Sep-79 15:55:39, EDIT BY HALL
;NDSNT IN NODE JSYS - CALL BLTUM1 INSTEAD OF BLTUM FOR EXTENDED
;ADDRESSING
;<4.MONITOR>NSPSRV.MAC.404, 25-Sep-79 10:29:52, EDIT BY GRANT
;TCO 4.2485 - SET UP T1 CORRECTLY AT ADIN10 BEFORE CALLING RELMES
;<4.MONITOR>NSPSRV.MAC.403, 13-Sep-79 15:05:28, EDIT BY GRANT
;TCO 4.2468 - ADD ROUTE HEADERS TO DATA, LS, AND INT MESSAGES
;<4.MONITOR>NSPSRV.MAC.402, 12-Sep-79 15:39:07, EDIT BY GRANT
;TCO 4.2461 - GET PORT NO. IN CORRECT AC FOR NSPRTH BUGCHK
;<OSMAN.MON>NSPSRV.MAC.1, 10-Sep-79 15:50:04, EDIT BY OSMAN
;TCO 4.2412 - Move definition of BUGHLTs, BUGCHKs, and BUGINFs to BUGS.MAC
;<4.MONITOR>NSPSRV.MAC.400, 4-Sep-79 16:38:40, EDIT BY GRANT
;TCO 4.2438 - DON'T TOUCH THE NODE NUMBER AFTER SETSPD RUNS
;<4.MONITOR>NSPSRV.MAC.399, 31-Aug-79 14:24:08, EDIT BY GRANT
;TCO 4.2434 - DON'T SUBTRACT LENGTH OF HEADER IN CIPSRV
;<4.MONITOR>NSPSRV.MAC.398, 3-Aug-79 10:12:50, EDIT BY GRANT
;TCO 4.2371 - MAKE MTOPR DO A SYNCHRONOUS DISCONNECT CORRECTLY
;<4.MONITOR>NSPSRV.MAC.397, 11-Jul-79 09:58:11, EDIT BY ENGEL
;FIX ERROR CODES AT SNINT. CHANGE DCNX14 TO DCNX12 AND DCNX11 TO DCNX14
;<4.MONITOR>NSPSRV.MAC.396, 14-Jun-79 16:03:21, EDIT BY KIRSCHEN
;RETURN ERROR CODE WHEN CANNOT SEND LS MSG ON READING INT MSG
;<4.MONITOR>NSPSRV.MAC.395, 3-May-79 14:27:53, EDIT BY KIRSCHEN
;FIX J0NRUN'S AND OTHER RANDOMNESS ON LINE DOWN IN DEDCOR
;<4.MONITOR>NSPSRV.MAC.394, 25-Apr-79 15:24:57, EDIT BY OSMAN
;ADD NAMINI TO SET NAME TO "TOPS20"
;<4.MONITOR>NSPSRV.MAC.393, 18-Apr-79 16:01:43, EDIT BY KIRSCHEN
;USE INPUT QUEUE INSTEAD OF OUTPUT QUEUE AT ONRAWQ AND MOVSEG
;<4.MONITOR>NSPSRV.MAC.392, 11-Apr-79 11:59:37, EDIT BY KIRSCHEN
;ANTICIPATE DECNET PHASE III AND REMOVE UNNEEDED CHECK FOR COUNT BIT
;<4.MONITOR>NSPSRV.MAC.391, 11-Apr-79 11:55:35, EDIT BY KIRSCHEN
;USE DIFFERENT SEGMENT SIZE IF INTERNAL LINK
;<4.MONITOR>NSPSRV.MAC.390, 27-Mar-79 13:17:08, EDIT BY ENGEL
;ADD NSBP10 FOR SAMPLING QUEUE LENGTH
;<4.MONITOR>NSPSRV.MAC.389, 21-Mar-79 14:07:39, EDIT BY KIRSCHEN
;PREVENT RELINT BUGCHKS FROM DELREL
;<4.MONITOR>NSPSRV.MAC.388, 19-Mar-79 16:22:31, EDIT BY KIRSCHEN
;INSURE CODE IS ALWAYS NOINT WHEN ASSIGNING FREE SPACE
;<4.MONITOR>NSPSRV.MAC.387, 8-Mar-79 13:14:26, EDIT BY ENGEL
;FIX FREE SPACE PROBLEM AT INSER1
;<4.MONITOR>NSPSRV.MAC.386, 4-Mar-79 18:43:23, EDIT BY KONEN
;UPDATE COPYRIGHT FOR RELEASE 4
;<4.MONITOR>NSPSRV.MAC.385, 25-Feb-79 13:31:33, EDIT BY KIRSCHEN
;SAVE STATUS FROM CORRECT AC AT CONIN1; FIX STKVAR IN TELDIS
;<4.MONITOR>NSPSRV.MAC.384, 21-Feb-79 21:43:04, EDIT BY KIRSCHEN
;FIX REGISTER CLOBBERAGE IN OUTSND
;<4.MONITOR>NSPSRV.MAC.383, 20-Feb-79 13:34:32, EDIT BY KIRSCHEN
;GIVE DRIVER TOPS20 ERROR CODES ON CONNECT/DISCONNECT NOTIFICATION
;<4.MONITOR>NSPSRV.MAC.382, 19-Feb-79 14:44:25, EDIT BY KIRSCHEN
;MORE OF PREVIOUS EDIT
;<4.MONITOR>NSPSRV.MAC.381, 18-Feb-79 09:09:56, EDIT BY KIRSCHEN
;NSPSRV.MAC.80 WAS EDIT TO FIX BACKGROUND TASK WAKEUP BUG
;<4.MONITOR>NSPSRV.MAC.379, 15-Feb-79 16:42:23, EDIT BY ENGEL
;ADD CODE TO ALLOW ATS TO SET FLOW CONTROL
;<4.MONITOR>NSPSRV.MAC.378, 12-Feb-79 16:33:42, EDIT BY ENGEL
;FIX NODDEL
;<4.MONITOR>NSPSRV.MAC.377, 9-Feb-79 14:45:14, EDIT BY KIRSCHEN
;RESTORE LINK BLOCK ADDRESS IF SQILS CALL FAILS IN ACKRUN
;<4.MONITOR>NSPSRV.MAC.376, 9-Feb-79 09:57:31, EDIT BY ENGEL
;FIX NODDEL TO ACCOUNT FOR TABLE CHANGES WHILE DELETING
;<4.MONITOR>NSPSRV.MAC.375, 8-Feb-79 17:48:54, EDIT BY MILLER
;FIX NETCLZ IF CLZSDI FAILS.
;<4.MONITOR>NSPSRV.MAC.374, 8-Feb-79 11:40:22, EDIT BY ENGEL
;ADD SOS T1 TO ADDINT AND REMNDX
;<4.MONITOR>NSPSRV.MAC.371, 7-Feb-79 10:10:22, EDIT BY OSMAN
;MOVE OURNAM INI CODE FROM HERE INTO MEXEC (SOLVES PROBLEMS OF NON-DECNET SYSTEMS)
;<4.MONITOR>NSPSRV.MAC.370, 6-Feb-79 08:20:45, EDIT BY ENGEL
;RE-ADJUST NSBP02 AND NSBP05
;<4.MONITOR>NSPSRV.MAC.369, 5-Feb-79 11:07:24, EDIT BY ENGEL
;MORE BREAKPOINTS
;<4.MONITOR>NSPSRV.MAC.368, 2-Feb-79 14:57:38, EDIT BY ENGEL
;MORE BREAKPOINTS
;<4.MONITOR>NSPSRV.MAC.367, 31-Jan-79 13:50:55, EDIT BY KIRSCHEN
;CHECK FOR ZERO POINTER TO NODE NAME IN INSNOD
;<4.MONITOR>NSPSRV.MAC.366, 30-Jan-79 13:18:49, EDIT BY ENGEL
;ADD MORE BREAKPOINTS
;<4.MONITOR>NSPSRV.MAC.365, 30-Jan-79 09:32:55, EDIT BY KIRSCHEN
;MAKE NSPERR INTERNAL
;<4.MONITOR>NSPSRV.MAC.364, 30-Jan-79 08:56:43, EDIT BY KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.363, 29-Jan-79 22:45:18, EDIT BY KIRSCHEN
;RETURN RIGHT NODE STATE (FIX TYPO)
;<4.MONITOR>NSPSRV.MAC.362, 29-Jan-79 18:53:35, EDIT BY ENGEL
;ADD BREAKPOINT LABELS FOR PERFORMANCE MEASUREMENT
;<4.MONITOR>NSPSRV.MAC.361, 29-Jan-79 13:04:33, EDIT BY KIRSCHEN
;DO NOT UNLOCK LINK BLOCK BEFORE GIVING CONNECT NOTIFICATION AT DSCMV1
;<4.MONITOR>NSPSRV.MAC.360, 29-Jan-79 12:59:43, EDIT BY KIRSCHEN
;CORRECTLY RETURN NODE STATE IN NDGNT
;<4.MONITOR>NSPSRV.MAC.359, 26-Jan-79 15:45:31, EDIT BY ENGEL
;FIX MONPDL PROBLEM IN NODDEL
;<4.MONITOR>NSPSRV.MAC.358, 24-Jan-79 16:57:42, EDIT BY KIRSCHEN
;RESTORE LINK BLOCK ADR AFTER TURNON FAILS
;<4.MONITOR>NSPSRV.MAC.357, 24-Jan-79 16:11:30, EDIT BY HALL
;COMMENT CALLING CONVENTIONS FOR TURNON AND SNDLS
;<4.MONITOR>NSPSRV.MAC.356, 16-Jan-79 12:31:09, EDIT BY KIRSCHEN
;DO NOT RELEASE LINK BLOCK TWICE IF CRTLNK FAILS
;<4.MONITOR>NSPSRV.MAC.355, 14-Jan-79 20:48:19, EDIT BY KIRSCHEN
;UPDATE NODE JSYS SYMBOLS
;<4.MONITOR>NSPSRV.MAC.354, 10-Jan-79 12:11:18, EDIT BY KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.353, 8-Jan-79 20:25:37, EDIT BY KIRSCHEN
;permit duplicate task names within the same job
;<4.MONITOR>NSPSRV.MAC.352, 4-Jan-79 09:21:45, EDIT BY KIRSCHEN
;ADD NSPERR ROUTINE
;<4.MONITOR>NSPSRV.MAC.351, 3-Jan-79 16:56:31, EDIT BY KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.350, 3-Jan-79 15:37:35, EDIT BY KIRSCHEN
;ADD NOOP AT NSPTSK FOR PERFORMANCE ANALYSIS
;<4.MONITOR>NSPSRV.MAC.349, 29-Dec-78 14:30:11, EDIT BY KIRSCHEN
;ADD NSP TO TOPS20 ERROR CODE TRANSLATION TABLE
;<4.MONITOR>NSPSRV.MAC.348, 21-Dec-78 13:44:23, EDIT BY KIRSCHEN
;TEST CORRECT AC AT VFYNOD+6
;<4.MONITOR>NSPSRV.MAC.347, 21-Dec-78 11:17:28, EDIT BY ENGEL
;FIX BAD CHANNEL CHECKING AT NDSIC
;<4.MONITOR>NSPSRV.MAC.346, 18-Dec-78 08:57:07, EDIT BY KIRSCHEN
;DO NOT PASS LS SEND FAILURE TO DRIVER; TRY AGAIN WHEN ACK RECEIVED
;<4.MONITOR>NSPSRV.MAC.345, 15-Dec-78 13:56:27, EDIT BY KIRSCHEN
;FIX UNLOCKING OF NODLOK IN VFYNOD
;<4.MONITOR>NSPSRV.MAC.344, 11-Dec-78 13:59:34, EDIT BY ENGEL
;ADD SOS TO REMNOD
;<4.MONITOR>NSPSRV.MAC.343, 8-Dec-78 09:00:02, EDIT BY KIRSCHEN
;REMOVE NODE AT MCBDED WITH ADDINT NOT ADDNOD
;<4.MONITOR>NSPSRV.MAC.342, 6-Dec-78 15:13:55, EDIT BY ENGEL
;ADD NEIGHBOR INFORMATION TO TOPOLOGY TABLE
;<4.MONITOR>NSPSRV.MAC.341, 1-Dec-78 12:02:00, EDIT BY KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.340, 1-Dec-78 11:56:04, EDIT BY KIRSCHEN
;ADD NDVFY FUNCTION
;<4.MONITOR>NSPSRV.MAC.339, 29-Nov-78 10:15:03, EDIT BY KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.338, 21-Nov-78 09:52:32, EDIT BY KIRSCHEN
;FIX DUPLICATE USE OF NAME NODMAX
;<4.MONITOR>NSPSRV.MAC.337, 15-Nov-78 15:28:51, EDIT BY KIRSCHEN
;DO NOT ACK INTERRUPT MESSAGES TWICE
;<4.MONITOR>NSPSRV.MAC.336, 9-Nov-78 08:58:37, EDIT BY KIRSCHEN
;DO NOT DELETE LINK BLOCK ON FAILURE FROM CRTLNK
;<4.MONITOR>NSPSRV.MAC.335, 6-Nov-78 11:06:35, EDIT BY ENGEL
;MAKE NDGLI USE 1/2 WORD LENGTH
;<4.MONITOR>NSPSRV.MAC.333, 27-Oct-78 17:29:43, EDIT BY OSMAN
;SET UP OURCNT IN .NDSLN
;<4.MONITOR>NSPSRV.MAC.332, 26-Oct-78 11:47:59, EDIT BY OSMAN
;use PARNDU instead of PARNOD
;<4.MONITOR>NSPSRV.MAC.331, 25-Oct-78 15:22:38, EDIT BY KIRSCHEN
;RETURN ERROR CODE IF ARG BLOCK TOO SMALL IN .NDGNT FUNCTION
;<4.MONITOR>NSPSRV.MAC.330, 25-Oct-78 10:37:47, EDIT BY ENGEL
; FIX THE .NDGLI FUNCTION
;<4.MONITOR>NSPSRV.MAC.329, 24-Oct-78 16:39:17, EDIT BY OSMAN
;MAKE NODE JSYS CALL PARNOD
;<4.MONITOR>NSPSRV.MAC.328, 17-Oct-78 16:57:48, EDIT BY ENGEL
;CHANGE OFFSETS IN .NDGLI
;<4.MONITOR>NSPSRV.MAC.327, 13-Oct-78 18:16:11, EDIT BY MILLER
;FIX NTMVOP TO CHECK FOR BYTE POINTER OF FORM -1,,N
;<4.MONITOR>NSPSRV.MAC.326, 13-Oct-78 13:49:23, EDIT BY ENGEL
;ZERO NAME ENTRY IN ITSNAM WHEN MCB DIES
;<4.MONITOR>NSPSRV.MAC.325, 12-Oct-78 15:44:24, EDIT BY ENGEL
;FIX CAME COMPARE FOR NTCTAB+NTCMAX-1
;<4.MONITOR>NSPSRV.MAC.324, 10-Oct-78 10:26:02, EDIT BY ENGEL
;CHANGE .BTSTS TO .BTLST IN GET LINE INFO NODE JSYS
;<4.MONITOR>NSPSRV.MAC.323, 6-Oct-78 16:01:17, EDIT BY ENGEL
;<4.MONITOR>NSPSRV.MAC.322, 6-Oct-78 15:36:10, EDIT BY ENGEL
;ADD NODE JSYS FUNCTIONS
;<4.MONITOR>NSPSRV.MAC.321, 3-Oct-78 17:03:12, EDIT BY KIRSCHEN
;DO NOTE NOTIFY DRIVER IN TELDIS IF LINK DISSOCIATED FROM PROCESS
;<4.MONITOR>NSPSRV.MAC.320, 24-Sep-78 11:35:38, EDIT BY HALL
;TCO 1900 - MAKE NSPTST CALL CKATSQ TO CHECK FOR ATS WORK
; MAKE NSPTSK CALL DOATSQ TO PROCESS ATS QUEUES
;<4.MONITOR>NSPSRV.MAC.319, 22-Sep-78 09:34:36, EDIT BY ENGEL
;<4.MONITOR>NSPSRV.MAC.318, 22-Sep-78 09:26:16, EDIT BY ENGEL
;FIX BAD REGISTER USAGE AT GOTMCB:
;<4.MONITOR>NSPSRV.MAC.317, 21-Sep-78 14:48:32, EDIT BY ENGEL
;UNLOCK TREE FOR +1 RETURN FROM OBJSRC AT DEDMC1+3
;<4.MONITOR>NSPSRV.MAC.316, 21-Sep-78 11:01:14, EDIT BY ENGEL
;MAKE DEDMCB RUN IN THE NSP BACKGROUND TASK
;<4.MONITOR>NSPSRV.MAC.315, 21-Sep-78 08:36:49, EDIT BY ENGEL
;FIX DEDMCB: DECLOCK WITH ATS
;<4.MONITOR>NSPSRV.MAC.314, 20-Sep-78 15:51:18, EDIT BY KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.313, 6-Sep-78 14:09:14, EDIT BY KIRSCHEN
;FIX REMOVAL OF NODES FROM KNOWN NODE TABLE
;<4.MONITOR>NSPSRV.MAC.312, 5-Sep-78 13:21:54, EDIT BY KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.311, 5-Sep-78 09:17:44, EDIT BY KIRSCHEN
;FIXES FOR DISCONNECT MSGS W/O ROUTING HDR
;REMOVE DN20'S FROM NODTBL AFTER THEY CRASH
;<4.MONITOR>NSPSRV.MAC.310, 30-Aug-78 16:50:28, EDIT BY KIRSCHEN
;NOTE IF A LINK IS LOCAL WHEN CI MSG RECEIVED
;<4.MONITOR>NSPSRV.MAC.309, 28-Aug-78 09:18:02, EDIT BY KIRSCHEN
;CHANGE TSTLCL TO USE NEW LLLOC FLAG
;<4.MONITOR>NSPSRV.MAC.308, 28-Aug-78 08:43:52, EDIT BY KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.307, 23-Aug-78 15:51:37, EDIT BY KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.306, 23-Aug-78 10:03:04, EDIT BY KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.305, 23-Aug-78 09:12:24, EDIT BY KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.304, 22-Aug-78 18:06:51, EDIT BY OPERATOR
;FIX NTMVOP TO CHECK FOR NEG COUNT
;<4.MONITOR>NSPSRV.MAC.303, 22-Aug-78 13:23:23, EDIT BY KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.302, 22-Aug-78 13:17:55, EDIT BY KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.301, 22-Aug-78 10:47:04, EDIT BY MILLER
;CHECK FO R BAD OPTDATA FIELD IN CC MESSAGE
;<4.MONITOR>NSPSRV.MAC.300, 22-Aug-78 10:05:43, EDIT BY KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.299, 22-Aug-78 08:17:06, EDIT BY MILLER
;REWRITE SKPFLD TO BE MORE EFFICIENT. SAVES SCEHDULER CYCLES
;<4.MONITOR>NSPSRV.MAC.298, 21-Aug-78 13:43:18, EDIT BY KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.297, 18-Aug-78 15:38:54, EDIT BY MILLER
;FIX TYPEO
;<4.MONITOR>NSPSRV.MAC.296, 18-Aug-78 13:49:05, EDIT BY KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.295, 18-Aug-78 10:11:37, EDIT BY KIRSCHEN
;RETURN ARGS IN CORRECT AC'S ON READ INTERRUPT MSG
;<4.MONITOR>NSPSRV.MAC.294, 18-Aug-78 09:07:23, EDIT BY MILLER
;FIX SKPFLD TO PASS NUMBER TO GTASCI
;<4.MONITOR>NSPSRV.MAC.293, 18-Aug-78 08:19:03, EDIT BY MILLER
;ADD MAXHST TO EXTN LIST
;<4.MONITOR>NSPSRV.MAC.292, 18-Aug-78 08:10:54, EDIT BY MILLER
;MAKE GTASCI AND GTBNRY CHECK FOR REASONABLE STRING SIZES
;<4.MONITOR>NSPSRV.MAC.291, 16-Aug-78 13:06:33, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.290, 14-Aug-78 13:23:15, Edit by HURLEY
;<4.MONITOR>NSPSRV.MAC.289, 11-Aug-78 13:56:00, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.288, 11-Aug-78 13:44:19, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.287, 11-Aug-78 13:28:05, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.286, 11-Aug-78 13:17:10, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.285, 11-Aug-78 12:09:09, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.284, 9-Aug-78 11:53:57, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.283, 9-Aug-78 11:33:54, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.282, 7-Aug-78 09:47:14, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.281, 2-Aug-78 08:55:43, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.280, 1-Aug-78 11:49:18, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.279, 1-Aug-78 11:46:17, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.277, 1-Aug-78 09:59:40, Edit by KIRSCHEN
;ADD NEW R4 NODE JSYS FUNCTIONS
;<4.MONITOR>NSPSRV.MAC.275, 31-Jul-78 10:31:18, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.274, 31-Jul-78 09:09:28, Edit by KIRSCHEN
;ADD ININOD ROUTINE
;<4.MONITOR>NSPSRV.MAC.272, 26-Jul-78 11:45:18, Edit by KIRSCHEN
;CLEAR LLQUE AT OUTSND WHEN REMOVING BLOCK FROM OUTQUE
;<4.MONITOR>NSPSRV.MAC.271, 21-Jul-78 11:13:22, EDIT BY HALL
;CHANGE LLNAM TO LLFNM IN CRTLNK
;<4.MONITOR>NSPSRV.MAC.270, 18-Jul-78 15:43:30, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.269, 17-Jul-78 16:37:24, Edit by KIRSCHEN
;FAIL AT SETIBF IF DRIVER ALREADY REFUSED TO PROVIDE A BUFFER
;<4.MONITOR>NSPSRV.MAC.268, 17-Jul-78 08:38:39, Edit by KIRSCHEN
;UPDATE COUNTS IN INTSET EVEN IF SOME DATA WOULD NOT FIT IN BUFFER
;<4.MONITOR>NSPSRV.MAC.267, 26-Jun-78 13:36:35, Edit by KIRSCHEN
;AWAKEN ATS BACKROUND PROCESS ON TIMER EXPIRATION
;<4.MONITOR>NSPSRV.MAC.266, 26-Jun-78 13:30:26, Edit by KIRSCHEN
;FIX BUG IN MTRDIN - DO NOT CLOBBER ADR OF MESSAGE BEFORE RELEASING IT
;<4.MONITOR>NSPSRV.MAC.265, 26-Jun-78 09:49:47, Edit by KIRSCHEN
;FIX AC TEST IN SQILS WHEN CHECKING NEED FOR LS MSG
;<4.MONITOR>NSPSRV.MAC.264, 23-Jun-78 09:32:27, Edit by KIRSCHEN
;DEFER SENDING VERIFICATION MSG UNTIL NODE INITS COMPLETED
;<4.MONITOR>NSPSRV.MAC.263, 21-Jun-78 17:12:29, EDIT BY MILLER
;GET LARGER BLOCK AT GETTSK
;<4.MONITOR>NSPSRV.MAC.262, 20-Jun-78 16:21:57, Edit by KIRSCHEN
;RETURN NSPX2 WHEN LLLKUP FAILS
;<4.MONITOR>NSPSRV.MAC.261, 16-Jun-78 15:11:28, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.260, 14-Jun-78 08:25:41, Edit by KIRSCHEN
;REMOVE LINK BLOCK FROM OUTQUE IN DELNOD
;<4.MONITOR>NSPSRV.MAC.259, 13-Jun-78 15:42:28, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.258, 13-Jun-78 15:22:29, Edit by KIRSCHEN
;ADD REMQUE ROUTINE
;<4.MONITOR>NSPSRV.MAC.257, 12-Jun-78 11:26:04, Edit by KIRSCHEN
;PROVIDE FOR SENDING OPTIONAL DATA ON CLOSE IN CLZSDI
;<4.MONITOR>NSPSRV.MAC.256, 12-Jun-78 09:59:06, Edit by KIRSCHEN
;DO NOT CLOBBER T1 IN NTMVOP
;<4.MONITOR>NSPSRV.MAC.255, 8-Jun-78 13:20:10, Edit by KIRSCHEN
;MAKE NTMVOP CALLABLE FOR INTERNAL LINKS
;<4.MONITOR>NSPSRV.MAC.254, 8-Jun-78 10:58:22, Edit by KIRSCHEN
;ADD SOME INTERNALIZING
;<4.MONITOR>NSPSRV.MAC.253, 7-Jun-78 12:14:30, Edit by KIRSCHEN
;CALL NRM TO DO NRM PROTOCOL IF NEEDED IN BACKGROUND TASK
;<4.MONITOR>NSPSRV.MAC.252, 7-Jun-78 08:01:16, EDIT BY MILLER
;MAKE NSPTSK STAY IN BALSET A LONG TIME
;<4.MONITOR>NSPSRV.MAC.251, 5-Jun-78 13:49:46, Edit by KIRSCHEN
;SUBROUTINIZE SENDING OF DI IN CLOSE, MAKE ROUTINE INTERNAL
;<4.MONITOR>NSPSRV.MAC.250, 5-Jun-78 08:53:35, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.249, 5-Jun-78 08:48:23, Edit by KIRSCHEN
;DONT TURN ON BLKF IN SNDDI (NOW DONE BY CALLERS)
;<4.MONITOR>NSPSRV.MAC.248, 1-Jun-78 10:45:44, Edit by KIRSCHEN
;MAKE CHKEMP INTERNAL
;<3A.MONITOR>NSPSRV.MAC.55, 26-May-78 16:31:55, EDIT BY MILLER
;MORE FIXES TO MTOPR CLOSE FUNCTION
;<3A.MONITOR>NSPSRV.MAC.54, 26-May-78 15:43:20, EDIT BY MILLER
;FIX UP NTMTCZ TO WAIT FOR ACKS
;<KIRSCHEN>NSPSRV.MAC.2, 26-May-78 11:53:28, Edit by KIRSCHEN
;<KIRSCHEN>NSPSRV.MAC.1, 26-May-78 11:49:45, Edit by KIRSCHEN
;REMOVE INTERNAL INTERFACE CODE
;<4.MONITOR>NSPSRV.MAC.245, 26-May-78 11:18:38, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.244, 24-May-78 09:28:46, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.243, 23-May-78 17:17:54, Edit by MCCLURE
; Add port number to NSPRTH
;<3A.MONITOR>NSPSRV.MAC.52, 22-May-78 08:09:38, EDIT BY MILLER
;ALWAYS REQUEST POSTING OF "NUMBERED SEGMENTS" FROM DEVICE DRIVER.
; DON'T "FLUSH" SEGEMENT STILL AWAITING POSTING
;<4.MONITOR>NSPSRV.MAC.241, 23-May-78 08:51:19, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.240, 19-May-78 14:10:28, EDIT BY OPERATOR
;FIX STRMSG NOT TO USE ACVAR
;<4.MONITOR>NSPSRV.MAC.239, 19-May-78 08:55:49, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.237, 18-May-78 10:42:57, Edit by MCCLURE
; Change KMCTSK to KDPTSK
;<4.MONITOR>NSPSRV.MAC.236, 17-May-78 13:23:46, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.235, 16-May-78 17:37:00, Edit by HALL
;TCO 1900 - MOVED CMPSTR TO FUTILI
;<4.MONITOR>NSPSRV.MAC.234, 16-May-78 16:52:51, Edit by ENGEL
;<4.MONITOR>NSPSRV.MAC.233, 16-May-78 13:52:39, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.232, 16-May-78 13:50:31, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.231, 15-May-78 10:20:02, Edit by KIRSCHEN
;BREAK OUT NSPPAR CODE
;<4.MONITOR>NSPSRV.MAC.230, 12-May-78 20:20:06, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.229, 12-May-78 08:25:18, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.228, 10-May-78 09:43:38, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.227, 10-May-78 09:42:18, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.226, 9-May-78 15:23:05, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.225, 9-May-78 14:12:37, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.224, 9-May-78 09:23:33, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.223, 9-May-78 09:18:11, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.222, 8-May-78 16:52:20, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.221, 8-May-78 14:23:41, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.220, 8-May-78 11:18:39, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.219, 5-May-78 14:00:52, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.218, 5-May-78 10:13:12, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.217, 4-May-78 09:22:02, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.216, 3-May-78 09:03:28, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.215, 3-May-78 08:39:03, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.214, 2-May-78 15:13:15, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.212, 1-May-78 10:22:30, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.211, 28-Apr-78 15:32:20, EDIT BY MILLER
;CHECK FOR DATA IN FILE SYSTEM AT CHKRAW
;<4.MONITOR>NSPSRV.MAC.210, 28-Apr-78 12:25:21, Edit by MCCLURE
; Add error codes in NDSLP
;<4.MONITOR>NSPSRV.MAC.209, 26-Apr-78 09:55:17, EDIT BY MILLER
;CHANGE .DCX40 TO .DCX39 IN DEDMCB
;<4.MONITOR>NSPSRV.MAC.208, 26-Apr-78 09:25:42, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.207, 25-Apr-78 11:14:49, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.206, 25-Apr-78 11:08:10, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.205, 25-Apr-78 09:11:09, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.204, 24-Apr-78 14:02:18, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.203, 24-Apr-78 13:31:14, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.202, 24-Apr-78 10:05:37, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.201, 24-Apr-78 08:32:53, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.200, 20-Apr-78 12:05:43, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.199, 20-Apr-78 12:04:18, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.198, 16-Apr-78 14:44:07, EDIT BY MILLER
;ADD GJFX50 ERROR CODES FOR BAD ATTRIBUTE ARGS
;<4.MONITOR>NSPSRV.MAC.197, 14-Apr-78 08:06:57, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.196, 13-Apr-78 16:29:43, EDIT BY MILLER
;ADD DECR LLDMT IF VERSEG FAILS
;<4.MONITOR>NSPSRV.MAC.195, 13-Apr-78 08:11:51, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.194, 12-Apr-78 13:31:36, Edit by MILLER
;<4.MONITOR>NSPSRV.MAC.193, 12-Apr-78 08:41:26, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.192, 12-Apr-78 08:23:03, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.191, 12-Apr-78 08:17:33, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.190, 11-Apr-78 15:40:12, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.189, 11-Apr-78 15:34:27, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.188, 10-Apr-78 14:47:05, EDIT BY MILLER
;CLEAR LINK WORD AT LSINT1
;<4.MONITOR>NSPSRV.MAC.187, 10-Apr-78 13:46:54, Edit by KIRSCHEN
;<4.MONITOR>MONSYM.MAC.1, 10-Apr-78 12:04:27, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.185, 7-Apr-78 09:36:51, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.184, 7-Apr-78 09:24:11, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.183, 7-Apr-78 09:20:04, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.182, 6-Apr-78 13:52:26, EDIT BY KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.180, 5-Apr-78 15:25:26, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.179, 5-Apr-78 12:28:53, EDIT BY MILLER
;FIX ANOTHER TYPEO IN NTRCOB
;<4.MONITOR>NSPSRV.MAC.178, 5-Apr-78 12:01:28, EDIT BY KIRSCHEN
;FIX NTRCOB TO USE PROPER FIELD
;<4.MONITOR>NSPSRV.MAC.177, 5-Apr-78 11:05:28, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.176, 5-Apr-78 10:38:53, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.175, 5-Apr-78 08:15:56, Edit by KIRSCHEN
;CHANGE FAL TO BE OBJECT 21
;<4.MONITOR>NSPSRV.MAC.174, 4-Apr-78 16:07:07, EDIT BY MILLER
;MORE FIXES TO NTMVOP
;<4.MONITOR>NSPSRV.MAC.173, 4-Apr-78 12:20:09, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.172, 4-Apr-78 09:43:44, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.171, 3-Apr-78 14:30:13, Edit by KIRSCHEN
;SEND NODE VERIFICATION MESSAGE IF REQUESTED AT NODE INIT
;<4.MONITOR>NSPSRV.MAC.170, 3-Apr-78 12:46:00, EDIT BY MILLER
;CHECK FOR MAX OPTDATA SIZE IN NTMVOP
;<4.MONITOR>NSPSRV.MAC.169, 3-Apr-78 12:10:34, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.168, 3-Apr-78 11:27:55, Edit by HALL
;ADD ATS AND NRM TO OBJPRO
;<3A.MONITOR>NSPSRV.MAC.32, 30-Mar-78 11:48:09, EDIT BY MILLER
;ALLOW DEST OBJECT FORMAT OF TWO. IF SO, IGNORE GROUP,USER
;<4.MONITOR>NSPSRV.MAC.166, 29-Mar-78 10:38:40, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.165, 29-Mar-78 08:11:12, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.164, 28-Mar-78 12:29:03, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.163, 24-Mar-78 12:32:04, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.162, 23-Mar-78 10:34:49, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.161, 23-Mar-78 09:20:11, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.160, 23-Mar-78 08:39:54, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.159, 23-Mar-78 08:29:36, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.158, 22-Mar-78 14:15:58, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.157, 22-Mar-78 11:04:36, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.156, 22-Mar-78 09:16:37, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.155, 21-Mar-78 15:43:34, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.154, 21-Mar-78 12:46:26, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.153, 21-Mar-78 10:13:57, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.152, 20-Mar-78 09:33:49, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.151, 16-Mar-78 09:11:39, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.149, 15-Mar-78 14:55:45, Edit by MCCLURE
; ADD LOOPBACK FOR 2020
;<4.MONITOR>NSPSRV.MAC.148, 15-Mar-78 12:19:19, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.147, 14-Mar-78 15:46:54, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.146, 14-Mar-78 14:55:44, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.145, 14-Mar-78 13:05:31, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.144, 14-Mar-78 10:13:22, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.143, 13-Mar-78 09:25:59, EDIT BY MILLER
;FIX UP VERSION NUMBERS IN NODE INIT MESSAGE
;<4.MONITOR>NSPSRV.MAC.142, 9-Mar-78 15:37:15, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.141, 9-Mar-78 10:18:55, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.140, 9-Mar-78 09:57:14, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.139, 8-Mar-78 16:56:31, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.138, 8-Mar-78 16:11:47, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.137, 7-Mar-78 16:40:07, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.136, 7-Mar-78 10:48:21, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.135, 6-Mar-78 14:48:38, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.134, 6-Mar-78 09:21:29, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.133, 2-Mar-78 09:52:33, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.132, 1-Mar-78 14:31:40, EDIT BY MILLER
;CHANGE RANGE CHECK ON NODE NUMBER IN NODE JSYS
;<4.MONITOR>NSPSRV.MAC.131, 1-Mar-78 12:05:49, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.130, 28-Feb-78 14:48:16, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.129, 28-Feb-78 10:30:37, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.128, 27-Feb-78 11:05:23, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.127, 27-Feb-78 10:42:56, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.126, 27-Feb-78 10:22:45, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.125, 24-Feb-78 14:13:20, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.124, 24-Feb-78 14:12:44, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.123, 24-Feb-78 14:10:59, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.122, 24-Feb-78 10:11:37, EDIT BY MILLER
;DEFINE OURNUM AND NODNUM AS EXTN'S
;<4.MONITOR>NSPSRV.MAC.121, 24-Feb-78 09:41:12, EDIT BY MILLER
;FIX SETTING OF NODE NUMBER IN NSPINI
;<4.MONITOR>NSPSRV.MAC.120, 24-Feb-78 09:02:10, EDIT BY MILLER
;ADD OURNUM. ADD FUNCTIONS TO NODE JSYS TO SET AND READ IT
;<4.MONITOR>NSPSRV.MAC.119, 22-Feb-78 15:16:36, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.118, 22-Feb-78 12:24:34, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.117, 22-Feb-78 12:17:48, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.116, 22-Feb-78 11:58:53, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.115, 21-Feb-78 09:48:36, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.114, 21-Feb-78 09:33:04, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.113, 20-Feb-78 13:52:15, Edit by PORCHER
;Fix typos in last edit
;<4.MONITOR>NSPSRV.MAC.112, 20-Feb-78 11:21:39, EDIT BY MILLER
;ADD LABEL QCK050
;<4.MONITOR>NSPSRV.MAC.111, 17-Feb-78 16:49:46, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.110, 17-Feb-78 11:23:57, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.109, 17-Feb-78 11:00:29, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.108, 16-Feb-78 11:13:46, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.107, 15-Feb-78 10:23:30, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.106, 15-Feb-78 10:17:16, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.105, 15-Feb-78 09:49:24, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.104, 15-Feb-78 09:06:11, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.103, 14-Feb-78 16:11:02, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.102, 14-Feb-78 11:34:26, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.101, 13-Feb-78 12:45:01, Edit by MCCLURE
;<4.MONITOR>NSPSRV.MAC.100, 13-Feb-78 09:44:56, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.99, 6-Feb-78 16:52:14, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.98, 3-Feb-78 10:37:54, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.97, 2-Feb-78 15:09:15, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.96, 2-Feb-78 15:07:23, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.95, 2-Feb-78 11:08:31, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.94, 1-Feb-78 12:49:01, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.93, 1-Feb-78 12:13:04, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.92, 1-Feb-78 12:09:54, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.91, 31-Jan-78 14:44:55, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.90, 31-Jan-78 13:11:36, Edit by HURLEY
;<4.MONITOR>NSPSRV.MAC.89, 30-Jan-78 13:20:57, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.88, 30-Jan-78 11:14:54, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.87, 30-Jan-78 11:09:34, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.86, 30-Jan-78 09:33:48, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.85, 28-Jan-78 23:06:14, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.84, 28-Jan-78 22:59:38, Edit by KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.83, 27-Jan-78 16:53:49, EDIT BY KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.82, 27-Jan-78 16:35:42, EDIT BY KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.81, 27-Jan-78 16:30:46, EDIT BY KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.80, 27-Jan-78 15:52:49, EDIT BY KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.79, 27-Jan-78 11:20:17, EDIT BY KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.78, 27-Jan-78 11:15:13, EDIT BY KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.77, 27-Jan-78 11:06:40, EDIT BY KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.76, 27-Jan-78 10:34:58, EDIT BY KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.75, 26-Jan-78 22:22:01, EDIT BY KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.74, 26-Jan-78 15:08:35, EDIT BY KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.73, 26-Jan-78 14:09:08, EDIT BY KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.72, 26-Jan-78 14:06:43, EDIT BY KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.71, 26-Jan-78 14:04:56, EDIT BY KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.69, 26-Jan-78 12:23:34, EDIT BY KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.68, 26-Jan-78 12:07:53, EDIT BY KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.67, 26-Jan-78 10:43:06, EDIT BY KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.66, 26-Jan-78 10:20:30, EDIT BY KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.65, 26-Jan-78 10:10:13, EDIT BY KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.64, 25-Jan-78 17:00:54, EDIT BY KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.63, 25-Jan-78 16:12:33, EDIT BY KIRSCHEN
; .
; .
; .
;<4.MONITOR>NSPSRV.MAC.14, 9-Jan-78 11:54:54, EDIT BY KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.13, 8-Jan-78 13:14:56, EDIT BY MILLER
;SET UP FOR INPUT AT NTMTOP
;<4.MONITOR>NSPSRV.MAC.12, 6-Jan-78 16:28:03, EDIT BY KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.11, 6-Jan-78 13:50:47, EDIT BY KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.10, 6-Jan-78 12:54:39, EDIT BY KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.9, 6-Jan-78 12:50:29, EDIT BY KIRSCHEN
;FIX BUG IN TSKLOK - DO NOT ASSUME TRVAR IS SET UP
;<4.MONITOR>NSPSRV.MAC.8, 5-Jan-78 15:57:39, EDIT BY KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.7, 4-Jan-78 15:49:30, EDIT BY KIRSCHEN
;MAKE OBJLOK INTERNAL
;<4.MONITOR>NSPSRV.MAC.6, 4-Jan-78 13:44:12, EDIT BY MILLER
;<4.MONITOR>NSPSRV.MAC.5, 30-Dec-77 16:47:10, EDIT BY MILLER
;FIX CREATION OF ACCESS FIELDS
;<4.MONITOR>NSPSRV.MAC.4, 28-Dec-77 15:26:17, EDIT BY KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.3, 28-Dec-77 14:36:26, EDIT BY KIRSCHEN
;<4.MONITOR>NSPSRV.MAC.2, 28-Dec-77 11:08:04, EDIT BY KIRSCHEN
;MOVE SOME FILESYSTEM ROUTINES TO MODULE FILNSP
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (C) 1976,1977,1978,1979,1980,1981,1982 BY DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.
SEARCH NSPPAR,PROLOG,PROKL
TTITLE (NSPSRV,,< - Network Services Protocol Interface to TOPS20 >)
EXTN <ADDOUT,OUTSEG,NODTBL,MAXHST>
EXTN <ASGWDW,BLKASG,CMPLEN,DCNNAM,DCNSET,EXTSET,ITSID>
EXTN <ITSNAM,ITSNUM,LASTSK,LLBIT,LLBITS,LLHEAD,LLLLCK>
EXTN <MAXBLK,MAXEXP,MAXLNK,MCBDTE,MSGQ,NAKCNT,NETDIR>
EXTN <NETSR1,NETSQ1,NETUIN,NETUOU,NODNUM,NSPLPB,NSPMAX>
EXTN <OBJMAX,OBJTBL,OPNDNC,OPNSRC,OURNUM>
EXTN <PRSNAM,RMSGQ,SMSGQ,SRCNAM,SRNSET,VERSET>
;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
;DEFINE LOCAL MACROS
DEFINE LLLOCK
< CALL LOKLL ;;GO LOCK UP THE TREE
> ;;END OF LLLOCK MACRO
DEFINE LLLULK
< CALL ULOKLL ;;GO UNLOCK THE TREE
> ;;DONE
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 NSP Initialization
;NAMINI INITIALIZES NODE NAME TO "TOPS20"
NAMINI::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
RET
;ROUTINE TO INIT NETWORK DATA BASES,ETC.
SWAPCD ;SWAPPABLE
NSPINI::UNLOCK LLLLCK ;UNLOCK LOCK
UNLOCK OUTLOK ;INITIALIZE LOCK ON BACKGROUND TASK'S QUEUE
UNLOCK NODLOK ;INITIALIZE LOCK ON NODTBL
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
MOVX T1,1B1 ;MAKE FORK HAVE ALL CAPS
SETZ T2,
CFORK ;GET A FORK
BUG (NSPFRK,<<T1,REASON>>)
MOVEI T2,TSKINI ;THE STARTING ADDRESS
MSFRK ;START IT
MOVX T2,FRKRUN ;SAY FORK IS RUNNING
IORM T2,MCBDTE ;SET FLAG
CALL ININOD ;INITIALIZE KNOWN NODE TABLE
BUG(NDINIT)
RET ;DONE
; INITIALIZE TABLE OF KNOWN NODES
ININOD: NOINT ;DO NOT PERMIT INTERRUPTS WHILE ASSIGNING SPACE
MOVX T1,MAXNOD+2 ;NEED 1 WORD PER NODE PLUS FREE BLOCK HEADER
; PLUS TBLUK HEADER
CALL ASGSWP ;ALLOCATE SOME SPACE FOR NODE TABLE
RETBAD (,<OKINT>) ;FAILED
OKINT ;PERMIT INTERRUPTS AGAIN
ADDI T1,1 ;POINT PAST FREE BLOCK HEADER
MOVEM T1,NODTBL ;SAVE ADDRESS OF NODE TABLE
MOVX T4,MAXNOD ;GET MAX NUMBER OF ENTRIES IN TABLE
MOVEM T4,(T1) ;INITIALIZE TBLUK HEADER
MOVEI T1,OURNAM ;GET POINTER TO OUR NODE NAME
MOVX T2,.NDSON ;STATE IS ON
SETZ T3, ;NO NEIGHBOR NODE
CALL ADDINT ;ADD US TO THE KNOWN NODES
RETBAD () ;FAIL
RETSKP ;DONE, RETURN SUCCESS
;ADDNOD - ROUTINE TO ADD A NODE TO THE TABLE OF KNOWN NODES
;
;ACCEPTS IN T1/ ADDRESS OF ASCIZ NODE NAME
; T2/ STATE OF NODE
; T3/ POINTER TO NEARER NEIGHBOR NODE (FOR STATE OF "ON")
; CALL ADDNOD
;RETURNS: +1 FAILED
; +2 SUCCESS, NODE ADDED IF NOT ALREADY IN TABLE
ADDNOD: ASUBR <ADNADR,ADNSTA,ADNABR,ADHLD>
; SEE IF NODE IS TO BE ADDED OR REMOVED FROM KNOWN NODE TABLE
HRRZ T3,ADNSTA ;GET NODE STATE
CAIN T3,.NDSOF ;NODE OFF ?
JRST [ CALL REMNOD ;REMOVE NODE FROM TABLE OF KNOWN NODES
RET ;FAILURE - RETURN
JRST ADDTEL] ;NOTIFY INTERESTED USERS THAT TOPOLOGY CHANGED
; CHECK TO SEE IF THE NODE IS ALREADY IN THE TABLE
NOINT ;DO NOT PERMINT INTERRUPTS WITH TABLE LOCKED
LOCK NODLOK ;LOCK THE TABLE
HRRZ T2,ADNADR ;GET ADDRESS OF NODE NAME STRING
HRLI T2,(POINT 7,) ;FORM POINTER TO NODE NAME STRING
MOVE T1,NODTBL ;GET ADDRESS OF NODE TABLE
TBLUK ;SEE IF THE NODE IS IN THE TABLE OF KNOWN NODES
ERJMP [UNLOCK NODLOK ;UNLOCK THE TABLE
OKINT ;PERMIT INTERRUPTS AGAIN
RET] ;AND RETURN FAILURE
TXNN T2,TL%EXM ;ALREADY IN TABLE (EXACT MATCH) ?
JRST ADDIT ;NO - ADD THIS NODE NAME
; NODE ALREADY EXISTS. CHECK THE NEIGHBOR
MOVEM T1,ADHLD ;YES - SAVE THE ENTRIES TABLE LOCATION
MOVE T1,ADNABR ;GET POINTER TO NEIGHBOR NAME
JUMPE T1,ADDND1 ;IF ZERO => NO NEIGHBOR
CALL NABROK ;CHECK FOR EXISTENCE OF NEIGHBOR
JRST [ UNLOCK NODLOK ;NONEXISTANT NEIGHBOR - ERROR
OKINT ;ALLOW INTERRUPTS
RET] ;ERROR RETURN
MOVE T2,ADHLD ;GET NODE ADDRESS
HLRZ T1,(T1) ;GET ADDRESS OF NEIGHBOR NAME
ADDND1: HRRM T1,(T2) ;ADD NEIGHBOR NAME TO NODE TABLE
; SINCE NODE WAS ALREADY IN TABLE WE CAN FREE THE NAME STRINGS
HRRZ T1,ADNADR ;GET ADDRESS OF STRINGS
SOS T1 ;POINT TO START OF BLOCK
CALL RELMES ;FREE THE SPACE
UNLOCK NODLOK ;UNLOCK THE NODE TABLE
OKINT ;ALLOW INTERRUPTS
RETSKP
; ADD THE NODE TO THE TABLE OF KNOWN NODES
ADDIT: MOVE T1,ADNABR ;GET ADDRESS OF NEIGHBOR NAME STRING
JUMPE T1,ADDIT1 ;IF ZERO => NO NEIGHBOR
CALL NABROK ;CHECK FOR IT'S EXISTENCE
JRST [ UNLOCK NODLOK ;UNLOCK THE NODE TABLE
OKINT ;ALLOW INTERRUPTS
RET]
HLRZ T1,(T1) ;GET ADDRESS OF NEIGHBOR NAME
ADDIT1: HRL T2,ADNADR ;GET ADDRESS OF NODE NAME STRING
HRR T2,T1 ;GET NODES NEIGHBOR NAME
MOVE T1,NODTBL ;GET ADDRESS OF NODE TABLE
TBADD ;ADD THE NODE TO TABLE OF KNOWN NODES
ERJMP [UNLOCK NODLOK ;UNLOCK THE TABLE
OKINT ;PERMIT INTERRUPTS AGAIN
RET] ;AND RETURN FAILURE
UNLOCK NODLOK ;UNLOCK THE TABLE
OKINT ;PERMIT INTERRUPTS AGAIN
;HERE TO NOTIFY INTERESTED USERS THAT TOPOLGY HAS CHANGED
ADDTEL: MOVEM Q1,ADNADR ;SAVE Q1
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
MOVE Q1,ADNADR ;RESTORE Q1
RETSKP
;REMNOD - ROUTINE TO REMOVE A NODE FROM THE TABLE OF KNOWN NODES
;
;ACCEPTS IN T1/ POINTER TO ASCIZ NODE NAME
; CALL REMNOD
;RETURNS: +1 FAILED
; +2 SUCCESS
REMNOD: ASUBR <RMNNAM>
NOINT ;DO NOT PERMINT INTERRUPTS WITH TABLE LOCKED
LOCK NODLOK ;LOCK THE TABLE
MOVE T1,NODTBL ;GET ADR OF HEADER OF KNOWN NODE TABLE
MOVE T2,RMNNAM ;GET NAME OF NODE
TBLUK ;FIND THE NAME IN THE KNOWN NODE TABLE
ERJMP REMNDX ;FAILED
TXNN T2,TL%EXM ;IN TABLE (EXACT MATCH) ?
JRST REMNDX ;NO - FAIL
CALL NODDEL ;YES - DELETE NODE AND REST OF TREE
JRST REMNDX ;ERROR - FAIL
MOVE T1,RMNNAM ;FREE THE BUFFER
SOS T1 ;BACK-UP TO HEADER WORD
CALL RELMES
UNLOCK NODLOK ;UNLOCK THE TABLE
OKINT ;PERMIT INTERRUPTS AGAIN
RETSKP ;DONE, RETURN SUCCESS
; HERE ON AN ERROR
REMNDX: UNLOCK NODLOK ;UNLOCK THE DATABASE
OKINT ;PERMIT INTERRUPTS AGAIN
RET ;FAIL
;ADDINT - ROUTINE TO ADD A NODE TO KNOWN NODE TABLE, NAME STRING ALREADY
; IN MONITOR.
;
;ACCEPTS IN T1/ POINTER TO NODE NAME STRING
; T2/ NODE STATE
; T3/ POINTER TO NEARER NEIGHBOR NODE (OR ZERO)
; CALL ADDINT
;RETURNS: +1 FAILED
; +2 SUCCESS
ADDINT: ASUBR <ADIPTR,ADISTA,ADINBR,ADIBLK>
; COPY THE STRING INTO A FREE BLOCK
NOINT ;DO NOT PERMIT INTERRUPTS WHILE ASSIGNING SPACE
MOVX T1,2*<<NODMAX+12>/5> ;ASSIGN SPACE FOR NODE NAMES
CALL ASGSWP ;GET SOME SPACE
RETBAD (,<OKINT>) ;FAILED
ADDI T1,1 ;POINT TO WHERE STRING GOES
MOVEM T1,ADIBLK ;SAVE DESTINATION ADDRESS OF STRING
MOVE T2,ADIPTR ;GET SOURCE STRING ADDRESS
MOVX T3,NODMAX ;MAX SIX CHARS
CALL MOVSTR ;MOVE STRING INTO FREE BLOCK
MOVE T1,ADIBLK ;NOW MOVE THE NEIGHBOR NAME
ADDI T1,<NODMAX+12>/5 ;POINT TO SECOND SLOT
MOVX T3,NODMAX ;MAXIMUM NODE NAME
SKIPE T2,ADINBR ;COPY NEIGHBOR (IF THERE)
CALL MOVSTR ;MOVE NEIGHBOR NAME
; ADD NODE TO TABLE OF KNOWN NODES
MOVE T1,ADIBLK ;GET ADDRESS OF NODE NAME STRING
MOVE T2,ADISTA ;GET NODE STATE
SKIPE T3,ADINBR ;PASS T3=0 IF NO NEIGHBOR
MOVEI T3,<<NODMAX+12>/5>(T1) ;POINT TO NEIGHBOR NAME
CALL ADDNOD ;ADD NODE TO KNOWN NODE TABLE
JRST ADIN10 ;FAILED, CLEAN UP
OKINT ;PERMIT INTERRUPTS AGAIN
RETSKP ;DONE, RETURN SUCCESS
; HERE ON AN ERROR
ADIN10: MOVEM T1,ADISTA ;SAVE ERROR CODE
MOVE T1,ADIBLK ;ADDRESS OF BLOCK
SOS T1 ;POINT TO HEADER
CALL RELMES ;RELEASE THE BLOCK
OKINT ;PERMIT INTERRUPTS AGAIN
MOVE T1,ADISTA ;RESTORE ERROR CODE
RETBAD () ;FAIL
;NODDEL - ROUTINE TO DELETE A GIVEN ENTRY FROM THE NODE TABLE
;ACCEPTS: T1/ ADDRESS OF ENTRY IN NODE TABLE (WITH NODTBL LOCKED)
;RETURNS: +1,ALWAYS, ALL AC'S PRESERVED
;*** N.B. *** THIS ROUTINE IS RECURSIVE. ***
;NODTBL IS REALLY A TREE OF NODES. EACH NODE HAS THE ADDRESS OF A NEARER
;NEIGHBOR (I.E. NEARER TO US THAN IT). WHEN REMOVING A NODE WE MUST REMOVE
;ALL THE NODES THAT HAVE IT AS A NEIGHBOR. THINGS BECOME RECURSIVE BECAUSE
;WHEN WE REMOVE THE SECONDARY NODES THEY COULD ALSO BE NEIGHBORS TO OTHER
;NODES.
NODDEL: SAVET
STKVAR <DELHLD>
MOVE T3,(T1) ;GET ENTRY WE ARE DELETING
MOVEM T3,DELHLD ;SAVE NODTBL POINTER
HLRZ T3,(T1) ;GET ADDRESS OF NODE NAME
MOVE T1,NODTBL ;GET ADDRESS OF NODE TABLE
MOVE T4,NODTBL ;HOLD FOR LOOP DECISION
; FIND ANY ENTRIES HAVING CURRENT NODE AS NEAREST NEIGHBOR
NODDL1: AOS T1 ;POINT TO NEXT ENTRY
HRRZ T2,0(T1) ;GET THE NEIGHBOR ADDRESS
CAMN T2,T3 ;IS THE CURRENT NODE THE NEIGHBOR
JRST [ HLRZ T2,0(T1) ;YES - IS THIS A POINTING TO SELF CASE?
CAMN T2,T3 ;???
JRST .+1 ;YES - THEN DO NOTHING
CALL NODDEL ;YES - REMOVE THAT NODE ***RECURSION***
RETBAD ;ERROR - FAIL
MOVE T1,NODTBL ;START AT TOP OF TABLE
JRST NODDL1] ;SEARCH WHOLE TABLE AGAIN
HLRZ T2,0(T4) ;GET CURRENT LENGTH OF TABLE
ADD T2,T4 ;T2<= ADDRESS OF LAST ENTRY
CAML T2,T1 ;ARE WE FINISHED
JRST NODDL1 ;NO - KEEP LOOKING
;...
;...
; HAVE CLEARED ALL ENTRIES DOWN THE TREE FROM HERE - DELETE THIS NODE
HLR T1,(T4) ;GET COUNT OF ENTRIES
MOVE T2,DELHLD ;LOOKING FOR THIS ENTRY
NODDL2: AOS T4 ;BUMP TO NEXT ENTRY
CAMN T2,(T4) ;THE ONE WE WANT?
JRST NODDL3 ;YES - DELETE IT
SOJG T1,NODDL2 ;NO - KEEP LOOKING
BUG (NDBDEL)
RETBAD
NODDL3: MOVE T2,T4 ;GET THE NODE TABLE ENTRY
HLRZ T4,(T2) ;GET ADDRESS OF FREE BLOCK HOLDING STRINGS
MOVE T1,NODTBL ;POINT TO NODE TABLE
TBDEL ;DELETE THE ENTRY
ERJMP [RETBAD] ;ERROR - HANDLE
MOVE T1,T4 ;RELEASE THE STRING BLOCK
SOS T1 ;POINT TO FIRST WORD OF FREE BLOCK
CALL RELMES ;FREE IT
RETSKP
;NABROK - ROUTINE TO CHECK FOR EXISTENCE OF A NODE
;ACCEPTS: T1/POINTER TO NODE STRING
;RETURNS: +1,NODE DOES NOT EXIST
; +2,NODE EXISTS
; T1/ADDRESS OF NODTBL ENTRY
NABROK: MOVE T2,T1 ;MOVE POINTER TO NODE NAME
MOVE T1,NODTBL ;POINT TO TABLE OF NODES
TBLUK ;IS IT THERE
ERJMP [RET] ;ERROR - RETURN
TXNN T2,TL%EXM ;EXACT MATCH?
RET ;NO - INDICATE NODE DOES NOT EXIST
RETSKP ;YES - INDICATE EXISTENCE
SUBTTL Routines to Manipulate Logical Link Blocks and Object Tables
SWAPCD ;CALLED ONLY IN PROCESS CONTEXT
;ROUTINES USED TO LOCK AND UNLOCK LL TREE
LOKLL:: NOINT ;PREVENT INTS
LOCK LLLLCK,<CALL LCKTST> ;LOCK UP THE TREE
RET ;DONE
ULOKLL::UNLOCK LLLLCK ;UNLOCK THE TREE
OKINT ;ALLOW INTS
RET ;AND DONE
;ROUTINES TO LOCK AND UNLOCK INDIVIDUAL LL BLOCKS
;LOCK A BLOCK.
; T1/ BLOCK ADDRESS
;RETURNS: +1 FAILED. BLOCK ROUTINE IN T1
; +2 SUCCESS
BLKLOK::SAVEAC (T4) ;PRESERVE TEMP AC
NOSKED ;PREVENT RACES
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
NOINT ;PREVENT INTERRUPT WHILE BLOCK LOCKED
OKSKED ;PERMIT SCHEDULING AGAIN
RETSKP ;DONE, BLOCK NOW LOCKED
; HERE IF LOCK WILL NOT BE PERMITTED - RETURN A SCHEDULER TEST
BLKLK1: OKSKED ;PERMIT SCHEDULING
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::NOSKED ;PREVENT SCHEDULING
DECR LLRCT,(T1) ;UNDO PREVIOUS LOCK
JN LLRCT,(T1),BLKUL1 ;UNDOING INITIAL LOCK ?
SETZRO LLRFK,(T1) ;YES, CLEAR ID OF LOCKER ALSO
BLKUL1: OKINT ;PERMIT INTERRUPT AGAIN
OKSKED ;AND PERMIT SCHEDULING AGAIN
RET ;DONE, RETURN
;ROUTINE TO INIT LL ADDRESS BIT TABLE. CALLED AT SYSTEM STARTUP
2
LLINIT: ACVAR <W1> ;GET A WORK REGISTER
MOVSI W1,-MAXLNK ; GET MAX LINK VALUE
AOS W1 ;SKIP ENTRY 0
LLINI1: HRRZ T1,W1 ;GET LINK ADDRESS
CALL FRELNK ;FREE LINK #
AOBJN W1,LLINI1 ;DO 'EM ALL
RET ;AND DONE
;**;[2607] ADD 1 LINE AT LLINI1:+4L PED 4-APR-82
ENDAV. ;[2607] END ACVAR
;LOKPIP - ROUTINE TO LOCK AN ATS DATA DATA OR CONTROL PIPE
;
;ACCEPTS IN T3/ ATS PIPE IDENTIFIER
; CALL LOKPIP
;RETURNS: +1 FAILED, SCHEDULER TEST IN T1
; +2 SUCCESS, PROCESS NOINT AND PIPE LOCKED
LOKPIP::TRVAR <LKPCOD,LKPLLB>
MOVEM T3,LKPCOD ;SAVE ATS ID
; GET THE ADDRESS OF THE LOGICAL LINK BLOCK
LLLOCK ;LOCK THE LOGICAL LINK TREE
MOVEI T1,CHKPIP ;GET COROUTINE TO FIND ATS PIPE
SETOM T2 ;ANY LINK
CALL OBJSRC ;GO FIND BLOCK
JRST [ LLLULK ;DOES NOT EXIST
BUG(NSPPWA)
RET ] ;UNLOCK THE TREE AND RETURN FAILURE
MOVEM T1,LKPLLB ;SAVE LOGICAL LINK BLOCK ADDRESS
; LOCK THE BLOCK
MOVE T1,LKPLLB ;GET LOGICAL LINK BLOCK ADDRESS
CALL BLKLOK ;GO LOCK THE LOGICAL LINK BLOCK
JRST [ LLLULK ;CANNOT LOCK IT NOW, UNLOCK THE TREE
RET ] ;RETURN SCHED TEST
LLLULK ;BLOCK IS NOW RESERVED. UNLOCK THE TREE
RETSKP ;DONE, RETURN WITH PIPE LOCKED
;CHKPIP - COROUTINE TO FIND ATS LINK BLOCK WITH GIVEN ATS DATA PIPE
;
;ACCEPTS IN TRVAR LKPCOD/ ATS ID FOR PIPE
; T1/ ADDRESS OF LINK BLOCK TO CHECK
; CALL CHKPIP
;RETURNS: +1 NOT DESIRED BLOCK
; +2 SUCCESS, FOUND BLOCK WITH REQUESTED ID
CHKPIP: SAVET ;PRESERVE TERMPORARY AC'S
JE LLINT,(T1),R ;LOOK AT INTERNAL LINKS ONLY
LOAD T2,LLDRV,(T1) ;GET DRIVER CORRELATION CODE
CAME T2,LKPCOD ;DESIRED ATS ID ?
RET ;NO, RETURN FAILURE
RETSKP ;YES, RETURN SUCCESS
;ULKPIP - ROUTINE TO UNLOCK AN ATS DATA OR CONTROL PIPE
;
;ACCEPTS IN T3/ ATS PIPE IDENTIFIER
; CALL ULKPIP
;RETURNS: +1 ALWAYS, WITH PIPE UNLOCKED
ULKPIP::TRVAR <LKPCOD>
MOVEM T3,LKPCOD ;SAVE ATS ID FOR COROUTINE
LLLOCK ;LOCK THE LOGICAL LINK TREE
MOVEI T1,CHKPIP ;GET COROUTINE ADDRESS
SETOM T2 ;ANY LINK
CALL OBJSRC ;GO FIND BLOCK
JRST [ LLLULK ;DOES NOT EXIST
BUG(NSPPHV)
RET ] ;UNLOCK THE TREE AND RETURN FAILURE
LLLULK ;UNLOCK THE TREE
CALLRET BLKULK ;UNLOCK PIPE AND RETURN
;ROUTINE TO FIND INDEX INTO LOGICAL LINK TABLES.
;ACCEPTS: T1/ LOGICAL LINK
; T2/ FOREIGN LINK I.D. -1 FOR ANY
; T3/ HOST NAME STRING IF LLLKUH USED
;RETURNS: +1 FAILED. LINK NOT FOUND
; T1/ INSERT POINT FOR NEW ENTRY
; +2 SUCCESS. T1/ ADDRESS OF LINK ENTRY
; T2/ PREVIOUS NODE ADDRESS
;PRESERVES T4
;LLLKUH MUST NOT BE CALLED FROM SCHED CONTEXT.
RESCD ;NEEDS TO BE RESIDENT
LLLKUP::SETOM T3 ;NO HOST MATCH IF ENTERED HERE
LLLKUH: SAVEAC <T4> ;PRESERVE AC
STKVAR <LASTM,LNKID,LLHO> ;REMEMBER INSERT POINT
MOVEM T3,LLHO ;SAVE HOST STRING POINTER
SETZM LASTM ;NO INSERT FOUND YET
MOVEM T1,LNKID ;SAVE DESIRED ADDRESS
MOVE T1,LLHEAD ;GET HEAD OF TREE
LLLKU1: JUMPE T1,LLFAIL ;NO THERE. ERGO, NOT FOUND
LOAD T3,LLLNK,(T1) ;GET THE LINK I.D.
CAME T3,LNKID ;IS THIS IT?
JRST [ MOVEM T1,LASTM ;REMEMBER THIS AS INSERT POINT
CAMG T3,LNKID ;NEED TO GO UP OR DOWN?
JRST [ LOAD T1,LLUPL,(T1) ;GET UP POINTER
JRST LLLKU1] ;AND GO SEE ABOUT IT
LOAD T1,LLDWN,(T1) ;DOWN. GET DOWN POINTER
JRST LLLKU1] ;AND GO SEE ABOUT IT
JUMPL T2,LLLKU2 ;IF NO HOST CHECK, FOUND IT
OPSTR <CAME T2,>,LLHLK,(T1) ;DOES THE HOST MATCH?
RETBAD (NSPX2) ;NO. GIVE ERROR
LLLKU2: MOVE T2,LASTM ;RETURN PREVIOUS NODE
SKIPG LLHO ;WANT HOST MATCH?
RETSKP ;NO. ALL DONE THEN
LOAD T2,LLHST,(T1) ;GET HOST STRING
EXCH T1,LLHO ;SAVE LINK. GET SOURCE HOST NAME
CALL CMPSTR ;DO COMPARE
RETBAD (NSPX2) ;NO MATCH
MOVE T1,LLHO ;A MATCH. GET LINK
MOVE T2,LASTM ;GET PREVIOUS
RETSKP ;AND DONE
;COULDN'T FIND REQUIRED LINK. RETURN INSERT POINT
LLFAIL: MOVE T1,LASTM ;FOUND AN INSERT POINT?
RET ;AND RETURN
;ALL OF THIS CODE IS UNSUITABLE FOR EXTENDED ADDRESSING. SINCE
;OBJECT NAMES CAN RESIDE IN SWAPPABLE FREE SPACE, OBJTBL
;NEEDS TO HAVE 36 BIT ADDRESSES POINTING TO THE STRINGS. ALSO,
;A REPLACEMENT FOR TBLUK IS NEEDED WHICH WILL DO LOOK UP, DELETE
;AND ADD ENTRIES TO SUCH AN "EXTENDED" TABLE. FOR THE TIME BEING,
;HOWEVER, THE CODE AS WRITTEN WILL SUFFICE.
;ROUTINE TO INITIALIZE THE OBJECT TABLE FOR THE MONITOR.
SWAPCD
OBJINI: MOVE T1,[OBJPRO,,OBJTBL]
BLT T1,OBJTBL+OBJENT ;INIT THE TABLE
RET ;AND DONE
;THIS TABLE SHOULD BE MOVED TO STG SOMEDAY*****************
;PROTOTYPE OBJECT TABLE
OBJPRO: OBJENT,,OBJMAX
[ASCIZ /ATS/],,3
[ASCIZ /FAL/],,21
[ASCIZ /NCU/],,23
[ASCIZ /NRM/],,7
[ASCIZ /TASK/],,0
OBJENT==.-OBJPRO-1 ;# OF ENTRIES
;ROUTINE TO LOOK UP AN OBJECT NAME IN THE SYSTEM OBJECT TABLES
;ACCEPTS: T1/ POINTER TO TEST OBJECT NAME
;RETURNS: +1 NOT FOUND. NO SUCH OBJECT
; +2 OBJECT FOUND
; T1/ OBJECT NUMBER
OBJLOK::ASUBR <OBJPTR> ;SAVE POINTER
MOVE T2,T1 ;COPY POINTER
MOVE T1,[OBJTBL] ;GET THE OBJECT TABLE
TBLUK ;LOOK UP THE OBJECT
TXNN T2,TL%EXM ;FOUND IT?
JRST OBJLO1 ;NO. GO CHECK FOR NUMBER
HRRZ T1,0(T1) ;YES. GET OBJECT NUMBER
RETSKP ;AND RETURN WITH IT
;TBLUK DIDNT'T FIND IT. SEE IF IT IS NUMERIC
OBJLO1: SETZ T1, ;GET AN ACCUMULATOR
OBJLO2: ILDB T2,OBJPTR ;GET NEXT BYTE
JUMPE T2,RSKP ;IF AT THE END, GOOD NUMBER
CAIL T2,"0" ;A VALID NUMBER
CAILE T2,"9" ;STILL?
RET ;NO. NOT A VALID NUMBER
IMULI T1,^D10 ;YES. ADJUST ACCUMULATOR
ADDI T1,-"0"(T2) ;AND ADD IN NEW QUANTITY
CAILE T1,OBJMAX ;STILL VALID?
RET ;NO. GIVE AN ERROR
JRST OBJLO2 ;GO DO ALL OF IT
;ROUTINE TO FIND A "LISTENING" OR ACTIVE OBJECT IN THE LOGICAL
;LINK TABLE. WILL ALSO DO SCAN OF ENTIRE TREE
;ACCEPTS:
; T1/ COUROUTINE ADDRESS TO CALL WHEN OBJECT IS FOUND
; T2/ 0 IF OBJECT MAY BE LISTENING OR ACTIVE
; 1 IF OBJECT MUST BE LISTENING ONLY
; -1 IF ANY LINK IS ACCEPTBLE
;RETURNS:
; +1 OBJECT NOT FOUND
; +2 OBJECT FOUND.
; T1/ POINTER INTO LINK TABLE FOR THIS OBJECT
; T2/ LINK I.D. OF THE OBJECT
;THE COROUTINE IS CALLED TO CHECK IF THE OBJECT IS THE ONE
;WANTED. THE COROUTINES ARE CALLED WITH THE FOLLOWING ARGS:
; T1/ ADDRESS OF LOGICAL LINK ENTRY
; ALL OF THE P AND Q REGISTERS INTACT
;THE COROUTINES RETURN AS FOLLOWS:
; +1 DON'T WANT THIS OBJECT
; +2 THIS IS THE ONE
;THE COROUTINE MUST PRESERVE ALL TEMPORARY AC'S
OBJSRC::DMOVE T3,T1 ;SAVE ARGS
SKIPN T1,LLHEAD ;ANY LINKS?
RET ;NO. CAN'T FIND IT THEN
PUSH P,[0] ;PUT A "FENCE" ON THE STACK
OBJSND: PUSH P,T1 ;SAVE THIS ONE
JUMPL T4,OBJSN2 ;IF ANY MATCH, GO HANDLE THIS ONE
JE LLFOB,(T1),OBJSNO ;IF NOT OBJECT, CAN'T BE A MATCH
JUMPN T4,[LOAD T2,LLSTA,(T1) ;IF MUST BE LISTENING, GET STATE
CAIE T2,LLSLIS ;IS IT LISTENING?
JRST OBJSNO ;NO. NOT INTERESTED THEN
JRST .+1] ;YES
OBJSN2: JUMPE T3,OBJSFD ;IF NO COROUTINE, DONE
CALL 0(T3) ;CALL THE COROUTINE
SKIPA ;NOT THE ONE
JRST OBJSFD ;FOUND IT
OBJSNO: LOAD T1,LLUPL,(T1) ;NOT THE ONE. GET THE UP POINTER
JUMPN T1,OBJSND ;HAVE ONE. GO LOOK AT IT
OBJSN1: POP P,T1 ;NOT FOUND. GET PREVIOUS ONE
JUMPE T1,R ;IF BACK TO FENCE, NO SUCH OBJECT
LOAD T1,LLDWN,(T1) ;GET DOWN SIDE
JUMPN T1,OBJSND ;IF HAVE ONE, GO LOOK AT IT
JRST OBJSN1 ;IF NOT, KEEP POPING
;FOUND THE OBJECT
OBJSFD: POP P,T2 ;MUST CLEAN UP THE STACK
JUMPN T2,.-1 ;KEEP CLEANING
LOAD T2,LLLNK,(T1) ;GET LOGICAL LINK I.D.
RETSKP ;DONE. RETURN GOOD
;ROUTINE TO GET A UNIQUE TASK NAME.
;ACCEPTS: T1/ LL POINTER
; LL TREE MUST BE LOCKED
;RETURNS: +1 ALWAYS
; LLTSK FILLED IN WITH NAME
;PRESERVES T1
GETTSK: TRVAR <LLADDR,TSKBLK>
MOVEM T1,LLADDR ;SAVE LL BLOCK ADDRESS
MOVEI T1,3 ;NEED A BLOCK OF THIS SIZE
CALL GETBLK ;GO GET A BLOCK
RET ;NO MORE SPACE
MOVEM T1,TSKBLK ;SAVE ADDRESS
GETTS1: HRLI T1,(<POINT 7,>) ;MAKE A BYTE POINTER
AOS T2,LASTSK ;GET A NUMBER FOR THE TASK NAME
MOVEI T3,10 ;CONVERT OCTAL
NOUT ;MOVE NUMBER
JFCL ;WILL WORK
XMOVEI T1,TSKLOK ;MAKE SURE IS UNIQUE
SETOM T2 ;ANY LINK
CALL OBJSRC ;GO LOOK FOR A MATCH
JRST [ MOVE T1,LLADDR
MOVE T2,TSKBLK ;GET BLOCK ADDRESS
STOR T2,LLTSK,(T1)
RETSKP] ;AND DONE
MOVE T1,TSKBLK ;FOUND IT
JRST GETTS1 ;TRY AGAIN
;COROUTINE TO CHECK FOR TASK MATCH
TSKLOK: SAVET ;SAVE ALL TEMPS
LOAD T2,LLTSK,(T1) ;GET THIS ONE'S ADDRESS
JUMPE T2,R ;IF NONE, CAN'T BE IT
MOVE T1,TSKBLK ;GET BLOCK ADDRESS
CALLRET CMPSTR ;GO DO THE COMPARE
;COLLECTION OF UTILITIES
;MOVE ONE STRING TO ANOTHER.
;ACCEPTS: T1/ DEST STRING BLOCK
; T2/ SOURCE STRIGN BLOCK
; T3/ COUNT OR -1
;RETURNS: +1 ALWAYS.
;ALL REGISTERS PRESERVED
MOVSTR::SAVET ;SAVE ALL TEMPS
ACVAR <W1,W2> ;GET SOME WORK REGS
MOVE W1,[POINT 7,0(T1)]
MOVE W2,[POINT 7,0(T2)] ;SET UP ARGS
MOVST0: ILDB T4,W2 ;GET NEXT BYTE
IDPB T4,W1 ;STASH IT
JUMPE T4,R ;IF NULL, ALL DONE
JUMPL T3,MOVST0 ;IF NO COUNT, KEEP GOING
SOJG T3,MOVST0 ;MORE IN THE COUNT?
RET ;NO. ALL DONE
;**;[2607] ADD 1 LINE AT MOVST0:+6L PED 4-APR-82
ENDAV. ;[2607] END ACVAR
;ROUTINE TO "FREE" A LL ADDRESS.
;ACCEPTS: T1/ LL ADDRESS TO FREE
;RETURNS: +1 ALWAYS
FRELNK: ANDI T1,MAXLNK ;ISOLATE LOCAL INDEX
IDIVI T1,44 ;COMPUTE WORD AND OFFSET
ADD T1,[LLBITS] ;GET BIT TABLE OFFSET
MOVE T2,BITS(T2) ;GET A BIT
IORM T2,0(T1) ;TURN OF THE BIT
RET ;AND DONE
;ROUTINES TO GET AND RETURN SWAPPABLE FREE SPACE
;ROUTINE TO GET A BLOCK FROM THE LL STRING SPACE POOL
;ACCEPTS: T1/ SIZE TO GET
;RETURNS: +1 FAILED. T1/ERROR CODE
; +2 SUCCESS T1/ BLOCK ADDRESS
GETBLK: MOVEI T2,1(T1) ;ACCOUNT FOR HEADER
ADD T2,BLKASG ;COMPUTE AMOUNT THIS WOULD MAKE
CAILE T2,MAXBLK ;WITHIN BOUNDS?
RETBAD (MONX01) ;NO. INSUFFICIENT RESOURCES
AOS T1 ;GET SPACE +1
CALL ASGSWP ;GET SOME SPACE
RETBAD ;FAILED. GIVE IT UP
HRRZ T2,0(T1) ;GET COUNT ASSIGNED
ADDM T2,BLKASG ;ACCOUNT FOR IT
AOS T1 ;POINT TO FIRST USEFUL BLOCK
RETSKP ;AND GOOD
;ROUTINE TO RETURN A STRING BLOCK
;ACCEPTS: T1/ ADDRESS OF FIRST DATA LOCATION (HEADER+1)
;RETURNS: +1 ALWAYS
RELBLK: SOS T1 ;POINT TO HEADER
HRRZ T2,0(T1) ;GET WORDS IN THIS BLOCK
EXCH T2,BLKASG
SUBM T2,BLKASG ;COMPUTE NEW COUNT
HRRZ T2,0(T1) ;GET SIZE OF THE BLOCK AGAIN
CALLRET RELSWP ;RELEASE THE BLOCK
;ROUTINE TO GET A RESIDENT FREE SPACE BLOCK
;ACCEPTS: T1/ SIZE REQUIRED
GETRES::HRLI T1,.RESP3 ;IN PROCESS CONTEXT
MOVE T2,[RS%SE0!.RESNP] ;FROM THE NETWORK
CALL ASGRES ;GET SOME SPACE
RETBAD() ;COULDN'T
RETSKP ;GOT IT
;ROUTINE TO MOVE A STRING FROM JSB FREE SPACE TO SWAPPABLE FREE SPACE.
;ACCEPTS: T1/ DESTINATION BLOCK ADDRESS
; T2/ SP TO JSB FREE SPACE
; T3/ COUNT
;CLOBBERS ALL TEMPS
MOVST1::STKVAR <MVSPTR>
MOVE T4,[POINT 7,0(T1)] ;FORM STRING POINTER
MOVEM T4,MVSPTR ;SAVE POINTER
MOVST2: ILDB T4,T2 ;GET A BYTE
IDPB T4,MVSPTR ;STORE IT
SOJG T3,MOVST2 ;DO ALL BYTES
RET ;DONE
SUBTTL Logical Link Creation
; ROUTINES TO SET INPUT/OUTPUT FLAGS IN LOGICAL LINK BLOCKS
;
;ACCEPTS IN T1/ LOGICAL LINK BLOCK ADDRESS
; CALL SETOPI/SETOPW
;RETURNS: +1 ALWAYS
SETOPI::SETONE LLOPI,(T1) ;SET INPUT FLAG
RET ;DONE, RETURN
SETOPW::SETONE LLOPW,(T1) ;SET OUTPUT FLAG
RET ;DONE, RETURN
; ROUTINES TO TEST THE DIRECTION OF I/O
;
;ACCEPTS IN T1/ LOGICAL LINK BLOCK ADDRESS
SKPFLO::JE LLFLO,(T1),R ;NON-SKIP IF FLOW NOT FROM FILE-SYSTEM
RETSKP ;SKIP IF FLOW IS FROM THE FILE-SYSTEM
SKPFLI::JE LLFLI,(T1),R ;NON-SKIP IF FLOW NOT TO THE FILE-SYSTEM
RETSKP ;SKIP if FLOW IS TO THE FILE-SYSTEM
; ROUTINES TO SET/CLEAR DIRECTION-OF-FLOW BITS
CLRFLO::SETZRO LLFLO,(T1) ;SWITCH FLOW TO BE "TO THE NETWORK"
RET ;DONE, RETURN
SETFLO::SETONE LLFLO,(T1) ;SWITCH FLOW TO BE "FROM FILE-SYSTEM"
RET ;DONE, RETURN
;GETBSZ - ROUTINE TO OBTAIN THE BYTE SIZE FOR A LOGICAL LINK
;
;ACCEPTS IN T1/ LOGICAL LINK BLOCK ADDRESS
; CALL GETBSZ
;RETURNS: +1 ALWAYS, WITH T3/ BYTE SIZE
;
; PRESERVES LOGICAL LINK BLOCK ADDRESS IN T1
GETBSZ::LOAD T3,LLBSZ,(T1) ;GET BYTE SIZE
RET ;DONE, RETURN
;GETSTA - ROUTINE TO RETURN CURRENT STATE OF A LOGICAL LINK
;
;ACCEPTS IN T1/ LOGICAL LINK BLOCK ADDRESS
; CALL GETSTA
;RETURNS: +1 ALWAYS, WITH T2/ LINK STATE
;
; PRESERVES LOGICAL LINK BLOCK ADDRESS IN T1
GETSTA::LOAD T2,LLSTA,(T1) ;GET CURRENT STATE
RET
;SETEOM - ROUTINE TO SET "END-OF-MESSAGE-NEEDED" FLAG FOR A LOGICAL LINK
;
;ACCEPTS IN T1/ ADDRESS OF LOGICAL LINK BLOCK
; CALL SETEOM
;RETURNS: +1 ALWAYS
SETEOM::SETONE LLFEM,(T1) ;SAY SHOULD GET EOM ON OUTPUT
RET ;DONE, RETURN
;GETMXS - ROUTINE TO GET MAX SEGMENT SIZE
;
;ACCEPTS IN T1/ LOGICAL LINK BLOCK ADDRESS
GETMXS::LOAD T4,LLSWG,(T1) ;GET MAX SEG SIZE
RET ;DONE, RETURN
;WORK ROUTINES TO OPEN DCN: OR SRV:
;
; OPNDWK - OPEN A FILESYSTEM DCN: LINK
; OPNSWK - OPEN A FILESYSTEM SRV: LINK
; OPNIWK - OPEN AN INTERNAL LINK
;
;ACCEPTS IN T1/ ADDRESS OF TASK STRING
; T2/ BYTE SIZE OF OPEN
; CALL OPNSWK/OPNDWK
;RETURNS: +1 FAILED, ERROR CODE IN T1
; +2 SUCCESS, WITH T1/ ADDRESS OF LOGICAL LINK BLOCK
OPNDWK::MOVEI T3,LKSIZE ;BASIC LL BLOCK SIZE
JRST OPNWRK ;CALL WORK ROUTINE
OPNSWK::MOVEI T3,LKSIZE+LKOBJS ;BASIC SIZE PLUS WORDS NEEDED FOR SRV: LINKS
JRST OPNWRK ;CALL WORK ROUTINE
OPNIWK::MOVEI T3,LKSIZE+LKISIZ ;BASIC SIZE PLUS WORDS NEEDED FOR INTERNAL LINKS
JRST OPNWRK ;GO DO THE OPEN
;OPNWRK - WORK ROUTINE TO OPEN A LOGICAL LINK
;
;ACCEPTS IN T1/ ADDRESS OF TASK STRING
; T2/ BYTE SIZE OF OPEN
; T3/ SIZE OF LOGICAL LINK BLOCK NEEDED
; CALL OPNWRK
;RETURNS: +1 FAILED, ERROR CODE IN T1
; +2 SUCCESS, WITH T1/ ADDRESS OF LOGICAL LINK BLOCK
OPNWRK: TRVAR <SAVBLK,SAVERR,SAVSTR,SAVBSZ>
; NOTE: TRVAR IS NEEDED HERE INSTEAD OF STKVAR
; BECAUSE COROUTINES ACCESS THE VARIABLES.
MOVEM T1,SAVSTR ;SAVE STRING BLOCK ADDRESS
MOVEM T2,SAVBSZ ;SAVE BYTE SIZE
MOVX T2,FRKRUN ;SEE IF NETWORK IS INTIALIZED
TDNN T2,MCBDTE ;IS IT?
RETBAD (DCNX11) ;NO. ILLEGAL TO USE IT THEN
MOVE T1,T3 ;COPY # OF ADDITIONAL WORDS NEEDED FOR LL BLOCK
HRLI T1,.RESP3 ;IN PROCESS CONTEXT
MOVEI T2,.RESNP ;FROM THE NETWORK POOL
CALL ASGRES ;GET A LL BLOCK
RET ;COULDN'T. MUST FAIL
MOVEM T1,SAVBLK
MOVEI T1,OPTSIZ ;SIZE OF OPTDATA BLOCK
CALL GETBLK ;GET A BLOCK OF PROPER SIZE
JRST RLBLK ;COULDN'T. FREE BLOCK
MOVE T2,SAVBLK ;GET BACK BLOCK ADDRESS
STOR T1,LLOPT,(T2) ;SAVE BLOCK ADDRESS
MOVE T1,T2 ;GET LL BLOCK ADDRESS
LLLOCK ;LOCK UP THE TREE
CALL MAKLNK ;GET LL ADDRESS AND INSERT ENTRY
JRST [ MOVEM T1,SAVERR ;SAVE ERROR CODE
LLLULK
MOVE T1,SAVBLK ;GET BLOCK
LOAD T1,LLOPT,(T1)
CALL RELBLK ;FREE UP OPT BLOCK
JRST RLBLK1] ;AND GET RID OF LL BLOCK
LLLULK ;RELEASE LOCK
; ..
;OPEN CONTINUED. CHECK QUOTA TO SEE IF CAN MAKE THIS LINK
NOSKED ;MUST MAKE THIS CHECK RACE FREE
OPSTRM <AOS T2,>,DCCUR ;GET AND INCREMENT COUNT
MOVE T3,CAPENB ;GET CURRENT CAPABILITIES
LOAD T4,DCMAX ;GET MAX COUNT ALLOWED
TXNN T3,SC%WHL!SC%OPR ;IS THIS A PRIVILEGED FORK?
CAIG T2,0(T4) ;NO. ALLOWED TO MAKE ANOTHER LINK?
SKIPA ;YES
JRST [ MOVEI T1,DCNX5 ;NO. GIVE ERROR
OKSKED ;ALLOW SCHEDULING AGAIN
JRST OPNFAI] ;AND GO FAIL
OKSKED ;AND ALLOW SCHEDULING AGAIN
MOVEI T1,2 ;SIZE OF HOST NAME BLOCK
CALL GETBLK ;GET ONE
JRST OPNFAI ;COULDN'T
MOVE T2,SAVBLK ;GET LL BLOCK ADDRESS
STOR T1,LLHST,(T2) ;SAVE IT
MOVEI T1,<MAXDSC+4>/4 ;A BLOCK FOR REMOTE DESCRIPTOR
CALL GETBLK ;GET ONE
JRST OPNFAI ;COULDN'T
MOVE T2,SAVBLK ;GET LL BLOCK
STOR T1,LLFDS,(T2) ;SAVE BLOCK
MOVE T1,SAVSTR ;GET POINTER TO EXTENSION BLOCK
JUMPE T1,OPNDFT ;NONE. GO DEFAULT TASK NAME
LDB T2,[POINT 7,(T1),6] ;GET FIRST BYTE
JUMPE T2,OPNDFT ;IF NULL EXTENSION. GO DEFAULT TASK NAME
; ..
;USER SPECIFIED EXTENSION. CHECK FOR DUPLICATE
HRLI T1,(POINT 7,) ;FORM POINTER TO THE STRING
MOVX T3,MAXLC ;GET MAX SIZE OF EXTENSION
CALL CMPLEN ;COMPUTE ACTUAL NUMBER OF BYTES IN STRING
IDIVI T3,5 ;COMPUTE NUMBER OF WORDS IN STRING
SKIPE T4 ;AND ROUND RESULT UP
ADDI T3,1 ; IF NEEDED
MOVE T1,T3 ;COPY SIZE OF STRING
CALL GETBLK ;GET A BLOCK TO HOLD IT
OPNFAI: JRST [ LLLOCK ;LOCK UP TREE
EXCH T1,SAVBLK ;GET BLOCK ADDRESS
CALL DELNOD ;RELEASE LL BLOCK
LLLULK ;RELEASE LOCK
MOVE T1,SAVBLK ;GET ERROR CODE
DECR DCCUR ;DISCOUNT THIS LINK
RET] ;DONE
MOVEM T1,SAVERR ;SAVE BLOCK ADDRESS
MOVE T2,SAVSTR ;GET STRING BLOCK
SETOM T3 ;NO COUNT
CALL MOVSTR ;MOVE THE STRING
MOVEI T1,TSKCHK ;COROUTINE ADDRESS
SETOM T2 ;SEARCH ALL LOGICAL LINKS
LLLOCK ;LOCK UP THE TREE
CALL OBJSRC ;DO IT
SKIPA ;NOT FOUND. CAN USE IT
JRST [ MOVE T1,SAVERR ;GET TASK NAME BLOCK
CALL RELBLK ;RELEASE IT
MOVE T1,SAVBLK ;GET LL BLOCK ADDRESS
CALL DELNOD ;RELEASE THE BLOCK
LLLULK ;FREE THE TREE LOCK
MOVEI T1,DCNX4 ;ILLEGAL TASK NAME
DECR DCCUR ;DISCOUNT THIS LINK
RET] ;AND DONE
MOVE T2,SAVERR ;GET TASK BLOCK
MOVE T1,SAVBLK ;GET LL BLOCK ADDRESS
STOR T2,LLTSK,(T1) ;STORE BLOCK ADDRESS
OPNEXT: SETONE LLBOM,(T1) ;NEXT OUTPUT WILL BE BOM
MOVE T3,SAVBSZ ;GET BYTE SIZE
STOR T3,LLBSZ,(T1) ;SAVE BYTE SIZE IN LOGICAL LINK BLOCK
CAIE T3,44 ;WORD MODE?
JRST OPENX1 ;NO. GO ON
SETONE LLFDI,(T1) ;YES. REMEMBER THIS
OPENX1: 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,DCNX4 ;?
RET] ;DONE
MOVE T1,SAVBLK ;GET BACK LL BLOCK ADDRESS
JRST OPNEXT ;AND DONE
;COROUTINE OF OPEN CODE TO CHECK VALIDITY OF A USER-SUPPLIED
;TASK NAME
TSKCHK: SAVET ;SAVE TEMPS
LOAD T2,LLFRK,(T1) ;SEE IF THE SAME FORK
HLRZ T2,FKJOB(T2) ;GET FORK'S JOB NUMBER
MOVE T4,FORKX ;GET THIS FORK'S NUMBER
HLRZ T4,FKJOB(T4) ;GET THIS FORK'S JOB NUMBER
CAMN T2,T4 ;IS IT?
RET ;YES. NO NEED TO CHECK ANYMORE
LOAD T2,LLTSK,(T1) ;GET THIS ONE'S ADDRESS
JUMPE T2,R ;IF NONE, CAN'T BE IT
MOVE T1,SAVERR ;GET TASK BLOCK ADDRESS
CALLRET CMPSTR ;GO DO THE COMPARE
SUBTTL Routines to Manipulate the Logical Link Tree
;DELETE NODE FROM LL TREE
; T1/ BLOCK ADDRESS
DELNOD::ASUBR <SAVBLK> ;SAVE BLOCK ADDRESS
LOAD T1,LLLNK,(T1) ;GET ITS ADDRESS
SETOM T2 ;ANY MATCH
CALL LLLKUP ;GO LOOK IT UP
BUG (DELNDF)
JUMPE T2,[SETZM LLHEAD ;IF THE HEAD. CLEAR HEADER
JRST DELNO1] ;AND PROCEED
LOAD T3,LLUPL,(T2) ;SEE IF THIS IS UP OR DOWN
NOSKED
CHNOFF DLSCHN ;TURN OFF INTERRUPTS
CAMN T3,T1
JRST [ SETZRO LLUPL,(T2) ;UP
JRST DELINS] ;GO DO INSERTS
SETZRO LLDWN,(T2) ;DOWN
DELINS: CHNON DLSCHN
OKSKED
DELNO1: LOAD T1,LLLNK,(T1) ;GET ADDRESS
CALL FRELNK ;RELEASE THE LINK #
MOVE T1,SAVBLK ;GET BACK LL BLOCK ADDRESS
LOAD T2,LLUPL,(T1) ;DOES THIS HAVE AN UP POINTER?
JUMPE T2,DELDWN ;NO
MOVE T1,T2 ;YES.
CALL ADDLNK ;GO PUT IT IN
MOVE T1,SAVBLK ;GET BACK ADDRESS
DELDWN: LOAD T2,LLDWN,(T1) ;SEE IF IT HAS A DOWN
JUMPE T2,DELDNE ;AND GO RELEASE BLOCKS
MOVE T1,T2 ;GET ADDRESS
CALL ADDLNK
MOVE T1,SAVBLK ;GET BACK BLOCK ADDRESS
DELDNE: OPSTR <SKIPE T2,>,LLOPT,(T1) ;HAVE AN OPTDATA STRING?
CALL DELREL ;YES. GET RID OF IT
OPSTR <SKIPE T2,>,LLTSK,(T1) ;HAVE A TASK NAME?
CALL DELREL ;YES. GET RID OF IT
OPSTR <SKIPE T2,>,LLHST,(T1) ;HAVE A HOST NAME STRING?
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
CALLRET RELRES ;FREE BLOCK AND RETURN
DELREL: SAVET
NOINT ;PREVENT INTERRUPTS WHILE DEASSIGNING SPACE
MOVE T1,T2 ;GET BLOCK ADDRESS
CALL RELBLK ;FREE BLOCK
OKINT ;PREMIT INTERRUPTS AGAIN
RET ;RETURN
;REMQUE - ROUTINE TO REMOVE A LINK FROM OUTQUE
;
;ACCEPTS IN T1/ ADDRESS OF LOGICAL LINK BLOCK
; CALL REMQUE
;RETURNS: +1 ALWAYS, WITH LINK REMOVED IF QUEUED
REMQUE: JE LLQUE,(T1),R ;NOTHING TO DO IF THIS LINK WAS NOT QUEUED
; INITIALIZATION
LOCK OUTLOK ;LOCK THE QUEUE
MOVEI T4,0 ;INITIALIZE CURRENT QUEUE ITEM
HRRZ T3,OUTQUE ;GET ITEM AT HEAD OF QUEUE
; SEARCH THE QUEUE FOR THE DESIRED LINK
RMQ010: CAMN T3,T1 ;FOUND DESIRED ITEM ?
JRST RMQ020 ;YES, GO REMOVE IT FROM THE QUEUE
MOVE T4,T3 ;NO, SAVE CURRENT ITEM AS PREVIOUS ITEM
LOAD T3,LLOUT,(T3) ;MAKE NEXT ITEM CURRENT ITEM
JUMPN T3,RMQ010 ;AND GO CHECK NEW CURRENT ITEM
BUG(NSPLNQ)
RET ;SHOULD NEVER HAPPEN
; HERE WITH THE DESIRED LINK ADDRESS IN T3, PREVIOUS ITEM IN T4
RMQ020: HLRZ T2,OUTQUE ;GET POINTER TO TAIL OF QUEUE
CAMN T2,T3 ;REMOVING TAIL OF QUEUE ?
HRLM T4,OUTQUE ;YES, SAVE POINTER TO NEW TAIL OF QUEUE
LOAD T2,LLOUT,(T3) ;GET POINTER TO NEXT BLOCK
SKIPN T2 ;REMOVING HEAD OF QUEUE ?
JRST [ HRRM T2,OUTQUE ;YES, SAVE NEXT BLOCK AS NEW HEAD
JRST RMQ030 ] ;AND CLEAN UP
STOR T2,LLOUT,(T4) ;STORE NEXT BLOCK IN PREVIOUS
; HERE WITH ITEM REMOVED FROM QUEUE
RMQ030: SETZRO LLQUE,(T1) ;CLEAR "LINK ON OUTQUE" FLAG
UNLOCK OUTLOK ;UNLOCK THE QUEUE
RET ;DONE, RETURN
;ROUTINE TO RESET AN LL BLOCK SO THAT IT CAN REVERT TO
;THE LISTENING STATE. USED WHEN A SERVER REJECTS A CONNECTION.
CLRBLK: 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
LOAD T2,LLFDS,(T1)
SETZM 0(T2) ;NO REMOTE DESCRIPTOR
SETZRO LLRSN,(T1) ;NO DISCONNECT REASON
JE LLFOB,(T1),R ;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
RET ;AND DONE
;ROUTINE TO GET A LL ADDRSS AND INSERT A NODE IN THE TREE
;MUST BE CALLED WITH LL LOCK LOCKED.
;ACCEPTS: T1/ BLOCK ADDRESS
;RETURNS: +1 SOME SORT OF FAILURE (SHOULDN'T HAPPEN)
; +2 INSERTED.
MAKLNK: ASUBR <SAVADR> ;SAVE BLOCK ADDRESS
MOVSI T1,-LLBIT ;# OF WORDS IN BIT TABLE
MOVE T2,[LLBITS] ;THE TABLE ITSELF
MAKLN1: SKIPN T3,0(T2) ;HAVE SOME BITS?
JRST [ AOS T2 ;NO. NEXT WORD THEN
AOBJN T1,MAKLN1 ;SEE IF ANY MORE
MOVEI T1,DCNX5 ;NO MORE LINKS
RET] ;AND DONE
JFFO T3,.+1 ;COMNPUTE LEADING ZEROES
MOVE T3,BITS(T4) ;GET THE BIT
ANDCAM T3,0(T2) ;TURN IT OFF
HRRZS T1 ;GET # OF FULL WORDS SKIPPED
IMULI T1,44 ;COMPUTE SKIPPED BITS
ADDI T1,0(T4) ;THE INDEX
HRRZ T2,TODCLK ;GET THE CURRENT CLOCK
LSH T2,MAXEXP ;ZERO RIGHT-HAND BITS
ANDI T2,177777 ;GET A 16 BIT QUANTITY
ADDI T2,0(T1) ;FORM LL ADDRESS
MOVE T1,SAVADR ;GET BACK BLOCK ADDRESS
STOR T2,LLLNK,(T1) ;PUT IN THE ADDRESS
MOVE T2,FORKX ;PUT IN FORK OWNER
STOR T2,LLFRK,(T1) ;TO THE BLOCK
CALL ADDLNK ;AND GO ADD IN THE LINK
RETSKP ;DONE
;ROUTINE TO ADD A BLOCK TO THE LL TREE
;ACCEPTS: T1/BLOCK TO ADD
;RETURNS: +1 ALWAYS.
;MUST BE CALLED WITH TREE LOCKED
ADDLNK: ASUBR <SAVBLK> ;SAVE BLOCK ADDRESS
LOAD T1,LLLNK,(T1) ;GET LINK I.D.
SETO T2, ;NO HOST CHECK
CALL LLLKUP ;GO GET INSERT POINT
SKIPA ;GOOD
BUG (ADDONF)
MOVE T2,SAVBLK ;GET BACK LL BLOCK
JUMPE T1,[MOVEM T2,LLHEAD ;FIRST ONE
RET] ;AND DONE
LOAD T3,LLLNK,(T2) ;GET THIS LINK I.D.
LOAD T4,LLLNK,(T1) ;GET INSERT I.D.
CAML T3,T4
JRST [ STOR T2,LLUPL,(T1)
RET] ;DONE
STOR T2,LLDWN,(T1) ;NEW LINK
RET ;AND DONE
SUBTTL More Link Creation Routines
;ROUTINE CALLED FROM GTJFN TO VERIFY AN ATTRIBUTE
;ACCEPTS: T1/ BLOCK ADDRESS
; T2/ ATTRIBUTE VALUE
;RETURNS: +1 INVALID. ERROR CODE IN T1
; +2 GOOD ATTRIBUTE
NETATR::ACVAR <W1> ;GET A WORK REG
MOVSI T3,-MAXNTA ;# OF ATTRIBUTES IN TABLE
NETAT2: OPSTR <CAME T2,>,NTATR,ATTRTB(T3) ;IS THIS IT?
JRST [ AOBJN T3,NETAT2 ;DO ALL OF THEM
RETBAD (GJFX49)] ;COULDN'T FIND IT
LOAD W1,NTATB,ATTRTB(T3) ;FOUND IT. GET BINARY BIT
LOAD T2,NTATC,ATTRTB(T3) ;GET MAX COUNT
SKIPE W1 ;BINARY?
IMULI T2,3 ;YES. ADJUST COUNT
HRLI T1,(<POINT 7,0,34>) ;FORM A BYTE POINTER
CNTLOP: ILDB T4,T1 ;GET NEXT BYTE
JUMPE T4,NETAT1 ;IF NULL, DONE
SOJL T2,[RETBAD (GJFX50)] ;ATTRIBUTE TOO LONG
JUMPE W1,CNTLOP ;IF NOT BINARY, GO GET MORE
CAIL T4,"0" ;IS BINARY. CHECK RANGE
CAILE T4,"7" ;""
SKIPA
JRST CNTLOP ;GOOD RANGE
RETBAD (GJFX50) ;INVALID
NETAT1: LOAD T2,NTATE,ATTRTB(T3) ;GET EXCLUSION PARTNER
SKIPE T2 ;HAVE ONE?
CALL FNDATR ;YES. GO LOOK FOR IT
RETSKP ;NOT THERE. ERGO, GOOD ARG
RETBAD (GJFX45) ;CONFLICT
;**;[2607] ADD 1 LINE AT NETAT1:+5L PED 4-APR-82
ENDAV. ;[2607] END ACVAR
;THE ATTRIBUTE TABLE
ATTRTB: ATTENT (.PFUDT,0,^D16,0)
ATTENT (.PFPWD,0,^D8,.PFBPW)
ATTENT (.PFBPW,1,^D8,.PFPWD)
ATTENT (.PFACN,0,^D16,0)
ATTENT (.PFOPT,0,^D16,.PFBOP)
ATTENT (.PFBOP,1,^D16,.PFOPT)
MAXNTA==.-ATTRTB
;ROUTINES TO OPEN NETWORK CONNECTION. CALLED FROM OPENF JSYS
;OPEN SRC JFN
SRCOPN::ACVAR <W1> ;GET A WORK REG
TRVAR <NTCNT,NTPNT,NTOBJ,NTDSC,NTDSS>
HLRZ T1,FILNEN(JFN) ;GET NAME FOR THE CONNECTION
CALL SRCNAM ;PARSE NETWORK NAME
RETBAD() ;ERROR
CALL OPNSRC ;GO DO COMMON OPEN SETUP
RETBAD() ;FAILED
MOVE W1,T1 ;SAVE LL BLOCK
SKIPG T2,NTOBJ ;GET OBJECT TYPE
JRST NOOOBJ ;NONE GIVEN
STOR T2,LLNAM,(W1) ;SAVE OBJECT
NOOOBJ: SKIPN T1,NTDSC ;HAVE A DESCRIPTOR?
JRST NODESC ;NO. GO ON
ADDI T1,4
IDIVI T1,5 ;COMPUTE WORDS NEEDED
CALL GETBLK ;GET ONE
RETBAD () ;FAILED, RETURN ERROR CODE
STOR T1,LLDSC,(W1) ;SAVE POINTER
MOVE T2,NTDSS ;GET STRING POINTER
MOVE T3,NTDSC ;GET COUNT
CALL MOVST1 ;MOVE THW STRING
MOVEI T1,OPNUNQ ;MUST VERIFY UNIQUENESS OF NAME
SETZM T2 ;NEED TO CHECK OBJECTS ONLY
CALL OBJSRC ;DO IT
JRST NODESC ;NOT FOUND. CAN HAVE IT
LOAD T2,LLFRK,(T1) ;FOUND ONE. WHICH JOB?
HLRZ T2,FKJOB(T2) ;""
MOVEI T1,DCNX9 ;DUPICATE NAME ERROR
CAME T2,JOBNO ;THIS JOB?
JRST SRCFAL ;NO. CAN'T HAVE IT
NODESC: CALL GTSBLK ;GET A BLOCK FOR USER NAME
JRST SRCFAL ;NONE
STOR T1,LLUSR,(W1) ;SAVE IT
CALL GTSBLK ;GET A BLOCK FOR THE ACCOUNT
JRST SRCFAL ;NONE
STOR T1,LLACT,(W1) ;SAVE IT
CALL GTSBLK ;GET A BLOCK FOR THE PASSWORD
JRST SRCFAL ;NONE
STOR T1,LLPSW,(W1) ;SAVE IT
CALL ASGWDW ;GO GET WINDOW PAGES
JRST SRCFAL ;FAILED
MOVEI T1,LLSLIS ;GET INITIAL STATE
STOR T1,LLSTA,(W1) ;SET UP THIS LISTENER
SETONE LLFOB,(W1) ;SAY THIS IS AN OBJECT
LLLULK ;FREE LOCK
RETSKP ;AND DONE
;COROUTINE OF SRCOPN TO CHECK FOR UNIQUE NAME
OPNUNQ: SAVET ;SAVE TEMPS
LOAD T2,LLNAM,(T1) ;GET OBJECT NUMBER
OPSTR <CAME T2,>,LLNAM,(W1) ;SAME AS OURS?
RET ;NO. NO CONFLICT THEN
LOAD T1,LLDSC,(T1) ;GET ITS DESCRIPTOR
LOAD T2,LLDSC,(W1) ;GET OURS
CALL CMPSTR ;SEE IF A MATCH
RET ;NO.
RETSKP ;YES. COULD BE A PROBLEM
;OPEN FAILURE ROUTINE. CLEAN UP FROM ATTEMPT
SRCFAL: DECR DCCUR ;ONE LESS LINK ON FAILURE
EXCH T1,W1 ;GET BLOCK ADDRESS
CALL DELNOD ;FREE THE NODE
LLLULK ;UNLOCK THE TREE
MOVE T1,W1 ;GET ERROR CODE
RET ;AND FAIL
;LOCAL ROUTINE TO GET A STRING BLOCK FOR SRCOPN.
;**;[2962] Change 1 line at GTSBLK:+0 DML 10-MAY-83
GTSBLK: MOVEI T1,SIZ39 ;[2962] THE PROPER SIZE
CALL GETBLK ;GET ONE
RET ;FAILED
RETSKP ;GOT IT
;**;[2607] ADD 1 LINE AT GTSBLK:+4L PED 4-APR-82
ENDAV. ;[2607] END ACVAR
;CRTLNK - ROUTINE TO CREATE A LOGICAL LINK
;
;ACCEPTS IN T1/ ADDRESS OF LOGICAL LINK BLOCK
; T2/ ADDRESS OF ATRIBUTE LIST
; T3/ OBJECT,,COUNT OF BYTES IN DESCRIPTOR
; T4/ POINTER TO DESCRIPTOR STRING
; TRVARS -- NTCNT,NTPNT,NTOBJ,NTDSC,NTDSS,NTHST,NTHSC
;
; CALL CRTLNK
;RETURNS: +1 FAILED, ERROR CODE IN T1
; +2 SUCCESS
CRTLNK::ACVAR <W1,W2,W3> ;GET A WORK REGISTER
STKVAR <CRLATR,CRLCIB,CRLCNT,CRLOBJ,CRLHST,CRLHSC,CRLDSS,CRLDSC>
; SAVE INPUT ARGUMENTS
MOVE W1,T1 ;SAVE LL BLOCK ADDRESS
MOVEM T2,CRLATR ;SAVE ATTRIBUTE LIST POINTER
HLRZM T3,CRLOBJ ;SAVE OBJECT
HRREM T3,CRLDSC ;SAVE COUNT OF BYTES IN DESCRIPTOR
MOVEM T4,CRLDSS ;SAVE DESCRIPTOR POINTER
MOVE T1,CRLOBJ ;GET OBJECT
STOR T1,LLFNM,(W1) ;SAVE IT
SKIPG T3,CRLDSC ;ANY DESCRIPTOR GIVEN
JRST DSCNUL ;NO, SKIP MOVING STRING
LOAD T1,LLFDS,(W1) ;GET DESCRIPTOR BLOCK
MOVE T2,CRLDSS ;GET JSB STRING POINTER
CALL MOVST1 ;AND MOVE IT
;ALL STRINGS ARE MOVED. MUST GENERATE CONNECT-INITIATE MESSAGE
DSCNUL: MOVEI T1,CONLEN+MSHDR+RTHLEN ;GET A BLOCK FOR THE CI
CALL GETRES ;GET A RESIDENT BLOCK
RETBAD () ;FAILED, RETURN ERROR
MOVEM T1,CRLCIB ;SAVE BLOCK ADDRESS
HRLI T1,(<POINT 8,>) ;MAKE A BYTE POINTER
ADDI T1,MSHDR ;RESERVE HEADER
MOVEM T1,LLBPTR(W1) ;SAVE IN LL BLOCK
SETZM LLBPCT(W1) ;ZERO COUNT
MOVE T1,W1 ;LL BLOCK ADDRESS
MOVEI T2,CNMRFL+CNMCI ;MESSAGE FLAGS
CALL RTHDCI ;PUT ON ROUTING HEADER AND FLAGS
CALL DOSRVS ;INSERT LL ADDRESSES AND STANDARD SERVICES
;..
; ..
;NOW BUILD OBJECT ADDRESSING FIELDS
SKIPG CRLDSC ;HAVE A COUNT FOR DESCRIPTOR
JRST [ MOVEI T2,OBJZRO ;GET OBJECT TYPE ZERO INDICATOR
CALL ONEBYT
MOVE T2,CRLOBJ ;GET OBJECT TYPE
CALL ONEBYT
LOAD T1,LLFDS,(W1) ;GET DESCRIPTOR STRING
SETZRO LLFDS,(W1) ;CLEAR LOCATION
CALL RELBLK ;RELEASE UNUSED BLOCK
MOVE T1,W1 ;RESTORE LL BLOCK ADDRESS
JRST DSCDON] ;DONE WITH THIS
MOVEI T2,OBJONE ;GET OBJECT TYPE 1
CALL ONEBYT ;STORE HEADER
MOVE T2,CRLOBJ ;GET OBJECT NUMBER
CALL ONEBYT ;PUT IT IN
LOAD T3,LLFDS,(T1) ;GET DESCRIPTOR STRING
CALL ASCIIZ ;PUT IT IN
;MESSAGE BUILT. INSERT SENDER'S NAME AND USER DATA
DSCDON: MOVEI T2,OBJONE ;SENDER IS A TASK
CALL ONEBYT
MOVEI T2,OBJTSK ;THE I.D. FOR TASK
CALL ONEBYT
LOAD T3,LLTSK,(T1) ;GET POINTER TO TASK NAME
CALL ASCIIZ ;AND INSERT IT
;NOW CHECK FOR AND INSERT ANY OPTIONAL DATA
MOVE T1,W1 ;GET LOGICAL LINK BLOCK ADDRESS
MOVE T2,CRLATR ;GET ADDRESS OF ATTRIBUTE LIST
CALL INSATR ;GO INSERT ATTRIBUTES IN MESSAGE
MOVEI T2,LLSCIS ;GET NEW STATE
STOR T2,LLSTA,(T1) ;STORE NEW STATE
LLLULK ;RELEASE TREE NOW
MOVE T2,CRLCIB ;GET BLOCK ADDRESS
CALL SNDCTL ;SEND MESSAGE TO THE NETWORK
RETSKP ;AND DONE FOR NOW
;**;[2607] ADD 1 LINE AT DSCDON:19.+L PED 4-APR-82
ENDAV. ;[2607] 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/ POINTER TO HOST NAME STRING
; T4/ POINTER TO DESCRIPTOR STRING
; CALL STRSAV
;RETURNS: +1 FAILED, ERROR CODE IN T1
; +2 SUCCESS, STRINGS SAVED
STRSAV::ACVAR <W1,W2,W3>
STKVAR <SSVHST,SSVHSC,SSVDSC,SSVDSS>
HLREM T2,SSVHSC ;SAVE HOST STRING BYTE COUNT
HRREM T2,SSVDSC ;SAVE DESCRIPTOR BYTE COUNT
MOVEM T3,SSVHST ;SAVE HOST NAME STRING POINTER
MOVEM T4,SSVDSS ;SAVE DESCRIPTOR STRING POINTER
MOVE W1,T1 ;SAVE LL BLOCK ADDRESS
SKIPG T3,SSVHSC ;HAVE A HOST NAME?
JRST [ SETONE LLLOC,(W1) ;NOTE THIS IS A LOCAL LINK
SKIPL W2,NSPLPB ;GET PORT FOR LOOPBACK
RETSKP ;NOT ACTIVE
MOVE T2,[POINT 7,OURNAM] ;POINT TO OUR NAME
MOVE T3,OURCNT ;LENGTH OF OUR NAME
JRST DCNOP8 ] ;USE LOOPBACK PORT FOR LINK
CAME T3,OURCNT ;SAME COUNT AS OUR NAME?
JRST DCNOP0 ;NO. CAN'T BE US THEN
MOVE T1,SSVHST ;GET BLOCK POINTER
MOVE T2,[POINT 7,OURNAM] ;GET POINTER TO OUR NAME
CALL COMPAR ;SEE IF THE SAME
JRST DCNOP0 ;NO. SAVE IT THEN
SETONE LLLOC,(W1) ;YES, NOTE LOCAL LINK
SKIPL W2,NSPLPB ;GET PORT FOR LOOPBACK
RETSKP ;NONE SO JUST RETURN
JRST DCNOP7 ;HAVE PORT TO USE
DCNOP0: MOVSI W2,-DCN ;MAKE PORT NUMBER COUNTER
SETOM W3 ;WHERE TO REMEMBER INT. NODE
DCNOP2: SKIPGE T2,MCBDTE(W2) ;IS PORT ACTIVE ?
TXNE T2,NTSHUT ;IS PORT SHUTTING DOWN ?
JRST DCNOP3 ;CAN'T USE THIS ONE
TXNN T2,NOTMCB ;IS THIS AN MCB?
HRRZ W3,W2 ;YES. REMEMBER PORT THEN
MOVE T3,SSVHSC ;GET COUNT OF CHARS IN NAME
OPSTR <CAME T3,>,NAMCN,MCBDTE(W2) ;SAME COUNT AS NODE NAME?
JRST DCNOP3 ;NO. THIS CAN'T BE IT THEN
MOVEI T2,ITSNAM(W2) ;ALMOST ADR OF NEIGHBOR'S NAME
ADDI T2,(W2) ;MAKE NEIGHBORS NAME
HRLI T2,(POINT 7,) ;FORM POINTER TO NAME
MOVE T1,SSVHST ;GET BLOCK POINTER AGAIN
CALL COMPAR ;SEE IF THIS MATCHES
DCNOP3: AOBJN W2,DCNOP2 ;LOOP BACK FOR REST OF PORTS
JUMPL W2,DCNOP7 ;IF FOUND MATCH
SKIPGE W2,W3 ;FOUND AN MCB?
RETBAD (DCNX13) ;NO, FAIL
DCNOP7: MOVE T2,SSVHST ;GET POINTER TO STRING TO BE MOVED
MOVE T3,SSVHSC ;GET COUNT
DCNOP8: STOR W2,LLPRT,(W1) ;SAVE PORT #
LOAD T1,LLHST,(W1) ;GET ADDRESS OF HOST STRING
CALL MOVST1 ;AND MOVE IT
RETSKP ;DONE, ALL STRINGS SAVED. RETURN SUCCESS.
;**;[2607] ADD 1 LINE AT DCNOP8:+4L PED 4-APR-82
ENDAV. ;[2607] END ACVAR
;LOCAL ROUTINE FOR STRSAV TO COMPARE TWO STRINGS
;ACCEPTS: T1/ POINTER TO STRING 1
; T2/ POINTER TO STRING 2
; T3/ COUNT
;RETURNS: +1 NO MATCH
; +2 MATCH
COMPAR: ACVAR <W1,W2,W3> ;GET SOME REGS
MOVE W1,T1 ;COPY POINTER TO FIRST STRING
MOVE W2,T2 ;COPY POINTER TO SECOND STRING
MOVE W3,T3 ;SAV COUNT
CMPRLP: ILDB T3,W1 ;GET NEXT BYTE
ILDB T4,W2 ;GET THIS ONE'S NEXT
CAME T3,T4 ;MATCH?
RET ;NO. NO MATCH THEN
SOSLE W3 ;ANY MORE BYTES?
JUMPN T3,CMPRLP ;DO ENTIRE STRING
RETSKP ;A MATCH!!!!
;**;[2607] ADD 1 LINE AT CMPRLP:+7L PED 4-APR-82
ENDAV. ;[2607] END ACVAR
;ROUTINE TO INSERT THE LL ADDRESSES IN A MESSAGE.
;ACCEPTS: T1/ LL BLOCK ADDRESS
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
;**;[2607] ADD 1 LINE AT PUTLL1:+1L PED 4-APR-82
ENDAV. ;[2607] END ACVAR
;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
OPSTR <SKIPE>,LLIMS,(T1) ;WANT MESSAGE COUNTS?
MOVEI T2,CISRVS+CIMCNT ;YES
CALL ONEBYT ;PUT IN SERVICES BYTE
MOVEI T2,LNKPRI ;GET DEFAULT PRIORITY
CALL ONEBYT
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
CAIG T2,SEGSIZ ;IS IT BIGGER THAN OURS?
JRST DOSRV1 ;NO. USE IT ON THE LINK
JRST .+1] ;YES, USE OURS ON THE LINK
MOVEI T2,SEGSIZ ;GET SEGMENT SIZE
DOSRV1: STOR T2,LLSWG,(T1) ;PUT SEG SIZE IN LL BLOCK
OPSTR <SKIPE>,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
;ROUTINE TO BUILD A ROUTING HEADER.
;ACCEPTS: T1/ LL BLOCK ADDRESS
; T2/ PROPER MESSAGE FLAGS
RTHDCI: SAVEAC (T2) ;PRESERVE THE FLAGS
STKVAR <MSGFLG> ;TO SAVE THE FLAGS
MOVEM T2,MSGFLG ;SAVE FLAGS
CALL TSTLCL
JRST RTHDC1
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
;**;[2607] ADD 1 LINE AT ASCII1:+2L PED 4-APR-82
ENDAV. ;[2607] END ACVAR
;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
;**;[2607] ADD 1 LINE AT MVBNR1:+4L PED 4-APR-82
ENDAV. ;[2607] 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
;**;[2607] ADD 1 LINE AT BINXT:+3L PED 4-APR-82
ENDAV. ;[2607] 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
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
;ROUTINES TO FIND AND PARSE ARBITRARY ATTRIBUTES
;FIND ATTRIBUTE:
;ACCEPTS: T2/ PREFIX VALUE
;RETURNS: +1/ NO SUCH PREFIX
; +2/ FOUND. T3=POINTER TO VALUE STRING
FNDATR: LOAD T3,FILATL,(JFN) ;GET LIST OF ATTRIBUTES
CALLRET GETATR ;GO FIND ATTRIBUTE
;GETATR - ROUTINE TO FIND AN ATTRIBUTE
;
;ACCEPTS IN T2/ PREFIX VALUE
; T3/ ADDRESS OF ATTRIBUTE LIST
; CALL GETATR
;RETURNS: +1 FAILED, NO SUCH PREFIX
; +2 SUCCESS, WITH T3/ POINTER TO VALUE STRING
GETATR: JUMPE T3,R ;IF NO MORE, ALL DONE
OPSTR <CAME T2,>,PRFXV,(T3) ;IS THIS THE ONE WE WANT
JRST [ LOAD T3,PRFXL,(T3) ;NO. GET NEXT
JRST GETATR] ;AND LOOK AT IT
MOVEI T3,1(T3) ;GET POINTER TO BLCOK
RETSKP ;AND SAY WE FOUND IT
;ROUTINE TO MAKE PROPER BYTE POINTER AND RETURN MAX COUNT FOR A
;BUFFER.
;ACCEPTS: T1/ WINDOW ADDRESS
; T3/ BYTE SIZE
;RETURNS: +1
; T1/ BYTE POINTER
; T2/ COUNT
MAKPTR: MOVE T4,T3 ;SAVE IT
IORI T3,4400 ;MAKE A BYTE POINTER
DPB T3,[POINT 12,T1,11]
MOVEI T2,44 ;BITS IN A WORD
IDIVI T2,0(T4) ;COMPUTE BYTES IN A WORD
LSH T2,PGSFT ;COMPUTE BYTES IN A PAGE
RET ;AND DONE
;SPECIAL ROUTINE TO MAKE AN INPUT POINTER FOR FLOW FROM NETWORK
MAKINP::PUSH P,T3 ;SAVE BYTE SIZE
CALL MAKPTR ;GET A POINTER
POP P,T3 ;GET BACK BYTE SIZE
CAIN T3,44 ;WORD MODE?
HRRZS T1 ;YES. GET ADDRESS ONLY
RET ;DONE
SUBTTL MTOPR Utility Functions
;READ LINK TASK NAME
NTRTN:: LOAD T2,LLTSK,(T1) ;GET THE NAME
NTCPY: CALL NTACPY ;DO THE WORK
CALL BLKULK ;RELEASE LL BLOCK
RETSKP ;AND DONE
;READ FOREIGN HOST NAME
NTRHN:: CALL MTRDCK ;VERIFY LINK STATE
JRST [ MOVEI T1,DCNX11 ;SAY NOT CONNECTED ANYMORE
JRST SQOBAD] ;AND DONE
LOAD T2,LLHST,(T1) ;YES. GET HOST STRING
CALL TSTLCL ;IS THIS A LOCAL CONNECTION?
MOVEI T2,OURNAM ;YES. USE LOCAL NAME THEN
CALLRET NTCPY ;AND GO COPY TO USER
;WORKER ROUTINE TO COPY AN ASCII STRING TO THE USER.
; T2/ ADDRESS OF STRING BLOCK
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
;**;[2607] ADD 1 LINE AT NTCPY2:+3L PED 4-APR-82
ENDAV. ;[2607] 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
OPSTR <SKIPE>,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
CAIE T2,LLSLIS ;LISTENING?
CAIN T2,LLSCIS ;OR CI SENT?
TXO T3,MO%WFC ;YES. WAITING FOR CONNECT THEN
CAIN T2,LLSCIR ;CI RECEIVED?
TXO T3,MO%WCC ;YES. WAITING FOR US TO CONFIRM
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
OPSTR <SKIPE>,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
CAIN T2,LLSCIR ;IN CIR STATE?
RETSKP ;YES. IS GOOD THEN
MTRNCK::LOAD T2,LLSTA,(T1) ;GET STATE
CAIN T2,LLSRUN ;RUNNING?
RETSKP ;YES.
MTOBJ1: RETBAD (DCNX11) ;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
;**;[2607] ADD 1 LINE AT NTMTGD:+2L PED 4-APR-82
ENDAV. ;[2607] 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
OPSTR <SKIPN>,LLDRW,(T1) ;HAVE ANY MESSAGES ON RAW Q?
SKIPE LLOMSG(T1) ;NO. ANY ORDERED MESSAGES?
CALL DATINR ;YES. GIVE INT THEN
RETSKP ;DONE
;ROUTINE TO VERIFY CHANNEL #
; T2/ CHANNEL
;RETURNS: +1 BAD CHANNEL
; +2 VALID CHANNEL
CHKCHL: CAIN T2,.MOCIA ;CLEAR?
JRST [ SETZM T2 ;IF SO. UNSETTING
RETSKP] ;SO, RETURN A ZERO
CAIN T2,.MONCI ;NO CHANGE?
JRST [ SETOM T2 ;YES
RETSKP] ;SO SAY SO
CAIL T2,44 ;WITHIN RANGE?
JRST CHKILL ;NO
CAILE T2,5 ;WITHIN RANGE 0-5?
CAIL T2,^D23 ;OR WITHIN RANGE 23-35
AOSA T2 ;YES. A GOOD CHANNEL
JRST CHKILL ;NO. ILLEGAL
RETSKP ;RETURN GOOD VALUE
CHKILL: RETBAD (ARGX13) ;INVALID CHANNEL
;COMMON ROUTINE TO GENERATE INTERRUPT RECEIVED INTERRUPT
INTINT: SAVET ;SAVE REGS
CALL TELINT ;GO NOTIFY DRIVER IF THIS IS AN INTERNAL LINK
LOAD T2,LLFRK,(T1) ;GET FORK TO INT
OPSTR <SKIPN T1,>,LLPII,(T1) ;HAVE AN INT CHANNEL?
RET ;NO
SOS T1 ;YES
CALLRET PSIRQ ;GO DO THE INTERRUPT
;TELINT - ROUTINE TO NOTIFY THE DRIVER WHEN AN INTERRUPT MSG IS RECEIVED
; FOR AN INTERNAL LOGICAL LINK
;
;ACCEPTS IN T1/ ADDRESS OF LOGICAL LINK BLOCK
; CALL TELINT
;RETURNS: +1 ALWAYS, WITH DRIVER NOTIFIED
TELINT: JE LLINT,(T1),R ;IF NOT AN INTERNAL LINK, THEN DONE
SAVET ;PRESERVE TEMPORARY AC'S
LOAD T4,LLVEC,(T1) ;GET DRIVER VECTOR ADDRESS
LOAD T1,LLDRV,(T1) ;GET DRIVER CORRELATION CODE
CALLRET @.NSINT(T4) ;NOTIFY DRIVER AND RETURN
;MORE MTORP FUNCTIONS...
;RECEIVE INTERRUPT MESSAGE
MTRDIN::MOVE T2,[IFIW![ XCTBUU [IDPB T2,3] ;ROUTINE TO RETURN BYTE
RET ]] ; AND DONE
UMOVE T3,3 ;GET USER'S DESTINATION POINTER
CALL RDINT ;GO READ AN INTERRUPT MESSAGE
JRST [ JUMPE T2,SQOBAD ;FAILED, RETURN ERROR
JRST ULKRET ] ; OR BLOCK IF NEEDED
UMOVEM T3,4 ;RETURN BYTE POINTER
UMOVEM T4,3 ;RETURN COUNT TO USER
CALL BLKULK ;DONE WITH BLOCK
MOVE T1,T2 ;GET FREE SPACE 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
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 T2,RDIRTN ;SAVE ROUTINE TO STORE BYTES
MOVEM T3,RDIPTR ;SAVE DESTINATION BYTE POINTER
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 [ MOVX T1,NSPX6 ;GET ERROR CODE
JRST RDINB ] ;AND RETURN FAILURE
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
;**;[2607] ADD 1 LINE AT MTRDI2:+6L PED 4-APR-82
ENDAV. ;[2607] END ACVAR
; HERE ON AN ERROR
RDINX: TDZA T2,T2 ;NOTE BLOCK NOT WANTED
RDINB: SETOM T2 ;BLOCK NEEDED
RET ;FAIL
;MORE MTOPR'S.... SEND INTERRUPT MESSAGE
MTSNIN::UMOVE T4,4 ;GET COUNT
UMOVE T3,3 ;GET BP
UMOVE T4,4 ;GET COUNT
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,MAXDSC ;WITHIN RANGE?
JRST [ MOVEI T1,DCNX12 ;ARG TOO LARGE
RET ] ;RETURN ERROR
JE LLMIC,(T1),[ MOVEI T1,DCNX14 ;ANY QUOTA?
RET ] ;NO, FAIL
MOVEI T1,INTLEN+MSHDR ;LENGTH
CALL GETRES ;GET SOME SPACE
RET ;NO SPACE, FAIL
MOVE W1,T1 ;SAVE BLOCK ADDRESS
MOVEI T2,MSHDR(T1) ;GET TO DATA PART
HRLI T2,(<POINT 8,>)
MOVE T1,FILLLB(JFN) ;GET LL BLOCK
MOVEM T2,LLBPTR(T1) ;THE POINTER
SETZM LLBPCT(T1) ;INIT COUNT
MOVEI T2,DATMFL+DATFLI+DATINT ;FLAGS
STOR T2,MSMFL,(W1) ;SAVE IN MESSAGE
CALL RTHDCI ;PUT ON ROUTE HEADER AND FLAGS
CALL PUTLLA ;PUT IN LL ADDRESSES
LOAD T2,LLISN,(T1) ;GET SEG #
AOS T2 ;NEXT ONE
ANDI T2,7777 ;MOD 4096
STOR T2,MSSEG,(W1) ;SAVE IN MESSAGE
STOR T2,LLISN,(T1) ;LAST SEG SENT
CALL TWOBYT ;PUT IN DATA PART
DECR LLMIC,(T1) ;ONE LESS PIECE OF QUOTA
MOVE T4,SIMCNT ;GET COUNT
MOVE T3,SIMPTR ;GET POINTER
TLC T3,-1
TLCN T3,-1
HRLI T3,(<POINT 7,>) ;FORM DEFAULT
MOVEM T3,SIMPTR ;SAVE UPDATED POINTER
JRST MSTSN2 ;GO SEND THEM
MSTSN1: CALL @SIMRTN ;GET NEXT BYTE
CALL ONEBYT ;STORE IN MESSAGE
MSTSN2: SOJGE T4,MSTSN1 ;DO THEM ALL
LOAD T2,LLLNK,(T1) ;GET LINK ADDRESS
STOR T2,MSLLA,(W1) ;SAVE IN MESSAGE
MOVEI T2,MSLSI ;GET TYPE OF THIS MESSAGE
STOR T2,MSTOM,(W1) ;SAVE IN MESSAGE
MOVE T2,W1 ;GET MESSAGE
CALL SNDSEG ;SEND IT
MOVE T3,SIMPTR ;RETURN UPDATED POINTER
RETSKP ;DONE, RETURN SUCCESS
;**;[2607] ADD 1 LINE AT MSTSN2:+9.L PED 4-APR-82
ENDAV. ;[2607] 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
;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
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,LLSRUN ;NOW CONNECTED?
JRST NTRCB1 ;NO. CAN'T DISCONNECT THEN
UMOVE T2,2 ;GET REASON,,.MOCLZ
HLRZS T2 ;GET TYPE OF CLOSE
SKIPE T2 ;SYNCHRONOUS DISCONNECT?
JRST [ CALL FLUSH ;NO, ABORT CLOSE. CLEAN OUT MESSAGES
JRST NTMCZ0] ;AND SEND THE MESSAGE
JE LLQOU,(T1),NTMCZ0 ;IF QUEUER EMPTY, GO ON.
CALL MOVSEG ;PICK UP ACKS
JRST OUTWAT ;NEED TO BLOCK
MOVEI T2,CHKEMP ;WAIT FOR ALL ACKS
JRST OUTWAT ; AND GO DO IT
;READY TO SEND THE MESSAGE
NTMCZ0: MOVEI T2,LLSDIQ ;SET STATE
STOR T2,LLSTA,(T1) ;""
CALL NTRFCI ;SEND DI
JRST SQOBAD ;MUST WAIT
MOVEI T2,LLSDIS ;NEW STATE
STOR T2,LLSTA,(T1) ;STORE IT
CALLRET NTMTGD ;AND DONE
;ROUTINE TO ACCEPT A CONNECTION
NTACPT::STKVAR <<OPTDAT,4>>
LOAD T2,LLSTA,(T1) ;GET STATE
CAIE T2,LLSCIR ;PROPER STATE
JRST NTRCB1 ;NO. ERROR
MOVEI T3,OPTDAT ;MOVE OPTDATA IF ANY
UMOVE T2,4 ;GET COUNT
UMOVE T4,3 ;GET USER'S POINTER
CALL NTMVOP ;GET OPTDATA ARG
JRST SQOBAD ;TOO LONG
CALL CNFCOM ;GO CONFIRM IT
JRST SQOBAD ;NEED TO WAIT
CALLRET NTMTGD ;DONE
;MTOPR TO RETURN MAX SEGMENT SIZE FOR THE LINK
MTGSS:: CALL MTRNCK ;MUST BE RUNNING
JRST SQOBAD ;NOT
LOAD T2,LLSWG,(T1) ;GET MAX SEG SIZE
UMOVEM T2,3 ;RETURN TO USER
CALLRET NTMTGD ;AND DONE
;COMMON ROUTINE USED TO SET UP FOR CALL TO SNDDI TO DISCONNECT
;OR REFUSE A CONNECTION.
NTRFCI: STKVAR <<OPTDAT,4>> ;GET SOME SPACE TO HOLD USER DATA
MOVEI T3,OPTDAT ;WHERE TO MOVE OPTDATA TO
UMOVE T2,4 ;GET COUNT
UMOVE T4,3 ;GET USER'S POINTER
CALL NTMVOP ;DO IT
RETBAD() ;TOO LONG
XCTU [HLRZ T2,2] ;GET REASON
MOVEI T4,CNMRFL+CNMDI ;GET PROPER FLAGS
CALL SNDDI ;SEND THE DI
JRST [ TQO <BLKF> ;SCHED TEST ALREADY IN T1, NOTE BLOCK NEEDED
RET ] ;COME BACK AGAIN LATER
CALL SNDCTL ;SEND THE MESSAGE
RETSKP ;AND DONE
;ROUTINE TO COPY OPTDATA TO A BUFFER AND RETURN PROPER OPTDATA
;ARG
; T2/ INPUT BYTE COUNT
; T3/ BUFFER ADDRESS
; T4/ INPUT POINTER
;RETURNS: +1 TOO LONG
; +2 DONE
NTMVOP::ACVAR <W1,W2,W3>
STKVAR <NMVCNT,NMVPTR>
TLC T4,-1 ;CHECK FOR SPECIAL POINTER
TLCN T4,-1 ;IS IT?
HRLI T4,(<POINT 7,>) ;YES. CONVERT IT THEN
MOVEM T4,NMVPTR ;SAVE POINTER TO INPUT
MOVEM T2,NMVCNT ;SAVE COUNT OF BYTES
MOVE W3,T3 ;SAVE BUFFER ADDRESS
SETZM T3 ;ASSUME NO DATA
MOVE T4,NMVCNT ;GET COUNT
JUMPE T4,RSKP ;IF NONE, NO ARG
SKIPL T4 ;COUNT MUST BE POSITIVE
CAILE T4,MAXDSC ;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
;**;[2607] ADD 1 LINE AT NTMV01:+5L PED 4-APR-82
ENDAV. ;[2607] 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 BLKLOK ;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
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
OPSTR <SKIPE>,LLFLO,(T1); FLOW NOW TO F/S?
SKIPE T2 ;YES. ANY BYTES?
SKIPA ;HAVE DATA TO SEND
JRST CLZCMS ;ALL DATA SENT. WAIT FOR ACKS
SETONE LLFEM,(T1) ;SAY EOM IN THIS BUFFER
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 FLUSH ;KILL OF QUEUES
CALL BLKULK ;FREE THE BLOCK
JRST CLZDN1] ;AND GO FINISH UP
MOVEI T2,CHKDCR ;WAIT FOR DC TO COME BACK
JRST OUTWAT
;MORE CLOSE ROUTINES
;DC HAS ARRIVED. FIND OUT IF IT WHAT WE WANTED
CLZDIR: ;CLOSE IN DI RECEIVED STATE
CLZABT: LOAD T2,LLRSN,(T1) ;GET REASON
SKIPE T2 ;NON-SPECIAL ERROR?
CAIN T2,.DCX42 ;OR REPLY TO DI?
JRST CLZDON ;YES. GOOD CODE
TXNN W2,CZ%ABT ;NOT. ARE WE ABORTING?
JRST [ CALL BLKULK ;NO. SYNCH DI DIDN'T WORK
RETBAD (DCNX11)] ;SAY SO
CLZDON: CALL FLUSH ;CLEAN UP Q'S
LLLOCK ;LOCK THE TREE
CALL DELNOD ;GET RID OF NODE
LLLULK
OKINT ;MATCH BLKLOK THAT IS NEVER MATCHED
CLZDN1: DECR DCCUR ;GIVING BACK A LINK
HLRZ T1,FILWND(JFN) ;GET OUTPUT WINDOW
SKIPE T1
CALL RELPAG ;RELEASE IT
HRRZ T1,FILWND(JFN) ;GET INPUT WINDOW
SKIPE T1
CALL RELPAG ;RELEASE IT
SETZM FILBFO(JFN)
SETZM FILBFI(JFN)
RETSKP ;AND DONE
;**;[2607] ADD 1 LINE AT CLZDN1:+11.L PED 4-APR-82
ENDAV. ;[2607] END ACVAR
;CLZSDI - ROUTINE TO SEND A DI FOR A CLOSE
;
;ACCEPTS IN T1/ LOGICAL LINK BLOCK ADDRESS
; T2/ 0 IF SYNCHRONOUS CLOSE, -1 IF ABORT
; T3/ COUNT OF BYTES IN OPTIONAL DATA (0 IF NONE)
; T4/ ADDRESS OF OPTIONAL DATA BUFFER
; CALL CLZSDI
;RETURNS: +1 FAILED, COULD NOT SEND DI
; +2 SUCCESS, WITH DI SEND
CLZSDI::ASUBR <CDILLB,CDIFLG,CDICNT,CDIBUF>
STKVAR <<CDIOPT,4>>
MOVE T1,CDILLB ;GET LOGICAL LINK BLOCK ADDRESS
MOVEI T2,LLSDIQ ;DI IS NOW QUEUED
STOR T2,LLSTA,(T1) ;MARK STATE CHANGE
SETZM T3 ;START BY ASSUMING NO OPTIONAL DATA
SKIPE CDICNT ;ANY OPTIONAL DATA ?
JRST [ MOVEI T3,CDIOPT ;YES, GET DESTINATION BUFFER ADDRESS
MOVE T2,CDICNT ;GET NUMBER OF BYTES IN OPTIONAL DATA
MOVE T4,CDIBUF ;GET SOURCE BUFFER ADDRESS
HRLI T4,(POINT 8,) ;AND FORM A POINTER TO OPTIONAL DATA
CALL NTMVOP ;CHECK OPTIONAL DATA, SETUP T3 WITH COUNT
RETBAD () ;FAILED, RETURN ERROR TO USER
JRST .+1] ;T3 SET UP, CONTINUE WITH SETUP FOR DI MESSAGE
LOAD T2,LLRSN,(T1) ;GET OUR REASON
MOVEI T4,CNMRFL+CNMDI ;IS A DI
CALL SNDDI ;GO SEND DI
JRST [ SKIPN CDIFLG ;ABORT ?
RETBAD () ;NO. BLOCK THEN
TQZ <BLKF> ;YES. UNDO BLOCK
BUG (CLZDIN)
MOVE T1,CDILLB ;GET BACK LOGICAL LINK BLOCK ADDRESS
RETBAD ()] ;AND DONE
CALL SNDCTL ;SEND THE MESSAGE
CLZDQ1: MOVEI T2,LLSDIS ;SAY DI IS SENT
STOR T2,LLSTA,(T1)
RETSKP ;DONE, RETURN SUCCESS
;ROUTINE TO SEND A DI OR A DC
;ACCEPTS: T1/ LL BLOCK ADDRESS
; T2/ REASON
; T3/ <COUNT>B5+PTR TO USER DATA
; T4/ FLAGS
;RETURNS: +1/ COULDN'T. TEST ROUTINE IN T1
; +2/ ALL SENT
SNDDI: ASUBR <LLBLK,DISRSN,DIUDAT,DIFLGS>
STKVAR <LLMSGB>
MOVX T1,DILEN+MSHDR ;GET A BLOCK FOR THE DI
CALL GETRES ;GET IT
JRST TIMWAT ;FAILED
MOVEM T1,LLMSGB ;SAVE BLOCK ADDRESS
MOVEI T2,MSHDR(T1) ;GET TO START OF DATA PORTION
HRLI T2,(<POINT 8,>)
MOVE T1,LLBLK ;GET BACK LL BLOCK ADDRESS
MOVEM T2,LLBPTR(T1) ;SAVE POINTER
SETZM LLBPCT(T1) ;INIT 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 BLKLOK ;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
OPSTR <SKIPE>,LLFLI,(T1) ;IS FLOW FROM NETWORK?
SKIPN T3 ;NO. NEED BYTES?
CALL NETSET ;YES. GO GET SOME BYTES
MOVE T1,FILLLB(JFN) ;GET BACK LL BLOCK ADDRESS
TQZ <BLKF> ;IGNORE BLOCKING IF SET
NETIN2: CALL BLKULK ;FREE LOCK
MOVE T2,FILBFI(JFN) ;GET INPUT BYTE POINTER
HRRZ T1,FILBCT(JFN) ;GET COUNT
MOVE T3,FILLLB(JFN) ;GET LL BLOCK
OPSTR <SKIPE>,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
OPSTR <SKIPN>,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
OPSTR <SKIPN>,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
;**;[2823] Change 1 [2628] line at OUTRR:+6L PED 28-SEP-82
;**;[2628]Change one line at OUTRR: +6L CLB 15-JUN-82
JRST OUTRR1 ;[2823][2628] 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
;**;[2823] Remove 2 [2628] lines at OUTRR:+22L PED 28-SEP-82
JUMPE T2,RSKP ;IS NONE LEFT, ALL DONE
HRLM T2,FILBCT(JFN) ;STORE COUNT TO SEND
;**;[2823] Remove 4 [2628] lines at OUTRR:+24L PED 28-SEP-82
; ..
;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
;**;[2823] Delete a label at OUTRR1+2L PED 28-SEP-82
;**;[2628] Add a label OUTRR1: + 2L CLB 15-JUN-82
CALL SNDCHK ;[2823] [2628] 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
;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
;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
;ROUTINE TO MAKE A STANDARD TEST WORD
MAKTST::LOAD T1,LLLNK,(T1) ;GET LL BLOCK ADDRESS
HRLS T1 ;TO THE LH
HRRI T1,0(T2) ;TEST ROUTINE
RET ;DONE
;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
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
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 SEG NUMBER
AOS T2 ;NEXT ONE
STOR T2,LLDSN,(T1) ;PUT IT BACK
ANDI T2,7777 ;ONLY 12 BITS
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: OPSTR <SKIPE>,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
NOSKED ;PREVENT RACES
CALL DECMSM ;ADJUST FLOW CONTROL
OKSKED ;AND ALLOW SCHEDULING AGAIN
MKFL30: MOVE T2,T4 ;COPY MESSAGE 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
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
;ROUTINES OF NETSQO GOTTEN TO BY STATE TRANSITION TABLE
;SET UP BLOCK UNTIL LINK IS CONNECTED
SQOLIS: MOVEI T2,CHKCON ;WAIT UNTIL CONNECTED
JRST OUTWAT ;AND GO ARRANGE FOR THE BLOCK
;IMPLICIT CONFIRM
SQOCNF: SETZM T3 ;NO OPTDATA
CALL CNFCOM ;GO CONFORM CONNECTION
JRST SQOBAD ;FAILED
JRST NETSQ1 ;AND COMPLETE OUTPUT REQUEST
;LINK HAS BEEN CLOSED BY PROCESS OR NSP. GIVE ERROR
SQOABT: SKIPA T1,[DCNX11] ;NSP ABORT
SQODIS: MOVEI T1,DCNX8 ;ILLEGAL USER OPERATION
TQO <ERRF> ;SAY HAVE AN ERROR
JRST SQOBAD ;DONE
;FOREIGN HOST HAS DISCONNECTED
SQODIR: TQO <ERRF> ;USER ERROR
MOVEI T1,DCNX11 ;GIVE ERROR
JRST SQOBAD ;AND DONE
SQOEOF: TQO <EOFF> ;NO. SAY EOF
JRST SQOBAD ;DONE
;ROUTINE TO BUILD BASIC CC MESSAGE
; T1/ LL BLOCK ADDRESS
; T3/ <COUNT>B5+OPTDATA STRING
;RETURNS +1 NO FREE SPACE. NEED TO BLOCK
; +2 READY. T2/ BLOCK ADDRESS
SNDCC: ASUBR <SAVLL,SAVBLK,SAVOPT>
MOVEI T1,MSHDR+CCLEN ;GET ENOUGH SPACE
CALL GETRES ;GET IT
RET ;FAILED. WAIT FOR A WHILE
MOVEM T1,SAVBLK
MOVEI T2,MSHDR(T1) ;GET START OF DATA
HRLI T2,(<POINT 8,>)
MOVE T1,SAVLL ;GET BACK LL BLOCK
MOVEM T2,LLBPTR(T1)
SETZM LLBPCT(T1)
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
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 CONTROL MESSAGE
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
CAIE T2,LLSLIS ;LISTENING?
CAIN T2,LLSCIS ;OR CI SENT?
JRST 0(4) ;YES. NOT CONNECTED THEN
JRST 1(4) ;NO. 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: CALL CHKSET ;VERIFY LINK STATE
JRST 1(4) ;LINK CHANGED STATED
JN LLMSM,(T1),1(4) ;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.
OPSTR <SKIPN>,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 IT 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 LLMSG(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)
LOAD T2,LLSTA,(T1) ;GET STATE
CAIE T2,LLSABT ;DC RECEIVED?
JRST 0(4) ;NO. KEEP WAITING
JRST 1(4) ;YES. AWAKE
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
;ROUTINES FOR SEQUENTIAL INPUT
;ROUTINE TO TAKE SEGMENTS OFF OF THE RAW DATA QUEUE AND
;PUT THEM ON THE ORDERED DATA QUEUE
SWAPCD
;**;[2607] CHANGE 1 LINE AT MOVSEG: PED 4-APR-82
MOVSEG::ACVAR <W1,W2,W3> ;[2607]
STKVAR <MSGLLB>
MOVEM T1,MSGLLB ;SAVE LOGICAL LINK BLOCK ADDRESS
OPSTR <SKIPE>,LLFNN,(T1) ;NEED A NACK?
CALL MOVNAK ;YES. SEND NACK
MOVSE1: SKIPN T2,LLMSG(T1) ;HAVE ANY?
RETSKP ;NO. MUST BE DONE THEN
NOSKED ;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
OKSKED ;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
TQZ <BLKF> ; 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
;**;[2607] ADD 1 LINE AT MOVSE2:+4.L PED 4-APR-82
ENDAV. ;[2607] END ACVAR
;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
;LOCAL ROUTINE TO HANDLE AN ACK FOUND ON LLMSG 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
;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
;ROUTINE TO VERIFY A SEGMENT
;ACCEPTS: T1/ LL BLOCK ADDRESS
; T2/ SEGMENT ADDRESS
; T3/ SEGMENT TYPE
;RETURNS: +1 BAD SEGMENT.
; T3=0 MEANS BADLY FORMED (PROTOCOL ERROR)
; T3=/0 MEANS OLD SEGMENT. NEEDS TO BE IGNORED
; +2 GOOD. T3/ "AGE"
VERSEG: TRVAR <MSGCNT,MSGBYP,MSGBLK,MSGSGT>
MOVEM T3,MSGSGT ;SAVE SEGMENT TYPE
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 ;GET ACKNUM
JRST VERBDY ;BAD
TRZN T2,ACKIND ;IS THIS AN ACKNUM?
JRST GOTSEG
MOVE T3,MSGSGT ;GET TYPE
CALL ACKCHN ;AND GO HANDLE THE ACK
CALL GETTWO ;GET SEGNUM
JRST VERBDY ;BAD
;**;[2823] Reinsert 2 lines at GOTSEG:+0L PED 28-SEP-82
;**;[2628] Delete two lines at GOTSEG: 0L CLB 15-JUN-82
GOTSEG: SKIPG MSGCNT ;[2823] HAVE ANY BYTES LEFT?
JRST VERBDY ;[2823] NO, BADLY FORMED MESSAGE
MOVE T3,T2 ;SAVE SEGMENT #
MOVE T2,MSGSGT ;GET TYPE
XCT [ LOAD T4,LLIIN,(T1)
LOAD T4,LLIDN,(T1)]-1(T2)
MOVE T2,MSGBLK ;GET BLOCK
STOR T3,MSSEG,(T2) ;SAVE SEGMENT #
SUBI T3,0(T4) ;COMPUTE "AGE"
ANDI T3,7777 ;MOD 4096
SKIPE T3 ;IS IT CURRENT ONE?
CAILE T3,MAXDIF ;NO. IS IT NEW?
AOJA T3,R ;NO. IS OLD
RETSKP ;YES. RETURN AGE IN T3
VERBDY: MOVE T2,MSGBLK ;GET BACK BLOCK ADDRESS
SETZM T3 ;SAY PROTOCOL ERROR
RET ;AND DONE
;ROUTINE TO DO SEQUENTIAL INPUT.
NETSQI::MOVE T1,FILLLB(JFN) ;GET LL BLOCK ADDRESS
CALL BLKLOK ;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
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
OPSTR <SKIPN>,LLFLI,(T1) ;IS FLOW FROM THE NETWORK?
JRST SQI22 ;YES. ALL SET TO GO THEN
SETZRO LLFIM,(T1) ;NO LONGER EOM
SETZRO LLFLI,(T1) ;NO. SET FLOW FROM THE NETWORK
LOAD T3,LLBSZ,(T1) ;GET BYTE SIZE
HRRZ T1,FILWND(JFN) ;GET WINDOW PAGE
CALL MAKINP ;GO GET INPUT POINTER
MOVEM T1,FILBFI(JFN) ;SAVE BYTE POINTER
SETZM SQICNT ;SAVE CURRENT COUNT
SQI23: MOVE T1,FILLLB(JFN) ;RESTORE LL BLOCK
SQI22: CALL MOVSEG ;FIRST, PICK UP ACKS
RETBAD() ;OOPS. AN ERROR
JN LLFNA,(T1),SQISNA ;IF NEED ACK ONLY, GO DO IT
JN LLLSC,(T1),SQISN2 ;NEED AN LS MESSAGE?
SQI2: MOVE T1,FILLLB(JFN) ;GET ADDRESS OF JFN BLOCK
MOVE T2,FILBFI(JFN) ;GET BUFFER ADDRESS
MOVEI T3,4000 ;MAX NUMBER OF BYTES IN JFN BUFFERS
CALL MOVMSG ;GO REMOVE MESSAGES FROM QUEUE AND PUT IN BUFFER
RETBAD () ;FAILED
MOVEM T1,FILBFI(JFN) ;STORE NEW BUFFER POINTER
MOVEM T2,SQICNT ;SAVE COUNT OF BYTES MOVED
MOVE T1,FILLLB(JFN) ;RESTORE LOGICAL LINK BLOCK ADDRESS
;**;[2628] Add 8 Lines SQI2: + 10L CLB 15-JUN-82
SKIPE T2 ;[2628] ANY BYTES IN SEGMENT?
JRST SQIEMP ;[2628] YES, ONWARD
TMNE LLFIM,(T1) ;[2628] NO, EOM?
IFNSK. ;[2628] YES, A NULL MESSAGE
SETZRO LLFIM,(T1) ;[2628] TURN OFF EOM
TQO <NSPNUL> ;[2628] SET THE FILSTS WORD
JRST SQIEM1 ;[2628] FINISH PROCESSING THE MESSAGES
ENDIF. ;[2628]
; ..
;NETSQI CONTINUED....
;GOT ALL MESSAGES MOVED.
SQIEMP: SKIPG SQICNT ;GET ANY BYTES?
JRST SQINOB ;NO. NOTHING TO DO
;**;[2628] Add a label SQIEMP: + 2L CLB 15-JUN-82
SQIEM1: LOAD T3,LLBSZ,(T1) ;[2628] GET BYTE SIZE
HRRZ T1,FILWND(JFN) ;GET WINDOW ADDRESS
CALL MAKPTR ;MAKE A POINTER
MOVEM T1,FILBFI(JFN) ;TO THE BLOCK
MOVE T4,FILLLB(JFN)
LOAD T3,LLBSZ,(T4) ;GET BYTE SIZE
MOVE T2,SQICNT ;GET COUNT WE FOUND
CAIN T3,44 ;WORD MODE?
JRST [ IDIVI T2,11 ;YES. COMPUTE BYTES
LSH T2,1 ;""
JUMPE T3,.+1 ;AN ODD WORD ON THE END?
AOJA T2,.+1] ;YES. COUNT IT
HRRM T2,FILBCT(JFN) ;SAVE IT
SQISNA: MOVE T1,FILLLB(JFN) ;GET ADDRESS OF LOGICAL LINK BLOCK
CALL SQIACK ;SEND ANY ACK'S REQUIRED
JRST CHKFRE ;FAILED, GO CHECK TYPE OF FAILURE
SQISN2: MOVE T1,FILLLB(JFN) ;GET ADDRESS OF LOGICAL LINK BLOCK
CALL SQILS ;SEND LS IF NEEDED
JRST [ MOVE T2,FILLLB(JFN) ;GET BACK LL BLOCK
SKIPN LLMSG(T2) ;HAVE A MESSAGE NOW?
JRST CHKFRE ;NO. MUST BLOCK THEN
JRST SQI23] ;AND GO TRY AGAIN
MOVE T1,FILLLB(JFN) ;RESTORE LOGICAL LINK BLOCK ADDRESS
SQISN3: SETONE LLFLI,(T1) ;FLOW IS NOW TO F/S
RETSKP ;ALL DONE. WITH GOOD DATA
;COULDN'T FIND ANY BYTES
SQINOB: SKIPE LLMSG(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 T2,LLOMSG(T1) ;GET TOPMOST SEGMENT
JRST [ MOVE T1,MVMBFI ;RESTORE BUFFER ADDRESS
MOVE T2,MVMCNT ;AND COUNT
SETZM T3 ;PROBLEM WAS NOT FITTING ALL DATA IN BUFFER
RETSKP ] ;ALL DONE THEN
LOAD T3,MSSEG,(T2) ;GET SEGMENT NUMBER
LOAD T4,LLIDN,(T1) ;GET LAST ACKED DATA SEGMENT
AOS T4 ;THE ONE WE EXPECT
ANDI T4,7777 ;MOD 12
CAIE T3,0(T4) ;IS THIS IT?
JRST [ MOVE T1,MVMBFI ;RESTORE BUFFER ADDRESS
MOVE T2,MVMCNT ;AND COUNT
SETZM T3 ;PROBLEM WAS NOT FITTING ALL DATA IN BUFFER
RETSKP ] ;ALL DONE THEN
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
TRNE T2,100000 ;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 [ MOVE T1,MVMBFI ;NO, RESTORE BUFFER ADDRESS
MOVE T2,MVMCNT ;GET NUMBER OF BYTES MOVED
SETOM T3 ;NOTE NOT ALL DATA WOULD FIT
RETSKP ] ;ALL DONE THEN
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: OPSTR <SKIPE>,LLIMS,(T1) ;MESSAGE INTERFACE?
JRST [ JE LLFIM,(T1),SQI4 ;YES. HAVE EOM IN BUFFER?
JRST .+1] ;YES
INCR LLLSC,(T1) ;NEED ANOTHER BUFFER SENT
SQI4: 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 ;RESTORE LL BLOCK POINTER
SQIMV1: MOVE T2,LLOMSG(T1) ;GET EXPENDED MESSAGE
LOAD T3,MSSEG,(T2) ;GET SEG #
STOR T3,LLIDN,(T1) ;AND UPDATE LL BLOCK
LOAD T3,MSLNK,(T2) ;GET NEXT
MOVEM T3,LLOMSG(T1) ;NEW HEAD
MOVE T1,T2 ;MESSAGE BLOCK
CALL RELRES ;FREE IT
MOVE T1,MVMLLB ;GET BACK LL ADDRESS
DECR LLDMT,(T1) ;ONE LESS DATA MESSAGE
OPSTR <SKIPN>,LLFIM,(T1) ;HAVE EOM?
JRST MVM010 ;AND TRY AGAIN
MOVE T1,MVMBFI ;NO, GET UPDATED POINTER
MOVE T2,MVMCNT ;AND COUNT
SETZM T3 ;NO PROBLEM FITTING ALL DATA IN BUFFER
RETSKP ;DONE, RETURN SUCCESS
;ROUTINE TO MOVE WORDS FROM THE NETWORK TO AN INPUT BUFFER
SQIWRD: STKVAR <<MDPTR,2>>
DMOVEM Q1,MDPTR ;SAVE WORK REGS
SQIWR1: SETZB Q1,Q2 ;INIT WORDS
MOVEI T3,11 ;GET MAX BYTE COUNT
CAIGE T4,11 ;ENOUGH FOR FULL 2 WORDS?
MOVE T3,T4 ;NO. GET WHAT IS LEFT THEN
SUBI T4,11 ;TAKE SOME BYTES
SQIWR2: LSHC Q1,10 ;SHIFT BYTES
ILDB T2,MSGBYP ;GET NEXT BYTE FROM NET BUFFER
DPB T2,[POINT 8,Q2,35] ;STASH IT
SOJG T3,SQIWR2 ;DO THEM ALL
JUMPL T4,[LSHC Q1,-4 ;ALIGN ODD WORD
MOVEM Q2,@FILBFI(JFN) ;STORE ODD WORD
AOS FILBFI(JFN) ;MOVE TO NEXT WORD
JRST SQIWR3] ;AND DONE
DMOVEM Q1,@FILBFI(JFN) ;STORE BOTH WORDS
MOVEI Q1,2 ;INCREMENTER
ADDM Q1,FILBFI(JFN)
JUMPG T4,SQIWR1 ;DO MORE
SQIWR3: DMOVE Q1,MDPTR ;RESTORE REGS
RET ;ALL DONE
;ERROR ROUTINE FOR BADLY FORMED SEGMENT ENCOUNTERED
SEGERR: TQO <ERRF> ;SET FILE SYSTEM ERROR
RETBAD (DCNX11) ;AND RETURN WITH ERROR INDICATOR
;ROUTINE TO ANALYZE FAILURE TO SEND ACK OR LS MESSAGE. IF IT IS
;A FREE SPACE FAILURE, THEN A DATA INT IS ISSUED TO INSURE THE PROCESS
;TRIES AGAIN SOON
CHKFRE: TQO <BLKF> ;NOTE BLOCK NEEDED
HRRZ T3,T1 ;GET TEST ROUTINE
CAIE T3,BLOCKM ;A FREE SPACE FAILURE?
RET ;NO. DONE THEN
EXCH T1,FILLLB(JFN) ;YES. GET LL BLOCK
CALL DATINR ;REQEUST DATA INT
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
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
;SQIACK - ROUTINE TO SEND ANY ACK'S NEEDED AFTER INPUT HAS BEEN PROCESSED
;
;ACCEPTS IN T1/ ADDRESS OF LOGICAL LINK BLOCK
; CALL SQIACK
;RETURNS: +1 FAILED, COULD NOT SEND THE ACK
; +2 SUCCESS
SQIACK: STKVAR <SQALLB>
MOVEM T1,SQALLB ;SAVE ADDRESS OF LOGICAL LINK BLOCK
LOAD T2,LLIDN,(T1) ;GET SEG # TO ACK
MOVEI T3,MSDAT ;ON THE DATA CHANNEL
OPSTR <SKIPE>,LLFNN,(T1) ;NEED A NACK?
NSBP08: TXO T2,ACKBIT ;YES.
CALL SNDACK ;SEND IT
JRST [ MOVE T2,SQALLB ;FAILED, GET ADDRESS OF LOGICAL LINK BLOCK
SETONE LLFNA,(T2) ;SAY NEED TO DO IT AGAIN
RET ] ;RETURN FAILURE
SETZRO <LLFNA,LLFNN>,(T1) ;CLEAR ACK FLAGS
RETSKP ;DONE, RETURN SUCCESS
;ROUTINES TO ADJUST FLOW CONTROL COUNTS FOR A LL
;INCREMENT COUNT
INCMSM: ACVAR <W1> ;USE A PRESERVED REG
LOAD W1,LLMSM,(T1) ;GET CURRENT COUNT
AOS W1 ;INCREMENT IT
STOR W1,LLMSM,(T1) ;NEW COUNT
RET ;DONE
;**;[2607] ADD 1 LINE AT INCMSM:+5L PED 4-APR-82
ENDAV. ;[2607] END ACVAR
;DECREMENT COUNT
DECMSM: ACVAR <W1> ;USE A PRESERVED REG
LOAD W1,LLMSM,(T1) ;GET COUNT
SOS W1 ;DECREMENT IT
STOR W1,LLMSM,(T1) ;NEW COUNT
RET ;DONE
;**;[2607] ADD 1 LINE AT DECMSM:+5L PED 4-APR-82
ENDAV. ;[2607] END ACVAR
;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!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!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!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!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!DIABT ;DIS - ABORT IT
IFIW!DIABT ;DIQ - ABORT IT
IFIW!DIABT ;DIR - ABORT IT
IFIW!DCDCS ;ABORTED - SEND DC AND IGNORE IT
;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!DCABT ;DIS - VALID REPLY TO DI SENT
IFIW!DCABT ;DIQ - ABORT THE LINK
IFIW!DCABT ;DIR - ABORT THE 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!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!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 4,<
IFIW!CCDON> ;DIS,DIQ,DIR,ABORTED - IGNORE
SUBTTL NSP Error Code to TOPS20 Error Code Translation
;NSPERR - ROUTINE TO CONVERT AN NSP ERROR CODE INTO A TOPS20 ERROR CODE
;
;ACCEPTS IN T1/ NSP ERROR CODE
; CALL NSPERR
;RETURNS: +1 FAILED, NO SUCH NSP ERROR CODE
; +2 SUCCESS, WITH T1/ TOPS20 ERROR CODE
NSPERR::MOVSI T4,-ERRLEN ;SET UP TO LOOP THRU ERROR TABLE
NSPER1: HLRZ T2,ERRTAB(T4) ;GET AN NSP ERROR CODE
CAMN T2,T1 ;FOUND NSP ERROR CODE TO BE TRANSLATED ?
JRST NSPER2 ;YES, GO GET CORRESPONDING TOPS20 CODE
AOBJN T4,NSPER1 ;NO, LOOP OVER ENTIRE TABLE
RETBAD (MONX03) ;NO SUCH NSP ERROR CODE, RETURN FAILURE
; HERE HAVING FOUND THE NSP ERROR CODE
NSPER2: HRRZ T1,ERRTAB(T4) ;GET CORRESPONDING TOPS20 ERROR CODE
RETSKP ;DONE, RETURN SUCCESS
; TABLE OF NSP/TOPS20 ERROR CODE CORRESPONDENCE
ERRTAB: .DCX0,,NSPX00
.DCX1,,NSPX01
.DCX2,,NSPX02
.DCX3,,NSPX03
.DCX4,,NSPX04
.DCX5,,NSPX05
.DCX6,,NSPX06
.DCX7,,NSPX07
.DCX8,,NSPX08
.DCX9,,NSPX09
.DCX24,,NSPX10
.DCX32,,NSPX11
.DCX33,,NSPX12
.DCX34,,NSPX13
.DCX35,,NSPX14
.DCX36,,NSPX15
.DCX37,,NSPX16
.DCX38,,NSPX17
.DCX39,,NSPX18
.DCX40,,NSPX19
.DCX41,,NSPX20
.DCX42,,NSPX21
.DCX43,,NSPX22
ERRLEN==.-ERRTAB
SUBTTL NSP Background Task - Main Dispatching Loop
;THIS CODE IS THE REQUEST QUEUER AND THE BACKGROUND NSP
;TASK. THE QUEUER IS RESPONSIBLE FOR "ROUTING" ALL MESSAGES
;TO EITHER THE NETWORK (VIA THE DTE OR WHATEVER ELSE CONNECTS
;US TO THE NETWORK) OR TO ANOTHER LOGICAL LINK ON THE SAME HOST.
;ALSO, IT IS RESPONSIBLE FOR RETRANSMITTING ANY NACK'ED MESSAGES.
;THE BACKGORUND PROCESS RUNS AS A FORK OF JOB 0 AND IS RESPONSIBLE
;FOR PARSING ALL CONTROL MESSAGE, COMPLETING ALL CONNECTS, PROCESSING
;ACK AND LINK SERVICE MESSAGES, ACTING AS A SERVICE OF NETSQI FOR
;ACTING ON ACKS THAT ARE PIGGY-BACKED ONTO DATA SEGMENTS, AND FOR
;GENERATING PROCESS INTERRUPTS. ALSO, THIS PROCESS WILL EVOLVE OVER
;TIME TO HANDLE ALL ROUTING STRATEGIES.
SWAPCD ;ALL OF THIS CODE IS SWAPPABLE
TSKINI: MCENTR ;GET INTO MONITOR CONTEXT
SE1ENT ;MAKE IT RUN IN PROPER SECTION
TRVAR <MSGCNT,MSGBYP,MSGSRC,MSGDST,MSGBLK,MSGLLB,MSGOBJ,<MSGDDC,5>,<MSGHSN,2>,MSGW1,MSGW2,MSGSOB,<MSGSDC,5>,<MSGDML,LKSIZE>,MSGLCL>
MOVEI T1,MAXQ ;DON'T ALLOW THIS FORK TO BE "COMPUTE-BOUND"
MOVEM T1,JOBBIT ;BY PREVENTING MAXQ SCHEDULING BEHAVIOR
NSPTSK:
SKIPE MSGQ ;ANYTHING ON THE QUEUE?
CALL DOMSGQ ;YES, GO PROCESS NSP TASK'S QUEUE
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
SKIPE NSPMCB ;ANY DEAD MCB'S TO CLEAN UP?
CALL MCBDED ;YES - GO CLEAN THEM UP
MOVEI T1,NSPTST ;REST UNTIL WORK TO DO
HDISMS (^D1500) ;WAIT, BUT STAY IN BALSET
JRST NSPTSK ;AND TRY AGAIN
;TEST ROUTINE FOR NSPTSK
RESCD
NSPTST: 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
SKIPE MSGQ ;ANY MESSAGES TO DO?
JRST 1(4) ;YES, WAKE UP
SKIPE NSPMCB ;ANY DEAD LINES TO CLEAN UP?
JRST 1(4) ;YES, WAKE UP
JRST 0(4) ;NO, WAIT SOME MORE
SWAPCD
;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
RESCD
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: NOSKED ;GET SET TO PULL A MESSAGE OFF
CHNOFF DLSCHN ;TURN OFF DTE
HRRZ T1,MSGQ ;GET TOP MOST ENTRY
LOAD T2,MSLNK,(T1) ;GET LINK
HRRM T2,MSGQ ;STASH IT
SKIPN T2 ;WAS A MESSAGE THERE?
SETZM MSGQ ;NO. CLEAR ENTIRE HEADER
CHNON DLSCHN ;TURN ON DTE
OKSKED ;AND ALLOW SCHEDULING
SETZM MSGLCL ;ASSUME LOCAL IN TRVAR
OPSTR <SKIPN>,MSLCL,(T1) ;DID IT COME FROM DRIVER?
JRST [SKIPL T3,NSPLPB ;YES, IS THERE A LOOPBACK LINE RUNNING?
JRST DOMSG1 ;NO
HRRZS T3 ;GET RID OF LOOPBACK FLAGS
LOAD T4,MSPRT,(T1);GET PORT OF MESSAGE
CAME T3,T4 ;IS IT THE LOOPER?
JRST DOMSG1 ;NO
SETONE MSLCL,(T1) ;YES, SAY LOCAL IN THE MESSAGE BLOCK
JRST .+1]
SETOM MSGLCL ;SAY LOCAL IN TRVAR
DOMSG1: MOVEM T1,MSGBLK ;SAVE BLOCK ADDRESS
LOAD T2,MSCNT,(T1) ;GET BYTE COUNT OF THE MESSAGE
MOVEM T2,MSGCNT ;SAVE IT
ADDI T1,MSHDR ;GET TO START OF DATA
HRLI T1,(<POINT 8,>) ;FORM BYTE POINTER
MOVEM T1,MSGBYP ;AND SET UP BYTE POINTER
; ..
;MESSAGE ALL SET UP. GET MESSAGE FLAGS
;HAVE A MESSAGE. SEE WHAT IT IS
SETZM MSGHSN ;ASSUME NO HOST NAME
CALL GETBYT ;GET A BYTE
JRST BADMSG ;BADLY FORMED. REJECT 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
MOVEI T4,MAXHST
CALL GTASCI ;AND GET ASCII FIELD
JRST BADMSG ;BADLY FORMED MESSAGE
CALL GETBYT ;GET MESSAGE FLAGS
JRST BADMSG ;BADLY FORMED
DOMSG: MOVE T3,MSGBLK ;GET MESSAGE BLOCK
STOR T2,MSMFL,(T3) ;SAVE FLAGS
;**;[3144] Add 2 lines at DOMSG:+2L (W.Nichols edit) DEE 31-JUL-84
CAIN T2,RCIMFL ;[3144] IS THIS A PHASE IV RETRANSMITTED CI?
;**;[3145] Change 1 line at DOMSG+3L (fix 3144) DEE 6-AUG-84
JRST BADMSG ;[3144] 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!CIDON ;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 T2,MSPRT,(T1) ;GET PORT I.D.
BUG (NSPRTH,<<T1,MSGADR>,<T2,DTE>>)
CALL PROOFF ;TURN OFF THE INT THAT DID IT
JRST CIDON ;AND GIVE UP
;GOT A STARTUP MESSAGE
;GOT A STARTUP MESSAGE
STRMSG: SETZM Q2 ;INITIALIZE "VERIFICATION REQUESTED" FLAG
MOVE T2,MSGBLK ;POINT TO MSG BLOCK AGAIN
LOAD Q1,MSPRT,(T2) ;GET PORT MESSAGE CAME FROM
JN INIRCV,MCBDTE(Q1),BADSTR ;IF ALREADY RUNNING, ERROR
CALL GETBYT ;GET STARUP TYPE
JRST BADSTR ;BADLY FORMED
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
CALL GETBYT ;GET SUPPORTED FUNCTIONS
JRST BADSTR ;BAD
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
CALL GETBYT ;GET ITS REQUIRED FUNCS
JRST BADSTR ;BAD
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
MOVEM T2,NSPMAX(Q1) ;YES. SET UP NSPMAX THEN
MOVEI T4,10 ;BYTES TO IGNORE
STRMS1: CALL GETBYT ;GET A BYTE
JRST BADSTR
SOJG T4,STRMS1 ;SKIP BYTES
MOVE T3,Q1 ;GET PORT
IMULI T3,^D9 ;ITSID IS 9 WORDS/PORT
ADDI T3,ITSID ;WHERE TO PUT IS ID
MOVEI T4,^D36
CALL GTASCI ;GET IT
JRST BADSTR
HRRM Q1,MCBDTE(Q1) ;SAVE PORT WE INITED ON
LOAD T1,NAMCN,MCBDTE(Q1) ;GET LENGTH OF ITS NAME
CAME T1,OURCNT ;SAME LENGTH AS OURS ?
JRST STRMS6 ;NAMES ARE NOT THE SAME
MOVEI T1,(Q1) ;COPY PORT NUMBER
ADDI T1,ITSNAM(Q1) ;POINT TO PORTS NAME
MOVEI T2,OURNAM ;POINT TO OUR NAME
CALL CMPSTR ;SEE IF SAME NAME
JRST STRMS6 ;NAMES ARE NOT THE SAME
SKIPE T1,NSPLPB ;GET PORT FOR LOOPBACK
CAIE Q1,(T1) ;IS THIS PORT INTENDED FOR LOOPBACK ?
JRST BADSTR ;NOT SUPPOSED TO BE IN LOOPBACK
SETONE ND%LPR,NSPLPB ;LOOPBACK NOW RUNNING
JRST STRMS7 ;WE ARE NOW IN LOOPBACK MODE
STRMS6: SKIPN T1,NSPLPB ;GET PORT FOR LOOPBACK
JRST STRMS7 ;NO PORT SCHEDULED FOR LOOPBACK
CAIN Q1,(T1) ;IS THIS PORT SCHEDULED FOR LOOPBACK ?
JRST BADSTR ;FLUSH THE PORT
STRMS7: SETONE INIRCV,MCBDTE(Q1) ;NOTE INIT MSG RECEIVED
JUMPN Q2,[JE INISNT,MCBDTE(Q1),[SETONE REQVER,MCBDTE(Q1)
JRST .+1]
MOVE T1,Q1 ;VERIFICATION WANTED, GET PORT NUMBER
CALL NODVER ;SEND VERIFICATION MESSAGE
JRST .+1 ] ;DONE, CONTINUE
MOVEI T1,(Q1) ;GET PORT
ADDI T1,ITSNAM(Q1) ;POINT TO NAME FOR NEIGHBOR(2 WDS / PORT)
MOVX T2,.NDSON ;STATE IS ON
SETZ T3, ;NO NEIGHBOR NODE
CALL ADDINT ;ADD NODE TO TABLE OF KNOWN NODES
BUG(NSPSTR)
JRST CIDON ;AND GO TO IT
BADSTR: CALL PROOFF ;TURN OFF FE
BUG (ILLSTR,<<Q1,DTE>>)
JRST BADMSG ;DON'T INIT
;ROUTINE USED BY STRMSG TO TURN OFF AN MCB IF NODE INIT
;FAILS
PROOFF: MOVE T1,MSGBLK ;GET MESSAGE
LOAD T3,MSPRT,(T1) ;GET PORT I.D.
MOVEI T2,T3 ;POINT TO ARG BLOCK
MOVEI T1,.BTTPR ;TURN OFF PROTOCOL
BOOT ;DO IT
ERJMP .+1 ;?
RET ;DONE
;ROUTINE USED TO SHUT ALL LINKS TO AN MCB THAT HAS DIED.
;ACCEPTS: T1/ PORT NUMBER
DEDMCB::SKIPL MCBDTE(T1) ;WAS THAT OURS
RET ;NO
SKIPL T1 ;IS PORT NUMBER OUT OF RANGE
CAIL T1,35
JRST [ BUG (NSPBPN,<<T1,BADDTE>>)
RET]
MOVE T1,BITS(T1) ;GET THE PROPER BIT NUMBER
IORM T1,NSPMCB ;AND SET IT. THIS WILL WAKE NSP BCKGRND TASK
RET
;ROUTINE TO CLOSE ALL LINKS ON ALL DEAD MCB'S
MCBDED: TRVAR <WAITER,DEDPRT,<DEDDUM,14>,MSGW1>
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)
MOVEI T1,ITSNAM(T2) ;FORM ADDRESS OF NODE NAME OF
ADD T1,DEDPRT ; CRASHED DN20
HRLI T1,(POINT 7,) ;FORM POINTER TO NAME
MOVX T2,.NDSOF ;NODE STATE IS NOW OFF
SETZ T3, ;SHOW NO NEIGHBOR NODE
CALL ADDINT ;REMOVE NODE FROM KNOWN NODE TABLE
JFCL ;FAILED, NOT IMPORTANT.
MOVE T2,DEDPRT ;GET PORT NUMBER
;**;[2647] Add 1 line at GOTMCB:+12.L PED 13-AUG-82
LSH T2,1 ;[2647] CONVERT TO PROPER OFFSET
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,LLPRT,(T1) ;GET PORT
CAME T2,DEDPRT ;THIS ON THIS MCB?
RET ;NO
JN LLDED,(T1),R ;DON'T PROCESS IF ALREADY PROCESSED
CALL BLKLOK ;YES. LOCK IT
JRST [ LLLULK ;CAN'T.UNLOCK TREE
MOVEM T1,WAITER ;STORE WAIT
RETSKP] ;AND STOP NOW
LOAD T2,LLSTA,(T1) ;GET LINK STATE
CAILE T2,LLSLIS ;DONE IF THIS IS A LISTENING LINK
CALL TSTLCL ;IS IT LOCAL?
CALLRET BLKULK ;YES. NOT INTERESTED
LLLULK ;UNLOCK THE TREE
LOAD T2,LLSTA,(T1) ;GET STATE
SETONE LLDED,(T1) ;INDICATE THIS BLOCK PROCESSED FOR DEAD MCB
CAIG T2,LLSDIR ;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]-2(T2) ;AND, FINALLY, FOR DI REC
SETZM WAITER ;FLAG INDICATES "CONTINUE AT TOP OF TREE"
JN LLSDE,(T1),[ OKINT ;IF DISASSOCIATED
CALL DELNOD ;RELEASE NODE
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: 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
CALL GETBYT ;GET FORMAT OF DEST OBJECT
INVPRC: JRST [ MOVEI T2,.DCX5
JRST CIDC] ;AND ERROR
CAILE T2,OBJTWO ;IS IT A FORMAT WE UNDERSTAND?
JRST INVPRC
MOVE T4,T2 ;SAVE OBJECT TYPE
CALL GETBYT ;GET OBJECT NUMBER
JRST INVPRC
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: CALL GETBYT ;GET SOURCE OBJECT TYPE
JRST INVPRC
CAILE T2,OBJTWO ;VALID?
JRST INVPRC
MOVE T4,T2 ;SAVE IT
CALL GETBYT ;GET OBJECT #
JRST INVPRC
MOVEM T2,MSGSOB ;SAVE SOURCE OBJECT #
SETZM MSGSDC ;ASSUME NO DESCRIPTOR
SETZM MSGDML ;ASSUME NO GROUP,USER
CAIN T4,OBJTWO ;DOES IT INCLUDE A GROUP?
JRST [ CALL GETTWO ;YES. GET GROUP
JRST INVPRC ;BAD
HRLM T2,MSGDML ;SAVE IT
CALL GETTWO ;GET USER
JRST INVPRC
HRRM T2,MSGDML ;SAVE IT
JRST .+1] ;AND PROCEED
CAIGE T4,OBJONE ;HAVE A DESCRIPTOR?
JRST DSCNO1 ;NO. GO FIND MATCH
MOVEI T3,MSGSDC ;MOVE DESCRIPTOR
MOVEI T4,MAXDSC
CALL GTASCI ;GET IT
JRST INVPRC
; ..
;CIMSG CONTINUED .....
DSCNO1: MOVE T2,MSGBLK ;POINT TO MSG BLOCK AGAIN
LOAD T2,MSPRT,(T2) ;GET PORT MESSAGE CAME FROM
OPSTR <SKIPE>,NTSHUT,MCBDTE(T2) ;SHUTTING DOWN?
SKIPE MSGLCL ;YES. IS THIS A FOREIGN HOST?
JRST DSCNO2 ;NO. ALLOW IT.
MOVEI T2,.DCX3 ;"NODE SHUTTING DOWN"
JRST CIDC ;AND REJECT THE CONNECT
DSCNO2: MOVEI T1,CICOR ;COROUTINE ADDRESS
MOVEI T2,1 ;LOOK FOR LISTENING OBJECT ONLY
LLLOCK ;LOCK THE TREE
CALL OBJSRC ;GO LOOK FOR IT
JRST [ LLLULK ;RELEASE TREE
MOVEI T2,.DCX4 ;NO SUCH OBJECT
JRST CIDC]
CALL BLKLOK ;LOCK THE BLOCK
JRST [ LLLULK ;COULDN'T.
MDISMS ;WAIT HERE
JRST DSCNO2] ;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
SKIPE MSGLCL ;LOCAL CONNECTION?
JRST [SETONE LLLOC,(T1) ;YES, NOTE THIS IS A LOCAL LINK
JRST HOSTNL] ;LEAVE NULL HOST NAME
MOVEI T2,MSGHSN ;GET POINTER TO HOST NAME
LOAD T1,LLHST,(T1) ;GET OUT HOST STRING
SETOM T3 ;NO COUNT
CALL MOVSTR ;MOVE THE STRING
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
HOSTNL: CALL FILLIN ;GO FILL IN COMMON QUANTITIES
MOVE T2,MSGSOB ;GET SOURCE OBJECT
STOR T2,LLFNM,(T1) ;SAVE IT
LOAD T1,LLFDS,(T1) ;GET DESCRIPTOR STRING
SKIPN T2,MSGSDC ;HAVE A DESCRIPTOR?
JRST [ CALL RELBLK ;FREE THE BLOCK
MOVE T1,MSGLLB ;GET BACK LL BLOCK
SETZRO LLFDS,(T1) ;CLEAR IT
JRST DSCMOV]
SETOM T3 ;UNTIL A NULL
MOVEI T2,MSGSDC ;GET POINTER TO STRING
CALL MOVSTR ;MOVE IT
MOVE T1,MSGLLB ;GET BACK BLOCK ADDRESS
; ..
;CIMSG CONTINUED. FOUND BLOCK. GET OPTIONAL ACCESS CONTROL STUFF
DSCMOV: CALL GETBYT ;GET MENU BYTE
JRST NODATA ;NONE. NO OPTIONAL DATA THEN
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,MAXDSC
CALL GTASCI ;GET IT
JRST BADUDT ;BADLY FORMED
LOAD T3,LLPSW,(T1) ;WHERE TO PUT PASSWORD
MOVEI T4,^D8 ;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,MAXDSC
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,MAXDSC
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
BADMSG: ;IGNORE THE MESSAGE
CIDON: MOVE T1,MSGBLK ;GET BACK MESSAGE BLOCK
CALL RELRES ;FREE THE BLOCK
RET ;RETURN TO BACKGROUND TASK DISPATCHER
;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,MSGW1 ;GET FC OPTION
STOR T2,LLMFC,(T1) ;STORE IT
MOVE T2,MSGW2 ;GET SEGSIZE
LOAD T3,LLBSZ,(T1) ;GET BYTE SIZE
CAIE T3,44 ;WORD MODE?
JRST FILLI1 ;NO.
IDIVI T2,11 ;YES. MAKE IT EVEN # OF WORDS THEN
IMULI T2,11 ;""
FILLI1: STOR T2,LLSWG,(T1) ;SAVE IT
MOVE T2,MSGSRC ;GET FOREIGN LINK I.D.
STOR T2,LLHLK,(T1) ;SAVE IT
RET ;AND DONE
;COMMON ROUTINE TO GEN CONNECT INTERRUPT
CONINT: SAVET ;SAVE TEMPS
STKVAR <CNTLLB,CNTSTS>
MOVEM T1,CNTLLB ;SAVE LOGICAL LINK BLOCK ADDRESS
JN LLINT,(T1),CONIN1 ;IF INTERNAL LINK GO NOTIFY DRIVER OF CONNECT
LOAD T2,LLFRK,(T1) ;GET OWNING FORK
OPSTR <SKIPN T1,>,LLPIC,(T1) ;HAVE A CONNECT PI?
RET ;NONE TO DO
SOS T1 ;GET PROPER CHANNEL
CALLRET PSIRQ ;GEN INTERRUPT
; HERE FOR INTERNAL LINKS
CONIN1: CALL RDSTS ;GO GET LINK STATUS
MOVEM T3,CNTSTS ;SAVE STATUS
HRRZ T1,CNTSTS ;GET NSP ERROR CODE
CALL NSPERR ;CONVERT TO TOPS20 ERROR CODE
JFCL ;USE TRANSLATION ROUTINE'S ERROR CODE
HRR T2,T1 ;GET TOPS20 ERROR CODE
HLL T2,CNTSTS ;GET STATUS FLAGS
MOVE T1,CNTLLB ;RESTORE LOGICAL LINK BLOCK ADDRESS
LOAD T4,LLVEC,(T1) ;GET ADDRESS OF DRIVER FUNCTION VECTOR
LOAD T1,LLDRV,(T1) ;GET DRIVER CORRELATION CODE
CALL @.NSCND(T4) ;NOTIFY DRIVER OF CONNECTION
RET ;DONE, RETURN
;INTTST - ROUTINE TO DETERMINE IF CONNECTED TO AN INTERNAL LINK
;
;ACCEPTS IN TRVARS MSGLCL/ LOCAL-FOREIGN FLAG
; MSGSRC/ LINK ID OF SOURCE OF CI MESSAGE
; MSGLLB/ LOGICAL LINK BLOCK ADDRESS OF DESTINATION LINK
; CALL INTTST
;RETURNS: +1 ALWAYS, WITH LLCIL SET IF CONNECTED TO AN INTERNAL LINK
INTTST: ACVAR <W1>
SAVET ;PRESERVE LOCAL AC'S
SKIPN MSGLCL ;LOCAL CONNECTION ?
RET ;NO, DONE
; LOCK SOURCE LOGICAL LINK BLOCK AND SEE IF IT IS AN INTERNAL LINK
INTT10: LLLOCK ;LOCK LOGICAL LINK TREE
MOVE T1,MSGSRC ;GET SOURCE LINK ID
SETOM T2 ;NO SPECIAL CRITERIA
CALL LLLKUP ;FIND THE LINK ADDRESS
JRST [ LLLULK ;FAILED, UNLOCK THE TREE
RET ] ;RETURN, LINK MUST HAVE DISAPPEARED
MOVEM T1,W1 ;SAVE LOGICAL LINK BLOCK ADDRESS OF SOURCE
CALL BLKLOK ;LOCK THE SOURCE LINK BLOCK
JRST [ LLLULK ;CANNOT LOCK IT, UNLOCK THE TREE
MDISMS ;WAIT UNTIL AVAILABLE
JRST INTT10 ] ;GO TRY TO LOCK BLOCK AGAIN
LLLULK ;UNLOCK LOGICAL LINK TREE
JE LLINT,(W1),INTT20 ;IF SOURCE IS NOT AN INTERNAL LINK, WE ARE DONE
MOVE T4,MSGLLB ;GET LOGICAL LINK BLOCK ADDRESS OF DESTINATION
SETONE LLCIL,(T4) ;NOTE CONNECTED TO AN INTERNAL LINK
; HERE WHEN DONE, UNLOCK BLOCK AND RETURN
INTT20: MOVE T1,W1 ;RESTORE LOGICAL LINK BLOCK ADDRESS
CALL BLKULK ;UNLOCK THE BLOCK
RET ;DONE, RETURN
;**;[2607] ADD 1 LINE AT INTT20:+4L PED 4-APR-82
ENDAV. ;[2607] 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
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,MAXDSC
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 CIDON ;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 CIDON ;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: 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
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
JRST CONREJ ;AND FAKE A CI REJECT
;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
JN LLINT,(T1),[CALL SQILS ;INTERNAL LINK, TRY LS SEND AGAIN
MOVE T1,MSGLLB ;FAILED, RESTORE LINK BLOCK ADDRESS
JRST CCDON]
OPSTR <SKIPE>,LLLSA,(T1) ;WANT TO RETRY A LS SEND?
CALL DATINR ;YES. MAKE PROCESS WAKE NOW THEN
JRST CCDON ;AND DONE
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
LOAD T3,LLOPT,(T1) ;GET OPTDATA, IF ANY
MOVEI T4,MAXDSC
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 DIMSG3 ;SEND DC
;HERE FOR DI RECEIVED WHEN IN NON-RUN STATE
DIABT: CALL CHKFRN ;SOURCE ADDR MUST MATCH
JRST CCJECT ;DOESN'T
JN LLSDE,(T1),[ CALL RELLNK ;IF DISASSOCIATED
MOVEI T2,.DCX9 ;SAY A USER ABORT
JRST CIDC] ;AND SEND DC
CALL RJECT1 ;GO CHANGE LINK STATE
JRST DIMSG3 ;SEND DC
;DI OR DC RECIEVED IN RUN STATE
DIMSG2: CALL CHKFRN ;SOURCE ADDR MUST MATCH
JRST CCJECT ;DOESN'T
CALL SHUTLK ;SHUT DOWN LINK
DIMSG3: SKIPN T2,MSGW1 ;HAVE A BAD REASON?
;COMMON POINT FOR DI OR DC IN RUN STATE OR DC IN ABT STATE
DCDCS: MOVEI T2,.DCX42 ;NO. SAY REPLY TO DI THEN
JRST CCJEC1 ;AND GO SEND DC
;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
CALLRET TELDIS ;NOTIFY DRIVER IF THIS IS AN INTERNAL LINK
;FOR DI OR DC RECEIVED IN RUN STATE
SHTLK1: SKIPA T3,[LLSDIS] ;NEW STATE
SHUTLK: MOVEI T3,LLSDIR ;NEW STATE
MOVE T2,MSGW1 ;GET REASON
STOR T2,LLRSN,(T1) ;SAVE IT
STOR T3,LLSTA,(T1) ;SAVE NEW STATE
CALL DATINR ;GIVE INT IF NECESSARY
SKIPE MSGW1 ;SYNCHRONOUS DI?
JRST [ SETZRO LLFDI,(T1) ;NO. CLEAR THIS JUST IN CASE
CALL FLUSH ;AND CLEAN UP LINK
JRST SHUT10] ;GO NOTIFY DRIVER IF INTERNAL LINK
SETONE LLFDI,(T1) ;YES. SAY SO
SHUT10: CALLRET TELDIS ;NOTIFY DRIVER IF AN INTERNAL LINK
;ROUTINE USED BY DIMSG TO VERIFY SOURCE ADDR
; T1/ LINK ADDRESS
;RETURNS: +1 NOT A MATCH
; +2 A MATCH
CHKFRN: LOAD T2,LLHLK,(T1) ;GET FOREIGN HOST I.D.
CAME T2,MSGSRC ;IS THIS WHO SENT IT?
RET ;NO
RETSKP ;YES
;TELDIS - ROUTINE TO NOTIFY A DRIVER OF A DISCONNECT ON AN INTERNAL LINK
;
;ACCEPTS IN T1/ ADDRESS OF LOGICAL LINK BLOCK
; CALL TELDIS
;RETURNS: +1 ALWAYS, WITH DRIVER NOTIFIED
TELDIS: SAVET
STKVAR <TDSLLB,TDSSTS>
MOVEM T1,TDSLLB ;SAVE LOGICAL LINK BLOCK ADDRESS
JE LLINT,(T1),R ;DONE IF NOT AN INTERNAL LINK
JN LLSDE,(T1),R ;DONE IF LINK DISSOCIATED FROM PROCESS
CALL RDSTS ;GO GET LINK STATUS
MOVEM T3,TDSSTS ;SAVE STATUS
HRRZ T1,TDSSTS ;GET NSP ERROR CODE
CALL NSPERR ;CONVERT TO TOPS20 ERROR CODE
JFCL ;FAILED, USE ERROR CODE FROM TRANSLATION ROUTINE
HRR T2,T1 ;GET TOPS20 ERROR CODE
HLL T2,TDSSTS ;GET STATUS BITS
MOVE T1,TDSLLB ;RESTORE LOGICAL LINK BLOCK ADDRESS
LOAD T4,LLVEC,(T1) ;GET ADDRESS OF DRIVER FUNCTION VECTOR
LOAD T1,LLDRV,(T1) ;GET DRIVER CORRELATION CODE
CALLRET @.NSDIS(T4) ;NOTIFY DRIVER OF DISCONNECT
;RECEIVED A DC MESSAGE
DCMSG: CALL GETLLA ;GET LINK ADDRESSES
JRST BADMSG ;BADLY FORMED
CALL GETTWO ;GET REASON
SETOM T2 ;NONE THERE
DCMSG4: MOVEM T2,MSGW1 ;SAVE IT
DCMSG1: MOVE T1,MSGDST ;GET OUR NAME
MOVE T2,MSGSRC ;GET SOURCE ADDRESS
LLLOCK ;LOCK THE TREE
CALL LLLKUP ;FIND THE LINK
JRST [ LLLULK ;FREE THE TREE
JRST CIDON] ;IGNORE THE MESSAGE
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 NON-RUN STATE
DCABT: JN LLSDE,(T1),[ CALL RELLNK ;IF DISASSOCIATED
JRST CIDON] ;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 LOCK
CALLRET DELNOD ;FREE NODE AND RETURN
;DATA MESSAGE RECEIVED
DATMSG: 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
LOAD T2,LLSTA,(T1) ;GET STATE
JRST @DATSTA-1(T2) ;GO DO IT
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
; HERE FOR INTERNAL LINKS - ASSEMBLE DATA INTO DRIVER'S BUFFER
INTRUN: CALL INTSET ;GO DO INPUT FOR INTERNAL LINK
JFCL ;FAILED, IGNORE FAILURE FOR NOW
CALL BLKULK ;UNLOCK THE LOGICAL LINK BLOCK
RET ;AND RETURN TO BACKGROUND TASK'S DISPATCHER
; NOT A DATA MESSAGE - MUST BE INTERRUPT OR LINK SERVICES MESSAGE
INTLS: CALL GETTWO ;GET ACK NUMBER
JRST ABTMSG ;GO KILL LINK
TXZE T2,ACKIND ;AN ACK?
JRST [ MOVEI T3,MSLSI ;GET PROPER CHANNEL
CALL ACKCHN ;DO ACK
CALL GETTWO ;GET SEGNUM
JRST ABTMSG ;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 ;HAVE IT
CAILE T3,MAXDIF ;OLD OR NEW?
JRST LSIDON ;TOO NEW. IGNORE IT FOR NOW
INTLS1: CALL ACKLI ;OLD SEG. GO REACK SUBCHANNEL
JRST [ MDISMS ;NO FREE SPACE. WAIT AWHILE
MOVE T1,MSGLLB ;RESTORE BLOCK ADDRESS
JRST INTLS1] ;AND TRY AGAIN
JRST LSIDON ;AND DONE
;HAVE A GOOD INT OR LS MESSAGE
LSINT1: STOR T2,LLIIN,(T1) ;STORE SEG #
MOVE T4,MSGW1 ;GET BACK SUBTYPE
TRNN T4,2 ;INT OR LS MESSAGE?
JRST LSMSG ;LS
SKIPE LLMSI(T1) ;NOW HAVE AN INTERRUPT MESSAGE?
JRST ABTMSG ;KILL LINK
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
CALL ACKLI ;GO ACK IT
JFCL ;IGNORE BLOCK REQUEST
MOVE T1,MSGLLB ;GET BACK LL BLOCK
JRST DATDON ;AND DONE
;HAVE A LS MESSAGE
LSMSG: CALL ACKLI ;ACK THE LS MESSAGE NOW
JRST [ MDISMS ;WAIT HERE UNTIL CAN DO IT
MOVE T1,MSGLLB ;GET BACK LL BLOCK
JRST LSMSG] ;AND TRY AGAIN
CALL GETBYT ;GET LSFLAGS BYTE
JRST ABTMSG ;BADLY FORMED
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
CALL GETBYT ;GET NEXT
JRST ABTMSG ;BADLY FORMED
TXNE T3,4 ;DATA COUNTS?
JRST [ OPSTR <ADD T2,>,LLMIC,(T1) ;NO. COMPUTE NEW VALUE
TXNE T2,200 ;WITHIN RANGE?
JRST ABTMSG ;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 ABTMSG ;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: JN LLINT,(T1),[ CALL INTOUT ;IF INTERNAL LINK SEND ANY OUTPUT STILL LEFT
JFCL ;IGNORE FAILURE HERE
JRST .+1] ;CONTINUE
CALL BLKULK ;FREE THE BLOCK
JRST CIDON ;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
INTSET::SAVET
STKVAR <INSLLB,INSCNT,INSFLG>
MOVEM T1,INSLLB ;SAVE LOGICAL LINK BLOCK ADDRESS
SETZM INSFLG ;INITIALIZE "ALL DATA FIT IN BUFFER" FLAG
; SET UP INPUT BUFFER IF NOT ALREADY SET UP, AND PUT SEGMENTS ON ORDERED QUEUE
INS010: MOVE T1,INSLLB ;GET LOGICAL LINK BLOCK ADDRESS
SETZRO LLFIM,(T1) ;START BY ASSUMING NOT END OF MESSAGE
CALL MOVSEG ;PLACE SEGMENTS ON ORDERED MESSAGE QUEUE
RET ;FAILED, RETURN ERROR
MOVE T1,INSLLB ;RESTORE LOGICAL LINK BLOCK
SKIPN LLOMSG(T1) ;ANY MESSAGES TO PROCESS ?
RETSKP ;NO, DONE.
MOVE T1,INSLLB ;GET LOGICAL LINK BLOCK ADDRESS
CALL SETIBF ;SET UP BUFFER IF REQUIRED
RETSKP ;FAILED, WAIT FOR BUFFER FROM DRIVER
; IF TRUNCATING CURRENT NSP MESSAGE, DISCARD THIS SEGMENT
MOVE T1,INSLLB ;GET ADDRESS OF LOGICAL LINK BLOCK
JN LLTRM,(T1),[ CALL TRNMSG ;GO DISCARD THIS SEGMENT
RET ;FAILED
JRST INS030] ;GO SEND ANY ACK'S OR LS MESSAGES NEEDED
; COPY DATA IN RECEIVED SEGMENTS INTO DRIVER'S BUFFER
MOVE T1,INSLLB ;GET LOGICAL LINK BLOCK ADDRESS
LOAD T2,LLBPI,(T1) ;GET CURRENT BUFFER POINTER
LOAD T3,LLICT,(T1) ;GET MAX NUMBER OF CHARACTERS IN INPUT BUFFER
CALL MOVMSG ;GO COPY DATA INTO DRIVER'S BUFFER
RET ;FAILED, RETURN ERROR
MOVE T4,INSLLB ;RESTORE LOGICAL LINK BLOCK ADDRESS
MOVEM T2,INSCNT ;SAVE NUMBER OF BYTES THAT WERE INPUT
MOVEM T3,INSFLG ;SAVE FLAG NOTING WHETHER ALL DATA FIT IN BUFFER
STOR T1,LLBPI,(T4) ;STORE NEW BUFFER POINTER
SKIPG INSCNT ;ANY BYTES INPUT ?
JRST INS020 ;NO, DO NOT UPDATE COUNT
LOAD T3,LLICT,(T4) ;GET PREVIOUS COUNT
SUB T3,T2 ;COMPUTE NUMBER OF BYTES LEFT IN BUFFER
STOR T3,LLICT,(T4) ;UPDATE NUMBER OF BYTES REMAINING
; ..
; ..
; IF SEGMENT DID NOT FIT IN BUFFER, SEE IF DRIVER WANTED TO TRUNCATE
INS020: MOVE T2,INSFLG ;GET FLAG INDICATING IF ALL DATA FIT IN BUFFER
CAMN T2,[-1] ;DID LAST SEGMENT FIT IN THE BUFFER ?
JRST [ JE LLTRC,(T4),.+1 ;NO. JUST CONTINUE IF NOT TRUNCATING MESSAGES
SETONE LLTRM,(T4) ;REMAINDER OF THIS MESSAGE NOT NEEDED
JRST .+1] ;AND CONTINUE
; CALL DRIVER IF EITHER BUFFER WAS FILLED OR A COMPLETE MESSAGE WAS RECEIVED
MOVE T1,INSLLB ;GET ADDRESS OF LOGICAL LINK BLOCK
MOVE T2,INSCNT ;GET NUMBER OF BYTES INPUT
MOVE T3,INSFLG ;GET FLAG NOTING IF ALL DATA FIT IN BUFFER
CALL TELDAT ;NOTIFY DRIVER THAT DATA HAS ARRIVED
; IF NO BYTES WERE INPUT, ALL DONE. RETURN TO DISPATCHER
SKIPN INSCNT ;WERE ANY BYTES INPUT ?
RETSKP ;NO, ALL DONE THEN
; SEND ANY ACK MESSAGES OR LINK SERVICES MESSAGES NEEDED
INS030: MOVE T1,INSLLB ;GET ADDRESS OF LOGICAL LINK BLOCK
CALL SQIACK ;SEND ANY ACK'S NEEDED
RET ;FAILED, RETURN ERROR
MOVE T1,INSLLB ;GET ADDRESS OF LOGICAL LINK BLOCK AGAIN
CALL SQILS ;SEND ANY LINK SERVICES MESSAGES NEEDED
JFCL ;IGNORE FAILURE, ACK'S WILL CAUSE RETRY
JRST INS010 ;GO SEE IF THERE ARE MORE MESSAGES TO PROCESS
;TELDAT - ROUTINE TO ADVISE THE DRIVER IF A COMPLETE MESSAGE HAS ARRIVED
;
;ACCEPTS IN T1/ ADDRESS OF LOGICAL LINK BLOCK
; T2/ NUMBER OF BYTES INPUT, -1 IF NOT ENOUGH ROOM IN BUFFER
; CALL TELDAT
;RETURNS: +1 ALWAYS, WITH DRIVER NOTIFIED IF NEEDED
TELDAT: STKVAR <TLDLLB,TLDCNT,TLDFLG>
MOVEM T1,TLDLLB ;SAVE LOGICAL LINK BLOCK ADDRESS
MOVEM T2,TLDCNT ;SAVE COUNT OF BYTES INPUT
MOVEM T3,TLDFLG ;SAVE FLAG NOTING IF ALL DATA FIT IN BUFFER
; DETERMINE IF DRIVER MUST BE NOTIFIED
MOVE T4,TLDLLB ;GET LOGICAL LINK BLOCK ADDRESS
LOAD T3,LLICT,(T4) ;GET # OF BYTES LEFT IN BUFFER
JUMPE T3,TLDT10 ;IF NONE, BETTER TELL DRIVER !
MOVE T2,TLDFLG ;GET FLAG
CAME T2,[-1] ;INSUFFICIENT ROOM IN BUFFER FOR THIS MSG ?
JRST [ JE LLFIM,(T1),R ;NO, RETURN UNLESS A COMPLETE MESSAGE RECEIVED
JRST TLDT10 ] ;...
; COMPUTE NUMBER OF BYTES IN BUFFER AND NOTIFY DRIVER OF DATA ARRIVAL
TLDT10: LOAD T4,LLVEC,(T1) ;GET ADDRESS OF DRIVER FUNCTION VECTOR
LOAD T3,LLIIC,(T1) ;YES, GET INITIAL COUNT OF BYTES IN BUFFER
LOAD T2,LLICT,(T1) ;GET CURRENT COUNT OF BYTES LEFT FOR INPUT
SUB T3,T2 ;COMPUTE NUMBER OF BYTES ALREADY INPUT
JN LLFIM,(T1),[TXO T3,NS%MSG ;BUFFER BEING RETURNED BECAUSE EOM SEEN
JRST .+1] ;...
LOAD T2,LLBFI,(T1) ;GET ADDRESS OF DRIVER'S BUFFER
LOAD T1,LLDRV,(T1) ;GET DRIVER CORRELATION CODE
CALL @.NSDAT(T4) ;ADVISE DRIVER THAT INPUT HAS ARRIVED
MOVE T4,TLDLLB ;RESTORE LOGICAL LINK BLOCK ADDRESS
JUMPN T1,[JN LLFIM,(T4),.+1 ;ONLY SET TRUNCATE IF NOT FULL MSG
SETONE LLTRM,(T4) ;NOTE TRUNCATION IF DRIVER REQUESTED IT
JRST .+1] ;...
; UPDATE APPROPRIATE COUNTS AND RETURN
MOVE T1,TLDLLB ;RESTORE LOGICAL LINK BLOCK ADDRESS
SETZRO <LLICT,LLIIC>,(T1) ;CLEAR BYTE COUNTS
SETZRO LLBFI,(T1) ;NOTE WE NO LONGER HAVE AN INPUT BUFFER
RET ;DONE, RETURN
;TRNMSG - ROUTINE TO DISCARD A SEGMENT BECAUSE MESSAGE IS BEING TRUNCATED
;
;ACCEPTS IN T1/ ADDRESS OF LOGICAL LINK BLOCK
; CALL TRNMSG
;RETURNS: +1 FAILED
; +2 SUCCESS, SEGMENT THROWN AWAY
TRNMSG: STKVAR <TMSLLB>
MOVEM T1,TMSLLB ;SAVE LOGICAL LINK BLOCK ADDRESS
TRNM10: MOVE T1,TMSLLB ;GET LOGICAL LINK BLOCK ADDRESS
MOVE T2,[POINT 0,0,2] ;GET NUL POINTER (THROW BYTES AWAY)
MOVX T3,.INFIN ;NO LIMIT ON NUMBER TO DISCARD
CALL MOVMSG ;DISCARD THE DATA
RET ;FAILED
MOVE T1,TMSLLB ;RESTORE LOGICAL LINK BLOCK ADDRESS
JE LLFIM,(T1),RSKP ;IF STILL DON'T HAVE ENTIRE MESSAGE THEN DONE
SETZRO LLTRM,(T1) ;MESSAGE ENTIRELY DISCARDED, STOP TRUNCATING
RETSKP ;DONE, RETURN SUCCESS
;SETIBF - ROUTINE TO SET UP AN INPUT BUFFER FOR AN INTERNAL LINK
;
;ACCEPTS IN T1/ LOGICAL LINK BLOCK ADDRESS (LINK ASSUMED LOCKED)
; CALL SETIBF
;RETURNS: +1 FAILED, COULD NOT SET UP BUFFER NOW
; +2 SUCCESS, WITH BUFFER INFO STORED IN LINK BLOCK
SETIBF: JN LLBFI,(T1),RSKP ;IF ALREADY HAVE A BUFFER THEN DONE
JN LLDRB,(T1),R ;FAIL IFDRIVER ALREADY REFUSED TO PROVIDE BFR
ASUBR <SBFLLB>
LOAD T4,LLVEC,(T1) ;GET DRIVER FUNCTION VECTOR ADDRESS
LOAD T1,LLDRV,(T1) ;GET DRIVER CORRELATION CODE FOR THIS LINK
CALL @.NSBFR(T4) ;REQUEST DRIVER TO SUPPLY A BUFFER
JRST [ MOVE T1,SBFLLB ;RESTORE LOGICAL LINK BLOCK ADDRESS
SETONE LLDRB,(T1) ;NOTE THAT DRIVER REFUSED TO PROVIDE BUFFER
RET ] ;AND DONE
MOVE T4,SBFLLB ;RESTORE LOGICAL LINK BLOCK ADDRESS
STOR T1,LLBFI,(T4) ;STORE BUFFER ADDRESS
STOR T2,LLICT,(T4) ;STORE COUNT OF BYTES CURRENTLY LEFT IN BUFFER
STOR T2,LLIIC,(T4) ;ALSO STORE AS INITIAL COUNT OF BYTES IN BUFFER
HRLI T1,(POINT 8,) ;FORM POINTER TO FIRST BYTE IN THIS BUFFER
STOR T1,LLBPI,(T4) ;SAVE AS POINTER TO NEXT BYTE TO BE INPUT
TXNE T2,NS%TRN ;DRIVER WANT MESSAGES TRUNCATED IF TOO LONG ?
JRST [ SETONE LLTRC,(T4) ;YES, NOTE TRUNCATION DESIRED
JRST .+1 ] ;AND CONTINUE
RETSKP ;DONE, RETURN WITH BUFFER INFO IN LINK BLOCK
;ROUTINES USED BY DATMSG.....
;KILL OFF LINK AFTER PROTOCOL ERROR.
ABTMSG: MOVEI T2,.DCX40 ;DATA LOSS
MOVEM T2,MSGW1 ;SAVE CODE
CALL SHTLK1 ;SHUT IT OFF
MOVEM T1,MSGLLB ;SAVE LL BLOCK
MOVEI T4,CNMRFL+CNMDI ;SEND A DI
SETZM T3 ;NO OPTDATA
CALL SNDDI ;GO DO IT
JRST [ TQO <BLKF> ;NOTE BLOCK NEEDED
MOVE T1,MSGLLB ;RESTORE BLOCK ADDRESS
MOVEI T2,LLSDIQ ;NEW STATE
STOR T2,LLSTA,(T1)
JRST LSIDON] ;AND DONE
CALL SNDCTL ;SEND THE MESSAGE
JRST LSIDON ;DONE
;ROUTINE TO FILL IN MESSAGE COUNTS IN MESSAGE BLOCK
SETCNT: MOVE T3,MSGBLK ;GET BLOCK ADDRESS
MOVE T4,MSGBYP ;GET CURRENT BYTE POINTER
MOVEM T4,MSBPTR(T3) ;SAVE IT
MOVE T4,MSGCNT ;GET CURRENT COUNT
STOR T4,MSDTC,(T3) ;SAVE IT
RET ;AND DONE
;ROUTINE TO SEND INTIAL LS MESSAGE TO OTHER END OF THE LINK.
;ACCEPTS: T1/ LL BLOCK ADDRESS
;RETURNS: +1 FAILED. MESSAGES NOT SENT
; T1/ SCHEDULER TEST WORD
; +2 SUCCESS. MESSAGES SENT
; T1/ LL BLOCK ADDRESS (UNCHANGED)
TURNON:
;**;[3059] Remove 1 Line at TURNON: +0L CRJ 19-Dec-83
; JE LLOPI,(T1),RSKP ;IF NOT OPEN FOR READ, DON'T SEND LS
MOVEI T3,MSDAT ;ON THE DATA SUBCHANNEL
LOAD T2,LLMQI,(T1) ;GET MAX QUEUE VALUE
;**;[3059] Add 4 Lines at TURNON: +3L CRJ 19-Dec-83
JE LLOPI,(T1),[ ;Write-only?
JN LLFOB,(T1),RSKP ;If also SRV: forget it. Otherwise,
CLEAR T2, ; WO DCN:, send an LS so other side will give
CALLRET SNDLS ] ; one back, set flow to 0 and send
OPSTR <SKIPE>,LLIMS,(T1) ;MESSAGE?
MOVEI T2,1 ;YES. ONE MESSAGE THEN
CALLRET SNDLS ;SEND IT OFF
;ROUTINE TO CHECK IF A CONNECTION IS TO ANOTHER TASK
;ON THE SAME NODE.
; T1/ LL BLOCK ADDRESS
;RETURNS: +1 IS TO A LOCAL
; +2 TO ANOTHER NODE
TSTLCL:: JN LLLOC,(T1),R ;RETURN IF LOCAL
RETSKP ;SKIP RETURN IF NOT LOCAL
;COLLECTION OF ROUTINES TO GET FIELDS FROM A MESSAGE
;MOST ARE RESIDENT BECAUSE THEY ARE USED BY THE CHANNEL 7 CODE
;GET A BYTE
RESCD ;CALLED FROM SCHEDULER
GETBYT: SOSGE MSGCNT ;HAVE ANOTHER BYTE?
RET ;NO. PROBABLY ERROR
ILDB T2,MSGBYP ;GET A BYTE
RETSKP ;AND DONE
;GET TWO BYTE FIELD
;PRESERVES T4
GETTWO: CALL GETBYT ;GET A BYTE
RET ;FAILED
LSHC T2,-10 ;SAVE LOW ORDER BYTE
CALL GETBYT ;GET NEXT ONE
RET ;FAILED
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
CALL GETBYT ;GET COUNT FIELD
JRST [ SETZM T2 ;NO COUNT WORD
RET] ;DONE
CAMLE T2,T4 ;WITHIN RANGE?
RET ;NO.
MOVE W2,T2 ;SAVE COUNT
SKIPN T4,T2 ;SAVE COUNT
JRST GTASCD ;NO COUNT
GTASC1: CALL GETBYT ;GET A BYTE
RET ;FAILED
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
;**;[2607] ADD 1 LINE AT GTASCD:+4L PED 4-APR-82
ENDAV. ;[2607] END ACVAR
;MORE BYTE MANIPULATION ROUTINES
;SKIP AN IMAGE FIELD
SKPFLD: CALL GETBYT ;GET IMAGE COUNT
RET ;BADLY FORMED
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
SWAPCD ;ONLY FROM PROCESS CONTEXT
GETEXT: SETZB T3,T4 ;INIT ACCUMULATOR AND COUNTER
GETEX1: CALL GETBYT ;GET NEXT BYTE
RET ;BAD
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
;[2633] Add routine MAKEXT after routine GETEXT CLB 21-JUL-82
;[2633] Make an extensible field
;[2633] Accepts: T1/ LL block address
;[2633] T3/ the value
;[2633] Returns: +1
;[2633] Preserves T1
MAKEXT: MOVEI T2,177 ;[2633] Get extensible field mask
AND T2,T3 ;[2633] Get a byte's worth
LSH T3,-7 ;[2633] Adjust the remaining quantity
SKIPE T3 ;[2633] more bytes to come?
TXO T2,NSPEXT ;[2633] Put in extensible flag bit
CALL ONEBYT ;[2633] Put byte in message
JUMPN T3,MAKEXT ;[2633] If more, go do it
RET ;[2633] Done
;ROUTINE USED BY CI AND CC TO PROCESS COMMON FIELDS
SWAPCD ;SWAPPABLE
CIPSRV: CALL GETBYT ;GET SERVICES
RET ;BAD
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
CALL GETBYT ;GET LINK PRI
RET ;ASSUME IT IS GOOD
CALL GETTWO ;GET SEGSIZE
RET ;BAD
SKIPN MSGLCL ;LOCAL LINK?
CALL CIPSR1 ;NO, CHECK FOR SEGMENT SIZE ADJUSTMENT
MOVEM T2,MSGW2 ;SAVE IT
RETSKP ;ALL GOOD
CIPSR1: SAVEAC (T3) ;PRESERVE T3
MOVE T3,MSGBLK ;GET ADDRESS OF MESSAGE BLOCK
LOAD T3,MSMFL,(T3) ;GET MESSAGE FLAGS
CAIN T3,CIMMFL ;IS IT A CI?
RET ;YES, NOTHING TO DO
CAIG T2,SEGSIZ ;NO, A CC - THEIR SEG SIZE BIGGER THAN OURS?
RET ;NO, USE THEIR'S
MOVEI T2, SEGSIZ ;YES, USE OURS
RET ;DONE
;REQUEST QUEUER ROUTINES
;SEND CONTROL MESSAGE
;ACCEPTS: T1/ LL BLOCK ADDRESS
; T2/ MESSAGE BLOCK
;RETURNS: +1 ALWAYS
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
CALL TSTLCL ;SEE IF TO A LOCAL
JRST CTLLCL ;YES. GO HANDLE IT
SNDSG0: LOAD T1,LLPRT,(T1) ;GET PORT I.D.
; HRLI T1,MSGPST ;POSTING ADDRESS
HRLI T1,RELRES ;MAKE DRIVER RELEASE THE BLOCK
SNDMSG: STKVAR <SAVPST,SAVFF> ;TEMP SAVE LOCATIONS
MOVEM F,SAVFF ;SAVE F
MOVE F,T2 ;UNIQUE CODE FOR POST
OPSTR <SKIPE>,MSMS1,(T2) ;SENT THIS MESSAGE ONCE YET?
TXO T3,1B0 ;YES. TELL DRIVER OF THIS THEN
SETONE MSMS1,(T2) ;SAY SENT IT ONCE
MOVEI T2,MSHDR(T2) ;GET DATA PORTION OF MESSAGE
HRLI T2,(<POINT 8,>) ;MAKE A BYTE POINTER
HLRZM T1,SAVPST ;SAVE POSTING ADDRESS
CALL DCNMSO ;SEND THE MESSAGE
JRST [ MOVE T1,F ;FAILED. PORT MUST BE TURNED OFF.
;SET UP FOR POST IF ANY
SKIPE T2,SAVPST ;WANT A POST ON DONE?
CALL 0(T2) ;YES. DO IT THEN
JRST .+1] ;AND GO FINISH UP
MOVE F,SAVFF ;RESTORE F
RET ;AND DONE
;CONNECTION IS TO A TASK ON THIS NODE
CTLLCL: SETONE MSLCL,(T2) ;REMEMBER IS LOCAL
SKIPGE T4,NSPLPB ;IS THERE A RUNNING LOOPBACK LINE?
JRST [STOR T4,LLPRT,(T1);YES, SAY WHICH PORT
JRST SNDSG0] ;GIVE "LOCAL MESSAGE" TO DRIVER FOR LOOPBACK
CALLRET ONMSQ ;AND GO DO IT
;VARIOUS QUEUENING ROUTINES USED BY INT, SCHED, AND PROCESS LEVELS
;ROUTINE TO PUT A MESSGE ON NSPTSK'S QUEUE
RESCD
ONMSGQ: MOVEI T3,MSGQ ;GET QUEUE HEAD
CALLRET PUTONQ ;PUT DATA ON
;ROUTINE TO QUEUE UP EXPENDED MESSAGE BLOCKS FROM DTESRV
REPEAT 0,< ;NOT USED PRESETNLY
MSGPST: MOVE T2,RMSGQ ;GET OLD HEAD
MOVEM T1,RMSGQ ;MAKE NEW HEAD
STOR T2,MSLNK,(T1) ;LINK IN
RET ;AND DONE
> ;END OF REPEAT 0
;ROUTINE CALLED FROM INTERRUPT LEVEL TO PUT A MESSAGE ON THE SCHEDULER'S
;QUEUE
; T2/ DATA ADDRESS
NSPQ:: MOVEI T2,-MSHDR(T2) ;GET POINTER TO HEADER
MOVEI T3,SMSGQ ;GET QUEUE HEAD
CALLRET PUTONQ ;AND DO IT
;ROUTINE TO SEND A DATA,LS, OR INT MESSAGE
;ACCEPTS: T1/ LL BLOCK
; T2/ MESSAGE BLOCK
SWAPCD ;IS SWAPPABLE
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
CALL TSTLCL ;LOCAL CONNECTION?
JRST SNDLCL ;YES.
LPBSEG: CALL ONSEGQ ;PUT IT ON THE SEG QUEUE
SNDSE2: 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
;ROUTINE TO PUT A DATA,LS, OR INT SEGEMENT ON THE SEND Q
;ACCEPTS: T1/ LL BLOCK ADDRESS
; T2/ MESSAGE BLOCK
ONSEGQ: INCR LLQOU,(T1) ;ONE MORE ON Q
ONSGQ0: MOVEI T3,LLSEGQ(T1) ;GET HEADER
CALLRET PUTONQ ;PUT SEG ON THE Q
;LOCAL ROUTINE TO PUT MESSAGE ON INPUT QUEUE
ONMSQ: NOSKED ;NO SCHEDULING
CALL ONMSGQ ;PUT MESSAGE ON THE QUEUE
OKSKED ;AND SCHEDULING
RET ;AND DONE
;ENTRY USED TO RESEND A NACKED MESSAGE
SNDSE0: ASUBR <SNLBLK,SNMSG>
CALLRET SNDSE2 ;SEND IT
;SNDSEG CONTINUED...
;ROUTINE TO SEND SEGMENT TO A LOCAL CONNECTION
SNDLCL: SETONE MSLCL,(T2) ;SAY IS LOCAL
SKIPGE T4,NSPLPB ;IS THERE A RUNNING LOOPBACK LINE?
JRST [STOR T4,LLPRT,(T1);YES, SAY WHICH PORT
JRST LPBSEG] ;GIVE "LOCAL MESSAGE" TO DRIVER FOR LOOPING
LOAD T3,MSMFL,(T2) ;GET FLAGS
TXNE T3,DATFLI ;IS THIS AN INTERRUPT MESSAGE?
JRST SNDBAD ;YES. GO HANDLE VIA NSPTSK
LOAD T2,LLLNK,(T1) ;GET OUR I.D.
LOAD T1,LLHLK,(T1) ;GET I.D. OF OTHER PROCESS
LLLOCK ;LOCK UP THE TREE
CALL LLLKUP ;GO FIND ENTRY
JRST [ LLLULK ;RELEASE THE TREE
JRST SNDBAD ] ;NOT THERE
LLLULK ;RELEASE THE TREE
MOVE T2,SNMSG ;GET MESSAGE BLOCK
NOSKED ;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.
CALL ONRAWQ ;GO PUT ON THE QUEUE
OKSKED ;ALL DONE
JRST SNDSE1 ;GO Q IT UP ON SEG Q
;ERROR ROUTINES
SNDBA1: OKSKED
SNDBAD: MOVE T2,SNMSG ;GET MESSAGE ADDRESS
CALL ONMSQ ;PUT DATA MESSAGE ON NSPTSK'S Q
JRST SNDSE1 ;AND DONE FOR NOW
;ROUTINES USED BY INTERRUPT LEVEL TO QUEUE UP PACKETS
;PUT A DATA MESSAGE ON THE LINK'S QUEUE
; T1/ LL BLOCK ADDRESS
; T2/ MESSAGE BLOCK
RESCD ;MUST BE RESIDENT
ONRAWQ: NOSKD1 ;HOLD OFF SCHEDULER
LOAD T3,MSMFL,(T2) ;GET MESSAGE FLAGS
TXNE T3,ACKFLM ;IS IT AN ACK?
JRST [ JN LLLSA,(T1),ONRAW2 ;IN LS SEND WAIT?
JRST ONRAW1] ;NO. GO ON
OPSTR <AOS T3,>,LLDMT,(T1) ;ACCOUNT FOR ONE MORE DATA MESSAGE
LOAD T4,LLMQI,(T1) ;GET MAXIMUM INPUT QUEUE LENGTH
CAMLE T3,T4 ;TOO MANY ON Q?
JRST [ SETONE LLFNN,(T1) ;YES.
PUSH P,T1 ;SAVE LL BLOCK
MOVE T1,T2 ;GET DATA BLOCK ADDRESS
CALL RELRES ;GET RID OF IT
POP P,T1
CALL DATINR ;REQUEST INT
JRST ONRAW3] ;AND GO WRAP UP
STOR T3,LLDMT,(T1) ;NO. SAVE NEW COUNT
OPSTRM <AOS T3,>,LLDRW,(T1) ;INCREMENT DATA MESSAGE COUNT
CAIN T3,1 ;NO. IS THIS NOT THE FIRST ONE?
ONRAW2: CALL DATINR ;GIVE INT
ONRAW1: MOVE T3,LLMSG(T1) ;GET HEAD OF QUEUE
MOVEM T2,LLMSG(T1) ;STORE NEW HEAD
STOR T3,MSLNK,(T2) ;COMPLETE LINK
ONRAW3: OKSKD1
RET ;AND DONE
;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
;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
SWAPCD
ACKCHN: CALL TSTLCL ;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
TRZE T2,ACKBIT ;IS IT A NACK?
JRST [ CALL ACKCHN ;DO IT
JRST DONACK] ;AND GO DO THE NACK
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.
MOVEI T4,LLSEGQ(T1) ;THE Q ADDRESS
CALL UNQSEG ;REMOVE SEGEMENT
DECR LLQOU,(T1) ;ONE LESS SEG IN QUEUER
EXCH T1,W1 ;GET BLOCK
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: JN LLINT,(T1),[ CALL INTOUT ;IF INTERNAL LINK SEND ANY OUTPUT STILL LEFT
JFCL ;IGNORE FAILURE HERE
JRST .+1] ;CONTINUE
RET ;AND DONE
;LOCAL ROUTINE TO TAKE A SEGMENT OFF OF A SEGMENT Q
UNQSEG: JUMPE W2,[LOAD T3,MSLNK,(W1) ;IS HEAD
HRRM T3,0(T4) ;MAKE NEW HEAD
SKIPN T3 ;NOW EMPTY?
SETZM 0(T4) ;YES
RET] ;AND DONE
LOAD T3,MSLNK,(W1) ;GET LINK
STOR T3,MSLNK,(W2) ;REMOVE FROM Q
SKIPN T3 ;REMOVING THE TAIL?
HRLM W2,0(T4) ;YES. MAKE NEW TAIL THEN
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 [ CALL INCMSM ;YES. ACCOUNT FOR THE NACK
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
TXNE T3,DATEOM ;IS THIS THE EOM?
CALL INCMSM ;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.
CALL DECMSM ;YES. COUNT DOWN
DONRES: MOVE T2,W1 ;GET SEG
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
;**;[2607] ADD 1 LINE AT DONRQ:+3L PED 4-APR-82
ENDAV. ;[2607] END ACVAR
;ROUTINE TO PUT A DATA MESSAGE ON A SEGMENT Q
; T2/ THE MESSAGE
; T3/ THE QUEUE ADDRESS
;CLOBBERS T4
RESCD
PUTONQ: SKIPN T4,0(T3) ;HAVE A QUEUE?
JRST [ HRRM T2,0(T3) ;NO MAKE ONE
HRLM T2,0(T3)
JRST PUTOND] ;DONE
HLRZS T4 ;GET TAIL
STOR T2,MSLNK,(T4) ;LINK THIS IN
HRLM T2,0(T3) ;AND MAKE IT THE TAIL
PUTOND: SETZRO MSLNK,(T2) ;TIE IT OFF
RET ;AND DONE
;ROUTINE TO RESEND NACK'ED SEGMENTS
;ACCEPTS: T1/ BLOCK ADDRESS
; BLOCK MUST BE LOCKED
RESEND: JE LLQUN,(T1),R ;ANY NAKED SEGS?
JN LLBRP,(T1),R ;YES. IS FLOW ON?
JE LLMFC,(T1),RSEND0 ;IF NO FLOW CONTROL, GO RESEND NOW
LOAD T3,LLMSM,(T1) ;GET COUNT
SKIPE T3 ;IF ZERO
TXNE T3,200 ;OR IF NEG
RET ;CAN'T RESEND
RSEND0: HRRZ T2,LLSEGQ(T1) ;GET HEAD OF Q
RSEND1: OPSTR <SKIPN>,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
TXNE T3,DATEOM ;IS THIS EOM?
RSEND2: CALL DECMSM ;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,LLMSG,LLOMSG
; T1/ LL BLOCK LL TREE MUST BE LOCKED
;RETURNS +1 ALWAYS
SWAPCD
FLUSH:: SETZRO <LLQUN,LLQOU>,(T1) ;CLEAR COUNTS
MOVEI T2,LLOMSG(T1) ;GET ORDERED QUEUE
CALL PRUNE ;KILL IT
MOVEI T2,LLMSG(T1) ;GET ORDERED Q
CALL PRUNE ;KILL IT
MOVEI T2,LLMSI(T1) ;INT MESSAGES
CALL PRUNE ;KILL THIS AS WELL
MOVEI T2,LLSEGQ(T1) ;GET SENT Q
CALLRET PRUNE ;GET RID OF THEM
;WORKER ROUTINE TO FLUSH A LINK Q
PRUNE: SAVET ;SAVE ALL REGS
HRRZ T1,0(T2) ;GET HEAD
SETZM 0(T2) ;CLEAR Q
PRUNE1: JUMPE T1,R ;IF AT THE END, DONE
LOAD T2,MSLNK,(T1) ;GET NEXT
PUSH P,T2 ;SAVE IT
;**;[1925] Change 1849 lines at PRUNE1: +3L JGZ 19-AUG-81
;**;[1849] Change one line at PRUNE1: +3L DAD 15-Apr-81
JN MSPST,(T1),CHKPST ;[1849] 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.
RESCD
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
SWAPCD ;BACK TO SWAPPABLE MONITOR
;ROUTINE TO SEND AN ACK MESSAGE.
; T1/ LL BLOCK
; T2/ SEGMENT # TO ACK
; T3/ SUBCHANNEL TO ACK
;RETURNS +1 ALL REGS PRESERVED
SNDACK: ASUBR <LLBLK,ACKNO,ACKTYP>
NSBP09: CALL TSTLCL ;SEE IF A LOCAL CONNECTION
JRST [ SKIPGE NSPLPB ;YES, IS THERE A RUNNING LOOPBACK LINE?
JRST ACKRMT ;YES, GIVE MESSAGE TO DRIVER
JE LLCIL,(T1),RSKP ;NO, DONE IF NOT CONNECTED TO INTERNAL LINK
CALL SKDOUT ;INTERNAL LINK, SCHEDULE OUTPUT
RETSKP ] ;DONE, RETURN
JRST ACKRMT ;NEED TO SEND A MESSAGE
;HANDLE LOCAL ACK
;THIS CODE HAS BEEN REMOVED AS IT IS NO LONGER NECESSARY.
;NOTE, THERE IS A BUG IN IT ANYWAY,AS A FAILURE TO LOCK THE
;OTHER BLOCK WILL CAUSE CONFUSION IN NETSET. IF THIS CODE
;IS EVER TURNED ON AGAIN, THEN CHKFRE MUST INCLUDE A CHECK
;FOR LOCK FAILURE AS WELL AS FREE SPACE FAILURE. ASM
REPEAT 0,<
LOAD T2,LLLNK,(T1)
LOAD T1,LLHLK,(T1) ;GET OTHER ONE'S ADDRESS
LLLOCK ;LOCK THE TREE
CALL LLLKUP ;GO LOOK UP MATCHER
JRST ACKLO2 ;NOT THERE. THIS WILL GET FIXED
LOAD T2,LLSTA,(T1) ;GET CURRENT STATE?
CAIE T2,LLSRUN ;RUNNING
CAIN T2,LLSDIQ ;OR DI QUEUED?
JRST ACKLO1 ;IS GOOD
ACKLO2: LLLULK ;FREE TREE
ACKLO3: MOVE T1,LLBLK ;RETURN LL BLOCK ADDRESS
RETSKP ;AND RETURN
ACKLO1: CALL BLKLOK ;LOCK THE BLOCK
JRST [ LLLULK ;FAILED
RET] ;TRY AGAIN LATER
LLLULK ;FREE TREE
MOVE T2,ACKNO ;GET NUMBER
MOVE T3,ACKTYP ;AND THE TYPE
CALL ACKCHN ;GO DO THE ACK
CALL BLKULK ;UNLOCK THE BLOCK
JRST ACKLO3 ;AND GO WRAP UP
> ;END OF REPEAT 0
;ROUTINE TO ACK THE LS/INT CHANNEL
ACKLI: LOAD T2,LLIIN,(T1) ;GET SEG TO ACK
MOVEI T3,MSLSI ;THE CHANNEL I.D.
CALLRET SNDACK ;SEND ACK
;SNDACK CONTINUED.....
;SEND ACK TO REMOTE NODE.
ACKRMT: STKVAR <MSGBL> ;PLACE TO SAVE MESSAGE BLOCK
MOVEI T1,ACKLEN+MSHDR ;LENGTH REQUIRED
CALL GETRES ;GET IT
CALLRET TIMWAT ;FAILED
MOVEM T1,MSGBL ;SAVE BLOCK ADDRESS
MOVE T2,T1
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.
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
;[2633] Make node number an extensible field at NODINI: +20L CLB 21-JUL-82
MOVE T3,OURNUM ;[2633] GET LOCAL NUMBER
CALL MAKEXT ;[2633] Stash it extensibly
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,SEGSIZ ;OUR SEG SIZE
CALL TWOBYT
MOVEI T2,SEGSIZ ;OUR NSP 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
CALL SNDSG0 ;SEND IT
MOVE T1,NODPRT ;GET PORT NUMBER
SETONE INISNT,MCBDTE(T1) ;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
CALL ONEBYT
;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
CALLRET SNDSG0 ;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>
CALL TSTLCL ;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
LOAD T2,LLISN,(T1) ;GET SEG #
AOS T2 ;NEXT ONE
ANDI T2,7777
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) ;""
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
;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
NOSKED
CAIE T3,MSDAT ;DATA
JRST [ OPSTRM <ADDM T2,>,LLMIC,(T1) ;NO
JRST SNDLS1] ;GO WRAP UP
OPSTRM <ADDM T2,>,LLMSM,(T1) ;YES
SNDLS1: OKSKED
LLLULK ;FREE TREE
JE LLINT,(T1),RSKP ;SENDER OF LS CONNECTED TO AN INTERNAL LINK ?
CALL SKDOUT ;YES, NOTE CAN SEND MORE NOW
RETSKP ;DONE
;ROUTINES CALLED FROM INT LEVEL TO GET AND QUEUE UP BUFFERS
;GET A BUFFER
; T1/ PORT # (E.G. DTE#)
; T2/ # OF BYTES REQUIRED
;RETURNS:
; +1 COULDN'T GET BLOCK
; +2 T1=BLOCK ADDRESS.
RESCD
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 I.D.
STOR T2,MSPRT,(T1) ;SAVE IT
MOVE T2,PRTCNT ;GET COUNT OF BYTES IN MESSAGE
STOR T2,MSCNT,(T1) ;SAVE IT
ADDI T1,MSHDR ;POINT TO DATA PORTION
RETSKP ;AND RETURN WITH BLOCK
SUBTTL NSP Background Task - Output on Internal Links
;OUTSND - ROUTINE TO CHECK "OUTPUT REMAINING" QUEUE AND SEND ANY REMAINING DATA
;
; CALLED PERIODICALLY FROM NSP BACKGROUND TASK DISPATCHER (NSPTSK)
SWAPCD
OUTSND: SAVEPQ
SETZM OUTTIM ;RESET TIME AT WHICH TASK SHOULD AWAKEN
LOCK OUTLOK ;LOCK THE QUEUE WHILE PROCESSING ENTRIES
HRRZ Q1,OUTQUE ;GET ADR OF FIRST LINK BLOCK TO PROCESS
MOVEI Q2,0 ;INITIALIZE "PREVIOUS BLOCK" ADDRESS
; LOCK THE LOGICAL LINK BLOCK AND SEND REMAINING OUTPUT
OUTCK0: JUMPE Q1,[UNLOCK OUTLOK ;IF END OF QUEUE, UNLOCK THE QUEUE
RET] ; AND RETURN
MOVE T1,Q1 ;GET ADR OF CURRENT LOGICAL LINK BLOCK
CALL BLKLOK ;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
SKDOUT::SAVET
MOVE T4,TODCLK ;GET CURRENT TIME
ADD T4,OUTIVL ;GET TIME INTERVAL TO WAIT BEFORE TRYING AGAIN
MOVEM T4,OUTTIM ;SCHEDULE WAKEUP AT LATER TIME
RET ;DONE, RETURN
;INTOUT - ROUTINE TO PERFORM OUTPUT FOR AN INTERNAL LINK
;
;ACCEPTS IN T1/ ADDRESS OF LOGICAL LINK BLOCK
; CALL INTOUT
;RETURNS: +1 FAILED, MORE OUTPUT WILL HAVE TO BE DONE LATER
; +2 SUCCESS, ALL REMAINING OUTPUT HAS BEEN SENT
;
; ASSUMES LOGICAL LINK BLOCK IS LOCKED. PRESERVES LINK BLOCK ADR IN T1
INTOUT: ASUBR <INOLLB>
; PROCESS ANY OUTSTANDING ACK'S FOR THIS LINK
MOVE T1,INOLLB ;GET LOGICAL LINK BLOCK ADDRESS
CALL MOVSEG ;PROCESS OUTSTANDING ACK'S
RET ;FAILED, TRY AGAIN LATER
MOVE T1,INOLLB ;GET LOGICAL LINK BLOCK ADDRESS
JE LLOCT,(T1),RSKP ;IF NO DATA LEFT, ALL DONE
; CHECK TO SEE IF THERE IS ANY MORE OUTPUT TO SEND
INO020: MOVE T1,INOLLB ;GET ADDRESS OF LOGICAL LINK BLOCK
JN LLOCT,(T1),INO025 ;IF DATA LEFT, GO TRY TO SEND IT
MOVE T1,INOLLB ;GET LOGICAL LINK BLOCK ADDRESS
CALL TELOBE ;GO TELL DRIVER THAT OUTPUT BUFFER NOW EMPTY
MOVE T1,INOLLB ;GET ADDRESS OF LOGICAL LINK BLOCK
CALL TELOOK ;GO ADVISE DRIVER OUTPUT CAN BE DONE
MOVE T1,INOLLB ;RESTORE LOGICAL LINK BLOCK ADDRESS
RETSKP ;DONE, RETURN
;CHECK TO SEE IF ANY SEGMENTS CAN BE SENT NOW
INO025: MOVE T1,INOLLB ;GET LOGICAL LINK BLOCK ADDRESS
CALL SNDCHK ;CAN ANY SEGMENTS BE SENT ?
RET ;NO, TRY AGAIN LATER
MOVE T1,INOLLB ;YES, GET LOGICAL LINK BLOCK ADDRESS
CALL OUTSEG ;SEND THE SEGMENT
RET ;FAILED, TRY AGAIN LATER
JRST INO020 ;CHECK TO SEE IF ANOTHER SEGMENT CAN BE SENT
;TELOOK - ROUTINE TO CHECK TO SEE IF NECESSARY TO NOTIFY DRIVER THAT
; OUTPUT MAY NOW BE SENT
;
;ACCEPTS IN T1/ ADDRESS OF LOGICAL LINK BLOCK
; CALL TELOOK
;RETURNS: +1 ALWAYS, DRIVER NOTIFIED THRU FUNCTION VECTOR IF NEEDED
TELOOK: JE LLNDO,(T1),R ;RETURN IF DRIVER DOES NOT NEED NOTIFICATION
SETZRO LLNDO,(T1) ;NO LONGER NEED NOTIFICATION FLAG LIT
LOAD T4,LLVEC,(T1) ;GET DRIVER FUNCTION VECTOR ADDRESS
MOVX T2,.NSOMO ;GET "OUTPUT CAN BE SENT" TYPE CODE
LOAD T1,LLDRV,(T1) ;GET DRIVER'S CORRELATION CODE
CALLRET @.NSOOK(T4) ;NOTIFY DRIVER AND RETURN
;TELOBE - ROUTINE TO NOTIFY THE DRIVER THAT AN OUTPUT BUFFER IS NOW EMPTY
;
;ACCEPTS IN T1/ ADDRESS OF LOGICAL LINK BLOCK
; CALL TELOBE
;RETURNS: +1 ALWAYS, WITH DRIVER NOTIFIED THRU ITS FUNCTION VECTOR
TELOBE::ASUBR <OBELLB>
LOAD T4,LLVEC,(T1) ;DATA SENT, GET DRIVER FCN VECTOR ADR
LOAD T2,LLBFO,(T1) ;GET DRIVER'S BUFFER ADDRESS
LOAD T1,LLDRV,(T1) ;GET DRIVER CORRELATION CODE
CALL @.NSOBE(T4) ;TELL DRIVER IT CAN HAVE BUFFER BACK
MOVE T1,OBELLB ;GET LOGICAL LINK BLOCK ADDRESS
SETZRO LLBFO,(T1) ;NOTE THAT BUFFER IS NOW GONE
RET ;DONE, RETURN.
SUBTTL Scheduler Interface
;ROUTINE TO QUEUE UP A RECEIVED MESSAGE.
; T1/ BLOCK ADDRESS
RESCD
NSPMSG::TRVAR <MSGCNT,MSGBYP,MSGSRC,MSGDST,MSGBLK,NAKFLG>
MOVEI T2,MSHDR(T1) ;GET TO DATA PORTION
MOVEM T1,MSGBLK ;SAVE BLOCK ADDRESS
HRLI T2,(<POINT 8,>)
MOVEM T2,MSGBYP ;SAVE BYTE POINTER
LOAD T1,MSCNT,(T1) ;GET BYTE COUNT
MOVEM T1,MSGCNT ;SET UP COUNT
CALL GETBYT ;GET FIRST BYTE
JRST NSPMSE ;ERROR
TRNE T2,201 ;A ROUTINE HEADER?
JRST NSPMSE ;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 NSPMSE ;NO
CALL SKPFLD ;SKIP HOST NAME
JRST NSPMSE ;SOMETHING WRONG
CALL SKPFLD ;SKIP OTHER HOST NAME
JRST NSPMSE ;SOMETHING WRONG
CALL GETBYT ;GET FLAGS
JRST NSPMSE ;BAD MESSAGE
NSPMS1: MOVE T1,MSGBLK ;GET BLOCK
STOR T2,MSMFL,(T1) ;SAVE FLAGS
SETZM NAKFLG ;ASSUME NOT AN ACK OR NACK
TRNN T2,ACKFLM!CNMRFL!ACKLSI ;IS IT A DATA SEGMENT?
JRST NSPMS2 ;YES. KEEP IT THEN
TRNN T2,ACKFLM ;NO. IS IT AN ACK OR NACK?
JRST NSPMSE ;NO. IS CONTROL, LS, OR INT MESSAGE
AOS NAKFLG ;YES. NOTE THAT
NSPMS2: CALL GETLLA ;YES. GET LINK NUMBERS
JRST NSPMSE ;BAD MESSAGE
; ..
; ..
; MESSAGE PARSED - PLACE MESSAGE ON APPROPRIATE QUEUE FOR LATER HANDLING
MOVE T1,MSGDST ;GET OUR NAME
MOVE T2,MSGSRC ;GET ITS NAME
CALL LLLKUP ;FIND THE LINK
JRST NSPMSE ;COULDN'T.
JN LLINT,(T1),NSPMSE ;IF INTERNAL LINK, PUT MESSAGE ON TASKS'S QUEUE
LOAD T2,LLSTA,(T1) ;GOT IT. GET STATE
CAIE T2,LLSRUN ;RUNNING?
JRST NSPMSE ;NO
MOVE T2,MSGBLK ;YES.
MOVE T3,MSGCNT ;GET REMAINING COUNT
STOR T3,MSDTC,(T2) ;SAVE RESIDUAL COUNT
MOVE T3,MSGBYP
MOVEM T3,MSBPTR(T2) ;SAVE RESIDUAL BYTE POINTER
SKIPE NAKFLG ;IS THIS AN ACK OR NACK?
JRST [ CALL GETTWO ;YES. GET ACKNUM FIELD
JRST NSPMSE ;BAD MESSAGE
TRNE T2,ACKBIT ;A NACK?
JRST NSPMSE ;YES. GIVE IT TO NSPTSK
MOVE T2,MSGBLK ;NO, MUST RESTORE MESSAGE BLOCK ADDRESS
JRST .+1] ;GO ON
CALLRET ONRAWQ ;AND PUT IT ON LINK'S Q
NSPMSE: MOVE T2,MSGBLK ;GET BLOCK ADDRESS
CALLRET ONMSGQ ;PUT IN ON THE TASK'S Q
;ROUTINE CALLED BY THE SCHEDULER EVERY 20 MS TO PROCESS MESSAGES
;ARRIVED FROM THE NETWORK
NSPCH7::ACVAR <W1> ;GET A WORK REG
MOVEI W1,12 ;DO A LIMITED # PER PASS
NSPCH0: SKIPN T1,SMSGQ ;ANY MESSAGE TO DO?
RET ;NO. ALL DONE
CHNOFF DLSCHN ;TURN OFF NETWORK
HRRZS T1 ;GET HEAD POINTER
LOAD T2,MSLNK,(T1) ;GET POINTER
HRRM T2,SMSGQ ;NEW HEAD
SKIPN T2 ;ANY MORE IN THE Q?
SETZM SMSGQ ;NO
CHNON DLSCHN ;TURN ON NET
CALL NSPMSG ;GO PROCESS THE MESSAGE
SOJGE W1,NSPCH0 ;GO DO MORE
RET ;ALL DONE
;**;[2607] ADD 1 LINE AT NSPCH0:+12.L PED 4-APR-82
ENDAV. ;[2607] END ACVAR
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
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
RETSKP ;SUCCESS RETURN
;NDGLN - RETURN LOCAL NODE NAME
NDGLN: UMOVE T2,2 ;GET ADDRESS OF USER'S ARGUMENT BLOCK
UMOVE T1,.NDNOD(T2) ;GET POINTER TO WHERE NODE NAME IS TO GO
MOVEI T3,.NDNOD(T2) ;GET ADDRESS TO RETURN UPDATED POINTER
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: UMOVE T2,2
UMOVE T2,0(T2) ;GET NUMBER
CAIL T2,2
CAILE T2,177 ;WITHIN RANGE?
RETBAD() ;NO
MOVEM T2,OURNUM ;SET IT
RETSKP ;DONE
;GET LOCAL NODE NUMBER
NDGNM: UMOVE T2,2
MOVE T3,OURNUM
UMOVEM T3,0(T2) ;STORE NUMBER
RETSKP ;DONE
;SET LOOPBACK PORT
NDSLP: MOVE T1,CAPENB ;GET CURRENTLY ENABLED CAPABILITIES
TXNN T1,SC%WHL!SC%OPR!SC%MNT ;WHEEL OPERATOR OR MAINTENANCE CAPABILITY REQUIRED
RETBAD (CAPX2) ;WHEEL, OPERATOR, or MAINTENANCE capability required
UMOVE T2,2 ;GET ADDRESS OF USERS ARGUMENT BLOCK
UMOVE T3,.NDPRT(T2) ;GET PORT WANTS TO SET IN LOOPBACK
SKIPE T2,NSPLPB ;IS ANOTHER PORT ALREADY ASSIGNED ?
JRST [ CAIE T3,(T2) ;IS IT SAME PORT ?
RETBAD (NODX03) ;Another line already looped
RETSKP ] ;ALL DONE
MOVEI T1,.BTSTS ;WANT TO GET PORT STATUS
MOVEI T2,T3 ;ADDRESS OF ARGUMENT BLOCK
BOOT ;GET ARGUMENT STATUS
ERJMP [RETBAD (ARGX19)] ;Invalid unit number
CAME T4,[EXP -1] ;IS PORT TURNED OFF
RETBAD (NODX02) ;Line not turned off
HRLI T3,(ND%LPA) ;HAVE A PORT FOR LOOPBACK NOW
MOVEM T3,NSPLPB ;REMEMBER WHICH PORT WILL BE LOOPED
RETSKP
;CLEAR LOOPBACK PORT
NDCLP: MOVE T1,CAPENB ;GET CURRENTLY ENABLED CAPABILITIES
TXNN T1,SC%WHL!SC%OPR!SC%MNT ;WHEEL OPERATOR OR MAINTENANCE CAPABILITY REQUIRED
RETBAD (CAPX2) ;WHEEL, OPERATOR, or MAINTENANCE capability required
SKIPN T1,NSPLPB ;GET LOOPBACK PORT NUMBER
RETSKP ;NONE SO DONE
UMOVE T2,2 ;GET ADDRESS OF USERS ARGUMENT BLOCK
UMOVE T3,.NDPRT(T2) ;GET PORT TO CLEAR LOOPBACK
CAIE T3,(T1) ;SAME PORT AS IS LOOPED BACK ?
RETBAD (ARGX19) ;Invalid unit number
MOVEI T1,.BTTPR ;TERMINATE PROTOCOL
MOVEI T2,T3 ;ADDRESS OF ARGUMENT BLOCK
BOOT ;DISABLE LINE
ERJMP .+1 ;CAN'T TURN OFF ?
SETZM NSPLPB ;NOTHING IS LOOPED BACK NOW
RETSKP
;FIND LOOPBACK PORT
NDFLP: UMOVE T2,2 ;GET ADR OF USERS ARGUMENT BLOCK
MOVE T1,NSPLPB ;GET LOOPED BACK LINE
UMOVEM T1,.NDPRT(T2) ;GIVE ANSWER TO USER
RETSKP
; SET NETWORK TOPOLOGY INFO
NDSNT: STKVAR <<SNTBLK,MAXNOD>,SNTCNT>
; CHECK CAPABILITIES
MOVE T1,CAPENB ;GET CURRENTLY ENABLED CAPABILITIES
TXNN T1,SC%WHL!SC%OPR ;WHEEL, OPERATOR CAPABILITY REQUIRED
RETBAD (CAPX1) ;WHEEL OR OPERATOR capability required
; CHECK NUMBER OF ITEMS TO BE ENTERED AND COPY POINTERS TO NODE BLOCKS
UMOVE T2,2 ;GET ADDRESS OF USER'S ARGUMENT BLOCK
UMOVE T1,.NDCNT(T2) ;GET NUMBER OF ITEMS SUPPLIED IN NODE BLOCKS
CAIGE T1,.NDNXT+1 ;AT LEAST NAME, STATE, AND NEIGHBOR REQUIRED
RETBAD (ARGX17) ;FAIL, NODE BLOCKS TOO SMALL
UMOVE T1,.NDNND(T2) ;GET NUMBER OF NODES TO BE ENTERED
CAIL T1,0 ;WITHIN VALID
CAILE T1,MAXNOD ; RANGE ?
RETBAD (ARGX17) ;NO, INVALID ARGUMENT BLOCK LENGTH
MOVEM T1,SNTCNT ;SAVE NUMBER OF NODES TO BE ADDED
ADDI T2,.NDBK1 ;POINT TO FIRST WORD TO BE MOVED
MOVEI T3,SNTBLK ;GET ADDRESS OF BLOCK TO HOLD POINTERS
CALL BLTUM1 ;COPY POINTERS TO NODE BLOCKS
; LOOP, ADDING EACH NODE TO THE TABLE OF KNOWN NODES
XMOVEI Q1,SNTBLK ;GET ADDRESS OF BLOCK OF POINTERS
MOVE Q2,Q1 ;COPY STARTING ADDRESS OF BLOCK
ADD Q1,SNTCNT ;COMPUTE FIRST ADR PAST END OF BLOCK
NDSN10: CAML Q2,Q1 ;ANOTHER NODE TO ADD ?
RETSKP ;NO, DONE
MOVE T1,(Q2) ;GET POINTER TO NODE BLOCK IN USER SPACE
CALL INSNOD ;INSERT NODE IN TABLE OF KNOWN NODES
RETBAD () ;FAILED
ADDI Q2,1 ;POINT TO NEXT ITEM IN ARG BLOCK
JRST NDSN10 ;LOOP OVER ALL ENTRIES IN TABLE
; 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 (MONX01) ;SHOW WE HAVE NO MORE ROOM
STOR T1,NTCCHN,(T4) ;SAVE THE CHANNEL NUMBER
MOVE T1,FORKX ;NOW GET THE FORK NUMBER
STOR T1,NTCFRK,(T4) ;AND SAVE
SETONE FKNTC,(T1) ;FLAG IN FORK DATA BASE
RETSKP
;NDCIC - CLEAR INTERRUPT CHANNEL FOR NETWORK TOPOLOGY CHANGE
NDCIC:
NTCOFF::MOVEI T1,NTCTAB ;FIND THE FORK'S ENTRY
NDCIC1: LOAD T2,NTCFRK,(T1) ;GET THE FORK NUMBER FOR THIS ENTRY
CAMN T2,FORKX ;THIS FORKS ENTRY
JRST [ SETZM (T1) ;CLEAR ENTRY
MOVE T1,FORKX ;GET FORK INDEX
SETZRO FKNTC,(T1) ;CLEAR THE ITEM IN FORK DATA BASE
RETSKP]
CAIE T1,NTCTAB+<NTCMAX-1> ;AT END OF TABLE
AOJA T1,NDCIC1 ;NO - KEEP LOOKING
RETSKP ;INDICATE SUCCESS EVEN WHEN NEVER SET
;NDGVR - GET NSP VERSION INVORMATION
NDGVR: UMOVE T3,T2 ;GET THE USER BLOCK POINTER
MOVX T2,2 ;GET NUMBER OF VERSIONS TO RETURN
UMOVEM T2,.NDNVR(T3) ;STORE IN USER ARGUMENT BLOCK
UMOVE T1,.NDCVR(T3) ;GET THE ADDRESS OF THE COMMUNICATION BLOCK
MOVEI T2,COMVER ;COMMUNICATION VERSION NUMBER
UMOVEM T2,.NDVER(T1) ;SAVE IN USER SPACE
MOVEI T2,COMECO ;COMMUNICATION ECO
UMOVEM T2,.NDECO(T1) ;SAVE IN USER SPACE
MOVEI T2,COMCST ;GET THE CUSTOMER CHANGE NUMBER
UMOVEM T2,.NDCST(T1) ;SAVE IN USER SPACE
;NOW GIVE USER THE ROUTING VERSION INFORMATION
UMOVE T1,.NDRVR(T3) ;GET THE ADDRESS OF THE ROUTING BLOCK
MOVEI T2,ROUVER ;ROUTING VERSION NUMBER
UMOVEM T2,.NDVER(T1) ;SAVE IN USER SPACE
MOVEI T2,ROUECO ;ROUTING ECO
UMOVEM T2,.NDECO(T1) ;SAVE IN USER SPACE
MOVEI T2,ROUCST ;GET THE CUSTOMER CHANGE NUMBER
UMOVEM T2,.NDCST(T1) ;SAVE IN USER SPACE
RETSKP ;RETURN
;INSNOD - ROUTINE TO INSERT NODE INTO TABLE OF KNOWN NODES
;
;ACCEPTS IN T1/ ADDRESS OF NODE BLOCK IN USER SPACE
; CALL INSNOD
;RETURNS: +1 FAILED
; +2 SUCCESS, NODE ADDED IF NOT ALREADY IN TABLE
INSNOD: ASUBR <INDBLK,INDSTA,INDADR,INDERR>
MOVE T4,INDBLK ;GET ADDRESS OF NODE BLOCK
UMOVE T2,.NDNAM(T4) ;GET ADDRESS OF NODE NAME STRING
ERJMP R ;FAILED
JUMPE T2,R ;FAIL IF NO NAME SPECIFIED
UMOVE T1,.NDSTA(T4) ;GET NODE STATE
ERJMP R ;FAIL IF NON-EX USER PAGE
MOVEM T1,INDSTA ;SAVE STATE
MOVX T1,2*<<NODMAX+12>/5> ;ASSIGN SPACE FOR NODE NAME
NOINT
CALL ASGSWP ;GET SOME SPACE
RETBAD () ;FAILED
MOVEM T1,INDADR ;SAVE ADDRESS OF BLOCK
MOVE T2,INDBLK ;GET BACK ADDRESS OF NODE BLOCK
UMOVE T2,.NDNAM(T2) ;GET ADDRESS OF NODE NAME STRING
ERJMP INSERR ;FAIL IF NON-EX USER PAGE
MOVX T3,NODMAX ;MAX # OF CHARS IN NODE NAME
CALL CPYFU2 ;GET STRING FROM USER
JRST INSERR ;ERROR - HANDLE
MOVE T1,INDADR ;GET ADDRESS OF BUFFER
ADDI T1,<NODMAX+12>/5 ;POINT TO SECOND SLOT
MOVE T2,INDBLK ;GET ADDRESS OF BLOCK
UMOVE T2,.NDNXT(T2) ;GET ADDRESS OF NEIGHBOR NODE NAME STRING
ERJMP INSERR ;FAIL IF NON-EX USER PAGE
JUMPE T2,INSND1 ;NO NEIGHBOR - NO NEED TO COPY
MOVX T3,NODMAX ;MAX # OF CHARS IN NODE NAME
CALL CPYFU2 ;GET STRING FROM USER
JRST INSERR ;ERROR - HANDLE
SETOM T2 ;SHOW THERE EXISTS A NEIGHBOR
INSND1: MOVE T1,INDADR ;GET ADDRESS OF BUFFER
AOS T1 ;POINT TO START OF MESSAGE
SKIPE T3,T2 ;MAKE T3 ZERO IF NO NEIGHBOR
MOVEI T3,<<NODMAX+12>/5>(T1) ;POINT TO NEIGHBOR NAME
MOVE T2,INDSTA ;RESTORE STATE
CALL ADDNOD ;ADD NODE TO TABLE OF KNOWN NODES
JRST INSERR ;ERROR - HANDLE
OKINT
RETSKP ;DONE, RETURN
INSERR: MOVEM T1,INDERR ;SAVE ERROR CODE
MOVE T1,INDADR ;ADDRESS OF BLOCK
CALL RELMES ;RELEASE THE BLOCK
INSER1: MOVE T1,INDERR ;RESTORE ERROR CODE
OKINT
RETBAD () ;FAIL
; GET NETWORK TOPOPLOGY INFORMATION
NDGNT: STKVAR <<GNTBLK,MAXNOD>,GNTCNT>
; SET UP TO LOOP OVER EACH NODE
UMOVE T4,2 ;GET ADDRESS OF USER'S ARGUMENT BLOCK
UMOVE T1,.NDNND(T4) ;GET NUMBER OF WORDS IN BLOCK
ADD T1,T4 ;COMPUTE LAST ADDRESS TO USE
MOVEM T1,GNTCNT ;SAVE LAST ADDRESS IN USER SPACE TO STORE INTO
MOVEI Q1,.NDBK1(T4) ;SET UP ADDRESS OF NEXT POINTER TO USE
MOVE T2,NODTBL ;GET ADDRESS OF KNOWN NODE TABLE
JUMPE T2,RSKP ;IF NO NODE LIST, THEN DONE
HLRZ T3,(T2) ;GET NUMBER OF ITEMS IN KNOWN NODE TABLE
JUMPE T3,RSKP ;IF NONE, THEN ALL DONE
MOVE Q2,Q1 ;COPY STARTING ADDRESS OF NODE BLOCK POINTERS
ADD Q2,T3 ;COMPUTE STARTING ADDRESS OF NODE BLOCK AREA
CAMLE Q2,GNTCNT ;ENOUGH ROOM FOR ALL THE NODE BLOCK POINTERS ?
RETBAD (ARGX04) ;NO, FAIL
XCTU [HRLM T3,.NDNND(T4)] ;YES, STORE COUNT OF ITEMS RETURNED
MOVN Q3,T3 ;COMPUTE -NUMBER OF NODES
HRLZ Q3,Q3 ;FORM AOBJN POINTER TO NODE TABLE
HRRI Q3,1(T2) ;FORM AOBJN POINTER TO FIRST ENTRY
MOVX T1,.NDNBS ;GET SIZE OF A NODE BLOCK
UMOVEM T1,.NDCNT(T4) ;STORE IN USER ARG BLOCK
; LOOP OVER EACH KNOWN NODE
NOINT ;DO NOT PERMIT INTERRUPTS WITH LOCK LOCKED
LOCK NODLOK ;LOCK THE TABLE
NDGN10: UMOVEM Q2,(Q1) ;STORE POINTER TO NODE BLOCK
ERJMP NDGNX ;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 [ MOVX T1,ARGX04 ;NO, GET "ARG BLOCK TOO SMALL" CODE
JRST NDGNX ] ;RETURN ERROR TO USER
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
HLRZ T1,(Q3) ;GET ADDRESS OF NODE NAME STRING
HRLI T1,(POINT 7,) ;FORM POINTER TO NODE NAME
CALL STONOD ;STORE NODE NAME STRING IN USER SPACE
JRST NDGNX ;FAILED
ADDI Q1,1 ;INCREMENT ADDRESS OF NEXT NODE BLOCK POINTER
HRRI Q2,1(T3) ;GET ADDRESS OF NEXT NODE BLOCK
AOBJN Q3,NDGN10 ;LOOP OVER EACH NODE NAME TO BE RETURNED
; HERE WHEN ALL INFO RETURNED TO USER - STORE COUNT OF ITEMS RETURNED
NDGN30: UNLOCK NODLOK ;UNLOCK THE NODE TABLE
OKINT ;PERMIT INTERRUPTS AGAIN
NDGN40: RETSKP ;DONE, RETURN SUCCESS
; HERE ON AN ERROR
NDGNX: UNLOCK NODLOK ;UNLOCK NODE TABLE
OKINT ;PERMIT INTERRUPTS AGAIN
RET ;FAIL
; GET LINE INFORMATION INFORMATION
NDGLI: STKVAR <<LITBLK,MAXNOD>,LITCNT>
; SET UP TO LOOP OVER EACH NODE
XCTU [ HRRZ T2,2] ;GET ADDRESS OF USER'S ARGUMENT BLOCK
XCTU [ HRRZ T1,.NDNLN(T2)] ;GET NUMBER OF WORDS IN BLOCK
ADD T1,T2 ;COMPUTE LAST ADDRESS TO USE
MOVEM T1,LITCNT ;SAVE LAST ADDRESS IN USER SPACE TO STORE INTO
MOVEI Q1,.NDNLN+1(T2) ;SET UP ADDRESS OF NEXT POINTER TO USE
MOVEI T3,DCN ;GET MAXIMUM NUMBER OF POSSIBLE LINES
JUMPE T3,[SETZM T4 ;IF NO INFO, RETURN 0
JRST NDLI40 ] ; IN THE USER ARGUMENT BLOCK
UMOVE T4,2 ;GET ADDRESS OF USER'S ARGUMENT BLOCK
XCTU [HRLM T3,.NDNLN(T4)] ;STORE COUNT OF ITEMS RETURNED
MOVE Q2,Q1 ;COPY STARTING ADDRESS OF LINE BLOCK POINTERS
ADD Q2,T3 ;COMPUTE STARTING ADDRESS OF LINE BLOCK AREA
CAMLE Q2,LITCNT ;ENOUGH ROOM FOR ALL THE LINE BLOCK POINTERS ?
RETBAD (ARGX04) ;NO, FAIL
MOVN Q3,T3 ;COMPUTE -NUMBER OF LINES
HRLZ Q3,Q3 ;FORM AOBJN POINTER TO LINE TABLE
; LOOP OVER EACH KNOWN LINE
NDLI10: UMOVEM Q2,(Q1) ;STORE POINTER TO LINE BLOCK
MOVEI T1,.NDLSZ+2(Q2) ;COMPUTE ADDRESS AFTER THIS LINE BLOCK
CAMLE T1,LITCNT ;ENOUGH ROOM FOR THIS LINE BLOCK AND NAME ?
RETBAD(ARGX04) ;NO, FAIL
MOVEI T1,.BTSTS ;USE BOOT JSYS TO GET STATUS OF LINE
MOVEI T2,3 ;HAVE IT PUT DATA IN AC'S
HRRZ T3,Q3 ;GET LINE NUMBER
UMOVEM T3,.NDLNM(Q2) ;SAVE THE PORT NUMBER
BOOT
ERJMP [ MOVE T1,LSTERR ;GET THE LAST ERROR MESSAGE
RETBAD()]
MOVEI T3,.NDLON ;TRANSLATE BOOT CODE TO NODE JSYS CODE
CAIE T4,.VNMCB ;IS IT RUNNING MCB
CAIN T4,.VNDDC ;NO - IS IT RUNNING DDCMP
JRST NDLI11 ;YES - THEN IT IS ON
MOVEI T3,.NDLCN ;IS IT CONTROLLER LOOPBACK?
CAIN T4,.VNCNL ;???
JRST NDLI11 ;YES
MOVEI T3,.NDLCB ;CABLE LOOPBACK?
CAIN T4,.VNCBL ;??
JRST NDLI11 ;YES
MOVEI T3,.NDLOF ;SEE IF IT'S OFF
NDLI11: UMOVEM T3,.NDLST(Q2) ;STORE STATE IN LINE BLOCK IN USER SPACE
HRRI T3,.NDLSZ(Q2) ;GET ADDRESS WHERE NAME WILL GO
HRLI T3,(POINT 7,) ;FORM POINTER TO LINE NAME DESTINATION
UMOVEM T3,.NDLND(Q2) ;STORE POINTER TO LINE NAME IN USER SPACE
HRRZ T1,Q3 ;ITSNAM INDEX IS TWICE THE LINE NUMBER
LSH T1,1
HRRI T1,ITSNAM(T1) ;GET ADDRESS OF LINE NAME STRING
HRLI T1,(POINT 7,) ;FORM POINTER TO LINE NAME
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
;STONOD - ROUTINE TO STORE NODE NAME STRING IN USER SPACE
;
;ACCEPTS IN T1/ POINTER TO SOURCE STRING
; T3/ POINTER TO DESTINATION IN USER SPACE
; CALL STONOD
;RETURNS: +1 FAILED
; +2 SUCCESS
STONOD:
; LOOP OVER EACH CHARACTER IN NODE NAME
NDGN20: ILDB T2,T1 ;GET A BYTE
JUMPE T2,NDGN25 ;IF NULL, ALL DONE
XCTBU [IDPB T2,T3] ;STORE BYTE
ERJMP R ;FAILED, RETURN ERROR
JRST NDGN20 ;DO THEM ALL
NDGN25: XCTBU [IDPB T2,T3] ;APPEND A NULL
ERJMP R ;FAILED, RETURN ERROR
RETSKP ;DONE, RETURN SUCCESS
; NDVFY - VERIFY NODE NAME IS IN MONITOR'S DATABASE OF KNOWN NODES
NDVFY: SAVEAC (Q1)
STKVAR <<NDVNOD,WPN>>
; GET NODE NAME FROM USER SPACE
UMOVE Q1,T2 ;GET ADDRESS OF USER ARGUMENT BLOCK
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 KNOWN TO THE MONITOR
HRRI T1,NDVNOD ;GET ADDRESS OF NODE NAME
HRLI T1,(POINT 7,) ;FORM POINTER TO NODE NAME
CALL VFYNOD ;VERIFY NODE NAME
TDZA T1,T1 ;FAILED, NOT A KNOWN NODE
MOVX T1,ND%EXM ;SUCCESS, NODE IS KNOWN
UMOVEM T1,.NDFLG(Q1) ;STORE RESULT IN USER SPACE
RETSKP ;DONE, RETURN SUCCESS
;VFYNOD - ROUTINE TO VERIFY THAT A NODE IS KNOWN TO THE MONITOR
;
;ACCEPTS IN T1/ POINTER TO NODE NAME
; CALL VFYNOD
;RETURNS: +1 FAILED, NODE IS NOT KNOWN TO THE MONITOR
; +2 SUCCESS, NODE IS IN MONITOR'S DATABASE
VFYNOD: LOCK NODLOK ;LOCK THE KNOWN NODE TABLE
MOVE T2,T1 ;COPY POINTER TO NODE NAME
MOVE T1,NODTBL ;GET ADDRESS OF KNOWN NODE TABLE
TBLUK ;LOOK UP THE NODE NAME
ERJMP [UNLOCK NODLOK ;FAILED, UNLOCK THE TABLE
RET ] ;RETURN "NOT KNOWN"
UNLOCK NODLOK ;UNLOCK THE TABLE
TXNN T2,TL%EXM ;EXACT MATCH ?
RET ;NO, RETURN "NOT KNOWN"
RETSKP ;YES, RETURN "KNOWN NODE"
TNXEND
END