1 ;;; Copyright (c) 1999 Massachusetts Institute of Technology
3 ;;; This program is free software; you can redistribute it and/or
4 ;;; modify it under the terms of the GNU General Public License as
5 ;;; published by the Free Software Foundation; either version 3 of the
6 ;;; License, or (at your option) any later version.
8 ;;; This program is distributed in the hope that it will be useful,
9 ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
10 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 ;;; General Public License for more details.
13 ;;; You should have received a copy of the GNU General Public License
14 ;;; along with this program; if not, write to the Free Software
15 ;;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 SUBTTL ARPANET NCP variables and tables
20 IMPMQS==13. ;MESSAGE QUEUE SIZE (LENGTH WORD, 6-WORD LEADER, 6-WORD TEXT)
21 ;MAIN PROGRAM CONTROL MESSAGE VARIABLES
22 IMPMPU: -1 ;-1 => FREE
24 IMPMPL: -1 ;LINK WORD FOR CONTROL LINK QUEUE
25 IMPMPC: BLOCK IMPMQS ;FIRST WORD HAS IMPHTB INDEX,,LENGTH OF TEXT
27 ;PI CONTROL MESSAGE VARIABLES
28 IMNPIC==NNETCH+3 ;NUMBER OF BLOCKS IN PI CONTROL QUEUE
29 ;HOPEFULLY THIS IS ENOUGH. THE CODE RESPONDS VERY UNGRACEFULLY TO THIS
30 ;QUEUE FILLING UP. IN PARTICULAR, WHEN IT HOLDS UP INPUT IT CAN CAUSE
31 ;A DEADLOCK BY PREVENTING ITSELF FROM SEEING A CONTROL-LINK RFNM IT
32 ;NEEDS IN ORDER TO SEND SOMETHING THAT'S IN THE QUEUE AND FREE UP SOME
33 ;SPACE. FURTHERMORE THE IMP IS UNGRACEFUL AND WILL SOMETIMES REFUSE TO
34 ;READ INPUT FROM US (EVEN IN THE MIDDLE OF A MESSAGE) UNTIL WE READ
35 ;INPUT FROM IT. BUT WE DO THE SAME THING WHEN THIS QUEUE FILLS UP.
36 ;FURTHERMORE SOMETIMES THE CORE JOB WILL WAIT FOR A NETWORK
37 ;TRANSMISSION TO COMPLETE SO IT CAN MOVE A NETWORK BUFFER, HANGING THE
38 ;ENTIRE SYSTEM. THE CORE-JOB WILL UNHANG AFTER THE IMP TIMES OUT AND
39 ;FLASHES ITS READY LINE (SEE IMPBER).
40 ;** BUT SOMETIMES THE IMP NEVER TIMES OUT AND SO THE SYSTEM IS HUNG **
42 IMPCQ: REPEAT IMNPIC-1,[
43 .+IMPMQS+1 ;POINTER TO NEXT FREE OR NEXT IN QUEUE
44 BLOCK IMPMQS ;FIRST WORD HAS IMPHTB INDEX,,LENGTH OF TEXT
48 IMPNCQ: -1 ;NEXT ENTRY TO BE SENT. -1 IF NONE
49 IMPLCQ: -1 ;POINTER TO LAST ENTRY IN CONTROL QUEUE
50 IMFFCQ: IMPCQ ;POINTER TO FIRST FREE. -1 IF NONE
51 IMFCQL: IMNPIC ;NUMBER FREE CONTROL QUEUE ENTRIES LEFT
54 IMNPQ==20 ;NUMBER OF PENDING QUEUE ENTRIES
55 ;(0) POINTER TO NEXT IN CHAIN OR NEXT FREE. -1 IF NONE
56 ;(1) LOCAL SOCKET NUMBER
57 ;(2) FOREIGN SOCKET NUMBER
58 ;(3) 4.9 = 1 => RTS = 0 => STR
59 ; 1.1-1.8 = LINK NUMBER OR BYTE SIZE
60 ; 1.9-2.7 = FOREIGN HOST NUMBER
61 ; 3.1-3.9 = TIME RFC RECEIVED, IN SECONDS MOD 512.
62 IMPPQ ;IMPBPQ-1 IS BEGINNING OF GETSYS BLOCK, THIS WORD FOR UNRELOCATION
63 IMPBPQ: -1 ;BEGINNING OF PENDING QUEUE. -1 IF EMPTY
64 IMPPQ: REPEAT IMNPQ-1,[
70 IMPEPQ: -1 ;END OF PENDING QUEUE. -1 IF EMPTY (IMPEPQ IS END FOR GETSYS BLOCK)
71 IMFFPQ: IMPPQ ;FIRST FREE PENDING QUEUE ENTRY. -1 IF NONE
75 IMSOKB: IMPSTL ;BEGIN OF GETSYS BLOCK, LENGTH STORED HERE
77 IMSOC1: REPEAT IMPSTL,0 ;0 => FREE
78 ;>0 MEANS ALLOCATED, NOT SET UP YET
79 ;4.9 = 1 => SOCKET IN USE
80 ;4.8 = 1 => CHNL TRYING TO BE CLOSED
81 ;3.1-4.7 = MASK FOR CHANNEL SOCKET IS OPEN ON.
84 IMSOC2: BLOCK IMPSTL ;1.1-4.5 = LOCAL SOCKET NUMBER
85 ;4.6-4.9 0 (MAKES COMPARISONS EASIER)
86 IMSOC3: BLOCK IMPSTL ;1.1-4.5 = FOREIGN SOCKET NUMBER
88 IMSOC4: BLOCK IMPSTL ;3.1-3.8 = LINK NUMBER
89 ;3.9-4.7 = FOREIGN HOST NUMBER (IMPHTB INDEX)
90 ; 377 MEANS NOT USING ANY HOST
91 ;4.8 = SET BY RCV CLS - MAKES MATCH USING IMSCHD FAIL
92 ;4.9 = SEND THIS BUFFER NOW
93 .SEE %NS ;RH = SOCKET STATE
94 IMSOC5: BLOCK IMPSTL ;1.1 - 1.9 => TTY # OF STY, IF CONNECTED TO ONE.
95 ;2.1-2.9 = CLOSE-REASON
96 ;3.1-3.8 = CONNECTION BYTE SIZE
97 ;3.9 => ASCII MODE - 7 BIT
98 ;4.1 => ASCII MODE - 8 BIT
100 ;4.3 => NET INT (INR\INS) RECEIVED
101 ;4.4 => HAVE BEGUN COUNTING THE CLOSE TIME-OUT.
102 ;4.5 => CLOSED WHILE IN RFNM WAIT, EXPECT ANOTHER RFNM
103 ;4.6 => CONNECTED DIRECTLY TO A STY.
104 ;4.7 => DON'T BUFFER MORE OUTPUT THAN ALLOCATION
105 ;4.8 => STY WANTS WAKEUP AT 1/2 SEC CLK
106 ;4.9 => TRANSFER IN 32 BIT MODE
107 IMSOC6: BLOCK IMPSTL ;RH => BUFFER ADDRESS
108 ;4.9 => LOCKED BY CORE JOB
109 ;4.8 => ACTIVE AT PI LEVEL
110 ;4.7 => INPUT OCCURRED WHILE BUFFER LOCKED
111 ;3.1-3.8 => IOBFT INDEX (377 IF USING BIG BUFFER)
112 IMSOC7: BLOCK IMPSTL ;BIT ALLOCATION
113 IMSOC8: BLOCK IMPSTL ;MESSAGE ALLOCATION
114 IMSC7I: BLOCK IMPSTL ;AMT TO INCREASE BIT ALLOCATION BY IN NEXT ALLOC MSG (INPUT)
115 ;FOR OUTPUT, HAS NUMBER OF BITS IN BUFFER
116 IMSC8I: BLOCK IMPSTL ;AMT TO INCREASE MESSAGE ALLOCATION BY NEXT ALLOC MSG (INPUT)
117 IMSOCT: BLOCK IMPSTL ;TIME WHEN FIRST MESS PUT INTO BUF
118 ;(DURING INPUT HAS NUMBER OF DATA BYTES LEFT IN CUR MSG)
119 ;(DURING CLOSE HAS TIME TIME-OUT STARTED)
120 IMSMPP: BLOCK IMPSTL ;MAIN PROGRAM POINTER, ILDB OR IDPB FOR NEXT BYTE
121 IMSMPC: BLOCK IMPSTL ;MAIN PROGRAM COUNTER, FOR OUTPUT HAS NUMBER OF DATA
122 ; BYTES OF ROOM LEFT IN BUFFER. FOR INPUT HAS TOTAL
123 ; NUMBER OF DATA BYTES IN BUFFER.
124 IMSPIP: BLOCK IMPSTL ;INTERRUPT LEVEL POINTER, FOR OUTPUT ILDB TO GET NEXT
125 ; BYTE OUT AT P.I. LEVEL. FOR INPUT POINTS TO WHERE
126 ; HEADER WORD OF NEXT MESSAGE IN WILL BE STORED.
127 IMSBFE: BLOCK IMPSTL ;BYTE POINTER TO LAST BYTE IN BUFFER
128 ;USE CAILE X,@IMSBFE(I) TO CHECK A WORD ADDRESS
129 IMSOKE==.-1 ;END OF BLOCK FOR GETSYS CALL
133 IMSCLN: 221000,,IMSOC4(I) ;LINK NUMBER
134 IMSCBS: 221000,,IMSOC5(I) ;BYTE SIZE
135 IMSCLS: 111100,,IMSOC5(I) ;CLOSE REASON
136 IMSCFH: 321000,,IMSOC4(I) ;FOREIGN HOST
137 IMSCHD: 222100,,IMSOC4(I) ;FOREIGN HOST AND LINK NUMBER
138 ; EXTRA BIT, SET WHEN RCV CLS
139 IMSCHL: 222000,,IMSOC4(I) ;FOREIGN HOST AND LINK WITHOUT EXTRA BIT
141 NTRFCL: SIXBIT /NETRFC/ ;FOR ICP ON ANY SOCKET < 1000
145 NETSRS==1000 ;SMALLEST USER RECEIVE SOCKET NUMBER
146 NRSOC: NETSRS ;NUMBER OF NEXT RECEIVE SOCKET TO BE GENERATED
147 NETOSW: -1 ;SWITCH LOCKED AT NET OPEN
149 NETHSW: -1 ;SWITCH LOCKED IF HACKING HOST TABLE (IMPHTB)
151 NETLST: 0 ;LIST OF USERS IN NETWORK OPEN CODE
153 ;INPUT BUFFER FORMAT:
154 ;THE BUFFER IS CIRCULAR, AND EITHER 200 OR 2000 WORDS LONG.
155 ;MAY CONTAIN SEVERAL MESSAGES. EACH CONSISTS OF A HEADER WORD CONTAINING
156 ; THE NUMBER OF BYTES IN THE MESSAGE, FOLLOWED BY THE BYTES, FOLLOWED BY
157 ; UNUSED BITS UP TO THE NEXT WORD BOUNDARY. THIS WEIRD FORMAT IS USED
158 ; TO AVOID HAVING TO DO BYTE OPERATIONS AT P.I. LEVEL.
159 ;A HEADER WORD OF -1 MEANS THAT THAT MESSAGE HAS NOT YET BEEN STORED.
160 ;IMSPIP(I) ALWAYS CONTAINS THE ADDRESS OF A HEADER WORD OF -1.
161 ;IMSMPP(I) HAS A BYTE POINTER TO THE NEXT DATA BYTE TO BE READ.
162 ;P.I. LEVEL CAN STORE A MESSAGE INTO THE PART OF THE BUFFER FROM
163 ;@IMSPIP TO @IMSMPP-1.
164 ;IMSOCT(I) HAS THE NUMBER OF BYTES THAT MAIN PROGRAM LEVEL CAN
165 ; READ BEFORE IT GETS TO THE END OF THE CURRENT MESSAGE AND HAS
166 ; TO CHECK THE NEXT HEADER.
167 ;IMSMPC(I) HAS THE TOTAL NUMBER OF DATA BYTES IN ALL THE MESSAGES
170 ;OUTPUT BUFFER FORMAT:
171 ;THE BUFFER IS CIRCULAR, AND EITHER 200 OR 2000 WORDS LONG.
172 ;IT SIMPLY CONTAINS A STRING OF BYTES.
173 ;IMSMPP(I) HAS A BYTE POINTER TO WHERE THE NEXT BYTE TO BE OUTPUT WILL BE DEPOSITED.
174 ;IMSPIP(I) HAS A BYTE POINTER TO WHERE THE NEXT BYTE TO BE SENT OUT AT P.I.
175 ; LEVEL WILL COME FROM. P.I. LEVEL TRIES TO KEEP EVERYTHING ALIGNED ON
176 ; WORD BOUNDARIES SO THAT IT DOESN'T HAVE TO DO BYTE OPERATIONS.
177 ;IMSMPC(I) HAS THE NUMBER OF BYTES THAT MP LEVEL MAY STORE BEFORE RUNNING
178 ; INTO OLD BYTES THAT HAVEN'T YET BEEN TRANSMITTED.
179 ;IMSOCT(I) IS SET TO THE TIME THE FIRST BYTE IS PUT INTO THE BUFFER.
180 ; IT IS CLEARED WHENEVER THE BUFFER GETS EMPTIED.
184 SUBTTL ARPANET NCP Main Prog system call routines
186 ;NET .CALL RCHST/RFNAME
187 NETRCH: MOVEI W,8 ;WE RETURN 8 VALUES.
189 JUMPL I,NETRC3 ;NET WENT DOWN AFTER THIS CHANNEL WAS OPENED.
190 MOVE B,IMSOC2(I) ;LOCAL SOCKET NUMBER
191 MOVE C,IMSOC3(I) ;FOREIGN SOCKET NUMBER
192 LDB TT,IMSCFH ;FOREIGN HOST FOR 4TH WORD.
194 TDZA D,D ; 377 MEANS NOT USING ANY HOST
197 MOVE A,IMPHTN(TT) ; Get host addr
198 TLO A,(NW%ARP) ; Make full HOSTS3 format
199 CALL CVH2NA ; Convert to HOSTS2 for compatibility
206 LDB D,[112000,,Q] ;TRANSLATE NEW HOST NUMBER TO OLD
207 ANDI Q,377 ;IF IT WILL FIT IN OLD NOTATION
214 LDB Q,IMSCBS ;GET BYTE SIZE FOR HERE AND BELOW
215 ;FOLLOWING LINE HAS BEEN PUNTED, AN INCOMPATIBLE CHANGE
216 ; DPB Q,[111100,,D] ;INTO 2.9-2.1 OF 4TH WORD
217 MOVE A,IMSOC5(I) ;RANDOM WORD
218 TLNE A,4000 ;SKIP IF 4.3 BIT OFF (NETWRK INT)
219 TLO D,400000 ;SET FOR USER
220 PUSHJ P,NETRC1 ;GET TIME IMP GOING DOWN,
221 HRR TT,IMSOC4(I) ;MERGE IN SOCKET STATE.
222 IMUL Q,IMSMPC(I) ;MULTIPLY BYTE SIZE BY BYTES AVAIL TO GET BITS AVAIL
223 LDB I,IMSCLS ;CLS REASON
226 NETRC3: MOVEI I,%NCNCP ;GIVE CLOSE REASON THAT OUR NCP WENT DOWN.
227 NETRC1: SKIPG TT,IMPDWN+1 ;SYS TIME AT WHICH IMP IS GOING DOWN
229 SUB TT,TIME ;(TIME TIL IMP DOWN -1=NOT. 0=DOWN, +=GOING DOWN, N/30. SEC)
231 MOVEI TT,1 ;IF SET TO GO DOWN, AND TIME "PASSED", SAY SOON IF NOT ALREADY DOWN
235 ;NET .CALL STATUS - SOCKET STATE IN BITS 2.4-2.9
236 STANET: TRNN A,400000 ;SKIP IF NET WENT DOWN ON THIS LOSER
237 SKIPA E,IMSOC4(A) ;GET STATE
238 MOVEI E,0 ;IF NCP WENT DOWN, STATE IS "CLOSED"
242 ;NET .CALL RESET - ONLY RESETS "INT FM NETWORK" BIT (INR/INS)
243 NETRS: HLRZ A,(R) ;GET LH IOCHNM
244 MOVSI B,4000 ;4.3 BIT
245 TRNN A,400000 ;SKIP IF SET TO -1 (NET WENT DOWN ON THIS CHAN)
246 ANDCAM B,IMSOC5(A) ;CLEAR BIT
249 ;NET .CALL IOPUSH/IOPOP - ALTER THE CHANNEL-OPEN MASK IN IMSOC1.
250 NETIOP: HRRZ T,UUAC(U)
251 IMUL I,CHNBIT(T) ;PUSHING => 0; ELSE BIT FOR CHANNEL BEING POPPED.
252 HLRZ T,(R) ;GET SOCKET TABLE IDX
253 TRNN T,400000 ;SKIP IF NET WENT DOWN ON THIS LOSER
254 DPB I,[222000,,IMSOC1(T)] ;STORE MASK AWAY.
258 ;RESULTS ARE %WYNET, SOCKET STATE, BYTES AVAIL, CLS REASON
259 NETWHY: HRRE I,A ;GET IMSOC INDEX
260 MOVEI A,%WYNET ;FIRST RESULT IS DEVICE CODE
261 SETZB B,C ;SET UP RESULTS 2-4 IN CASE NCP WENT DOWN
263 JUMPL I,POPJ1 ;RETURN IF NCP WENT DOWN ON THIS LOSER
264 HRRZ B,IMSOC4(I) ;SECOND RESULT IS SOCKET STATE
267 TLO B,400000 ;SIGN OF SECOND RESULT SET IF NETWRK INT
268 TLNE Q,40000 ;DIRECT CONNECTED?
269 TDZA C,C ;YES, NO BYTES AVAILABLE FOR INPUT
270 MOVE C,IMSMPC(I) ;THIRD RESULT IS BYTES AVAILABLE
271 LDB D,IMSCLS ;FOURTH RESULT IS CLOSE REASON
274 ;AIDS TO NETWORK OPEN AND NETHST CALLS
276 ;SET THINGS UP AND ALLOCATE AN IMSOC INDEX.
277 ;SKIP RETURNS WITH NETLST AND IMSOC1(I) LOCKED.
278 ;OR, RETURNS NO-SKIP WITH NOTHING LOCKED AND AN ERROR SIGNALLED.
279 NETO00: PUSHJ P,LSTSET ;ADD THIS JOB TO LIST OF NET OPENERS
281 PUSHJ P,SWTL ;GET AN IMSOC ENTRY TO GC-PROTECT OUR IMPHTB ENTRY
286 JUMPG I,OPNL6 ;DEVICE FULL
287 MOVEI H,377 ;NO HOST YET
289 HRRZM U,IMSOC1(I) ;IMSOC1 POSITIVE MEANS ALLOCATED BUT NOT INITED YET
290 PUSHJ P,LSWPOP ;NETOSW
291 PUSHJ P,LOSSET ;RETURN IMSOC ENTRY IF PCLSR
295 ;LOSSET ROUTINE TO RETURN IMSOC ENTRY
296 NETIRT: MOVE T,AC0S+I(U)
303 ;SUBROUTINE TO OPEN UP COMMUNICATIONS WITH THE DESIRED HOST.
304 ;ENTER WITH HOST NUMBER IN SRN3(U), SKIP-RETURN WITH HOST
305 ;UP AND IMPHTB INDEX IN H AND IMSCFH. OR NON-SKIP RETURN WITH ERROR SIGNALLED.
306 NETOR: MOVE T,SRN3(U) ;USER-SPECIFIED HOST NUMBER
307 JSP J,STDHST ;STANDARDIZE, OPNL25 IF IT IS NO GOOD
309 PUSHJ P,FNDHST ;H GETS HOST TABLE INDEX
310 JRST OPNL6 ;DEVICE FULL (HOST TABLE FULL)
311 DPB H,IMSCFH ;PROTECT IN IMSOC4
313 PUSHJ P,SWTL ;POSSIBLY SEND RST TO HOST OPENING CONNECTION TO
315 LDB J,IMHSBT ;GET STATUS
316 SOJG J,NETORS ;-1 => DOWN, 0 => RST SENT, 1 => UP
317 JUMPE J,NETOR1 ;WAIT FOR REPLY
318 PUSHJ P,NETOW ;WAIT FOR IMPMPC TO BE FREE
320 DPB W,[221100,,IMPHTB(H)]
322 DPB J,IMHSBT ;MARK AS SENT
324 PUSHJ P,STHSTM ;STORE HOST#, LINK 0 , MESSAGE TYPE 0
325 MOVE W,[8_24.+1_8] ;BYTE SIZE = 8, BYTE COUNT = 1
327 MOVE W,[12._28.] ;RST
330 HRRM W,IMPMPC ;MESSAGE LENGTH
331 PUSHJ P,IMPMPQ ;SEND IT OUT
332 NETOR1: PUSHJ P,LSWPOP ;NETHSW
335 TDNE T,IMPHTB(H) ;RRP -> 2000, DOWN -> 0000
337 LDB J,IMHSBT ;GET STATUS
338 SOJL J,OPNL41 ;HOST DOWN
339 JUMPE J,NETOR ;TRY ALL THIS AGAIN
342 NETORS: PUSHJ P,LSWPOP ;NETHSW
343 JRST POPJ1 ;HOST IS UP
351 ;BLK: MODE BITS,,(SIXBIT /NET/)
352 ; LOCAL SOCKET NUMBER (1.1-4.5)
353 ; FOREIGN SOCKET NUMBER (1.1-4.5)
354 ; FOREIGN HOST NUMBER
356 ;BLK: 3.1-3.3 => STANDARD ASCII/IMAGE, UNIT/BLOCK, INPUT/OUTPUT
357 ; 3.4 = 1 => GENERATE UNIQUE LOCAL RECEIVE (SEND) SOCKET NUMBER
358 ; 3.4 = 0 => USE LOCAL SOCKET NUMBER SPECIFIED IN BLK+1
359 ; 3.5 => OPEN SOCKET IN LISTEN MODE
360 ; 3.6 => IF IMAGE MODE, USE BYTE SIZE IN 4.1-4.6
361 ; IF ASCII MODE, USE 8 BIT BYTES RATHER THAN 7
362 ; 3.7 => USE BIG BUFFER (2000 WORDS INSTEAD OF 200)
363 ; 3.8 => DON'T BUFFER MORE OUTPUT THAN ALLOCATION
364 ; 4.1-4.6 = BYTE SIZE IN IMAGE MODE
371 JRST OPNL7 ;DEVICE NOT READY
377 IORM I,SUPCOR ;HAVE SYS JOB BRING UP THE NETWORK
379 SKIPE IMPTCU ;WAIT WHILE IT TRIES TO COME UP
382 JRST OPNL7 ;LOSE IF NOT UP BY NOW
383 NETOUP: TLZ A,740000 ;IGNORE EXTRA BITS IN SOCKET NUMBERS
385 PUSHJ P,NETO00 ;INITIALIZE THINGS
386 POPJ P, ;NETWORK NOT UP OR FULL
387 TLNE C,20 ;SKIP IF NOT LISTEN
389 PUSHJ P,NETOR ;DO RESET STUFF, OPEN COMMUNICATIONS WITH HOST
390 POPJ P, ;HOST DOWN OR ILLEGAL
391 MOVE J,B ;CHECK GENDER OF FOREIGN SOCKET
394 JUMPGE J,OPNL2 ;WRONG DIRECTION
397 NETO10: PUSHJ P,SWTL ;ONLY ONE PROCESS AT A TIME COMPARING SOCKET NUMBERS
399 TLNN C,20 ;SKIP IF LISTEN
400 PUSHJ P,NETOW ;GOBBLE MP CONTROL LINK BLOCK (FOR NETOS)
402 JRST NETO1 ;USE SOCKET NUMBER GIVEN IN WORD 2
403 MOVEI A,10 ;ADVANCE SYSTEM UNIQUE SOCKET NUMBER
405 SUBI A,10 ;UNIQUE RECEIVE SOCKET NUMBER
406 SKIPGE D ;SKIP IF OPEN IS FOR READ (RECEIVE)
407 IORI A,1 ;MAKE INTO SEND SOCKET
410 NETO1: MOVE J,A ;USER SPECIFIED SOCKET NUMBER
411 ROT J,-1 ;J 4.9: 0 => RECEIVE 1 => SEND
412 EQV J,D ;D 4.9: 0 => READ 1 => WRITE
413 JUMPGE J,OPNL2 ;WRONG DIRECTION
415 CAIL A,NETSRS ;SKIP IF SPECIAL SOCKET
416 TRZA J,7 ;J HAS BASE OF SOCKET GROUP
417 MOVNI J,1 ; OR -1 IF NOT IN A GROUP
420 NETO2: SKIPL W,IMSOC1(Q)
421 JRST NETO3 ;NOT HOOKED UP
423 JRST NETO2A ;DUPLICATE LOCAL SOC #
427 JRST NETO4 ;JUMP IF PART OF SOCKET GROUP
429 SKIPL J ;SKIP IF NOT PART OF A SOCKET GROUP
430 JUMPE E,OPNL23 ;FOUND NO EVIDENCE THAT THIS GUY OWNS THIS GROUP
433 NETO2A: TLNN W,200000 ;SKIP IF BEING CLOSED
434 JRST OPNL13 ;NO, GIVE ERROR
436 PUSHJ P,LSWPOP ;POP MP CONTROL LINK BLOCK
437 PUSHJ P,LSWPOP ;NETOSW
441 PUSHJ P,UFLS ;WAIT TILL CLOSED
442 JRST NETO10 ;TRY AGAIN
445 JRST OPNL23 ;SOMEONE ELSE HAS IT
446 MOVNI E,1 ;OK IF NO OTHER CONFLICTS
449 ;HERE WITH SUITABLE LOCAL SOCKET IN A
450 NETO6: TLNN C,4 ;SKIP IF IMAGE MODE
451 JRST NETOC ;ASCII MODE
453 TLNN C,40 ;SKIP IF BYTE SIZE SUPPLIED
455 LDB E,[330600,,C] ;USE USER SUPPLIED BYTE SIZE
456 IDIVI E,36. ;TT GETS BYTE SIZE MOD 36.
458 MOVEI TT,36. ;36 BITS ANYWAY
462 JUMPE TT,NETOB1 ;EXACT
465 JUMPE TT,[MOVEI TT,400000 ;32BIT MODE FLAG
467 MOVEI TT,2000 ;FUNNY BYTESIZE FLAG
472 NETOC: MOVEI TT,400410 ;7 BIT
474 MOVEI TT,401010 ;8 BIT
476 TRO TT,100000 ;DON'T BUFFER MORE OUTPUT THAN ALLOCATION
477 HRLZM TT,IMSOC5(I) ;STORE FLAGS AND BC, CLEAR CLOSE REASON
478 MOVEM A,IMSOC2(I) ;LOCAL SOCKET NUMBER
479 MOVEM B,IMSOC3(I) ;FOREIGN SOCKET NUMBER
480 SETZM IMSOCT(I) ;IF INPUT, NOT IN MIDDLE OF A MESSAGE
482 TLNE C,20 ;3.5 LISTEN
484 DPB H,[321000,,W] ;DON'T CHANGE HOST NUMBER FIELD OF IMSOC4
485 MOVEM W,IMSOC4(I) ;SET INITIAL STATE, CLEAR FLAGS
486 SKIPE IMSOC6(I) ;SKIP IF HAVEN'T ASSIGNED BUFFER YET
491 NETOE1: TLNN C,100 ;LAST PLACE TO PCLSR (REALLY NETMW)
493 PUSHJ P,TCALL ;GET FULL-PAGE BUFFER
497 DPB W,[MUR,,MEMBLT(A)]
498 DPB I,[MNUMB,,MEMBLT(A)]
500 MOVE W,A ;BUFFER START ADDRESS
501 HRLI W,377 ;NOT AN IOBFT-TYPE BUFFER
502 MOVEI A,1777(A) ;BUFFER END ADDRESS
505 NETOE7: MOVEI D,NFNETC(I)
507 JRST IUTCO1 ;GET 200-WD BUFFER
508 JRST NETMW ;NO MEM AVAIL
509 LDB W,[IOSA,,IOBFT(A)]
510 LSH W,6 ;STARTING ADDRESS
512 MOVEI A,177(W) ;BUFFER END ADDRESS
513 NETOE4: MOVEM A,IMSBFE(I) ;(LH WILL BE STORED LATER)
515 ;CLEAR THE BUFFER FOR EASE IN DEBUGGING. COMMENT USED TO CLAIM
516 ;THAT CLEARING IT WAS NECESSARY IN ORDER TO OUTPUT CORRECT HEADERS,
517 ;BUT THAT WAS FRAUDULENT SINCE HEADERS NEVER COME FROM THE BUFFER.
528 MOVSI Q,000100 ;SET UP THE VARIOUS BYTE POINTERS
529 LDB TT,IMSCBS ;TO POINT TO END OF BUFFER
530 MOVE E,IMSOC5(I) ;SO ILDB WILL GET FIRST BYTE IN BUFFER
531 TLNN E,2000 ;SKIP IF ONE BIT BYTES
532 DPB TT,[300600,,Q] ;OTHERWISE USE USER BYTE SIZE
534 TLO Q,040000 ;32 BIT WORD ENDS 4 BITS OVER
539 MOVE T,C ;GET 3.5 BIT OF C INTO
541 JUMPL D,NETOE5 ;JUMP IF SENDER
542 SETOM (W) ;NULL FIRST HEADER WORD
543 TLO Q,440000 ;-> LEFT END OF WORD
545 MOVEM Q,IMSPIP(I) ;SET PI PNTR TO POINT TO FIRST MESSAGE HEADER
546 SETZM IMSMPC(I) ;NO INPUT BYTES AVAILABLE YET
547 MOVEI TT,20. ;MESSAGE ALLOCATION ALWAYS 20
549 HRRZ TT,IMSBFE(I) ;COMPUTE BIT ALLOCATION
550 SUBI TT,2*20.(W) ;TT := # WORDS IN BUFFER, -1 FOR LUCK, -2 FOR EACH MSG
551 SKIPGE IMSOC5(I) ; (-1 FOR HEADER WORD, AND -1 FOR BREAKAGE)
552 IMULI TT,32. ;CONVERT TO # BITS
555 LDB Q,IMSCBS ;BREAKAGE WAS OVER-ESTIMATED BY 1 BYTE PER MSG
558 MOVEM TT,IMSOC7(I) ;STORE CORRECT BIT ALLOCATION
562 DPB Q,IMSCLN ;STORE IN LINK # FIELD
565 NETOE5: SETZM IMSOC7(I) ;INITIALIZE SENDER'S ALLOCATIONS
569 SUBI TT,(W) ;# BUFFER WORDS, -1 FOR LUCK
570 SKIPGE IMSOC5(I) ;SKIP IF 36BIT
571 IMULI TT,32. ;ALLOW 32 BITS PER WORD
573 IMULI TT,36. ;OR 36 BITS PER WORD
575 IDIVM TT,E ;CONVERT TO NUMBER OF BYTES
576 MOVEM E,IMSMPC(I) ;THAT MANY ARE FREE AT FIRST
577 NETOE6: PUSHJ P,IMPSPQ ;SEARCH PENDING QUEUE (LEAVES UTCOFF)
578 JRST NETOG ;NOTHING THERE
579 JUMPGE T,NETOH ;JUMP IF NOT LISTENING STATE
580 MOVE W,2(Q) ;FOREIGN SOCKET NUMBER
582 LDB H,[101000,,3(Q)] ;FOREIGN HOST IMPHTB INDEX
585 NETOH: MOVEI W,%NSOPN
587 JUMPGE D,NETOD1 ;JUMP IF RECEIVER
588 SKIPL W,3(Q) ;SKIP IF RTS, GET LINK #
589 JRST 4,. ;HE SENT STR
590 DPB W,IMSCLN ;STORE LINK NUMBER
591 NETOD: HRRZ Q,UUAC(U) ;CHANNEL OPEN ON
593 PUSHJ P,IMPUIM ;INTERRUPT SELF
594 JRST NETOG ;GO FINISH THE OPEN
596 NETOD1: SKIPGE W,3(Q) ;SKIP IF STR, GET BYTE SIZE
597 JRST 4,. ;HE SENT RTS
601 JRST NETOD ;BYTE SIZES DIFFER, LOSE
602 PUSHJ P,IMPBRT ;RETURN THE BUFFER
603 JRST OPNL22 ;SELF-CONTRADICTORY OPEN?
605 NETOG: HRRZ W,UUAC(U)
608 HRR W,U ;SETZ+<<INT MASK>,,<USER WHO HAS SOCKET>>
609 MOVEM W,IMSOC1(I) ;WE ARE NOW FULLY SET UP TO THIS SOCKET
611 TLNN C,20 ;SKIP IF LISTENING TYPE SOCKET
612 PUSHJ P,NETOS ;SEND RFC (CAN'T HANG, ALREADY GOT NETOW)
613 PUSHJ P,LSWPOP ;UNLOCK NETOSW, NOW THAT IMSOC1 4.9 IS SET
614 PUSHJ P,LSWDEL ;UNLOCK IMSOC1(I)
615 PUSHJ P,LSWPOP ;REMOVE FROM LIST OF NETWORK OPENS IN PROGRESS
616 HRLZ A,I ;LEFT HALF OF IOCHNM GETS SOCKET INDEX
624 ;GOBBLE MAIN PROGRAM CONTROL LINK BLOCK
626 NETOW: JUMPL U,NETOW1 ;FROM STYNET CLOCK LEVEL
628 SKIPGE IMPHTB(H) ;SKIP IF NOT RFNM WAIT ON LINK 0
630 PUSHJ P,SWTL ;GRAB CONTROL LINK BLOCK
632 SKIPL IMPHTB(H) ;DID CTL LINK TO THIS HOST GET BACK INTO RFNM WAIT?
634 PUSHJ P,LSWPOP ;YES, RELEASE RESOURCE WHILE AWAITING RFNM
637 ;FROM NETIDC (AT CLOCK INTERRUPT LEVEL)
638 NETOW1: SKIPL IMPHTB(H)
640 CAIA ;INPUT CAN'T BE READ YET.
643 PUSHJ P,IMPUIN ;REACTIVATE SO WILL CHECK AGAIN
644 SUB P,[2,,2] ;THROW THROUGH NETI6, NETID
645 JRST NETOJ1 ;TAKE NO-INPUT-AVAILABLE EXIT
647 ;WAIT FOR MEMORY SO CAN ALLOCATE BUFFER
652 JRST [ PUSHJ P,UDELAY ;MAYBE MEMORY FROZEN, GIVE CORE JOB
653 JRST NETOE1 ] ;A CHANCE TO PCLSR US, THEN TRY AGAIN
654 CAMLE T,LMEMFR ;SKIP WHEN MORE THAN 3K FREE
658 ;SEND RFC AND MAYBE ALLOCATE. IMSOC INDEX IN I, HOST INDEX IN H.
660 NETOS: PUSHJ P,STHSTM ;STORE HOST ADDRESS IN IMPMPC+n, ALSO MESSAGE TYPE
661 MOVE J,[8_24.+13._8] ;BYTE SIZE = 8, BYTE COUNT = 13.
663 MOVEI J,1_4 ;3 NOPS + RTS
664 SKIPGE D ;SKIP IF INPUT
665 MOVEI J,2_4 ;3 NOPS + STR
667 LSH A,4 ;LOCAL SOCKET NUMBER
669 LSH B,4 ;FOREIGN SOCKET NUMBER
671 MOVEI TT,2(I) ;LINK NUMBER FOR RECEIVE SOCKET
673 LDB TT,IMSCBS ;BYTE SIZE FOR SEND SOCKET
677 CAIN J,%NSOPN ;SKIP IF CONNECTION NOT YET OPEN
678 JUMPGE D,NETOS2 ;JUMP IF CONNECTION OPEN AND READ
680 MOVEI TT,4 ;TEXT LENGTH
681 NETOS3: HRRM TT,IMPMPC
684 NETOS2: MOVEI J,<4_8>+2(I) ;NOP + ALL + LINK #
688 MOVE TT,IMSOC8(I) ;SEND MESSAGE ALLOC
691 MOVE TT,IMSOC7(I) ;SEND BIT ALLOC
694 MOVE TT,[8_24.+22._8] ;BYTE COUNT = 22.
696 MOVEI TT,6 ;MESSAGE LENGTH
699 ;.NETAC CH, ;ACCEPT CONNECTION
704 HRRZ T,IMSOC4(I) ;SOCKET STATE
706 JRST OPNL41 ;NOT IN RFC RECEIVED STATE
708 PUSHJ P,NETOW ;GET IMPMPC
709 MOVE A,IMSOC2(I) ;LOCAL SOCKET NUMBER
710 MOVE B,IMSOC3(I) ;FOREIGN SOCKET NUMBER
713 PUSHJ P,NETOS ;SEND RFC (AND MAYBE ALL)
718 HRRM TT,IMSOC4(I) ;CONNECTION OPEN
724 JRST OPNL34 ;NOT A NETWORK CHANNEL
725 HLRE I,(R) ;SOCKET TABLE INDEX
727 JRST OPNL41 ;OTHER END OF PIPELINE GONE (NET WENT DOWN)
729 ;.NETS CH, ;SEND BUFFER NOW
732 NETFRC: JSP T,NETCHK ;ENTRY FROM .CALL FORCE
735 JRST OPNL2 ;NOT SEND SOCKET
739 JRST NETOJ1 ;BUF EMPTY
740 MOVSI TT,400000 ;TURN ON SEND BUFFER BIT
742 PUSHJ P,IMPOST ;TURNS NETON
745 NETFIN: HRRZ TT,IMSBFE(I) ;ENTRY FROM .CALL FINISH (NETFRC HAS BEEN CALLED)
746 SUB TT,IMSOC6(I) .SEE NETOE5 ;FOR COMMENTS FOR THIS CODE
753 IDIVM TT,T ;T NOW HAS SIZE OF OUTPUT BUFFER IN BYTES
754 CAME T,IMSMPC(I) ;WAIT FOR BUFFER TO EMPTY OUT
756 MOVEI T,%NSRFN ;WAIT FOR RFNM
757 HLL T,IMSOC4(I) ;4.9 IS KNOWN TO BE OFF NOW!
762 ;.NETINT CH, ;SEND NETWORK INTERRUPT "INR" OR "INS"
763 ;INR FROM RECEIVER TO SENDER (LOCAL SOCKET EVEN, FOREIGN ODD)
764 ;INS FROM SND TO RCV ( -", -")
765 ;ALSO .CALL NETINT, ARG 1 IS CH
768 AOSA (P) ;GOING TO WIN, SKIP RETURN
769 ANETINT: JSP T,NETCHK ;I<- SOCKET TABLE INDEX
770 LDB H,IMSCFH ;HOST INDEX FOR NETOW
771 PUSHJ P,NETOW ;WAIT FOR IMPMPU
774 PUSHJ P,STHSTM ;STORE HOST ADDRESS
775 MOVE A,[8_24.+2_8] ;BYTE SIZE 8, COUNT 2
777 MOVE A,IMSOC2(I) ;LCL SOCK #
779 TRNE A,1 ;SKIP IF RCV
784 JRST IMPMPQ ;QUE IT, START OUTPUT (IMPOST)
786 ;STORE HOST ADDRESS FROM H INTO LEADER IN IMPMPC. BASHES W, Q.
787 STHSTM: MOVEI Q,IMPMPL
788 HRLM H,IMPMPC ;ALSO SAVE HOST INDEX FOR PI LEVEL
789 ;STORE HOST ADDRESS FROM H INTO LEADER IN (Q), BASHES W.
790 STHSTP: MOVE W,IMPHTN(H) ;FOREIGN HOST NUMBER
791 IFN 1, DPB W,[103000,,3(Q)] ; Store host address
792 IFN 0,[ DPB W,[301000,,3(Q)] ;STORE HOST NUMBER
794 DPB W,[102000,,3(Q)] ;STORE IMP NUMBER
796 MOVSI W,17_10. ;NEW-FORMAT FLAG
797 MOVEM W,2(Q) ;MESSAGE TYPE 0 (LINK, ETC. ARE ALWAYS ZERO)
800 ;.CALL NETBLK ;WAIT FOR STATE TO CHANGE OR TIME OUT
803 ; ARG 3 - TIME, AS IN .SLEEP (OPTIONAL) (WRITTEN BACK)
808 MOVE T,I ;SAVE INDEX IN T
810 CAIGE W,3 ;SKIP IF 3 ARGS (TIME GIVEN)
811 JRST ANETB3 ;USE DEFAULT TIME
812 TLNE C,1000 ;SKIP IF POINTER, RATHER THAN IMMEDIATE
814 XCTR XRW,[MOVES B,(C)] ;GET TIME FROM USER (CHECK WRITE ALSO)
815 JUMPL B,ANETB1 ;NEG MEANS ALREADY ABS TIME
817 SUB B,TIME ;-TIME TO GO TO
818 ANETB1: UMOVEM B,(C) ;STORE NEG TIME FOR PCLSR
820 ANETB4: MOVEM B,EPDL(U) ;ALSO USED IN B LATER
821 PUSHJ P,ANETB2 ;SKIP IF STATE CHANGE OR TIMEOUT
823 SUB B,TIME ;HOW MUCH USED?
824 HRRZ A,IMSOC4(I) ;RETURN STATE
827 ANETB2: HLR A,T ;DESIRED STATE
828 XOR A,IMSOC4(T) ;CURRENT STATE
829 TRNE A,-1 ;SKIP IF STILL MATCH
831 MOVE A,EPDL(U) ;SAVED TIME HERE
836 ANETB3: HRLOI B,377777 ;NO TIME SUPPLIED, USE INFINITY
839 ANETB5: HRRZ B,C ;IMMEDIATE TIME SUPPLIED
840 ADD B,TIME ;(TIMEOUT WILL RESTART ON EACH PCLSR, TOO BAD)
846 ;ARG 2 - NET INPUT CHANNEL TO CONNECT STY OUTPUT TO, OR -1 TO DISCONNECT
847 ;ARG 3 - NET OUTPUT CHANNEL TO CONNECT STY INPUT TO
848 ;ARG 4 - CHARS TO SEND WHEN OUTPUT .RESET HAPPENS ON STY'S TTY
849 ; UP TO 3 8-BIT CHARACTERS, LEFT JUSTIFIED.
851 NSTYNT: TLNN R,%CLSST
852 JRST OPNL34 ;1ST ARG NOT A STY CHANNEL.
853 HLRZ I,(R) ;GET TTY # OF STY
854 HRRES B ;ALLOW IMMEDIATE -1
855 JUMPGE B,NSTYN2 ;JUMP IF CONNECTING.
856 PUSHJ P,NSTYN0 ;DISCONNECT
857 JRST OPNL41 ;WASN'T CONNECTED
860 ;VARIOUS ROUTINES CALL HERE WITH THE TTY# OF A STY IN I, TO DISCONNECT THE
861 ; STY FROM THE NETWORK. NOTE THIS ROUTINE MUST NOT CHANGE U AND MUST NOT
862 ; LSWCLR, SINCE IT COULD BE CALLED FROM IODCL VIA STYCLS OR NETCLS.
864 NSTYN0: MOVSI B,%SSNET ;DISCONNECTING BOTH SIDES.
866 TDNN B,STYSTS-NFSTTY(I)
867 POPJ P, ;THIS STY NOT CONNECTED?
868 ANDCAB B,STYSTS-NFSTTY(I) ;MARK AS NO LONGER CONNECTED
869 MOVE C,STYNTL-NFSTTY(I) ;REMOVE THIS STY FROM ACTIVATION LIST
870 MOVEI D,STYNTA-STYNTL+NFSTTY
871 NSTYN1: CAMN I,STYNTL-NFSTTY(D) ;FIND THE STY THAT POINTS TO THIS ONE,
872 MOVEM C,STYNTL-NFSTTY(D) ;AND PATCH US OUT OF THE LIST.
873 SKIPE D,STYNTL-NFSTTY(D) ;SEARCH WHOLE LIST TILL FIND WHO POINTS TO US.
875 SETOB C,STYNTL-NFSTTY(I)
876 EXCH C,STYNTI-NFSTTY(I) ;MARK THIS STY AS HAVING NO CONNECTION, GET SOCKET INDICES
879 JRST [ MOVSI B,%SSCHA ;DISCONNECT FROM CHAOS NET
880 ANDCAM B,STYSTS-NFSTTY(I)
883 JRST 4,. ;CHAOS DOESN'T THINK IT WAS CONNECTED?
889 JRST 4,. ;SOCKET DOESN'T THINK IT WAS CONNECTED?
890 ANDCAM B,IMSOC5(C) ;AND MARK SOCKETS WE WERE CONNECTED TO AS DISCONNECTED
893 JRST 4,. ;SOCKET DOESN'T THINK IT WAS CONNECTED?
897 NSTYN2: MOVE Q,I ;SAVE TTY # OF STY
899 MOVE A,B ;DECODE THE NETWORK INPUT CHANNEL
905 JRST [ HLRZ I,(R) ;CONNECT TO CHAOS NET
909 JRST OPNL23 ;ALREADY CONNECTED, FILE LOCKED
910 MOVSI C,%SSNET+%SSCHA
911 TDNE C,STYSTS-NFSTTY(Q)
912 JRST OPNL23 ;ALREADY CONNECTED, FILE LOCKED
913 IORM B,CHSSTA(I) ;OK, HOOK UP
914 DPB Q,[$CFTTN,,CHSSTA(I)]
917 JSP T,NETCHK ;TEST LEGALITY; OPNL IF LOSES
919 JRST OPNL2 ;WRONG DIRECTION IF IT'S AN OUTPUT CHANNEL
920 MOVE B,I ;SAVE INPUT IMSOC INDEX
921 MOVE A,C ;DECODE OUTPUT CHANNEL
925 JRST OPNL2 ;WRONG DIRECTION IF INPUT SOCKET
928 TDNN E,IMSOC5(B) ;ERROR IF EITHER CHANNEL ALREADY CONNECTED
930 JRST OPNL23 ;"FILE LOCKED"
932 TDNE C,STYSTS-NFSTTY(Q)
933 JRST OPNL23 ;SIMILAR ERROR IF STY ALREADY CONNECTED
934 HRR E,Q ;GET 40000,,TTY #
936 IORM E,IMSOC5(B) ;MARK SOCKETS AS CONNECTED
937 NSTYN3: SKIPGE STYNTL-NFSTTY(Q) ;HALT IF STY'S VARS ARE NOT CORRECT FOR A
938 SKIPL STYNTI-NFSTTY(Q) ;NON-CONNECTED STY.
940 IORM C,STYSTS-NFSTTY(Q) ;ALL ERROR CAUGHT, SO MARK STY CONNECTED.
941 HRL B,I ;PUT INPUT IMSOC IDX,, OUTPUT IMSOC IDX
942 MOVSM B,STYNTI-NFSTTY(Q) ;INTO THE STY
943 TRZ D,7777 ;STORE THE OUTPUT RESET CHARACTERS - AT MOST 3
944 MOVEM D,STYORC-NFSTTY(Q)
945 IFN CHAOSP,[ ;ACTIVATE IN CASE HAS UNREAD INPUT
955 SUBTTL ARPANET MP I/O ROUTINES
958 ;CALL STYNTC AT CLOCK LEVEL TO PROCESS ALL NECESSARY TRANSFERS OF DATA
959 ;BETWEEN CONNECTED STYS AND NET SOCKETS
961 STYNTC: CONO PI,NETOFF
962 SKIPN I,STYNTA ;GET HEAD OF ACTIVATE LIST
964 SETZM STYNTA ;COPY LIST IN CASE A STY IS PUT BACK ON
966 STYNT7: MOVE A,STYNTL-NFSTTY(I) ;GET NEXT ON LIST
967 MOVEM A,STYNTB ;SAVE FOR NEXT TIME AROUND LOOP
968 SETOM STYNTL-NFSTTY(I) ;THIS ONE IS NO LONGER ON ACTIVATE LIST
969 MOVE A,STYSTS-NFSTTY(I)
971 JRST 4,. ;STY CLAIMS NOT TO BE CONNECTED??
975 JRST STYCHA ;CONNECTED TO CHAOS NET
981 JRST STYNT1 ;NO OUTPUT, CHECK FOR INPUT
982 ;HANDLE OUTPUT TO NET
983 HRRZ I,STYNTI-NFSTTY(I) ;GET IMSOC IDX OF OUTPUT CHANNEL
986 JRST 4,. ;SOCKET CLAIMS NOT TO BE CONNECTED??
987 STYNT5: CONO PI,NETOFF ;INCLUDES TTYOFF
988 PUSHJ P,NSOSE0 ;CAN WE OUTPUT TO NET NOW?
989 JRST STYNT6 ;NO, WAIT TILL LATER, PI LVL WILL REACTIVATE WHEN STATE CHANGES
990 LDB T,IMSCBS ;SINCE THIS IS PI LEVEL,
991 MOVE Q,IMSOC7(I) ;NO POINT IN SENDING MORE OUTPUT THAN ALLOCATED
993 IDIVM Q,T ;T GETS NUMBER OF BYTES ALLOCATED AND NOT BUFFERED
996 JUMPLE E,STYNT6 ;NO ALLOC, SEND NOTHING
997 EXCH R,I ;BEFORE EXCH, R HAS TTY #, I HAS NET IMSOC IDX
998 MOVEM D,DBBBP ;SET UP BUFFER-POINTING VARS FOR TTY OUTPUT INTERRUPT LEVEL
1003 PUSHJ P,TYP ;OUTPUT THROUGH THOSE POINTERS, INTO THE NET CHNL BUFFER
1010 PUSHJ P,NSOFIN ;FIGURE OUT HOW MANY CHARS WERE TYPED, AND UPDATE SOCKET.
1011 JRST STYNT4 ;MORE ROOM IN BUFFER => MAYBE TYPE SOME MORE.
1012 JRST STYNT6 ;ELSE TRY INPUT FROM NET, BUT SEND WHATEVER WE GOT
1014 STYNT4: SKIPL TTYOAC(R) ;MORE OUTPUT IN TTY BUFFER?
1015 JRST STYNT5 ;YES, PROCESS IT
1016 STYNT6: PUSHJ P,NSOFN1 ;NO, BE SURE NET BUFFER GETS SENT SOON
1018 ;HERE TO TRY TO HANDLE INPUT FROM NET
1019 STYNT1: HLRZ I,STYNTI-NFSTTY(R) ;INPUT IMSOC INDEX
1022 JRST 4,. ;SOCKET CLAIMS NOT TO BE CONNECTED?
1023 STYNT2: PUSHJ P,NETIDC ;GET CHAR FROM NET SOCKET
1024 JRST STYNT3 ;GOT CHAR IN W
1025 JRST STYNT8 ;NO CHAR AVAIL, HANDLE OTHER STYS
1026 ;2 SKIPS => GIVE UP, SPECIAL CHARACTER SEEN, OR BAD STATE
1027 PUSHJ P,IMPUIP ;WAKE UP THE TELNET SERVER
1028 MOVE I,R ;DISCONNECT THE STY AND SOCKETS
1032 STYNT8: SKIPE I,STYNTB ;GET NEXT STY FROM COPIED ACTIVATION LIST
1038 STYNT3: EXCH I,R ;HERE IF GET CHAR FROM NET IN W. I GETS TTY #.
1043 PUSHJ P,NTYI5 ;GIVE CHARACTER TO TTY INPUT INTERRUPT LEVEL.
1045 POP P,R ;TTY #; POP IN REVERSE ORDER TO UNDO THE EXCH
1047 JRST STYNT2 ;TRY TO GET ANOTHER INPUT CHARACTER.
1049 ;STYNTC'S INTERFACE TO NET INPUT IOT.
1050 ;I HAS IMSOC IDX OF INPUT SOCKET.
1051 ;1 SKIP => NO DATA AVAILABLE.
1052 ;2 SKIPS => TELNET CONTROL CHARACTER FOUND, SO DISCONNECT STY AND
1053 ;INTERRUPT THE USER PROGRAM.
1054 NETIDC: MOVNI U,1 ;U=-1 TELLS NETI IT CAME FROM HERE
1055 HRRZ H,IMSOC4(I) ;CHECK SOCKET STATE
1058 CAIGE H,%NSCLI ;SKIP IF IN ONE OF THE TWO INPUT AVAILABLE STATES
1059 JRST POPJ2 ;STATE IS ABNORMAL, SO DISCONNECT FROM STY.
1060 JRST NETID ;ELSE TRY AN IOT.
1062 ;NETWORK UNIT INPUT.
1063 NETI: HRRE I,A ;SOCKET TABLE INDEX
1065 NETIB: MOVE A,IMSOC5(I) ;ENTER HERE FROM BLOCK-MODE INPUT
1067 JRST IOCR10 ;CAN'T IOT AT M.P. LEVEL WHILE SOCKET CONNECTED TO A STY.
1068 NETID: MOVE A,IMSC8I(I)
1071 ADD B,IMSOC7(I) ;TOTAL NUMBER OF BITS YET TO BE READ
1072 CAIGE A,8. ;IF MESS REALL OF 8 OR MORE
1073 CAMG B,IMSC7I(I) ;OR BIT REALL SATISFIES "DOUBLE BUFFERING" CRITERION
1074 PUSHJ P,NETI6 ;THEN SEND ALLOCATE
1075 JUMPL U,NETI4 ;JUMP IF READING INPUT TO GIVE DIRECTLY TO A STY
1076 NETI0: CONO PI,NETOFF ;DON'T ALLOW INTO IMPUIN WHILE CHECKING STATE, #BITS
1078 JUMPE A,NETIB1 ;CONNECTION CLOSED
1083 JRST IOCR10 ;SOCKET IN BAD STATE
1085 SKIPG IMSMPC(I) ;WAIT FOR BITS TO ARRIVE
1087 CONO PI,NETON ;NETON IN CASE DIDN'T UFLS
1088 SKIPG IMSMPC(I) ;DID THEY?
1089 JRST NETI0 ;NO, STATE MUST HAVE CHANGED, CHECK IT AGAIN
1091 NETI4: SOSL IMSOCT(I) ;TAKE BYTE
1093 MOVE A,IMSMPP(I) ;END OF MESSAGE, FIND ADDRESS OF NEXT HEADER WORD
1094 MOVEI A,1(A) ;WHICH IS IN NEXT WORD AFTER LAST BYTE LOADED
1096 HRRZ A,IMSOC6(I) ;WRAP AROUND
1097 SOSGE B,(A) ;GET HEADER WORD, COUNT DOWN FOR BYTE ABOUT TO TAKE
1098 JRST 4,. ;NO MESSAGE, ALTHOUGH IMSMPC > 0
1099 MOVEM B,IMSOCT(I) ;SAVE # BYTES LEFT IN THIS MESSAGE
1100 HLL A,IMSBFE(I) ;SET UP BYTE POINTER LH TO LAST BYTE IN WORD
1101 MOVEM A,IMSMPP(I) ; SO ILDB WILL GET FIRST DATA BYTE OF THIS MSG
1102 AOS IMSC8I(I) ;INCREASE MESSAGE ALLOCATION
1103 NETI4A: MOVE TT,IMSMPP(I) ;CHECK FOR WRAP-AROUND
1106 JRST NETI2 ;JUMP IF ONE BIT BYTES
1108 JRST [ HRRZ TT,IMSOC6(I)
1109 HLL TT,IMSPIP(I) ;B.P. TO FIRST BYTE IN BUFFER
1114 NETI2: LDB E,IMSCBS ;BITS PER BYTE
1116 NETI1: CAME TT,IMSBFE(I)
1118 HRRZ TT,IMSOC6(I) ;WRAP AROUND
1127 NETI3: TRNN W,200 ;IS THIS A TELNET CONTROL CHAR (>= 200)?
1129 JUMPL U,[AOS IMSOCT(I) ;YES; IF DIRECT-CONNECTED TO A STY, BREAK CONNECTION.
1130 JRST POPJ2] ; WITHOUT GOBBLING THAT CHARACTER
1131 TLNE H,400 ;IF 7-BIT ASCII MODE, REPLACE CHARACTER BY ^@.
1133 NETI3A: MOVEM TT,IMSMPP(I)
1135 ADDM TT,IMSC7I(I) ;INCREASE BIT ALLOCATION
1136 CONO PI,NETOFF ;WHILE CHANGING STATE
1137 SOSLE IMSMPC(I) ;ONE LESS BYTE IN BUFFER
1138 JRST NETONJ ;OK, THERE IS MORE IN BUFFER
1139 MOVNI E,1 ;YES, STATE IS CHANGING.
1144 MOVEI E,%NSOPN ;NO INPUT AVAILABLE
1145 JUMPL E,[JRST 4,.] ;WAS IN SOME RANDOM STATE
1147 PUSHJ P,IMPUIP ;IF STATE CHANGING TO "CLOSED", GIVE USER AN INTERRUPT.
1151 ;COME HERE WHEN INPUT IOT FINDS THAT CONNECTION IS CLOSED
1152 NETIB1: CONO PI,NETON
1155 JRST IOCR10 ;ABNORMAL CLOSURE, GIVE IOCER INSTEAD OF EOF
1157 POP P,D ;GET OUR RETURN ADDRESS.
1159 CAIE D,AIOT3 ;IF WE ARE NOT DOING A UNIT MODE IOT,
1160 JRST 1(D) ;JUST RETURN WITH 1 SKIP.
1161 TLNN TT,1400 ;SKIP IF ASCII MODE
1162 JRST IOCER2 ;EOF IN IMAGE MODE IS IOCERROR.
1163 HRROI W,EOFCH ;EOF IN ASCII MODE RETURNS ^C.
1166 NETI6: HRRZ H,IMSOC4(I) ;SEND ALL MSG
1170 POPJ P, ;CLOSED, DON'T SEND ALLOCATE
1171 LDB H,IMSCFH ;HOST INDEX FOR NETOW
1172 PUSHJ P,NETOW ;GOBBLE MAIN PROG CONTROL LINK BLOCK
1173 MOVEI J,2(I) ;LINK #
1174 IORI J,<4_8> ;SEND ALLOC
1182 PUSHJ P,STHSTM ;STORE HOST ADDRESS, MESSAGE TYPE
1186 HRRM J,IMPMPC ;TEXT LENGTH
1194 ;UNIT MODE NETWORK OUTPUT (DOESN'T CLOBBER C)
1195 JRST NETSIO ;SIOT VECTOR
1196 NETW: HRRE I,A ;SOCKET TABLE INDEX
1201 NETWB: CONO PI,NETOFF ;BYTE TO OUTPUT IN A. HERE FROM BLOCK MODE.
1207 SKIPG IMSMPC(I) ;SKIP IF ROOM TO PUT BYTE IN BUF
1208 JRST [ MOVSI B,400000
1209 IORM B,IMSOC4(I) ;SET TO SEND IT NOW
1210 IFN DMIMP,CONSZ FI,70
1212 SKIPG IMSMPC(I) ;WAIT FOR AT LEAST ONE BYTE OF ROOM
1216 JRST NETWB ;NO ROOM, STATE MUST HAVE CHANGED
1223 MOVSI B,400000 ;ALLOCATION USED UP (AND FEATURE ENABLED)
1224 IORM B,IMSOC4(I) ;SEND BUFFER NOW
1226 CAMN T,IMSOC7(I) ;WAIT FOR DATA TO GO OUT OR ALLOC TO COME IN
1228 JRST NETWB ;TRY AGAIN
1230 NETW4: MOVE T,IMSMPP(I) ;GET POINTER
1232 CAMN T,IMSPIP(I) ;SKIP UNLESS BUFFER EMPTY
1233 MOVEM E,IMSOCT(I) ;SET TIME FOR FIRST BITS INTO BUF
1234 LDB B,IMSCBS ;BYTE SIZE
1235 MOVE E,IMSOC5(I) ;FLAGS
1236 CONO PI,NETOFF ;WANT TO MUNG POINTERS WITHOUT PI INTERFERENCE
1237 TLNE E,2000 ;SKIP IF BYTES FIT EXACTLY IN WORD
1238 TLNN T,770000 ;SKIP IF NOT AT RIGHT END OF WORD
1239 JRST NETW2 ;IDPB, CHECK FOR POINTER WRAP
1240 LDB TT,[360600,,T] ;GET BYTE POS
1241 CAML TT,B ;SKIP IF BYTE SPLITS ACROSS WORDS
1242 JRST NETW1 ;JUST DO IDPB
1243 DPB TT,[301400,,T] ;SET BYTE TO STORE IN RIGHT OF THIS WORD
1244 SUB TT,B ;=> -(# OVERFLOW BITS)
1245 ROT A,(TT) ;HIGH PART OF BYTE IN RIGHT END OF A
1246 DPB A,T ;STORE PART BYTE
1247 AOS T,IMSMPP(I) ;INCR TO NEXT WORD
1250 HRR T,IMSOC6(I) ;WRAP
1251 MOVEM A,@T ;STASH REST OF BYTE IN LEFT PART OF NEXT WORD
1252 ADDI TT,36. ;SET TO NEW POSITION
1253 DPB TT,[360600,,T] ;NEW BYT POS
1254 MOVEM T,IMSMPP(I) ;STORE UPDATED PTR
1257 ;DEPOSIT A BYTE WHICH MAY WRAP AROUND
1259 NETW2: CAME T,IMSBFE(I)
1265 ;DEPOSIT BYTE KNOWN TO FIT IN WORD
1267 NETW1: IDPB A,IMSMPP(I) ;STORE IT
1271 NETW3: SOS IMSMPC(I) ;1 BYTE LESS FREE
1276 ;NETWORK OUTPUT SIOT
1277 NETSIO: CONO PI,NETOFF
1278 PUSHJ P,NSOSET ;SET UP FOR FAST SIOT
1279 JRST NSIOT1 ;CHANNEL ISN'T SET UP FOR IT => USE NORMAL SIOT LOOP.
1282 NETSO0: XCTR XRW,[MOVES B,@-1(P)] ;COPY ARGS
1283 XCTR XRW,[MOVES C,@(P)]
1284 NETSO1: IBP B .SEE NSIOOL ;FOR WHY THIS HAIR IS NEEDED
1285 XCTRI XR,[MOVE TT,(B)]
1287 JRST NETSO3 ;PAGE FAULT, CLEAN UP IMSMPP BEFORE TAKING IT
1292 UMOVEM B,@-1(P) ;UPDATE USER'S ARGS
1293 XCTR XRW,[SOSLE C,@(P)]
1294 JUMPG E,NETSO1 ;LOOP IF BOTH USER AND SYSTEM WILLING
1297 JRST 4,. ;WENT TOO FAR!!
1298 PUSHJ P,NSOFIN ;FINISH UP HACKING NET CHANNEL.
1299 JRST NETSO2 ;OUTPUT BUFFER HAS MORE ROOM
1300 JUMPLE C,PPBAJ1 ;NO ROOM BUT DON'T WANT ANY MORE ANYWAY, SO RETURN
1301 SKIPG IMSMPC(I) ;NO ROOM, WAIT FOR SOME
1302 PUSHJ P,UFLS ;NOTE ANY STATE CHANGE WILL UNHANG
1303 POP P,C ;NOW TRY TO SIOT SOME MORE
1305 MOVE D,IOTTB(H) ;RESTORE D IN CASE GOES TO NSIOT1
1308 NETSO3: PUSHJ P,NSOFIN ;TOOK PAGE FAULT, CLEAN UP
1311 NETSO2: JUMPLE C,PPBAJ1 ;BUFFER HAS ROOM BUT NO DESIRE TO SEND ANY MORE, RETURN
1313 PUSHJ P,NSOSE0 ;SET UP TO SEND MORE
1314 JRST IOCR10 ;STATE MUST HAVE GONE BAD
1315 JRST NETSO0 ;OK, SEND MORE
1317 ;SET UP FOR NET OUTPUT SIOT, OR (NSOSE0) FOR DIRECT OUTPUT FROM STY.
1318 ;AT ENTRY, A HAS LH(IOCHNM).
1319 ;CALL WITH NETOFF, AND DON'T TURN IT BACK ON BEFORE CALLING NSOFIN,
1320 ;BECAUSE WE HAVE A COPY OF IMSMPP IN D, AND PI LEVEL MIGHT BE TRYING TO MUNG IT.
1321 ;SETS D TO POINTER, E TO COUNT OF CHARS OF SPACE, AND Q TO COPY OF COUNT.
1322 ;SETS I TO IMSOC IDX. CLOBBERS T AND TT.
1323 ;NO SKIP => CAN'T USE FAST SIOT, OR CAN'T DO DIRECT OUTPUT AT THIS MOMENT.
1324 ;IN THAT CASE, D HASN'T BEEN CLOBBERED YET.
1327 NSOSE0: MOVE E,IMSOC5(I)
1330 CAIN T,%NSRFN ;STATE BAD, OR BYTES CROSS WORD BOUNDARIES,
1332 JRST NETONJ ;IMPLIES CAN'T WIN THIS WAY.
1334 JRST NSOFN1 ;JUMP IF BUFFER FULL, SET SEND BUFFER AND NETONJ
1338 HRR D,IMSOC6(I) ;IF BUFFER STORING PTR POINTS AT END OF BUFFER,
1339 TLO D,440000 ;WRAP AROUND.
1340 NSOSE2: LDB Q,IMSCBS
1344 IDIVM TT,Q ;GET # BYTES/WD OF CONNECTION.
1347 IMUL TT,Q ;# BYTES BETWEEN POINTER AND END OF BUFFER.
1350 IDIVM T,Q ;# BYTES NOT STORED IN WORD POINTER POINTS AT
1351 ADD TT,Q ;THEY ARE AVAILABLE, TOO.
1353 MOVE E,TT ;GET MINIMUM OF FULL BYTES AND BYTES AFTER THE POINTER.
1356 CAMN Q,IMSPIP(I) ;SKIP IF BUFFER NOT EMPTY
1357 MOVEM T,IMSOCT(I) ;TIME FOR FIRST BITS INTO BUF.
1358 CAILE E,600 ;DON'T LEAVE NETOFF FOR MORE THAN ONE CLOCK TICK OR SO
1360 MOVE Q,E ;ORIGINAL E. (FOR NSOFIN)
1363 ;FINISH UP AFTER NET OUTPUT SIOT OR DIRECT OUTPUT FROM STY.
1364 ;SKIP IF BUFFER FULL
1365 ;ASSUME Q,I LEFT OVER FROM NSOSET, AND D,E ADVANCED BY STORING CHARS.
1366 NSOFIN: PI2SAF ;NETOFF SHOULD STILL BE IN EFFECT FROM NSOSET
1367 SUBM E,Q ;- <# BYTES XFERED>
1368 JUMPE Q,NETONJ ;IF OUTPUT NO BYTES, DON'T CHANGE IMSMPP (IMPORTANT!)
1369 MOVEM D,IMSMPP(I) ;UPDATE STORING POINTER OF SOCKET BUFFER
1373 ADDM TT,IMSC7I(I) ;INCREASE COUNT OF BITS IN BUFFER
1374 ADDB Q,IMSMPC(I) ;UPDATE COUNT OF FREE SPACE IN BUFFER.
1375 JUMPG Q,.+2 ;ANY SPACE LEFT => NO SKIP.
1377 JUMPG E,NETONJ ;ONLY SEND BUFFER IF CALL OUTPUT ALL IT COULD
1378 NSOFN1: MOVSI TT,400000 ;SEND BUFFER NOW.
1380 JRST IMPOST ;TURNS NETON
1384 XCTR XRW,[MOVES D,(C)] ;TAKE TRAP GETTING POINTER IF SWAPPED OUT
1386 TLNE E,1400 ;SKIP IF IMAGE MODE
1387 JRST NETBOA ;ASCII MODE
1388 JUMPGE D,CPOPJ ;TRANSFER NO WORDS
1389 NETBO1: UMOVEM D,(C)
1397 NETBOA: TLNN E,400 ;SKIP IF 7 BIT
1410 NETBA8: XCTR XRW,[MOVES D,(C)]
1412 CAIGE TT,4 ;ONLY 4 BYTES PER WORD (3 < CNT < 8)
1414 SKIPA TT,NETCHT-4(TT)
1415 NTBA8A: UMOVEM D,(C)
1422 ADD D,[700000,,] ;ADVANCE CHAR CNT
1423 JUMPL D,NTBA8A ;GO TO NEXT CHAR
1425 ADD D,[400001,,1] ;INCR TO NEXT WORD
1430 NETCHT: REPEAT 4,<44-<3-.RPCNT>*10>_12.+1000,,W
1434 XCTR XRW,[MOVES D,(C)] ;ENSURE POINTER WILL BE WRITABLE
1436 TLNE E,1400 ;SKIP IF IMAGE MODE
1437 JRST NETBIA ;ASCII MODE
1438 NETBI1: UMOVEM D,(C) ;STORE BACK POINTER
1439 XCTR XRW,[MOVES (D)] ;ENSURE BYTE WILL BE WRITABLE
1441 PUSHJ P,NETIB ;GET NEXT BYTE
1442 CAIA ;NORMAL RETURN.
1443 JRST POP1J ;NO INPUT AVAIL.
1451 NETBIA: TLNN E,400 ;SKIP IF 7 BIT ASCII
1456 NETBIR: PUSHJ P,NETI
1457 JRST [ MOVEI E,NETBIR ;INPUT IN W
1459 MOVE E,[600000,,NETBCC] ;NO INPUT AVAIL
1462 NETBCC: MOVEI H,EOFCH
1465 NTBIA8: HRRZS E ;8-BIT ASCII BLOCK MODE
1466 XCTR XRW,[MOVES D,(C)]
1470 SKIPA TT,NETCHT-4(TT)
1471 NTBI8A: UMOVEM D,(C)
1472 XCTR XRW,[MOVES (D)]
1478 JRST NETBI5 ] ;NORMAL RETURN - BYTE IN W.
1479 MOVSI E,600000 ;NO BYTES AVAIL - SOCKET CLOSED.
1501 NTBI8B: MOVEI H,EOFCH
1505 NETCLS: HRRE I,A ;SOCKET TABLE INDEX
1508 TRNN T,1 ;SKIP IF SEND SOCKET
1511 IORM T,IMSOC4(I) ;CAUSE BUFFER TO BE SENT
1513 NETCL2: MOVSI B,600000
1515 IORM B,IMSOC1(I) ;MARK CHANNEL TO BE CLOSED
1521 MOVE I,IMSOC5(I) ;IF CHANNEL CONNECTED TO A STY,
1524 ANDI I,777 ;DISCONNECT THEM.
1529 ;SEARCH PENDING QUEUE FOR LOCAL SOCKET NUMBER IN A,
1530 ;T 4.9 = 1 => LISTENING, 4.9 => 0 => ALSO CHECK
1531 ;FOREIGN SOCKET NUMBER IN B AND FOREIGN HOST NUMBER (IMPHTB INDEX) IN H
1532 ;SKIPS IF ENTRY IS FOUND. RETURNS ENTRY TO FREE LIST.
1533 ;Q GETS ADDRESS OF ENTRY BLOCK. RETURN WITH NETOFF
1535 IMPSPQ: CONO PI,NETOFF
1536 IMSPQP: SKIPGE Q,IMPBPQ ;BEGINNING OF QUEUE
1537 POPJ P, ;QUEUE EMPTY
1538 MOVNI J,1 ;PREVIOUS ENTRY
1539 IMSPQL: CAME A,1(Q) ;SKIP IF SAME LOCAL SOCKET NUMBER
1540 JRST IMSPQ1 ;TRY NEXT
1541 JUMPL T,IMSPQW ;WIN IF LISTENING SOCKET
1542 LDB W,[101000,,3(Q)] ;FOREIGN HOST IMPHTB INDEX
1543 CAMN W,H ;SKIP IF WRONG FOREIGN HOST
1544 CAME B,2(Q) ;SKIP IF FOREIGN SOCKET NUMBER AGREES
1545 JRST IMSPQ1 ;TRY NEXT
1546 IMSPQW: SKIPGE W,(Q) ;FOUND IT
1547 MOVEM J,IMPEPQ ;PATCH OUT OF THE QUEUE
1551 MOVE W,IMFFPQ ;ADD TO FREE LIST
1556 IMSPQ1: MOVE J,Q ;PREVIOUS ENTRY
1557 SKIPL Q,(Q) ;NEXT ENTRY
1561 SUBTTL ARPANET CLOCK LEVEL
1563 OVHMTR IMP ;NETWORK INTERRUPT LEVEL (NOT STYNET STUFF)
1565 ;HERE TO TIME OUT THE RFC QUEUE
1566 IMFCT1: CONO PI,NETOFF
1568 JRST NETONJ ;... IF QUEUE IS EMPTY
1569 MOVNI J,1 ;J HAS PTR TO PREV ELT OF LIST, FOR IMSPQW TO PATCH (DELQ).
1570 IMFCT2: LDB E,[221100,,3(Q)] ;TIME IN 16/15'THS, MOD 512., THAT RFC WAS RECEIVED
1571 LDB TT,[051100,,TIME] ;TIME, IN SAME UNITS, NOW.
1572 CAMLE E,TT ;MAKE SURE THE SUB TT,E GIVES A POSITIVE ANSWER.
1573 ADDI TT,1_9 ;WE ASSUME THAT TIME >= TIME OF RECEIPT.
1575 CAIGE TT,IMFCTO_<-5>
1576 JRST IMFCT3 ;THIS RFC HASN'T TIMED OUT - LOOK AT NEXT
1577 PUSHJ P,IMSPQW ;IT HAS - FLUSH IT
1579 JRST IMFCT1 ;AND START AGAIN LOOKING FOR RFC'S TO FLUSH
1584 JRST NETONJ ;END OF QUEUE
1586 ;FLUSH CLOSED NETWORK CHANNELS (CALLED AT HALF SEC CLOCK)
1587 IMPCCL: MOVSI I,-IMPSTL
1588 IMPCCR: CONO PI,NETON
1590 IMPCCZ: TDNN T,IMSOC1(I) ;LOOK FOR CHANNELS NO LONGER OPEN.
1595 IMPCCA: CONO PI,NETOFF
1597 TLNE B,600000 ;ACTIVE AT PI LEVEL OR LOCKED BY CORE JOB
1599 HRRZ B,IMSOC4(I) ;DISPATCH ON SOCKET STATE.
1616 IMPBRT: SKIPN IMSOC6(I)
1618 LDB A,[221000,,IMSOC6(I)]
1621 LDB A,[121000,,IMSOC6(I)]
1624 IMBRT1: PUSHJ P,IBRTN
1628 IMPCC1: PUSHJ P,IMPBRT
1631 JSP T,IMPC5D ;WAITING FOR FINAL RFNM
1633 SOS IMNCS ;WE HAVE FINISHED CLOSING ONE SOCKET
1634 IMPCCS: AOBJN I,IMPCCR ;WE CLOSED ONE, OR GAVE UP ON ONE; LOOK AT NEXT
1635 JRST NETONJ ;OR WE'RE FINISHED LOOKING AT ALL.
1637 IMPCC2: PUSHJ P,IMPBRT
1639 CAIG T,2 ;SKIP IF MORE THAN 2 FREE
1640 JRST IMPCCS ;NOT ENUF PI CONTROL QUEUE BLOCKS AVAIL
1641 LDB A,IMSCFH ;GET HOST#
1642 SKIPGE IMPHTB(A) ;SKIP IF NO RFNM WAIT ON LINK 0
1643 JRST IMPCCS ;NOT NOW!
1647 12.,,3 ;12. BYTES, 3 WORDS
1648 JRST 4,. ;NO SLOTS AVAIL. CHECKED BEFORE
1649 MOVEI H,3_4 ;3 NOPS + CLS
1651 MOVE H,IMSOC2(I) ;LOCAL SOCKET
1652 LSH H,4 ;MOVE INTO 32 BIT FIELD
1654 MOVE H,IMSOC3(I) ;FOREIGN SOCKET
1657 PUSHJ P,IMWCQ ;SEND CLS
1662 MOVEM H,IMSOCT(I) ;TIME CLS SENT
1665 IMPCC5: MOVE H,IMSOC2(I)
1666 TRNN H,1 ;SKIP IF SEND SOCKET
1667 JRST IMPC5B ;RECEIVE SOCKET
1669 CAMN A,IMSMPP(I) ;IS THERE STILL DATA TO SEND? AT MP LEVEL
1670 CAMN I,IMPOPI ;OR PI LEVEL? OR RFNM WAIT?
1671 IMPCC6: JSP T,IMPC5D ;YES, SEND IT AND GET RFNM BEFORE SENDING CLS
1672 IMPC5B: MOVEI H,%NSRFS ;NO, OK TO SEND A CLS NOW.
1673 HRRM H,IMSOC4(I);SET STATE SO WILL LOOP BACK TO IMPCC2
1676 IMPC5A: IORM H,IMSOC5(I)
1681 IMPC5D: MOVSI H,10000
1683 JRST IMPC5A ;TIME-OUT NOT ALREADY STARTED - START IT.
1684 IMPC7A: MOVE H,TIME ;ALREADY STARTED, OVER YET?
1686 CAIG H,IMPCTO ;SKIP IF TIMED OUT
1687 JRST IMPCCS ;NOT YET
1690 IMPCC7: JSP T,IMPC7A ;IF CLOSE TIME-OUT ISN'T UP, GIVE UP TO IMPCCS.
1691 JRST IMPCC1 ;ELSE FLUSH.
1693 ;HERE FROM 1/2 SECOND CLOCK IF IMNAS IS NON-ZERO.
1694 ;WE WAKE UP ANY STYNET CHANNELS THAT NEED IT.
1695 IMPAAA: SOS IMNAS ;DECREASE NEED-THIS-ROUTINE COUNT
1697 IMPAA1: MOVSI T,200000
1707 SUBTTL ARPANET NCP INPUT INTERRUPT LEVEL
1709 ;GET HERE PI IN PROG ON NETCHN
1710 ;IMP HAS NETCHN PIA, TT HAS CONI WORD, A HAS LAST WD OF CONTROL LINK MSG
1711 ;PROCESS THE CONTROL LINK HOST-HOST PROTOCOL OPCODES.
1712 IMPBK3: AOS B,IMBLKI ;STORE LAST WORD AS IF BLKI HAD
1714 MOVEI B,-IMPINB+1(B) ;B HAS NUMBER OF WORDS READ
1716 JRST IMPCIS ;MESSAGE IS SHORT
1717 MOVE A,IMPCBC ;NUMBER OF BYTES
1718 MOVE B,[441000,,IMPINB] ;8 BIT BYTE POINTER TO MESSAGE
1721 IMPBKL: SOJL A,IMPIR1 ;LOOP HERE TO PROCESS CONTROL MESSAGE
1722 MOVE H,IMPCSH ;RESTORE HOST INDEX
1725 JRST IMPCIG ;ILLEGAL OPCODE
1726 AOS IMPCMR(C) ;COUNT CTL MSG RCD
1727 JRST @IMPCDT(C) ;DISPATCH ON OPCODE
1729 IMPCIG: BUG INFO,[NET: NEW CTL MSG FM HST ],OCT,IMPHTN(H),[COD=],OCT,C,[CT=],OCT,A
1732 IMPCIS: MOVE H,IMPCSH
1733 BUG INFO,[NET: SHORT CTL MSG FM HST ],OCT,IMPHTN(H)
1737 IMPCDT: IMPBKL ;NOP ( 0)
1759 BUG INFO,[NET: SHORT CTL MSG HST ],OCT,IMPHTN(H),[COD=],OCT,C,[MISSING],OCT,A
1762 IMPNXR: ILDB C,B ;LINK NUMBER FOR NXR OR NXS
1763 SOJA A,IMPBKL ;JUST IGNORE IT, USELESS ANYWAY
1765 ;RFC RECEIVED C HAS OPCODE
1766 IMPRFC: SUBI A,9 ;MUST BE AT LEAST 9 MORE BYTES
1767 JUMPL A,IMSHRT ;MESSAGE IS SHORT
1768 ILDB D,B ;D GETS 32 BIT FOREIGN SOCKET NUMBER
1774 ILDB E,B ;E GETS 32 BIT LOCAL SOCKET NUMBER
1780 ILDB R,B ;LINK NUMBER OR BYTE SIZE
1782 EQVI Q,(C) ;Q 1.1 = 1 IF E 1.1 = C 1.1
1784 JUMPE Q,IMPRF3 ;WRONG DIRECTION RFC
1785 CAIE C,2 ;SKIP IF STR
1787 CAILE R,36. ;SKIP IF STR AND BYTE SIZE < 37
1788 JRST IMREFU ;REFUSE CONNECTION
1789 IMPRF5: PUSHJ P,IMPLLS ;LOOK FOR LOCAL SOCKET (RET INDEX IN I)
1790 JRST IMPRFQ ;NO SUCH SOCKET. QUEUE IT
1791 HRRZ W,IMSOC4(I) ;SOCKET STATE
1792 CAIE W,%NSLSN ;SKIP IF LISTENING
1794 MOVEM D,IMSOC3(I) ;STORE FOREIGN SOCKET NUMBER
1795 DPB H,IMSCFH ;STORE FOREIGN HOST INDEX
1797 HRRM Q,IMSOC4(I) ;RFC RECEIVED STATE
1798 CAIN C,2 ;SKIP IF RTS
1799 JRST [ LDB Q,IMSCBS ;STR, CHECK CONNECTION BYTE SIZE
1803 DPB R,IMSCLN ;RTS, STORE LINK #
1804 PUSHJ P,IMPUIN ;INTERRUPT USER
1805 IMRFCX: LDB Q,IMHSBT
1809 DPB Q,IMHSBT ;MARK HOST UP
1812 IMPRF3: BUG INFO,[NET: WRONG DIR RFC HST ],OCT,IMPHTN(H),[OP ],SIXBIT,[(C)[SIXBIT /RTS STR/]-1],[SOK],OCT,E
1815 IMPRF4: CAIE W,%NSRFS ;SKIP IF IN RFC SENT STATE
1816 JRST IMPRFQ ;QUEUE IT
1819 CAME D,IMSOC3(I) ;FROM CORRECT FOREIGN SOCKET?
1820 JRST IMREFU ;NO, REFUSE
1821 AOS IMSOC4(I) ;PUT INTO STATE 5 - OPEN
1822 CAIE C,1 ;SKIP IF RTS
1824 DPB R,IMSCLN ;STORE LINK #
1825 IMPRF1: PUSHJ P,IMPUIN ;INTERRUPT USER
1828 IMPRF2: LDB Q,IMSCBS
1830 JRST IMCLDA ;BYTE SIZES DIFFER, REFUSE
1832 8,,2 ;TEXT: 8 BYTES, 2 WORDS
1837 IOR H,IMSOC8(I) ;MSG ALLOC
1841 MOVE H,IMSOC7(I) ;BIT ALLOC
1844 PUSHJ P,IMWCQ ;SEND IT OUT
1847 IMPRFQ: CAIL E,NETSRS ;IF < 1000, START JOB "NETRFC"
1850 ; CAIE T,<IMPUS_-6>+<IMPUS&77>_9
1851 CAME T,[IMPUS3-NW%ARP] ; Compare with our own host (minus net #)
1854 JRST IMREFU ;REFUSE CONNECTION
1856 PUSHJ P,NUJBST ;LOAD SERVER
1857 JRST IMREFU ;RING BUFFER FULL
1858 IMRFQ5: SKIPGE Q,IMFFPQ ;SKIP IF ANY FREE SLOTS
1859 JRST IMRFQ1 ;CLS OLDEST
1861 MOVEM W,IMFFPQ ;NEW FIRST FREE
1862 IMRFQ9: SETOM (Q) ;END OF QUEUE
1863 MOVEM E,1(Q) ;LOCAL SOCKET NUMBER
1864 MOVEM D,2(Q) ;FOREIGN SOCKET NUMBER
1865 CAIE C,2 ;SKIP IF STR
1866 TLO R,400000 ;MARK AS RTS
1867 MOVEM R,3(Q) ;LINK NUMBER OR BYTE SIZE
1868 DPB H,[101000,,3(Q)] ;FOREIGN HOST INDEX
1869 LDB W,[051100,,TIME] ;STORE TIME OF RECEIPT, IN 16/15 MOD 512.
1870 DPB W,[221100,,3(Q)]
1871 SKIPGE W,IMPEPQ ;END OF QUEUE
1872 JRST IMRFQ2 ;QUEUE EMPTY
1873 MOVEM Q,(W) ;PUT IN AT END OF QUEUE
1874 MOVEM Q,IMPEPQ ;NEW END OF QUEUE
1877 IMRFQ2: MOVEM Q,IMPEPQ ;END OF QUEUE
1878 MOVEM Q,IMPBPQ ;AND BEGINNING OF QUEUE
1881 IMRFQ1: MOVE J,IMPBPQ ;BEGINNING OF PENDING QUEUE
1882 MOVE E,1(J) ;LOCAL SOCKET
1883 MOVE D,2(J) ;FOREIGN SOCKET
1885 LDB H,[101000,,3(J)] ;FOREIGN HOST INDEX
1887 PUSHJ P,IMPSCL ;SEND CLS
1888 JRST IMRFQ3 ;NO BUFFERS AVAILABLE
1889 AOSA IMNRFC ;# RFCS CLOSED
1890 IMRFQ3: AOS IMNRFI ;# RFCS IGNORED
1893 MOVE Q,IMPBPQ ;FLUSH FIRST ENTRY ON PENDING QUEUE
1898 IMREFU: PUSHJ P,IMPSCL ;SEND CLS
1903 IMPCLS: SUBI A,8 ;MUST BE AT LEAST 8 MORE BYTES
1904 JUMPL A,IMSHRT ;MESSAGE IS SHORT
1905 ILDB D,B ;D GETS 32 BIT FOREIGN SOCKET NUMBER
1911 ILDB E,B ;E GETS 32 BIT LOCAL SOCKET NUMBER
1917 PUSHJ P,IMPLC ;LOOK FOR CONNECTION
1918 JRST IMCLSQ ;LOOK IN QUEUE
1919 MOVSI W,200000 ;SET CLS RCD BIT
1920 IORB W,IMSOC4(I) ;RH IS STATE FOR DISPATCH
1936 IM4CLS: HLLZS IMSOC4(I) .SEE %NSCLS
1940 IMECLS: MOVEI W,%NSCLI
1943 IMCLDA: HLLZS IMSOC4(I) .SEE %NSCLS
1944 MOVEI W,%NCBYT ;BYTE MISMATCH
1947 IM6CLS: MOVSI W,20000 ;CLSED DURING RFNM WAIT
1949 IM5CLS: TDZA W,W .SEE %NSCLS
1950 IM2CLS: MOVEI W,%NSRCL
1951 IMCCLS: HRRM W,IMSOC4(I) ;CHANGE STATE
1953 IMCLDB: DPB W,IMSCLS ;CLS REASON
1954 PUSHJ P,IMPUIN ;INTERRUPT USER
1955 IMCLQ2: PUSHJ P,IMPSCL ;SEND CLS
1959 IMPSCL: JSP T,IMSTCM ;SEND A CLS TO LOCAL SOCKET IN E AND FOREIGN SOCKET IN D (CLOBBERS D AND E)
1960 12.,,3 ;TEXT: 12 BYTES, 3 WORDS
1962 MOVEI H,3_4 ;3 NOPS + CLS
1965 MOVEM E,11(Q) ;LOCAL SOCKET NUMBER
1967 MOVEM D,12(Q) ;FOREIGN SOCKET NUMBER
1968 PUSHJ P,IMWCQ ;SEND CLS
1974 IM7CLS: HLLZS IMSOC4(I) .SEE %NSCLS
1979 MOVE A,E ;LOCAL SOCKET NUMBER
1981 MOVE B,D ;FOREIGN SOCKET NUMBER
1982 PUSHJ P,IMSPQP ;SEARCH PENDING QUEUE
1983 JRST IMCLQ1 ;NOT THERE
1987 JRST IMCLQ2 ;SEND HIM A CLS
1991 JRST IMPCLI ;CAN'T FIND HIM. IGNORE
1993 IMPALL: SUBI A,7 ;MUST BE AT LEAST 7 MORE BYTES
1994 JUMPL A,IMSHRT ;MESSAGE IS SHORT
1999 IORI D,(T) ;D GETS MESSAGE ALLOCATION
2000 ILDB E,B ;E GETS BIT ALLOCATION
2006 MOVE T,IMPCSH ;FOREIGN HOST
2008 IOR R,T ;HEADER (HOST AND LINK #)
2009 MOVEI W,1 ;TO TEST DIRECTION OF SOCKET
2011 IMPAL2: LDB T,IMSCHD ;FOREIGN HOST AND LINK NUMBER
2012 SKIPGE IMSOC1(I) ;SKIP IF SLOT NOT IN USE
2013 CAME T,R ;SKIP IF HEADER AGREES
2015 TDNE W,IMSOC2(I) ;SKIP IF NOT SEND
2017 IMPAL1: AOBJN I,IMPAL2
2019 BUG INFO,[NET: IGNORED ALLOC HST ],OCT,IMPHTN(H),[LNK],OCT,R
2026 LDB T,IMSCBS ;GET BYTESIZE
2027 IDIV E,T ;TRUNCATE TO 0 MODULO BYTESIZE
2028 IMUL E,T ;(CLOBBER TT)
2032 ADDB D,IMSOC8(I) ;INCREASE ALLOCATIONS
2035 TLNE Q,140000 ;ACTIVATE IF USER (OR DIRECT CONN) CHECKING ALLOC
2038 CAME T,IMSMPP(I) ;SKIP IF OUTPUT BUFFER EMPTY
2039 PUSHJ P,IMPIOS ;THIS GUY MAY HAVE STUFF TO GO OUT
2042 IMPLLS: MOVSI I,-IMPSTL ;LOOK FOR SOCKET IN E
2044 IMPLL2: TDNN W,IMSOC1(I)
2045 SKIPL IMSOC1(I) ;NOT IN USE
2047 CAME E,IMSOC2(I) ;SKIP IF RIGHT LOCAL SOCKET NUMBER
2048 IMPLL1: AOBJN I,IMPLL2
2049 JUMPL I,POPJ1 ;RETURN SOCKET TABLE INDEX IN RH OF I
2052 ;INTERRUPT USER ASSOCIATED WITH CHANNEL IN I
2053 IMPUIN: MOVSI U,200000
2055 POPJ P, ;CHNL BEING CLOSED
2058 JRST IMPUIS ;JUMP IF SOCKET IS CONNECTED TO A STY.
2059 IMPUIP: HRRZ U,IMSOC1(I) ;USER INDEX
2060 LDB Q,[222000,,IMSOC1(I)] ;MASK FOR CHANNEL OPEN ON
2061 IMPUIM: AND Q,MSKST2(U) ;ONLY ENABLED CHANNELS.
2062 PUSH P,T ;VALIDATE THE USER INDEX
2069 MOVSI T,(SETZ) ;PCLSR SO IT GETS IOC ERROR IF NEEDFUL
2070 IORM T,PIRQC(U) ; EVEN IF IT DOESN'T HAVE NORMAL INTERRUPTS ENABLED
2072 IORM Q,IFPIR(U) ;GEN SECOND WORD INTERRUPT
2075 IMPUIS: PI2SAF ;HERE FOR INT. ON SOCKET CONNECTED TO A STY:
2077 SKIPL STYNTL-NFSTTY(U)
2078 POPJ P, ;ALREADY ACTIVATED
2079 MOVE Q,STYNTA ;PUT THAT STY ON THE XFER ACTIVATION LIST.
2080 MOVEM Q,STYNTL-NFSTTY(U)
2081 MOVEM U,STYNTA ;THEN RETURN. DON'T ACTUALLY INTERRUPT THE JOB;
2082 POPJ P, ;IF ANYTHING FUNNY HAS HAPPENED, STYNTC WILL INTERRUPT.
2084 ;LOOK FOR CONNECTION: LOCAL SOCKET IN E, FOREIGN SOCKET IN D, FOREIGN HOST IN H
2085 IMPLC: MOVSI I,-IMPSTL
2086 IMPLC2: SKIPGE IMSOC1(I) ;NOT IN USE
2087 CAME E,IMSOC2(I) ;LOCAL SOCKET NUMBER
2090 CAMN D,IMSOC3(I) ;FOREIGN SOCKET NUMBER
2092 IMPLC1: AOBJN I,IMPLC2
2096 IMPINR: SOJL A,IMSHRT ;SHORT COUNT
2098 DPB H,[101000,,D] ;CONCAT HOST&LINK
2100 LDB E,IMSCHD ;GET HOST FOR SOCKET
2102 AOBJN I,.-2 ;SEARCH FOR MATCHING HOST&LINK
2103 JUMPGE I,IMPILS ;NOT FOUND
2104 NCPIRS: HRRZ E,IMSOC4(I) ;STATE
2105 MOVE E,CHNBIT(E) ;BIT TO CORRESPOND
2106 TRNN E,1_%NSRFC+1_%NSRFS+1_%NSOPN+1_%NSRFN+1_%NSCLW+1_%NSINP
2107 ;OK STATES RFCRCV, RFCSNT, OPEN, RNMWT, CLSSNT, DATA
2108 JRST IMPILS ;IN BAD STATE
2109 TRNE E,1_%NSCLW ;IGNORE INT IF CLSSNT STATE (NOT ERROR)
2112 IORM D,IMSOC5(I) ;INT FLAG 4.3 BIT OF IMSOC5(SOCK)
2113 PUSHJ P,IMPUIN ;INT TO USER
2116 IMPINS: SOJL A,IMSHRT ;SHORT
2118 MOVEI I,-2(D) ;0,1 -> 777776,777777 ILLEGAL LINKS
2119 CAIGE I,IMPSTL ;CHECK IN RANGE 2 TO IMPSTL+1
2120 SKIPL IMSOC1(I);AND IN USE
2121 JRST IMPILS ;BAD LINK
2123 CAMN T,IMPCSH ;SKIP IF HOST NOT MATCHED BY MSG
2125 IMPILS: BUG INFO,[NET: BAD INT CTL MSG HST ],OCT,IMPHTN(H),[LNK ],OCT,D,[IMSOC4],OCT,IMSOC4(I)
2126 JRST IMPBKL ;NOTE- I MAY BE -1 OR -2 OR UP TO 256, IF LNK BAD, IGNORE
2128 IMPECI: AOS IMPNEI ;WILL EVENTUALLY GIVE JOB TO MAIN PROG
2131 IMPECO: ILDB D,B ;GET 8 BIT DATA TO ECHO
2134 JRST IMPECI ;ONLY ONE TO A CUSTOMER
2136 2,,1 ;TEXT: 2 BYTES, 1 WORD
2138 LSH D,20. ;DATA TO BE ECHOED
2139 TLO D,(10._28.) ;ERP
2141 PUSHJ P,IMWCQ ;SEND IT OUT
2145 IMPERM: SUBI A,11. ;COUNT BYTES
2148 MOVE C,IMPHTN(H) ;REAL HOST NUMBER
2150 MOVE C,[441100,,IMPERB+2]
2151 MOVEI D,11. ;BYTES TO COPY
2152 ILDB T,B ;COPY BYTES FROM THEIR MSG
2155 BUG INFO,[NET: ERR MSG FM HST ],OCT,IMPERB+1,[MSG],OCT,IMPERB+2,OCT,IMPERB+3
2156 ;ONLY PRINTS FIRST 8 BYTES OF ERR INFO
2157 JUMPGE A,IMPBKL ;IF COUNT OK, GET MORE
2158 JRST IMSHRT ;SHORT COUNT
2163 IMPRST: MOVE T,IMPHTN(H)
2164 ; CAIE T,<IMPUS_-6>+<IMPUS&77>_9 ;IF RST FROM OURSELVES, JUST SEND RRP
2165 CAME T,[IMPUS3-NW%ARP]
2170 1,,1 ;TEXT: 1 BYTE, 1 WORD
2172 MOVSI D,(13._28.) ;RRP
2174 PUSHJ P,IMWCQ ;SEND IT OUT
2179 IMPRSR: MOVSI I,-IMPSTL ;LOOK FOR USERS OF THIS HOST
2181 IMPRS2: TDNN TT,IMSOC1(I) ;GUY GOING AWAY ANYHOW
2184 LDB C,IMSCFH ;FOREIGN HOST
2186 JRST IMPRS1 ;WRONG HOST
2190 MOVEI D,%NSCLI ;INPUT STILL AVAILABLE
2193 DPB D,IMSCLS ;CLS REASON IS RST
2194 PUSHJ P,IMPUIN ;INTERRUPT USER
2195 IMPRS1: AOBJN I,IMPRS2
2196 ;IF HOST CAN SEND A RST, IT IS UP, BUT DON'T
2197 ;REALLY CONSIDER IT UP UNTIL RRP, RTS, OR STR IS RECEIVED
2198 ;I DON'T KNOW WHY IT'S DONE THIS WAY
2201 IMPRRP: LDB J,IMHSBT
2203 JUMPG J,IMPBKL ;ALREADY UP, MAYBE BECAUSE OF PRIOR RTS,STR
2205 DPB J,IMHSBT ;MARK HIM UP
2209 IMPRR1: BUG INFO,[NET: RRP W-O RST HST],OCT,IMPHTN(H)
2212 ;GET CONTROL QUEUE SLOT
2213 IMGCQS: SKIPG IMFCQL ;SKIP IF ANY LEFT
2215 SKIPG Q,IMFFCQ ;POINTER TO SLOT
2218 MOVEM W,IMFFCQ ;PATCH OUT OF FREE LIST
2220 SOS W,IMFCQL ;NUMBER FREE LEFT
2221 CAIN W,1 ;SKIP IF MORE THAN ONE LEFT
2222 SETOM IMPHI ;SET FLAG TO HOLD UP INPUT
2228 IMWCQ: PUSHJ P,IMWPCQ
2229 JRST IMPIOS ;START OUTPUT
2231 ;ADD BLOCK IN Q TO OUTPUT CONTROL QUEUE, BASHES W
2234 JRST IMWCQ1 ;CONTROL QUEUE EMPTY
2236 JRST 4,. ;END OF QUEUE DIDN'T POINT TO -1
2241 IMWCQ1: MOVEM Q,IMPLCQ
2245 ;ADD MAIN PROGRAM BLOCK TO PI QUEUE (CALL AT MP LEVEL)
2247 IORM Q,IMPMPU+1 ;NOT LOCKED BY THIS JOB ANY MORE
2248 SKIPL U ;SKIP IF CALLED FROM DIRECT-CONNECT CLOCK LEVEL
2249 PUSHJ P,LSWDEL ;PI LEVEL WILL UNLOCK
2256 ;CALL BY JSP T,IMSTCM
2257 ;SET UP STANDARD PI CONTROL MESSAGE
2258 ;BYTE COUNT,,TEXT LENGTH
2261 IMSTCM: PUSHJ P,IMGCQS ;GET CONTROL QUEUE SLOT IN Q
2262 JRST 1(T) ;NONE AVAILABLE
2263 MOVSI H,17_10. ;MESSAGE TYPE = 0, LINK # = 0, NEW FMT
2265 MOVE H,IMPCSH ;GET IMP AND HOST
2267 IFN 1, DPB H,[103000,,3(Q)] ; Store host addr
2268 IFN 0,[ DPB H,[301000,,3(Q)] ;STORE HOST
2270 DPB H,[102000,,3(Q)] ;STORE IMP
2272 HLRZ H,(T) ;BYTE COUNT
2274 IOR H,[8_24.] ;BYTE SIZE = 8
2278 MOVSM H,1(Q) ;HOST INDEX,,TEXT LENGTH
2279 JRST 2(T) ;NORMAL RETURN (NOTE THAT H HAS BEEN RESTORED TO IMPCSH)
2281 ;RECEIVED LEADER OF REGULAR MESSAGE NOT ON CONTROL LINK
2282 ;THE HOST-HOST LEADER WORD (WD 6) HAS NOT YET BEEN DATAI'ED.
2283 ;SWITCH TO 32-BIT MODE FIRST IF NECESSARY.
2286 CAIE B,IMPILB+4 ; Verify that NCP leader is next word
2287 JRST IMPLD3 ; Barf...
2293 SUBI I,2 ;SOCKET TABLE INDEX
2294 JUMPL I,IMPRM7 ;BAD LINK #
2296 TLNE A,200000 ;SKIP IF NOT BEING CLOSED
2297 JRST IMPRM7 ;SOCKET DOESNT EXIST OR BEING CLOSED
2300 TDNE A,IMSOC2(I) ;SKIP IF RECEIVER
2301 JRST IMPRM7 ;BAD LINK # OR MESSAGE FOR A SENDER
2302 LDB C,IMSCHD ;HEADER
2303 CAME D,C ;SEE IF HEADERS AGREE
2304 JRST IMPRM7 ;NOPE, I.E. FROM WRONG HOST OR CLOSED
2310 IMPRMA: SKIPGE IMSOC6(I) ;SKIP IF NOT LOCKED BY CORE JOB
2311 JRST IMPRMP ;LOCKED, COME BACK LATER
2313 SKIPL IMSOC5(I) ;SKIP IF 32 BIT TRANSFER
2314 CONO IMP,IMI32C ;SET 36 BIT INPUT
2315 SKIPGE IMSOC5(I) ;SKIP IF NOT 32 BIT TRANSFER
2316 CONO IMP,IMI32S ;SET 32 BIT INPUT
2318 SKIPL IMSOC5(I) ;SKIP IF 32BIT
2319 CONO FI,FII32C ;SET 36BIT
2320 SKIPGE IMSOC5(I) ;SKIP IF 36 BIT
2321 CONO FI,FII32S ;SET 32 BIT
2323 DATAI IMP,IMPILB+5 ;GET THE HEADER WORD
2326 LDB B,IMSCBS ;Check for fraudulent byte size
2328 JRST IMPRMZ ;Discard message
2331 MOVEM B,IMPNBI ;SAVE BYTE COUNT FOR LATER
2333 JRST IMRMAF ;MESSAGE ALLOCATION EXCEEDED
2334 JUMPE B,IMPIRT ;ZERO LENGTH MESSAGE
2337 ADDB D,IMSOC7(I) ;REMAINING BIT ALLOCATION
2338 JUMPL D,IMRMAH ;BIT ALLOCATION EXCEEDED
2340 JRST IMRMAG ;MESSAGE IS SHORT
2342 IORB D,IMSOC6(I) ;ACTIVE AT PI LEVEL
2348 ADDI A,1 ;NUMBER OF WORDS MESSAGE WILL TAKE
2349 HRRZ B,IMSPIP(I) ;ADDRESS WHERE MESSAGE HEADER WILL GO
2351 JRST 4,. ;HEADER WORD SHOULD BE -1
2352 HRRZ C,IMSBFE(I) ;GET ADDRESS OF LAST WORD IN BUFFER
2354 MOVEI B,-1(D) ;HEADER IS LAST IN BUFFER, SO DATA IS FIRST
2355 MOVE E,B ;RH(BLKI POINTER) IN E
2356 ADD A,B ;ADDRESS WHERE LAST WORD OF MESSAGE WILL GET STORED
2357 SETZM IMNWSI ;ASSUME WILL ONLY NEED ONE BLKI
2359 JRST IMPRM8 ;JUMP IF NO WRAP
2362 SUB B,C ;- # WDS TO READ FIRST TIME
2363 SUB A,C ;+ # WDS TO READ SECOND TIME
2367 MOVN C,A ;NEG OF REMAINING WORD COUNT
2368 MOVSS C ;TO LEFT HALF FOR BLKI POINTER
2369 HRRI C,-1(D) ;RING AROUND TO BEGIN OF BUFFER
2370 MOVEM C,IMNWSI ;STORE FOR INTCHN BLKI RUNOUT (FLAG IF -)
2372 HRRZM C,IMPNIW ;EXPECTED END OF BLKI
2374 IMPRM8: SUBM B,A ;A GETS - # WORDS TO READ
2376 HRL B,A ;BLKI POINTER
2377 SUB E,A ;EXPECTED LAST WORD
2378 SKIPE IMNWSI ;IF DOING 2 BLKIS, EXPECTED END ALREADY STORED
2380 MOVEM E,IMPNIW ;EXPECTED LAST BLKI ADDRESS
2381 HRRZ A,IMSPIP(I) ;SEE IF CLOBBERING GOOD-DATA PART OF BUFFER
2382 CAIL A,@IMSMPP(I) ;SKIP IF MPP > PIP
2390 IMPRMT: HRRZ A,IMSOC6(I) ;SEE IF CLOBBERING CORE NOT PART OF BUFFER
2394 HRRZM I,IMPIPI ;THIS SOCKET NOW ACTIVE AT P.I. LEVEL
2395 MOVEI C,%ISIND ; New state = reading NCP data message
2396 JRST IMPRM9 ; Start reading
2398 IMPRMP: MOVSI D,100000 ;SET INPUT HELD UP BY CORE JOB
2403 SETZM IMPPIA ;TURN OFF NETWORK FOR A WHILE
2405 IFN DMIMP,CONO FI,FIIN+0 ;SET PIA TO 0 FOR A WHILE, CORE JOB WILL GET BACK
2416 ; Got Last Imp Word (in A) of regular NCP data message
2417 ; Comes here from IMPBKX.
2419 IMPRMB: MOVE I,IMPIPI
2422 JRST IMPRMC ;ONE EXTRA WORD OF IMP PADDING, IGNORE IT
2423 ADD B,[1,,1] ;ADDR TO NEXT WORD, COUNT TO ZERO
2426 MOVEM A,(B) ;STORE LAST WORD
2427 IMPRMC: MOVE E,IMPNBI ;# BYTES IN
2428 ADDM E,IMSMPC(I) ;MAKE AVAIL TO M.P.
2429 MOVEM E,@IMSPIP(I) ;STORE HEADER
2430 AOS E,IMPNIW ;WORD AFTER MSG WILL BE NEXT HEADER
2432 HRRZ E,IMSOC6(I) ;WRAP
2433 HRRM E,IMSPIP(I) ;LEAVE LH OF IMSPIP ALONE
2435 JRST 4,. ;BUFFER 1 WORD TOO SMALL?
2438 HRRM E,IMSOC4(I) ;INPUT AVAILABLE
2439 PUSHJ P,IMPUIN ;INTERRUPT USER
2440 MOVSI D,200000 ;CLEAR ACTIVE AT P.I. LEVEL
2445 IMPRMY: HRRZ E,IMPNIW ;NOT ENDING WHERE IT'S SUPPOSED TO
2446 SUBI E,(B) ;E GETS NUMBER OF MISSING WORDS
2448 BUG INFO,[NET: MSG FM HST ],OCT,IMPHTN(H),[SHORT ],DEC,E,[WDS, BC],DEC,IMPCBC
2449 JRST IMPRMC ;PRETEND HOST TRANSMITTING GARBAGE
2451 IMPRMZ: MOVE H,IMPCSH
2452 BUG INFO,[NET: HST ],OCT,IMPHTN(H),[SENT BYTE SIZE ],DEC,A,[SHOULD BE],DEC,B
2453 JRST IMPIRT ;Discard message
2455 SUBTTL ARPANET NCP OUTPUT INTERRUPT LEVEL
2457 ;HERE ON COMPLETION OF TRANSMISSION OF CONTROL MESSAGE
2461 JRST IMPRET ;THAT WAS A NOP
2462 HLRZ B,1(A) ;HOST TABLE INDEX
2464 IORM D,IMPHTB(B) ;SET RFNM WAIT BIT
2466 LDB D,[051100,,TIME]
2467 DPB D,[221100,,IMPHTB(B)] ;STORE TIME TOO
2474 JRST 4,. ;IMPLCQ GAVE WRONG LAST MESS NO.
2478 IMOB7A: CAIN A,IMPMPL ;SKIP IF NOT MAIN PROG BLOCK
2483 JRST 4,. ;MAKING INFINITE LOOP
2487 SKIPGE B,IMPHI ;RETURN IF INPUT NOT HELD UP
2488 CAIG A,1 ;SKIP IF INPUT HELD UP AND NOW ENOUGH FREE
2491 AOJE B,IMPRET ;INPUT WAS NOT YET SUCCESSFULLY HELD UP
2492 AOJN B,[JRST 4,.] ;IMPHI SHOULD HAVE BEEN -2
2494 MOVE TT,IMSTAS ;GET OLD CONI
2504 TRNE TT,IMPLW ;RESUME INPUT
2510 ;HERE ON COMPLETION OF TRANSMISSION OF DATA MESSAGE
2516 AOS IMSOC4(I) .SEE %NSRFN ;PUT INTO RFNM WAIT STATE
2521 ANDCAB Q,IMSOC6(I) ;NO LONGER ACTIVE AT P.I. LEVEL
2523 MOVN A,IMPNBT ;BITS SENT
2524 ADDM A,IMSC7I(I) ;DECREASE BITS IN BUFFER
2525 ADDB A,IMSOC7(I) ;DECREASE ALLOCATION
2526 SKIPL A ;SKIP IF ALLOC LOST
2527 SOSGE IMSOC8(I) ;SKIP IF MSG ALLOC DIDN'T LOSE
2530 TLNN Q,140000 ;INTERRUPT USER IF DIRECT CONNECT (CHEAP), DEPEND ON ALLOC,
2531 SKIPN IMSMPC(I) ; OR IF OUTPUT BUFFER WAS FULL,
2532 PUSHJ P,IMPUIN ; SINCE HE MAY WANT TO SEND MORE
2533 MOVE A,IMPNBO ;# BYTES FREED IN BUFFER BY REMOVAL OF MSG
2534 ADDM A,IMSMPC(I) ;SPACE USED BY MESSAGE NOW FREE
2535 MOVE A,IMPNPT ;UPDATE IMSPIP
2536 HRRZ Q,IMSOC6(I) ;VALIDATE THIS
2538 JRST 4,. ;POINTS BEFORE BUFFER
2541 JRST 4,. ;POINTS AFTER BUFFER
2542 MOVEM A,IMSPIP(I) ;..
2545 ;OUTPUT A DATA MESSAGE.
2549 SKIPL IMSOC4(I) ;SKIP IF WANT TO SEND THIS BUFFER
2550 CAIL T,30.*2 ;SKIP IF BUFFER FIRST WRITTEN LESS THAN 2 SEC AGO
2552 JRST IMPOBA ;DON'T SEND NOW, GO BACK AND LOOK FOR OTHERS
2554 IMOBD1: MOVE TT,IMSPIP(I)
2555 CAMN TT,IMSMPP(I) ;SKIP IF ANY BITS TO SEND
2557 SKIPE IMSOC7(I) ;SKIP IF NO BITS ALLOCATED
2558 SKIPN IMSOC8(I) ;SKIP IF MSG ALLOCATED
2559 JRST IMPOBA ;NO BITS OR NO MSGS ALLOWED
2561 IORB Q,IMSOC6(I) ;ACTIVE AT PI LEVEL
2563 ;CODE TO SEND OUT A BUFFER OR PARTIAL BUFFER
2564 ;ON ENTRY - I/ SOCKET TABLE INDEX
2565 ; Q/ BUFFER POINTER FROM IMSOC6
2566 ; TT/ BYTE POINTER TO FIRST BYTE TO SEND
2567 ;SETS UP - T/ WORD SIZE (32 OR 36)
2568 ; E/ FLAGS FROM IMSOC5
2574 MOVEM T,IMOB0Z ;SAVE FOR DEBUGGING
2576 SKIPL E,IMSOC5(I) ;SKIP IF IN 32BIT MODE
2577 MOVEI T,36. ;SET 36BIT
2578 LDB B,IMSCBS ;BYTE SIZE
2579 HRRZ C,IMSMPP(I) ;COMPUTE # OF BYTES TO SEND
2581 JUMPL C,[MOVE D,IMSBFE(I) ;WRAPS AROUND
2583 ADDI C,1(D) ;SO ADD # WDS IN BUFFER
2585 IMUL C,T ;FIRST GUESS AT NUMBER OF BITS
2586 LDB A,[360600,,TT] ;GETS POSITION FIELD OF BYTE PTR
2587 LDB D,[360600,,IMSMPP(I)]
2588 SUBM A,D ;CORRECTION TO NUMBER OF BITS
2589 ADD C,D ;C NOW HAS NUMBER OF SENDABLE BITS IN BUFFER
2590 SKIPL E ;SKIP IF 32BIT
2591 JUMPN A,IMOB5A ;36BIT - JUMP IF NOT 0 (MIDDLE OF WORD)
2592 CAILE A,4 ;32BIT - SKIP IF 4, OR 36BIT 0 - SKIP IF NOT MID-WORD
2593 JRST IMOB5B ;32BIT MID-WORD - SEND PART OR REST OF WORD
2594 CAME TT,IMSBFE(I) ;AT RIGHT OF WORD, IS IT LAST WORD?
2595 AOSA TT ;NO, ADVANCE TO NEXT
2596 HRR TT,Q ;YES, WRAP AROUND TO FIRST
2597 TLO TT,440000 ;SWITCH FROM RIGHT OF WORD TO LEFT OF WORD
2598 CAMG C,IMSOC7(I) ;SKIP IF TOO BIG FOR ALLOCATE
2599 CAILE C,8000. ;FITS IN ALLOCATE, SKIP IF FITS IN IMP MESSAGE
2600 JRST IMOB1 ;MUST SEND LESS THAN ALL THE BITS IN BUFFER
2601 IMOB0F: MOVE D,IMSMPP(I) ;SENDING WHOLE BUFFER
2602 LDB J,[360600,,D] ;ADVANCE IMSMPP TO NEXT WORD BOUNDARY
2603 ADDI J,-36.(T) ;RH(J) := # BITS TO ADVANCE TO WORD BOUNDARY
2606 ADDM J,IMSMPC(I) ;SUBTRACT FROM FREE THE BYTES SKIPPED OVER
2607 MOVNM J,IMPNBO ;BUT RETURN TO FREE AFTER TRANSMISSION
2608 HLL D,IMSBFE(I) ;NOW ADVANCE IMSMPP TO RIGHT END OF WORD
2609 MOVEM D,IMSMPP(I) ;AND IMSPIP WILL GET SET EQUAL TO IMSMPP
2610 IMOB0A: MOVEM D,IMPNPT ;ILDB -> FIRST BYTE TO SEND OUT NEXT TIME
2611 JUMPLE C,[JRST 4,.] ;SOMEBODY COMPUTED BAD # BITS
2613 IDIV C,B ;C := # BYTES GETTING SENT
2614 JUMPN D,[JRST 4,.] ;LOSS, TRYING TO SEND PARTIAL BYTE
2615 ADDM C,IMPNBO ;# BYTES TO RETURN TO FREE AFTER MSG SENT
2616 MOVEM A,IMPNBT ;# BITS TO SUBTRACT FROM ALLOCATION THEN
2619 ;NOW SET UP BUFFER HEADER FOR IMP MESSAGE IN IMOLDR
2620 ; TT -> FIRST WORD TO SEND
2621 ; A NUMBER OF BITS TO SEND
2627 LDB H,IMSCFH ;HOST TABLE INDEX
2628 MOVEI Q,IMOLDR-2 ;HACK HACK
2629 PUSHJ P,STHSTP ;STORE HOST NUMBER, MESSAGE TYPE 0
2630 LDB Q,IMSCLN ;LINK NUMBER
2631 DPB Q,[001000,,IMOLDR+1]
2632 LDB Q,[221000,,IMSOC6(I)] ;GET BUFFER TYPE
2636 DPB D,[400400,,IMOLDR+1] ;STORE HANDLING TYPE, DEPENDING ON BUFFER SIZE
2637 DPB B,[201000,,C] ;STORE SIZE IN SAME WD AS COUNT
2639 MOVEM C,IMOLDR+5 ;HOST-HOST HEADER - 00,SIZE,BYTE-COUNT,0000
2640 IFN KAIMP,CONO IMP,IMO32C
2641 IFN DMIMP,CONO FI,FIO32C ;36BIT MODE FOR HEADER, AND NO PIA YET
2642 DATAO IMP,IMOLDR ;OUTPUT THE FIRST LEADER WORD
2643 SETZM IMOPNT ;START AT BEGINNING OF IMOLST
2644 MOVE B,[-5,,IMOLDR] ;SEND REST OF LEADER
2649 MOVEM B,IMOMOD ;SEND DATA IN 32 OR 36 BIT MODE AS APPROPRIATE
2650 ADDI A,-1(T) ;ROUND UP IF NOT EXACT
2651 IDIV A,T ;# WDS TO SEND
2652 MOVEI D,-1(TT) ;FIRST WORD TO SEND MINUS ONE
2653 ADDI D,(A) ;LAST WORD TO SEND
2654 CAIG D,@IMSBFE(I) ;SKIP IF WRAP
2656 HRRZ B,IMSBFE(I) ;COMPUTE # TO SEND FIRST TIME
2657 SUBI B,-1(TT) ;B GETS PLUS NUMBER TO SEND FIRST TIME
2658 SUBM B,A ;A GETS MINUS NUMBER TO SEND SECOND TIME
2660 HRLI C,-1(TT) ;C GETS SWAPPED BLKO POINTER FOR FIRST TIME
2661 MOVE Q,IMSOC6(I) ;POINTER TO BUFFER
2663 MOVEI B,3 ;SEND LAST WORD SEPARATELY
2666 ] HRLI A,-1(Q) ;BLKO POINTER FOR SECOND TIME
2671 HRROM A,IMOBK3 ;STORE BLKO POINTER TO LAST WORD
2675 IMOB7: MOVSI C,3 ;NO WRAP, SO NO SECOND BLKO
2679 HRROM D,IMOBK3 ;DO LAST WORD SEPARATELY
2680 SOJE A,IMOB8 ;SPECIAL CASE LAST WORD IS ONLY WORD
2682 MOVNI C,(A) ;MAKE BLKO POINTER
2684 IMOB8: MOVSM C,IMOBK1
2685 MOVSI TT,400000 ;TURN OFF "SEND ME"
2687 HRRZM I,IMPOPI ;SAVE INDEX FOR BLKO RUNOUT
2689 MOVEI C,%ISOND ;STATE FOR "END OF DATA"
2692 ;BUFFER CANNOT BE SENT AS 1 MSG. GRT ALLOC OR 8000 BITS.
2694 IMOB1: MOVE C,IMSOC7(I) ;ALLOC
2696 MOVEI C,8000. ;C := MIN(BITS IN BUFFER, ALLOC, MAX IMP MSG SIZE)
2697 TLNE E,2000 ;SKIP IF BYTES EXACTLY FIT IN WORD
2698 JRST IMOB3 ;MUST SEND MULTI WORDS
2699 CAMGE C,T ;SKIP IF ALLOC GEQ WDSIZ
2700 JRST IMOB2 ;MUST SEND PART WORD
2703 IMUL C,T ;#BITS IN THOSE WDS
2704 IMOB1A: ADDI D,-1(TT) ;LAST WORD OUTPUT
2707 SUBI D,@IMSBFE(I) ;WRAP AROUND
2709 HLL D,IMSBFE(I) ;PUT IN BYTE PART (RIGHT END OF WORD)
2710 JRST IMOB0A ;BUILD HEADER AND OUTPUT
2712 ;SEND PART OF WORD BECAUSE ALLOC IS TOO SMALL
2714 IMOB2: MOVE D,TT ;-> FIRST BYTE TO BE SENT
2715 MOVNI A,-36.(C) ;36-BITS SENT
2716 DPB A,[360600,,D] ;IS NEXT BYTE TO GO
2719 ;SEND PARTIAL BUFFER OF BYTES WHICH DO NOT FIT EXACTLY IN WORDS (E.G. 7BIT BYTES)
2720 ;MUST SEND A "QUANTUM" WHICH FOR LAZINESS' SAKE IS 36 BYTES
2722 IMOB3: MOVEI A,36. ;#BITS IN A WORD
2723 IMUL A,B ;#BITS IN A QUANTUM
2725 JUMPE C,IMOB4 ;NOT ENOUGH ALLOC FOR EVEN 1 QUANTUM, SORRY CHARLIE
2727 IMUL C,A ;#BITS TO SEND
2728 IMUL D,B ;#WDS TO SEND (36 BYTES TAKE <BYTESIZE> WDS)
2731 ;NEED MORE ALLOCATE TO SEND A BUFFER FOR THIS ODD-SIZE CONNECTION
2733 IMOB4: MOVSI T,200000
2734 ANDCAM T,IMSOC6(I) ;CLEAR "ACTIVE AT PI LEVEL" BIT
2735 JRST IMPOBA ;MAYBE TRY ANOTHER ONE
2737 ;SENDING REST OF PARTIAL WORD (PI PTR NOT AT WORD BOUNDARY)
2738 ;A/ BITS LEFT IN WORD
2740 IMOB5A: SKIPA C,A ;36BIT GETS WHOLE WD
2741 IMOB5B: HRREI C,-4(A) ;32BIT GETS 4 LESS
2742 MOVNI J,-36.(A) ;# BITS SHIFT TO LEFT JUSTIFY
2744 CAIN D,@IMSMPP(I) ;IF WHOLE REST OF BUFFER IS IN THIS WORD
2745 JRST [ LDB D,[360600,,IMSMPP(I)]
2746 SUB A,D ;A := NUMBER OF BITS TO SEND
2747 MOVE C,(TT) ;ALIGN BITS TO BE SENT IN LEFT OF WORD
2751 JRST IMOB0F ] ;RE-ALIGN POINTERS TO WORD BOUNDARY
2752 CAMLE C,IMSOC7(I) ;SKIP IF WILL FIT IN ALLOC
2753 JRST IMOB6 ;MUST SEND BYTES NOT LEFT JUST IN WD, AND MORE TO RIGHT
2754 MOVE D,(TT) ;GET WORD
2755 LSH D,(J) ;LEFT JUSTIFY
2758 HLL D,IMSBFE(I) ;ADVANCE PI POINTER TO END OF THIS WORD
2759 JRST IMOB0A ;BUILD HDR & SEND
2761 ;SEND MIDDLE PART OF WORD. BECAUSE OF SMALL ALLOCATES, THE LEFT END OF THE
2762 ; WORD WAS SENT AND ALSO THERE IS NOT ENOUGH ALLOCATE TO SEND THE REST
2763 ; OF THE ONE WORD. THIS MIGHT NEVER OCCUR EXCEPT FOR 8 BIT BYTES.
2764 ;MUST MOVE GOOD BITS TO LEFT END OF WORD, WITHOUT DISTURBING BITS TO THE RIGHT
2766 IMOB6: MOVE C,IMSOC7(I) ;CAN ONLY SEND ALLOC BITS
2767 SUB A,C ;POS OF LO BIT TO PICK UP
2768 DPB A,[360600,,TT] ;POS IN BYTE PTR
2769 MOVE D,TT ;SAVE ADVANCED PI PNTR
2770 DPB C,[300600,,TT] ;STORE AS SIZE OF BYTE
2772 MOVNI A,-36.(C) ;POS OF LO BIT TO STORE
2773 DPB A,[360600,,TT] ;POS IN B PTR
2774 DPB R,TT ;STORE BYTE AWAY
2775 JRST IMOB0A ;SEND THE BYTE(S)
2777 OVHMTR UUO ;YET MORE RANDOM UUOS