Consolidate license copies
[its.git] / system / impold.wthncp
1 ;;; -*- Mode:MIDAS -*- 
2 ;;; Copyright (c) 1999 Massachusetts Institute of Technology
3 ;;;
4 ;;; This program is free software; you can redistribute it and/or
5 ;;; modify it under the terms of the GNU General Public License as
6 ;;; published by the Free Software Foundation; either version 3 of the
7 ;;; License, or (at your option) any later version.
8 ;;;
9 ;;; This program is distributed in the hope that it will be useful,
10 ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
11 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 ;;; General Public License for more details.
13 ;;;
14 ;;; You should have received a copy of the GNU General Public License
15 ;;; along with this program; if not, write to the Free Software
16 ;;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 SUBTTL  ARPANET HARDWARE DEFINITIONS
19
20 IFNDEF BLIMPP,BLIMPP==INETP     ; Use IMP blockage avoidance code
21 IMPVRS==.IFNM2  ; Version of IMP/NCP code
22
23 IFN KAIMP,[
24 ; Hardware description of AI-KA/ML/MC IMP interface, device "IMP".
25 ; For a more detailed description, see AI Hardware Memo #10,
26 ; "ARPA Network Interface".
27 ; In particular, the "channel 1 multiplexing" feature of the ITS KA's
28 ; is used, so that:
29 ; When PI level 2 (NETCHN) is assigned, the IMP interface takes
30 ;       all interrupts on the normal channel (goes to IMPINT).
31 ; When PI level 1 (IMPCHN) is assigned,
32 ;       IMPID+(-IMPLIW) => Pseudo channel 4, location 70 (IMPILC)-> various
33 ;       IMPOD => Pseudo channel 5, location 72 (IMPOLC)-> various
34 ;       else normal PI channel 1 (PI0LOC+2)-> IMPBRK
35
36 ; CONI bits - starred items cause interrupt on PIA channel
37                 ; 1.1-1.3 => PIA
38 IMPID==10       ;* INPUT DONE - Turned on when interface has word for DATAI
39 IMPI32==20      ; Input in 32 bit mode
40 ;IMPIB==40      ; Input Busy
41 IMPOD==100      ;* OUTPUT DONE - Interface has finished giving word to IMP
42 ;IMPO32==200    ; Output in 32 bit mode
43 ;IMPOB==400     ; Output Busy
44 IMPERR==1000    ;* Imp Error (interrupt if IMPIC zero)
45 IMPR==2000      ;* Imp Ready (interrupt if IMPIC set)
46 ;IMPIC==4000    ; Imp interrupt condition (0 = int on IMPERR, 1= int on IMPR)
47 IMPHER==10000   ;* Host Error (interrupt if IMPIHE zero)
48 ;IMPHR==20000   ; Host Ready
49 ;IMPIHE==40000  ; Inhibit interrupt on Host Error (IMPHER)
50 IMPLW==100000   ;* Last Imp Word
51
52 ; CONO bits - starred flags are always copied directly to set states
53                 ;* 1.1-1.3 => PIA set from these bits
54 IMPIDC==10      ; Clear Input Done
55 IMI32S==20      ; Set input to 32 bit mode
56 IMI32C==40      ; Clear input in 32 bit mode
57 IMPODC==100     ; Clear Output Done
58 IMO32S==200     ; Set output to 32 bit mode
59 IMO32C==400     ; Clear output in 32 bit mode
60 IMPODS==1000    ; Set Output Done
61 IMPIR==4000     ;* Copied to IMPIC; 1= Enable int on imp ready
62 IMPHEC==10000   ; Clear Host Error
63 ;IMIIHE==40000  ;* Copied to IMPIHE; 1= Inhibit int on host error
64 IMPLHW==200000  ; Set Last Host Word (do this before last DATAO of msg)
65
66 ];DMIMP
67 \fIFN DMIMP,[    ;HARDWARE DESCRIPTION OF DM IMP INTERFACE (PER RMM)
68
69 ; Note that all PI level 2 interrupts go to normal ITS location
70 ;       and thence vectored to IMPINT.
71 ; However, PI 1 interrupts go to different places:
72 ;       Input Done -> loc 70 (IMPILC)
73 ;       Output Done -> loc 72 (IMPOLC)
74 ;       Control -> Should never get control interrupt at PI 1.
75 ;               Thus for example "Last Imp Word" interrupts go to
76 ;               IMPINT even though input side PIA is 1, because LIW is
77 ;               a control interrupt and control ints are always kept at PI 2.
78
79         ;IMP INTERFACE CONO FLAG DESCRIPTION
80
81 ;COMMON FLAG BITS TO CONTROLLER
82
83                 ;18-> 0 FOR INPUT SIDE, 1 FOR OUTPUT SIDE
84                 ;19->CLEAR TEST MODE (200000)
85                 ;20->SET TEST MODE (100000)
86
87                 ;21->CLEAR HOST READY
88                 ;22->SET HOST READY (20000)
89                 ;23->CLEAR IMP-WAS-DOWN (10000)
90
91                 ;24->FI DEVICE RESET (CLEAR ALL INPUT AND OUTPUT FLAGS) (4000)
92
93 ;CONO FI (424) TO OUTPUT SIDE
94         ;BIT    ;18->IS '1' INDICATING TO OUTPUT
95                 ;25->CLEAR OUTPUT 32-BIT MODE
96                 ;26->SET OUTPUT 32-BIT MODE
97
98                 ;27->SET OUTPUT EOT (CLEAR DONE, SET BUSY) (400)
99                 ;28->SET OUTPUT DONE (200)
100                 ;29->RESET OUTPUT (CLEAR ALL OUTPUT FLAGS) (100)
101
102                 ;30-32->CONTROL PI ASSIGNMENT
103
104                 ;33-35->OUTPUT DONE PI ASSIGNMENT
105
106 ;CONO FI (424) TO INPUT SIDE
107         ;BIT    ;18->IS '0' INDICATING TO INPUT
108                 ;25->CLEAR 32-BIT MODE (2000)
109                 ;26->SET 32-BIT MODE (1000)
110
111                 ;27->SUSPEND INPUT (400) DATAI WONT SET BUSY NOW
112                 ;28->SET INPUT BUSY (LISTENING TO NETWORK) (200)
113                 ;29->RESET INPUT (CLEAR ALL INPUT FLAGS!) (100)
114
115                 ;30-32->CONTROL PI ASSIGNMENT
116
117                 ;33-35->INPUT DONE PI ASSIGNMENT
118
119         ;FI CONI FLAG DESCRIPTION
120
121         ;BIT    ;00->TEST MODE IS ENABLED
122                 ;08->OUTPUT IS IN 32-BIT MODE
123                 ;17->INPUT IS IN 32-BIT MODE
124
125                 ;18->IMP IS DOWN
126                 ;19->IMP WAS DOWN
127                 ;20->HOST READY (?)
128
129                 ;21->OUTPUT EOT ON
130                 ;22->OUTPUT BUSY
131                 ;23->OUTPUT DONE
132                 ;24-26->OUTPUT-DONE PI ASSIGNMENT
133
134                 ;27->INPUT EOT ON
135                 ;28->INPUT BUSY
136                 ;29->INPUT DONE
137
138                 ;30-32->CONTROL INTERRUPT PI ASSIGNMENT
139
140                 ;33-35->INPUT DONE PI ASSIGNMENT
141
142 ;       SYMBOL ASSIGNMENTS FOR DM HARDWARE
143
144 ;       CONO BITS
145
146 FIIN==000000    ;(SIC) SPECIFY CONO FOR INPUT
147 FIOUT==400000   ;SPECIFY CONO FOR OUTPUT SIDE
148 ;FITSTC==200000 ;CLEAR TEST MODE
149 ;FITSTS==100000 ;SET TEST MODE
150
151 ;FIHSTC==040000 ;CLEAR HOST READY
152 FIHSTS==020000  ;SET HOST READY
153 FIIWDC==010000  ;CLEAR "IMP WAS DOWN"
154
155 FIRSET==004000  ;DO LOCAL IOB RESET FOR FI DEVICE
156
157 ;INPUT SIDE ONLY
158
159 FII32C==002000  ;CLEAR 32 BIT MODE, INPUT
160 FII32S==001000  ;SET 32 BIT MODE, INPUT
161
162 FISUSP==000400  ;"SUSPEND INPUT" CLEAR FLAG, NOT SET BUSY
163 FIIBSY==000200  ;SET INPUT BUSY, ALLOWS BITS IN FROM IMP
164 FIIDC==000100   ;CLEAR INPUT DONE
165
166 ;       0000X0  ;CONTROL PIA
167
168 ;       00000X  ;INPUT DONE PIA
169
170 ;OUTPUT SIDE ONLY
171
172 FIO32C==402000  ;CLEAR 32 BIT MODE, OUTPUT
173 FIO32S==401000  ;SET 32 BIT MODE, OUTPUT
174
175 FILHW==400400   ;SET "LAST HOST BIT TO IMP"
176 FIODS==400200   ;SET OUTPUT DONE
177 FIODC==400100   ;CLR OUTPUT DONE
178
179 ;       0000X0  ;CONTROL PIA
180
181 ;       40000X  ;OUTPUT DONE PIA
182
183 ;       CONI BITS
184
185 ;       LEFT HALF OF CONI WORD FOR FOLLOWING 3 BITS
186
187 ;FITSTM==400000 ;TEST MODE IS ON
188 ;FIO32==001000  ;OUTPUT IS IN 32 BIT MODE
189 FII32==000001   ;INPUT IS IN 32 BIT MODE
190
191 ;       RIGHT HALF OF CONI
192
193 FIDOWN==400000  ;IMP IS DOWN
194 FIWASD==200000  ;IMP WAS DOWN (OR IS) SINCE LAST RESET
195 ;FIHSTR==100000 ;HOST READY IS SET ON
196
197 ;FIOEOT==040000 ;OUTPUT LAST IMP BIT IS ON
198 ;FIOBSY==020000 ;OUTPUT IS BUSY AFTER DATAO
199 FIOD==010000    ;OUTPUT IS DONE, (INTERRUPTING)
200
201 ;       00X000  ;OUTPUT DONE PIA
202
203 FILW==000400    ;LAST BIT SET FROM IMP
204 FIIBSY==000200  ;INPUT IS BUSY, WORD BEING ASSEMBLED FROM IMP
205 FIID==000100    ;INPUT IS DONE (INTERRUPTING) TO DO DATAI
206
207 ;       0000X0  ;CONTROL PIA
208
209 ;       00000X  ;INPUT PIA
210
211 IMPLW==FILW     ;USEFUL TO TEST IN AC
212 IMP==FI         ;USEFUL FOR BLKO, DATAO INSTR
213 ]
214 \f
215 ; IMP 1822 PROTOCOL INFORMATION (EXTENDED-LEADER VERSION)
216
217 ; The IMP leader is 96 bits long, usually organized as 3 words of 32 bits.
218 ; For further details, these documents are available from the Network
219 ; Information Center:
220 ;       IMP-HOST protocol: BBN Report No. 1822
221 ;       NCP protocol: NIC 8246, Host-to-Host Protocol for the ARPANET
222 ;       IP, TCP: Internet Protocol Transition Workbook, and
223 ;                Internet Protocol Implementor's Guide
224 ;
225 ; For the benefit of the NCP code, ITS reads in the leader as 36-bit words
226 ; with sufficient IMP padding (5 16-bit wds) to cause NCP data to be aligned
227 ; on a word boundary. The first 4 words of the leader are read
228 ; in 36-bit mode:
229 ;------------------------------------------------------------------------
230 ;1:  4.9-4.6 not used (0)
231 ;    4.5-4.2 all 1's for new format, else old msg type (4=old nop)
232 ;    4.1-3.3 network number (0)
233 ;    3.2-2.8 not used (0)
234 ;        2.7 trace (ignored)
235 ;    2.6-2.4 leader flags (2.6 is to be ignored, 2.5-2.4 are not used!)
236 ;    2.3-1.5 message type (as of yore, but more bits) (see IMTDT)
237 ;    1.4-1.1 high 4 bits of handling type (0)
238 ;
239 ;2:  4.9-4.6 Low bits of handling type (7 for big buffers, 4 for small buffers,
240 ;    4.5-3.7 host number                        and 0 for the control link)
241 ;    3.6-1.9 Imp number
242 ;    1.8-1.1 Link number (high 8 bits of message-id)
243 ;
244 ;3:  4.9-4.6 Low 4 bits of message-id (0)
245 ;    4.5-4.2 Sub-type
246 ;    4.1-2.4 Message length (ignored)
247 ;    2.3-1.1 Padding
248 ;------------------------------------------------------------------------
249 ;               All non-regular messages (ie Host-Imp, not Host-Host)
250 ;               stop here, since padding and data only exist for regular
251 ;               messages (Type 0).
252 ;------------------------------------------------------------------------
253 ;4:  4.9-1.1 Padding
254 ;------------------------------------------------------------------------
255 ;               At this point there are still 32 bits of padding left.  The
256 ;               Internet Protocol messages are vectored off here (they are
257 ;               identified by a message-type of 0 and a link-number of 233).
258 ;------------------------------------------------------------------------
259 ; HOST-HOST REGULAR MESSAGES
260 ;       NETWORK CONTROL PROTOCOL (NCP) - read in 36-bit mode
261 ;5:  4.9-1.5 Padding
262 ;    1.4-1.1 M1 Host-host padding
263 ;
264 ;6:  4.9-4.6 M1 Host-host padding       ; NCP leader contained in this word.
265 ;    4.5-3.7 S  Byte size
266 ;    3.6-1.9 C  Byte count
267 ;    1.8-1.1 M2 Host-host padding
268 ;------------------------------------------------------------------------
269 ; HOST-HOST REGULAR MESSAGES
270 ;       INTERNET PROTOCOL (IP) - read in 32-bit mode
271 ;5:  4.9-1.5 Padding
272 ;6:  4.9-1.5 First word of IP datagram
273 ;------------------------------------------------------------------------
274
275 ;In message types 2 and 6, the going-down status 16-bit word is
276 ;in word 2 1.8-1.1 and word 3 4.9-4.2.
277
278 ;4.5-4.2 of word 3 are the padding count for type 4 (nop) from host.
279 ;This is 5.  Padding is only put on type-0 messages.
280
281 IMTBP:  041000,,IMPILB+0        ;BYTE POINTER FOR MESSAGE TYPE FIELD
282 IMOTBP: 340400,,IMPILB+0        ; Byte ptr for message format type
283 IMLNBP: 001000,,IMPILB+1        ;BYTE POINTER FOR LINK NUMBER FIELD
284 IMSABP: 103000,,IMPILB+1        ; Byte ptr for source address field (host+imp)
285 IMSHBP: 301000,,IMPILB+1        ;BYTE POINTER FOR SOURCE HOST FIELD
286 IMSIBP: 102000,,IMPILB+1        ;BYTE POINTER FOR SOURCE IMP FIELD
287 IMSTBP: 340400,,IMPILB+2        ; Byte ptr for subtype field
288 IMCBBP: 301000,,IMPILB+5        ;BYTE POINTER FOR CONNECTION BYTE SIZE FIELD
289 IMBCBP: 102000,,IMPILB+5        ;BYTE POINTER FOR BYTE COUNT FIELD
290
291 \f
292 SUBTTL  ARPANET VARIABLES AND TABLES
293
294 IFN NCPP,[
295 IMPSTL==NNETCH  ;SOCKET TABLE LENGTH (MUST BE .LE. 70)
296 IFG NNETCH-70,.ERR NNETCH SHOULD BE LESS THAN 70 OCTAL, PER BBN SPECS
297 ];NCPP
298
299 IFN INETP,[
300 IMPCLP: 0       ; HACK!! # to use for control-link link field.
301 ]
302 EBLK
303
304 IMPN::          ;IMP DATA AREA CLEARED WHEN IMPUP
305 IFN INETP,[
306 %IMXLN==:<<8159.-96.>+31.>/32.  ; Max # of 32-bit words in IMP regular msg,
307                 ; exclusive of leader and leader padding.  = 252.
308 IMPIBS: 0       ; Saved initial BLKI pointer for IP datagram read
309 IMPIDP: 0       ; Pointer to IP datagram being input at PI level
310 IMPODP: 0       ; Pointer to IP datagram being output at PI level
311 IMPPSW: 0       ; Flip-flop to alternate output of IP and NCP msgs
312 ]
313 IFN KAIMP,[
314 IMPI:   0       ;-1 => IMPCHN INPUT INTERRUPT OCCURRED
315 IMPO:   0       ;-1 => IMPCHN OUTPUT INTERRUPT OCCURRED
316 IMPB:   0       ;-1 => IMPCHN FLAG INTERRUPT OCCURRED
317 IMPIH:  0       ;-1 => INPUT WANTS PIA = IMPCHN
318 IMPOH:  0       ;-1 => OUTPUT WANTS PIA = IMPCHN
319 ]
320 IMPIS:  0       ;INPUT STATE
321  %ISIDN==:-1    ; Network shut off
322  %ISIDL==:0     ; Normal - idle, not expecting input (i.e. between msgs)
323  %ISIGN==:1     ; Ignore input until end of current message (36 bit mode)
324  %ISIML==:2     ; Reading IMP initial leader    (36 bit mode)
325  %ISINC==:3     ; Reading NCP control message   (32 bit mode)
326  %ISIND==:4     ; Reading NCP data message      (32 or 36 bit mode)
327  %ISINL==:5     ; Reading NCP-type IMP leader   (36 bit mode)
328  %ISIIL==:6     ; Reading IP-type IMP leader    (32 bit mode)
329  %ISIID==:7     ; Reading IP datagram           (32 bit mode)
330
331 IMPOS:  0       ;OUTPUT STATE
332  %ISODL==:0     ; Not expecting output done (i.e. between messages)
333  %ISONC==:1     ; Sending NCP control message
334  %ISOND==:2     ; Sending NCP data message
335  %ISOID==:3     ; Sending IP Datagram
336
337 IMPHI:  0       ;-1 TO HOLD UP INPUT
338                 ;-2 INPUT IS SUCCESSFULLY HELD UP
339 IMRFCT: 0       ;NUMBER OF HOST TABLE ENTRIES WITH PENDING
340                 ;TIMEOUTS FOR CONTROL-LINK RFNM OR RST-RRP.
341
342 ; ACTIVE HOST TABLE.  Entries herein are allocated as needed, using garbage
343 ; collection.  Most "host number" fields are really indices into
344 ; this table.
345 LIMPHT==<NNETCH/2+3>+<XBL+5>    ; NCP conns plus TCP conns plus a few extra
346 IMPHTN: BLOCK LIMPHT    ; Host number.  1.1-1.8 HOST, 2.1-3.7 IMP
347 IMPHTB: BLOCK LIMPHT    ;BITS:
348                 ;4.9 1=RFNM WAIT ON LINK 0 (NCP)
349                 ;4.8 GC MARK BIT
350                 ;4.7-4.3 UNUSED
351                 ;4.2-4.1 STATUS OF HOST 0 DOWN, 1 RST SENT, 2 UP
352                 ;3.9-3.1 TIME (MOD 2**9) LAST RFNM SENT ON LINK 0 (NCP)
353         .SEE IMPHDS     ;RH   LAST MESSAGE FROM IMP ABOUT "HOST DEAD STATUS"
354 IMPHTC: BLOCK LIMPHT    ; # active messages outstanding for host (8 max)
355 IMPHTT: BLOCK LIMPHT    ; Time of last RFNM received
356
357 IMNCS:  0       ;NUMBER OF CHANNELS BEING CLOSED
358 IMNAS:  0       ;NUMBER OF CHANNELS WITH 4.8 IN IMSOC5 SET
359 LIMPN==.-1 ;LAST LOCATION BLT'ED TO ZERO WHEN INITIALIZED
360 IMNBLK: 0       ; Number of times blockage avoided (output held up by ITS)
361 IMPHTF: -1      ;HOST TABLE FREE LIST, THREADED THROUGH IMPHTB, END WITH -1
362 IMPUP:  -1      ;0 => IMP UP  ;-1 => DOWN  ;-2 => COMING UP, PI LVL STILL OFF
363                 ;1 => DOWN FOR GOOD, UNTIL NEXT TIME IMP READY LINE CHANGES
364 IMPTCU: 0       ;0 IMP UP/DOWN STATUS NOT CHANGING
365                 ;>0 TRYING TO REINITIALIZE, SYS JOB HASN'T DONE SO YET
366                 ;-1 HAS BEEN REINITIALIZED, HAVEN'T EXCHANGED NOPS YET
367 IMPUCT: 0       ;IMP COMING UP TIMEOUT, IF 4 NOOPS DON'T GO THROUGH PROMPTLY.
368 IMPDWN: BLOCK 3 ;LAST MESSAGE FROM IMP THAT IT IS GOING DOWN
369                 ;WD0 "REASON" CLAIMED BY IMP (SEE CH 3 OF BBN REPORT 1822)
370                 ;WD1 TIME WHEN EXPECTED DOWN
371                 ;WD2 TIME WHEN EXPECTED UP (SYS TIME=1/30 SEC SINCE UP)
372 IFN KAIMP,IMPPIA: 0     ;CURRENT IMP PIA
373 IMPCNI: 0       ;CONI INTO HERE AT SLOW CLOCK LEVEL
374 IMERCN: -1      ;CONI INTO HERE WHEN NET GOES DOWN
375 IMNOPC: 0       ;< 0 => SEND NOPS
376 IMPA:   0       ;SAVE A AT IMPCHN PI LEVEL
377 IMPOAC: -1      ;-1 => OUTPUT INACTIVE
378 IMPERB: BLOCK 5 ;LAST "ERR" MESSAGE FROM A HOST
379                 ;WD 0 TIME WHEN RCVD, WD 1 HOST, WD2-4 11. 9-BIT BYTES OF DATA
380 IFN DMIMP,IMPSUS: 0     ;HOLDS INPUT WORD WHILE INPUT IS HELD UP
381 IMPILB: BLOCK 6         ;INPUT LEADER BUFFER
382 IMPINB: BLOCK 30.+5     ;30. WORDS @ 32 BITS/WD = 120. 8 BIT BYTES
383                         ;+5 WORDS FOR GOOD MEASURE
384                         ;THIS BUFFER IS FOR CONTROL-LINK MESSAGES
385 BBLK
386
387 IMHSBT: 330200,,IMPHTB(H)       ;RST/RRP STATUS
388 \f
389 EBLK
390
391 IMPCSH: -1      ;CURRENT SOURCE HOST (IMPHTB INDEX).  -1 WHEN IDLE.
392 IMPCLN: 0       ;CURRENT LINK NUMBER
393 IMPCBS: 0       ;CURRENT BYTE SIZE
394 IMPCBC: 0       ;CURRENT BYTE COUNT
395 IMPNIW: 0       ;EXPECTED LAST BLKI ADDRESS
396 IMNWSI: 0       ;SECOND BLKI POINTER, ZERO IF NONE
397 IMPSVP: 0       ;SAVE PIA AT IMPRMP
398 IMPSVQ: 0       ;SAVE CONTROL MESSAGE QUEUE POINTER AT IMPOB2
399 IMBLKI: 0       ;PLACE TO STORE BLKI POINTER
400 IMBLKO: 0       ;PLACE TO STORE BLKO POINTER
401 IMPNBI: 0       ;AMOUNT TO INCREMENT IMSMPC(I) BY, I.E. # OF DATA BYTES
402                 ; IN MESSAGE CURRENTLY COMING IN AT P.I. LEVEL
403 IMPNBO: 0       ;AMOUNT TO INCREMENT IMSMPC(I) BY, I.E. # OF DATA BYTES THAT WILL BE
404                 ; MADE FREE IN BUFFER BY MESSAGE CURRENTLY GOING OUT AT P.I. LEVEL
405 IMPNBT: 0       ;# BITS ACTUALLY BEING SENT, USED TO ADJUST ALLOCATION
406 IMPNPT: 0       ;NEW VALUE FOR IMSPIP(I) AFTER MSG IS SENT
407 IMPIPI: -1      ;IMSOC INDEX ACTIVE FOR INPUT AT P.I. LEVEL, OR -1 IF NONE
408 IMPOPI: -1      ;IMSOC INDEX ACTIVE FOR OUTPUT AT P.I. LEVEL, OR -1 IF NONE
409 IMOB0Z: 0       ;IMSMPP AT IMOBD1, FOR DEBUGGING
410
411 ;IMP OUTPUT LIST.  EXECUTED AT PI LEVEL 1.
412 ;NEGATIVE = BLKO POINTER, 0=STOP, 1=SET LAST WORD, 2=32-BIT MODE, 3=NOP
413 IMOPNT: 0       ;INDEX OF NEXT "INSTRUCTION" IN IMP OUTPUT LIST:
414 IMOLST: 0       ;BLKO FOR SECOND THROUGH SIXTH LEADER WORDS (FIRST IS DATAO'ED)
415 IMOMOD: 2       ;SWITCH TO 32-BIT MODE IF NECESSARY
416 IMOBK1: 0       ;FIRST BLKO POINTER
417 IMOBK2: 0       ;SECOND BLKO POINTER
418         1       ;SET LAST WORD
419 IMOBK3: 0       ;THIRD BLKO POINTER (SEND LAST WORD, NOT USED WITH DM INTERFACE)
420         0       ;STOP
421 IMOLDR: BLOCK 6 ;BUILD PREAMBLE HERE FOR DATA MESSAGES
422
423 IMPNEA: 0       ;NUMBER OF ECOS IN COMMAND MESSAGE THAT HAVE BEEN ANSWERED
424 IMPNRA: 0       ;NUMBER OF RSTS ANSWERED
425
426 ;METERS
427 IFN INETP,[
428 IMNIPI: 0       ; # of IP datagrams input (rcvd)
429 IMNIPF: 0       ; # of IP datagrams flushed (input threw away)
430 IMNIPO: 0       ; # of IP datagrams output (sent)
431 IMNIPR: 0       ; # of IP RFNMs received
432 IMNIP7: 0       ; # of IP Type 7 (Dest Host Dead) messages received
433 IMNIP8: 0       ; # of IP Type 8 (Error) msgs rcvd
434 IMNIP9: 0       ; # of IP Type 9 (Incomplete Transmission) msgs rcvd
435 IMNWIG: 0       ; # words ignored by "Ignore" state (%ISIGN)
436 IMNWIF: 0       ; # words flushed by IMPRM5
437 ] ;INETP
438 IFN NCPP,[
439 IMNOSH: 0       ;# OF SHUFFLES OF NET OUTPUT BUFFERS
440 IMNISH: 0       ;# OF SHUFFLES OF NET INPUT BUFFERS
441 IMNSCM: 0       ;NUMBER OF SHORT CONTROL LINK MESSAGES
442 IMPNEI: 0       ;NUMBER OF ERPS NOT SENT
443 IMPNRI: 0       ;NUMBER OF RRPS NOT SENT
444 IMNRFC: 0       ;NUMBER OF RFCS CLSED
445 IMNRFI: 0       ;NUMBER OF RFCS IGNORED
446 IMNCLI: 0       ;NUMBER OF CLS IGNORED
447 IMNALI: 0       ;NUMBER OF ALLS IGNORED
448 IMNPIL: 0       ;NUMBER OF TIMES PI CONTROL QUEUE EXCEEDED
449 IMNCNS: 0       ;NUMBER OF CLS NOT SENT
450 IMNANS: 0       ;NUMBER OF ALLS NOT SENT
451 IMNMNC: 0       ;NUMBER OF REGULAR MESSAGES FOR NON-EXISTANT CONNECTIONS
452 IMNMAE: 0       ;NUMBER OF TIMES MSG ALL EXCEEDED
453 IMNMSS: 0       ;NUMBER OF TIMES MSG SHORT
454 IMNBAE: 0       ;NUMBER OF TIMES BIT ALL EXCEEDED
455 ] ;IFN NCPP
456 IMPNPE: 0       ;NUMBER OF PROTOCOL ERRORS
457 IMNSRC: 0       ;NUMBER OF SPURIOUS RFNMS ON CONTROL LINK
458 IMNSRF: 0       ;NUMBER OF SPURIOUS RFNMS ON REG CONNECTIONS
459 IMNRFN: 0       ;NUMBER OF RFNMS NOT SENT
460 IMSTAS: 0       ;STATUS OF INPUT AT TIME HELD UP
461 IMPNIH: 0       ;NUMBER OF TIMES INPUT SUCCESSFULLY HELD UP
462 IMPNUH: 0       ;NUMBER OF TIMES INPUT HOLDUP UNDONE
463 IMRFTO==60.*30. ;RFNM WAIT TIME OUT
464 IFN NCPP,[
465 IMNORH: 0       ;NUMBER OF STYNET OUTPUT RESETS DELAYED
466 ;IMPRTO==30.*60.        ;RESET TIME OUT (IDENTICALLY = IMRFTO)
467 IMPCTO==30.*30. ;CLS TIME OUT
468 IMFCTO==55.*30. ;RFC QUEUE TIME OUT - SHOULD BE LESS THAN 2*IMPCTO
469 IMPCMR: BLOCK 20        ;COUNT OF CONTROL MESSAGES RCD
470 IMPCMS: BLOCK 20        ;COUNT OF CTL MSG SENT
471 ] ;IFN NCPP
472 IMPMSR: BLOCK 20        ;COUNT OF IMP MESSAGES RCD
473 IMPM1S: BLOCK 4         ; # Type 1 (Error in Leader) subtype msgs
474 IMPM9S: BLOCK 20        ; # Type 9 (Incomplete Transmission) subtype msgs
475 IMPMSS: BLOCK 1         ;COUNT OF IMP MSG SENT (WE ONLY SEND REGULAR MSGS)
476 IMCT1:  0       ;# TIMES AT IMPBKZ
477 IMCT2:  0       ;# TIMES AT IMPIBZ
478 IMCT3:  0       ;# TIMES AT IMPOBZ
479 BBLK
480 \f
481 SUBTTL  ARPANET MAIN-PROGRAM LEVEL
482
483 IMPINI:
484 IFN KAIMP,[
485         CONO IMP,IMI32C
486         DATAI IMP,A
487         CONO IMP,IMPODC         ;CLEAR OUTPUT DONE AND PIA
488         CONSZ IMP,IMPOD+7       ;CHECK OUTPUT DONE, PIA, CAUSE HOST READY
489          JRST 4,.               ;CONO DIDN'T CLEAR SOME BITS?
490         CONO IMP,IMPIR+IMPHEC   ;CLEAR HOST ERR, ENABLE INT ON IMP READY
491 ]
492 IFN DMIMP,[
493         CONO FI,FIRSET  ;RESET IMP INTERFACE, SET HOST READY
494         CONO FI,FIHSTS
495 ]
496         SETOM IMPIPI
497         SETOM IMPOPI
498         MOVE T,TIME
499         ADDI T,15.
500         CAMLE T,TIME
501          PUSHJ P,UFLS   ;WAIT FOR HALF SECOND
502 IFN KAIMP,[
503         CONO IMP,0      ;CLEAR "ENABLE IMP READY" INT (TURNS OFF IMP ERROR)
504         MOVEI A,NETCHN  ;IDLE PIA
505         MOVEM A,IMPPIA
506         MOVE A,[JSR IMPIBK]
507         MOVEM A,IMPILC
508         MOVE A,[JSR IMPOBK]
509         MOVEM A,IMPOLC
510 ]
511 IFN DMIMP,CONO FI,FIIWDC        ;CLEAR "IMP WAS DOWN"
512 IFN NCPP,[
513         MOVSI I,-IMPSTL
514 IMPINA: SKIPE IMSOC6(I)
515          JRST 4,.
516         SETZM IMSOC1(I)
517         AOBJN I,IMPINA
518 ] ;IFN NCPP
519         SETZM IMPILC+1
520         SETZM IMPOLC+1
521         SETOM IMPOAC
522         SETOM IMPUP     ;NOT UP YET
523         MOVNI A,20.     ;ALLOW 10 SECONDS TO COME UP
524         MOVEM A,IMPUCT
525         SETOM IMPTCU    ;TRYING TO COME UP
526         SETOM IMPHTF    ;WILL GC IMPHTB ON FIRST REFERENCE
527 IFN NCPP,[
528         SETOM IMPMPU
529         SETOM IMPMPL
530         SETOM IMPNCQ
531         SETOM IMPLCQ
532         MOVEI I,IMNPIC
533         MOVEM I,IMFCQL
534         MOVEI A,IMPCQ
535         MOVEM A,IMFFCQ
536         JRST IMPIN1
537
538 IMPIN2: ADDI A,IMPMQS+1
539         MOVEM A,-IMPMQS-1(A)
540 IMPIN1: SOJG I,IMPIN2
541         SETOM (A)
542         SETOM IMPBPQ
543         SETOM IMPEPQ
544         MOVEI A,IMPPQ
545         MOVEM A,IMFFPQ
546         MOVEI I,IMNPQ
547         JRST IMPIN4
548
549 IMPIN3: ADDI A,4
550         MOVEM A,-4(A)
551 IMPIN4: SOJG I,IMPIN3
552         SETOM (A)
553         MOVEI A,NETSRS
554         MOVEM A,NRSOC
555 ];NCPP
556         MOVE A,[IMPN,,IMPN+1]
557         SETZM IMPN
558         BLT A,LIMPN
559         SETOM IMPIS             ; Say IMP shut off
560         MOVE T,TIME
561         MOVEM T,LNETIM
562 IFN KAIMP,CONO IMP,NETCHN
563 IFN DMIMP,[
564         CONSZ FI,FIDOWN+FIWASD  ;SKIP IF STILL UP
565          POPJ P,        ;LOSE IF NOT IMP UP
566         CONO FI,FIIN\FIIBSY+NETCHN*11
567         CONO FI,FIOUT+NETCHN*11
568 ]
569         SETOM IMPDWN+1  ;TIME FOR IMP TO GO DOWN, NOT KNOWN
570         ;MOVE T,TIME
571         ADDI T,15.
572         CAMLE T,TIME
573          PUSHJ P,UFLS
574         SETZM IMPIS     ; Say up but idle
575         MOVNI A,4
576         MOVEM A,IMNOPC  ;SEND 4 NOPS
577 IMPOST: CONO PI,NETOFF
578 IFN DMIMP,[
579         CONSO FI,70     ;SKIP IF PIA NON-ZERO
580          JRST NETONJ    ;IF NO PIA, THEN DONT SET INT
581 ]
582 IFN KAIMP,MOVE TT,IMPPIA        ;MAIN PROGRAM OUTPUT START
583         AOSN IMPOAC     ;SKIP IF OUTPUT ALREADY ACTIVE
584 IFN KAIMP, CONO IMP,IMPODS(TT)  ;GENERATE OUTPUT INTERRUPT
585 IFN DMIMP, CONO FI,FIODS+NETCHN*11
586         JRST NETONJ
587
588 IMPIOS:
589 IFN KAIMP,[
590         AOSE IMPOAC     ;PI LEVEL OUTPUT START
591          POPJ P,
592         PUSH P,TT
593         CONO PI,400     ;TURN PI OFF, IMP MAY HAVE PIA = 1
594         MOVE TT,IMPPIA
595         CONO IMP,IMPODS(TT)
596         CONO PI,200
597         POP P,TT
598 ]IFN DMIMP,[
599         AOSN IMPOAC
600          CONO FI,FIODS+NETCHN*11
601 ]
602         POPJ P,
603
604
605
606 ;Check if IMP ready line is set
607 ; Called from SYSJOB.
608 ; Return +1 if IMP not ready, +2 if so
609 ;
610 IMPCKR:
611 IFN DMIMP,[
612         .ERR IMPCKR Missing for DMIMP!
613 ]
614 IFN KAIMP,[
615         CONSZ IMP,IMPR          ;Skip if IMP not ready
616          AOS (P)                ;Return +2 if ready
617         POPJ P,
618 ]
619
620 \f
621 SUBTTL  HOST-TABLE MANAGEMENT
622
623 ; FNDHST - Look up host-table index for a given IMP host address.
624 ;       Call with NETOFF or NETCHN PI in progress.
625 ;       T/ IMP host address (maybe someday other nets?)
626 ; Returns .+1 if failed (no room in table)
627 ; Returns .+2
628 ;       H/ host-table index
629 ; Smashes W.
630
631 FNDHST: MOVEI H,LIMPHT-1        ;SEARCH FOR AN ENTRY FOR THIS HOST
632         CAME T,IMPHTN(H)
633          SOJGE H,.-1
634         JUMPGE H,POPJ1          ;FOUND
635         SKIPGE H,IMPHTF         ;NOT FOUND, CONS ONE OFF FREE LIST
636          JRST FNDHS1            ;OOPS, MUST GARBAGE COLLECT
637         MOVE W,IMPHTB(H)
638 IFN INETP,[             ; Later make this check standard!
639         CAIGE H,LIMPHT          ; Make sure H is valid idx
640          CAIL W,LIMPHT          ; ditto W
641           BUG HALT,[NET: FNDHST idx clobbered!!!]
642 ]
643         MOVEM W,IMPHTF
644         MOVEM T,IMPHTN(H)
645         SETZM IMPHTB(H)         ;NOTHING IS KNOWN ABOUT THIS HOST
646         SETZM IMPHTC(H)         ; Assume no RFNMs outstanding
647         SETZM IMPHTT(H)         ; Clear out time of last RFNM.
648         JRST POPJ1
649
650 ; Host-Table full, attempt to GC it and flush unused entries, by
651 ; scanning all possible pointers into table.
652 ;       IMP pointers are IMPCSH and IMPHTC(H)
653 ;       NCP pointers are IMSOC4<3.9-4.7>, RFC queue, PI ctl msg queue,
654 ;               and the RFNM-wait and RST-sent bits in table.
655 ;       TCP pointers are XBNADR(I)
656
657         ; GC mark phase - mark entries in use
658 FNDHS1: PUSH P,I
659         MOVSI W,200000          ;MARK BIT
660         MOVEI H,LIMPHT-1        ;CLEAR ALL MARK BITS
661         ANDCAM W,IMPHTB(H)
662         SOJGE H,.-1
663         SKIPL H,IMPCSH          ;MARK FROM IMPCSH
664          IORM W,IMPHTB(H)
665
666 IFN TCPP,[
667         MOVEI I,XBL-1
668         SKIPL H,XBNADR(I)       ; See if TCP conn has a net addr specified
669          IORM W,IMPHTB(H)       ; Yes, set the mark bit.
670         SOJGE I,.-2
671 ] ;IFN TCPP
672 IFN NCPP,[
673         MOVEI I,IMPSTL-1        ;MARK FROM IMSOC4
674 FNDHS2: SKIPN IMSOC1(I)         ;SKIP IF IMSOC4 IS BEING USED BY ANYONE
675          SOJGE I,FNDHS2
676         JUMPL I,FNDHS3
677         LDB H,IMSCFH
678         CAIE H,377
679          IORM W,IMPHTB(H)
680         SOJGE I,FNDHS2
681 FNDHS3: MOVE I,IMPBPQ           ;MARK RFC PENDING QUEUE
682         JUMPGE I,[ LDB H,[101000,,3(I)]
683                    IORM W,IMPHTB(H)
684                    MOVE I,(I)
685                    JRST . ]
686         MOVE I,IMPNCQ           ;MARK CONTROL QUEUE
687         JUMPGE I,[ HLRZ H,1(I)
688                    IORM W,IMPHTB(H)
689                    MOVE I,(I)
690                    JRST . ]
691 ] ;NCPP
692
693         ; GC sweep phase - free all unmarked entries
694         SETO I,                 ;FREE POINTER
695         MOVEI H,LIMPHT-1
696         MOVSI W,601000          ;PROTECT IF RFNM-WAIT, RST-WAIT, OR MARKED
697 FNDHS4:
698         SKIPG IMPHTC(H)         ; Also protect if any outstanding RFNMs
699          TDNE W,IMPHTB(H)
700           SOJGE H,FNDHS4
701         JUMPL H,FNDHS5
702         SETZM IMPHTN(H)         ;DON'T BELONG TO ANY HOST
703         MOVEM I,IMPHTB(H)       ;CONS ONTO FREE LIST
704         MOVE I,H
705         SOJGE H,FNDHS4
706 FNDHS5: MOVEM I,IMPHTF          ;FREE LIST
707         POP P,I
708         SKIPGE IMPHTF
709          POPJ P,                ;GC-OVERFLOW
710         JRST FNDHST             ;TRY AGAIN, SHOULD WIN
711 \f
712 SUBTTL  ARPANET INPUT INTERRUPT LEVEL
713
714 COMMENT |
715         The IMP interrupt level structure is fairly complicated and
716 deserves some explanation.  Because the IMP interface is not a DMA
717 device, all I/O is done "by hand", a word at a time; for this reason
718 all I/O is done at PI level IMPCHN=1 (the highest) whenever possible.
719 However, to prevent general IMP processing from taking complete
720 precedence over everything else, all non-I/O handling is done at
721 PI level NETCHN=2, which is the same level as disk devices.
722         The MIT-DMS interface (DMIMP) is much more complicated than the
723 AI-KA/ML/MC interface and was designed to facilitate this dual-level
724 interrupt processing by providing different PI channel assignments
725 for each of 3 possible conditions:
726         Input Done  (must usually read next word)
727         Output Done (must usually output next word)
728         Control Int (some unusual condition, including Last-IMP-Word)
729
730 Because the non-DM interface only has one PI assignment available,
731 the software to switch levels is much more complicated.  For either
732 case, the code will not make sense unless you understand the channel 1
733 multiplexing feature (see interface CONI bit descriptions).
734 |
735
736 ; Here when IMP interface is interrupting at PI level 2 (NETCHN)
737 ; TT has CONI bits.  Can clobber most ACs
738
739 IMPINT:
740 IFN KAIMP,[
741         AOSN IMPB       ; PI 1 control interrupt?
742          JRST IMPBKZ    ;   Yes
743         AOSN IMPI       ; PI 1 Input Done interrupt?
744          JRST IMPIBZ    ;   Yes
745         AOSN IMPO       ; PI 1 Output Done interrupt?
746          JRST IMPOBZ    ;   Yes already
747         TRNE TT,IMPLW+IMPHER+IMPERR     ; No PI 1 ints, check status bits
748          JRST IMPBKZ    ; PI 2 Control interrupt (error or Last Imp Word)
749         TRNE TT,IMPID
750          JRST IMPIBZ    ; PI 2 Input Done
751         TRNE TT,IMPOD
752          JRST IMPOBZ    ; PI 2 Output Done
753 ]IFN DMIMP,[
754         TRNE TT,FILW+FIWASD+FIDOWN
755          JRST IMPBKZ    ; PI 2 Control interrupt (error or Last Imp Word)
756         TRNE TT,FIID
757          JRST IMPIBZ    ; PI 2 Input Done
758         TRNE TT,FIOD
759          JRST IMPOBZ    ; PI 2 Output Done
760 ]
761         JRST 4,.        ; Must be one of above!!
762 \f
763 IFN KAIMP,[
764 ; IMPIBK - Default PI 1 Input Done routine, called from IMPILC.
765 ;       We're idling, switch to PI 2 to handle the input
766 ;       (normally 1st word of new IMP message)
767 EBLK
768 IMPIBK: 0
769 BBLK
770         SETOM IMPI              ; Set flag saying PI 1 Input Int seen
771         CONO IMP,NETCHN         ; Switch PIA to 2
772         JRST 12,@IMPIBK         ; Go re-interrupt, will get to IMPINT->IMPIBK
773 ]
774
775 IFN KAIMP,[
776
777 ; IMPBRK - PI 1 Control interrupt, called from PI0LOC+2 (= 42 on KA's)
778 ;       which is the standard PI 1 vector location.
779 ;       Again, switch to PI 2 to handle the condition
780 ;       (typically Last Imp Word seen on input)
781 EBLK
782 IMPBRK: 0               ; This interrupt is to 42, may not be the IMP
783 BBLK
784         CONSO IMP,IMPLW+IMPHER+IMPERR   ; This really from the IMP?
785 IFE NEWDTP,JRST RC1INT
786 IFN NEWDTP,JRST IMPBR1
787         SETOM IMPB              ; Yes, re-interrupt and handle at NETCHN level
788         CONO IMP,NETCHN         ; Switch PIA to 2 (NETCHN)
789         JRST 12,@IMPBRK         ; Go re-interrupt, will get to IMPINT->IMPBKZ
790
791 IFN NEWDTP,[
792 IMPBR1: CONSZ DTC,70            ; Allow for non-IMP interrupt on PI chan 1
793          JRST 12,@IMPBRK
794 ]
795
796 RC1INT: MOVEM 17,R1NTAC+17
797         MOVEI 17,R1NTAC
798         BLT 17,R1NTAC+16
799         MOVEI J,1
800         JSP E,SPUR
801         MOVSI 17,R1NTAC
802         BLT 17,17
803         JRST 12,@IMPBRK
804 ];IFN KAIMP
805
806 ; IMPRM4 - PI 1 Input-Done handler during readin of IMP data (not leader)
807 ;       BLKI has run out but haven't yet gotten Last Imp Word!
808 ;       Either read more (if 2nd ptr specifed) or ignore following data.
809 EBLK
810 IMPRM4: 0
811 BBLK
812         MOVEM A,IMPA    ; Save A
813         SKIPL A,IMNWSI  ; Second BLKI pointer exists?
814          JRST IMPRM6    ; Nope, none now
815         MOVEM A,IMBLKI  ; Yes, store it!
816         SETZM IMNWSI    ; Clear this flag so don't do it again
817         MOVE A,IMPA     ; Restore A
818         JRST 12,@IMPRM4 ; Return, continuing BLKI.
819
820 IMPRM6: MOVE A,[JSR IMPRM5]     ; Ugh!  Ignore additional input
821         MOVEM A,IMPILC          ; Set up new vector to "ignore" routine
822         MOVE A,IMPA
823         JRST 12,@IMPRM4
824
825 ; IMPRM5 - PI 1 Input-Done handler while ignoring IMP data, only
826 ;       set up by IMPRM6 above.
827 ;       Just reads a word and ignores it.  This loop is broken
828 ;       by a control interrupt when Last-Imp-Word is seen.
829 EBLK
830 IMPRM5: 0               ; Hmm? Flush input at PI 1
831 BBLK
832         DATAI IMP,IMPA
833 IFN INETP,AOS IMNWIF    ; See how often we come here.
834         JRST 12,@IMPRM5
835 \f
836 ; IMPIBZ - PI 2 (NETCHN) "Input Done" interrupt, via IMPINT.
837 ;       Note there is one input word waiting in the IMP interface,
838 ;       but it is NOT the last IMP word (if it was, we would get a
839 ;       control interrupt and go to IMPBKZ instead).  This situation
840 ;       should only happen while reading the IMP leader and there is
841 ;       more input than just the leader, i.e. it is a NCP or IP message.
842 ;       This is also where we come after being in idle state.
843 ;       TT/ IMP CONI word
844
845 IMPIBZ: AOS IMCT2
846 IFN DMIMP,[
847         TRC TT,IMPCHN   ;FIND IF INPUT PIA=IMPCHN
848         TRNN TT,7
849          JRST IMPRET    ;YES, ALREADY HANDLED BY IMPCHN
850 ];DMIMP
851 IFE INETP,[             ; Note IP datagram is read in 32-bit mode!
852 IFN DMIMP,TLNE TT,FII32
853 IFN KAIMP,TRNE TT,IMPI32
854          JRST 4,.       ; NCP-only, leader should always be read in 36-bit mode
855 ] ;IFE INETP
856         MOVE C,IMPHI
857         SKIPN B,IMPIS   ; Skip hold-up check unless at start of msg (idle)
858          AOJE C,IMPBKW  ; Jump if input needs to be held up (can only do at start or end of msg)
859 IFE INETP,CAILE B,%ISIML
860 IFN INETP,CAILE B,%ISIID
861          JRST 4,.       ; Unknown input state
862         JRST @.+2(B)    ; Dispatch, note data not read yet
863
864                 IMPIGN          ;-1 Supposed to be shut off, go ignore message.
865         OFFSET -.
866  %ISIDL::       IMSTR1          ; 0 Was idle, this is start of a message!
867  %ISIGN::       IMPIGN          ; 1 Ignoring this message.
868 IFE INETP,%ISIML:: IMPLD2       ; 2 Reading IMP leader, see what we got.
869 IFN INETP,[
870  %ISIML::       [JRST 4,.]      ; 2 Should only see %ISINL or %ISIIL
871  %ISINC::       [JRST 4,.]      ; 3 Was reading control msg!  Runout is error.
872  %ISIND::       [JRST 4,.]      ; 4 Was reading NCP data msg! Runout is error.
873  %ISINL::       IMPLD2          ; 5 Was reading NCP IMP leader
874  %ISIIL::       IMPLD2          ; 6 Was reading IP IMP leader.
875  %ISIID::       [JRST 4,.]      ; 7 Was reading IP datagram!  Runout is error.
876 ] ;INETP
877         OFFSET 0
878
879 IMPIGN: DATAI IMP,A     ; Ignore input (only come here via table above)
880 IFN INETP,AOS IMNWIG    ; See how often we come here.
881         ;JRST IMPRET
882
883         ; All routines dispatched to from IMPIBZ should return via IMPRET.
884 IMPRET:
885 IFN DMIMP,CONI FI,A
886         SKIPN IMPIS             ; Skip if input not in normal (idle) state
887 IFN KAIMP, CONSO IMP,IMPI32     ; It is, see if input is in 32-bit mode
888 IFN DMIMP, TLNN A,FII32
889           JRST .+2
890            JRST 4,.             ; Shouldn't be in 32 bit mode in normal state
891 IFN KAIMP,CONO IMP,@IMPPIA      ; Switch to desired exit PIA
892         JRST IMPEX
893
894 ; IMPBKZ - PI 2 (NETCHN) Control interrupt, via IMPINT.
895 ;       Error or Last Imp Word on input.
896 ;       TT/ IMP CONI word
897
898 IMPBKZ: AOS IMCT1       ; Bump count of control interrupts
899 IFN KAIMP,TRNE TT,IMPERR+IMPHER ; See if error or last-imp-word.
900 IFN DMIMP,TRNE TT,FIWASD+FIDOWN
901          JRST IMPBER    ; Jump if IMP Error or Host Error
902
903         ; Not an error, interface has Last Imp Word ready for DATAI'ing!
904         MOVE B,IMPHI    ; Check here to see if input should be held up
905         AOJN B,IMPBKX   ; Jump if not.
906
907         ; Input must be held up.  Also enter here from IMPIBZ if
908         ; at start of message (only other time input can be held up).
909 IMPBKW:
910 IFN KAIMP,CONO IMP,IMPIDC       ; Clear Input Done so we don't re-interrupt
911 IFN DMIMP,[
912         CONO FI,FISUSP  ; Suspend input, no bits accepted after DATAI
913         DATAI FI,IMPSUS ; Have to read word now
914         CONO FI,FIIDC+NETCHN_3  ; Have to do this to clear IMP Last Word
915 ]                               ; (also to clear Input-Done PIA)
916         SOS IMPHI       ; Set -2 to indicate successfully held up
917         MOVEM TT,IMSTAS ; Save status (CONI bits)
918         AOS IMPNIH      ; Bump meter - count of times input was held up.
919         JRST IMPRET
920 \f
921 ; IMPBKX - Auxiliary to IMPBKZ, PI 2 Control Interrupt
922 ;       Have got Last Imp Word and not holding up input, so go
923 ;       handle end of IMP message.
924
925 IMPBKX:
926 IFN KAIMP,[
927         MOVE A,[JSR IMPIBK]     ; Get rid of input BLKI
928         MOVEM A,IMPILC          ; Replace with default switch-PIA vector
929         SETZM IMPIH             ; Say don't need PI 1 for input any more.
930         MOVEI A,NETCHN          ; And change exit PIA to 2
931         SKIPL IMPOH             ; Unless output side still needs PI 1.
932          MOVEM A,IMPPIA         ; Set value of PI level desired on exit.
933         CONO IMP,IMI32C         ; Put back in 36 bit mode to start next msg
934         DATAI IMP,A             ; Get the last input word for processing
935 ]IFN DMIMP,[
936         CONO FI,FII32C+FISUSP   ; Hold up bits for following clear
937         DATAI FI,A              ; Get last input word
938         CONO FI,FIIDC+FIIBSY+NETCHN*11  ; Now clear Last-Imp-Word
939 ]
940         ; Enter here from IMOB6 if input had been held up.
941 IMPBKV: SKIPGE B,IMPIS          ; Unless network has been shut off
942          JRST IMPRET            ; (in which case ignore input)
943         JRST @IMSDT2(B)         ; then go process end of IMP message.
944
945 IMSDT2: OFFSET -.
946  %ISIDL::       IMPBKN  ; 0 Was idle - leader only 1 word long??
947  %ISIGN::       IMPIRT  ; 1 Ignore input
948  %ISIML::       IMPLD1  ; 2 End of IMP leader - can't be regular msg
949  %ISINC::       IMPBK3  ; 3 End of NCP control message
950  %ISIND::       IMPRMB  ; 4 End of NCP data input
951 IFN INETP,[
952  %ISINL::       IMPLD1  ; 5 End of NCP IMP leader?? Probably error.
953  %ISIIL::       IMPLD1  ; 6 End of IP IMP leader?? Probably error.
954  %ISIID::       IMPRMI  ; 7 End of IP datagram
955 ] ;INETP
956         OFFSET 0
957
958 ; Here from table above for old-type leader (1 word)
959 ; IMPBN1 is used by IMPLD2 if long leader has wrong format.
960
961 IMPBKN: MOVEM A,IMPILB          ; Store first (and only) word of leader
962 IMPBN1: LDB A,IMOTBP            ; Get message format type
963         CAIN A,4                ; Old-type NOP?
964          JRST IMPIRT            ;  Just ignore it.
965         CAIN A,16               ; Is it 1822L format?
966          BUG INFO,[IMP: 1822L leader],OCT,IMPILB
967         CAIE A,17               ; Is it not the long-leader format?
968          BUG INFO,[IMP: Old-type leader],OCT,IMPILB
969         JRST IMPIRT             ; Ignore rest of message, if any
970
971
972 \f
973 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
974 ;;;             IMP LEADER READING/DISPATCH             ;;;
975 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
976 ;;;     Code on this page handles the initial processing of
977 ;;;     IMP messages and dispatches to the appropriate
978 ;;;     routines for each message type.  Only Type 0 ("Regular")
979 ;;;     messages carry Host-Host traffic.
980
981 ; Here from IMPIBZ only, to handle first word of an IMP message.
982 ; (It's not the last word or IMPBKZ would complain about it)
983 ; Set up a BLKI to get the rest of the leader.
984
985 IMSTR1: DATAI IMP,A             ; Get 1st word from interface
986         ; Entry point from IMPOB6 only to restart input from "held-up" state
987         ; First word already in A
988 IMSTRT: MOVEM A,IMPILB          ; Store first word of leader
989         MOVEI C,%ISIML          ; Set new state = reading rest of IMP leader
990 IFE INETP,MOVE B,[-4,,IMPILB]   ; If not diverting IP, ask for it all.
991 IFN INETP,MOVE B,[-2,,IMPILB]   ; Must vector IP, ask for max 36-bit wds
992         JRST IMPRM9     ; Go read the leader.
993
994 ;       The code at IMPLD5 will switch to 32-bit mode at right place if
995 ; the message turns out to be an IP datagram.  Otherwise the message
996 ; is either a NCP Host-Host message, or an IMP-to-Host note of some kind;
997 ; both stay in 36-bit mode.
998
999 ; Here from IMPBKX only for a leader not followed by any data.
1000 ; Last word in A, IMPLW flag in TT.
1001 IMPLD1: AOS B,IMBLKI            ; Update pointer to buffer
1002         MOVEM A,(B)             ; and store last word in right place.
1003         ; Fall through to handle what should be an IMP-Host note.
1004         ; The IMPLW flag distinguishes this entry point from IMPLD2,
1005         ; so we know there isn't a data word in the interface.
1006
1007 ; Here from IMPIBZ only, for an IMP leader with more data following;
1008 ; almost certainly a "Regular" host-host message.  The 2 possible
1009 ; states are:
1010 ;       %ISINL - NCP, in 36-bit mode, have read 5 wds and 6th awaits.
1011 ;       %ISIIL - IP, in 32-bit mode, have read 4 wds and 5th awaits.
1012 ; We can't DATAI the current word from the interface until we know
1013 ; what mode the remaining data should be read in.
1014
1015 IMPLD2:
1016 IFN KAIMP,TRNE TT,IMPI32
1017 IFN DMIMP,TLNE TT,FII32
1018 IFE INETP, JRST 4,.             ; Input was in 32 bit mode when shouldn't!
1019 IFN INETP,[JRST [MOVE B,IMPIS   ; If reading IP IMP leader then 32 bit OK.
1020                 CAIE B,%ISIIL   ; Leader read in 32-bit mode, must be IP.
1021                  JRST 4,.       ; It isn't???
1022                 JRST .+1]
1023 ] ;INETP
1024         LDB T,IMOTBP            ; Examine new-format flag bits of leader
1025         CAIN A,16               ; Is it 1822L format?
1026          BUG INFO,[IMP: 1822L leader],OCT,IMPILB
1027         CAIE T,17               ; to verify that leader is "new" 96-bit fmt.
1028          JRST IMPBN1            ;   Something else?? Go discard.
1029         HRRZ B,IMBLKI           ;-> LAST WORD READ
1030         CAIGE B,IMPILB+2        ;MUST BE AT LEAST 3 WORDS TO BE VALID
1031          JRST IMPLD3
1032         LDB T,IMLNBP            ; Extract link number (high 8 bits of msg-id)
1033 IFN INETP,[
1034         CAMN T,IMPCLP           ; HACK!  If it matches our specified ctl link
1035          SETZ T,                ;  number, then make it look like ctl link!
1036 ]
1037         MOVEM T,IMPCLN
1038         LDB T,IMSABP            ; Get arpanet address (source host+imp)
1039 IFN 0,[ LDB T,IMSHBP            ;SOURCE HOST
1040         LDB A,IMSIBP            ;SOURCE IMP
1041         DPB A,[112000,,T]       ;FORM HOST ADDRESS
1042 ] ;ifn 0
1043         PUSHJ P,FNDHST          ;H GETS HOST TABLE INDEX
1044          JRST IMPLD9            ;HOST TABLE FULL
1045         MOVEM H,IMPCSH          ;SAVE CURRENT HOST
1046         LDB A,IMTBP             ;GET MESSAGE TYPE IN A
1047         CAILE A,10.
1048          JRST IMPUN             ;UNKNOWN TYPE
1049         AOS IMPMSR(A)           ;COUNT IMP MSGS RCD
1050         JRST @IMTDT(A)          ;DISPATCH
1051
1052 IMTDT:  IMPRM   ; 0 Regular Message
1053         IMPBE1  ; 1 Error in Leader (no msg-id)
1054         IMPGD   ; 2 IMP Going Down
1055         IMPUN   ; 3  -
1056         IMPIN   ; 4 NOP
1057         IMPRFN  ; 5 RFNM - Ready For Next Message (transmit succeeded)
1058         IMPHDS  ; 6 Host Dead Status (general info)
1059         IMPDHD  ; 7 Destination Host Dead (transmit failed)
1060         IMPBE8  ; 8 Error in Data (has msg-id)
1061         IMPINC  ; 9 Incomplete Transmission (transmit failed temporarily)
1062         IMPIRS  ;10 Interface Reset - IMP dropped its ready line
1063
1064 IMPLD9: BUG INFO,[IMP: Message discarded due to host table full],OCT,IMPILB,OCT,IMPILB+1,OCT,IMPILB+2
1065         JRST IMPIRT
1066
1067 ; Here from IMPLD2 if leader is too short
1068 IMPLD3: SUBI B,IMPILB-1         ;# WDS READ
1069         BUG INFO,[IMP: Short leader, ],DEC,B,[wds. WD1=],OCT,IMPILB,[WD2=],OCT,IMPILB+1
1070         ;JRST IMPIRT            ;FLUSH REST OF MESSAGE
1071
1072 ;;; IMP->Host Type 4 - NOP
1073
1074 IMPIN:  JRST IMPIRT     ; One more nop from IMP
1075
1076 ;;; IMP->Host Type 10 - Interface Reset
1077
1078 IMPIRS: BUG INFO,[IMP: Interface-reset msg]
1079         JRST IMPIRT     ; Probably nothing useful to do about it.
1080
1081 ;;; IMP->Host Type X (e.g. 3, 11-255) - bad type
1082
1083 IMPUN:  BUG INFO,[IMP: Unknown msg type ],OCT,A,[ leader ],OCT,IMPILB,OCT,IMPILB+1,OCT,IMPILB+2
1084         ;JRST IMPIRT
1085
1086 IFE NCPP,[
1087 IMPBK3::                ;Ignore NCP messages
1088 IMPRMB::
1089 ];NCPP
1090
1091 ; Here from all over, to flush rest of this message.
1092 ; All non-regular messages (not type 0) return here, as well as some
1093 ; errors with regular msgs.
1094 ; TT says whether there is any more data to read from this message.
1095 IMPIRT: SETZM IMPIS     ; Assume end of message, reset to normal state
1096         TRNN TT,IMPLW   ; But if we haven't yet read the last word,
1097          AOSA IMPIS     ; then change state to "Ignore" and flush input.
1098                         ; Note skip over following SETZM.
1099
1100 ; Regular messages (type 0) return here, when we already know this message
1101 ; was completely read.  TT isn't valid.
1102 IMPIR1: SETZM IMPIS     ; Reset to normal idle state
1103         SETOM IMPCSH    ; Say no current host
1104 IFN KAIMP,CONO IMP,IMI32C       ; Put world back in 36 bit input mode
1105 IFN DMIMP,CONO FI,FII32C+NETCHN*11
1106         JRST IMPRET
1107 \f
1108 ;;; IMP->Host Type 0 - Regular Host-Host message
1109 ;       Unless the source host screwed up and sent a dataless message,
1110 ; there is a word waiting to be read from the interface.
1111 ; For IP this is the 5th word and we are in 32-bit mode.
1112 ; For NCP it's the 6th (the NCP leader) and we're in 36-bit mode.
1113 ;       TT/ IMP CONI bits, 
1114 ;       B/ addr of last wd input (counted-out BLKI pointer)
1115
1116 IMPRM:  TRNE TT,IMPLW
1117          JRST IMPRM3    ; Foo, message shouldn't end so soon.  Go barf.
1118 IFE INETP,[
1119         CAIE B,IMPILB+4 ; Check that host-host leader word is next in
1120          JRST IMPLD3    ;   Barf
1121         SKIPE IMPCLN    ; Skip if link 0 - NCP control msg
1122          JRST IMPRMD    ;   Data message, go read into user buffer.
1123 ]
1124 IFN INETP,[
1125         SKIPN A,IMPCLN  ; Skip unless NCP control link message
1126          JRST IMPRM1    ; NCP control message, go handle it.
1127         CAIE A,233      ; Is link number the magic cookie for IP?
1128 IFN NCPP, JRST IMPRMD   ; No, go handle as NCP data message.
1129 IFE NCPP, JRST IMPIRT   ; No, ignore it if we don't have NCP
1130
1131         ; This is an Internet Protocol datagram.  Make sure we are
1132         ; in right mode for reading.
1133         AOS IMNIPI      ; Bump count of IP datagrams received
1134 IFN KAIMP,TRNN TT,IMPI32        ; Should already be in 32-bit mode
1135 IFN DMIMP,TLNN TT,FII32
1136          BUG PAUSE,[IMP: Reading IP dgm in 36-bit mode]
1137         DATAI IMP,IMPILB+4      ; Okay, read in the padding and get going.
1138         MOVEI A,%IMXLN  ; Specify max size of IMP message
1139                         ; (we can't trust msg-len leader field)
1140         PUSHJ P,IPGIPT  ; Call IP module - get input buffer pointer
1141          JRST [ AOS IMNIPF      ; Punted, bump cnt of datagrams lost
1142                 JRST IMPIRT]    ; Flush this message (err msg already printed)
1143         MOVEM A,IMPIDP  ; Save datagram pointer
1144         MOVEM B,IMPIBS  ; Save input BLKI pointer for later check
1145         MOVEI C,%ISIID  ; Set state = reading IP datagram
1146         JRST IMPRM9     ; Go do it.
1147
1148 IMPRM1: CAIE B,IMPILB+4 ; NCP control message, check that NCP leader is next 
1149          JRST IMPLD3    ;   Barf, short message??
1150 ] ;INETP
1151 IFN KAIMP,CONO IMP,IMI32S       ; NCP control message, set 32-bit mode
1152 IFN DMIMP,CONO FI,FII32S+NETCHN*11
1153         DATAI IMP,IMPILB+5      ; Get NCP leader word
1154         LDB A,IMCBBP
1155         MOVEM A,IMPCBS  ; Byte size
1156         LDB B,IMBCBP
1157         MOVEM B,IMPCBC  ; Byte count
1158         CAIN A,8        ; Byte size should be 8 for control link
1159          CAILE B,120.   ; Byte count shouldn't be > 120.
1160           JRST IMPBCM
1161         ADDI B,3
1162         LSH B,-2        ; Number of words necessary
1163         MOVEM B,IMPNIW  ; Number of input words expected
1164         HRLOI B,-1(B)
1165         EQVI B,IMPINB-1 ; BLKI pointer
1166         MOVEI C,%ISINC  ; New state = reading NCP control message
1167
1168 ; Set up BLKI.  Pointer in B, state in C.
1169 ; This place is jumped to by several things that initiate IMP input,
1170 ; specifically IMSTRT, IMPRMT, and IMPRM.
1171
1172 IMPRM9: MOVEM C,IMPIS
1173         MOVEM B,IMBLKI
1174         MOVE B,[BLKI IMP,IMBLKI]
1175         MOVEM B,IMPILC
1176         MOVE B,IMPBRO(C)        ; Get BLKI runout instruction and set vector;
1177         MOVEM B,IMPILC+1        ; will execute when ptr counts out.
1178 IFN KAIMP,[
1179         SETOM IMPIH             ; Say that input wants high pri
1180         MOVEI B,IMPCHN          ; And set our exit PIA to it (IMP)
1181         MOVEM B,IMPPIA
1182 ]
1183 IFN DMIMP,CONO FI,NETCHN_3+IMPCHN       ; Set control PIA = NET, input done = IMP
1184
1185         JRST IMPRET
1186
1187         ; This table holds the instruction to execute after the input
1188         ; BLKI has counted out the ptr and stored the current input word.
1189         ; Note that if the IMP message ends during the BLKI, a control
1190         ; interrupt will happen instead and control goes to IMPBKZ->IMPBKX
1191         ; where there is another state dispatch table.
1192         ; Normally only %ISIML and %ISINL actually use these instructions;
1193         ; the other states are impossible or expect to read the entire
1194         ; remaining message.
1195 IMPBRO: OFFSET -.
1196  %ISIDL::       JRST 4,IMPBRO   ; 0 Idle   - shouldn't be BLKI'ing.
1197  %ISIGN::       JRST 4,IMPBRO+1 ; 1 Ignore - shouldn't be BLKI'ing.
1198  %ISIML::
1199         IFE INETP,JSR IMPLD4    ; 2 Reading IMP leader (5 wds partial msg)
1200         IFN INETP,JSR IMPLD5    ; 2 Reading IMP leader (4 wds partial msg)
1201  %ISINC::       JSR IMPRM4      ; 3 Reading NCP control message (get all)
1202  %ISIND::       JSR IMPRM4      ; 4 Reading NCP data (get all)
1203 IFN INETP,[
1204  %ISINL::       JSR IMPLD4      ; 5 Reading NCP IMP leader (partial msg)
1205  %ISIIL::       JSR IMPLD4      ; 6 Reading IP IMP leader (partial msg)
1206  %ISIID::       JSR IMPRM4      ; 7 Reading IP datagram (get all)
1207 ] ;INETP
1208         OFFSET 0
1209
1210 IMPRM3: LDB B,IMBCBP    ;BYTE COUNT OF EMPTY CONTROL LINK MESSAGE
1211         JUMPE B,IMPIRT
1212         AOS IMPNPE      ;NO TEXT BUT BYTE COUNT NOT ZERO
1213         BUG INFO,[NCP: CTL MSG NO TXT, BC NOT 0. HST ],OCT,IMPHTN(H),[BC],DEC,B
1214         JRST IMPIRT
1215
1216 IFN INETP,[
1217 EBLK            ; PI 1 Input Done interrupt (from IMPILC+1, runout)
1218 IMPLD5: 0       ; JSR here on BLKI runout after reading 3rd wd of IMP leader.
1219 BBLK            ; Input Done is not set, because BLKI just turned it off.
1220         MOVEM A,IMPILC          ; Save A
1221         MOVE A,[JSR IMPLD6]     ; Make very next input word interrupt to IMPLD6
1222         EXCH A,IMPILC           ; Do it, restore A
1223         JRST 12,@IMPLD5
1224
1225 EBLK            ; PI 1 Input Done interrupt (from IMPILC)
1226 IMPLD6: 0       ; JSR here with 4th wd of leader in interface.
1227 BBLK            ; Must decide whether to continue reading leader in
1228                 ; 36-bit mode (NCP) or 32-bit mode (IP).
1229         MOVEM A,IMPILC          ; Save A
1230         MOVE A,IMPILB+1         ; Get word with link number in it
1231         ANDI A,377              ; Mask off
1232         CAIN A,233              ; Internet Protocol "link"?
1233          JRST IMPLI3            ; Yes!  Go handle it.
1234
1235         ; NCP read will immediately store current 36-bit word (4th),
1236         ; store another 36-bit word (5th), and then run out to IMPLD4.
1237         MOVE A,[-2,,IMPILB+2]   ; Reading NCP message.
1238         MOVEM A,IMBLKI
1239         MOVEI A,%ISINL          ; Reading NCP leader, set state thereto.
1240         MOVEM A,IMPIS
1241         MOVE A,[JSR IMPLD4]     ; And change dispatch vector.
1242         MOVEM A,IMPILC+1
1243         MOVE A,[BLKI IMP,IMBLKI]
1244         EXCH A,IMPILC           ; Set up BLKI and restore A
1245         JRST 12,@IMPLD6 ; Return.  Note current input word is still waiting.
1246
1247         ; IP read will immediately store current 36-bit word (4th),
1248         ; then set up so next input-done interrupt (on 5th, 32-bit word)
1249         ; goes directly to IMPIBZ->IMPLD2 with NETCHN PI.
1250         ; (For AI-KA/MC/ML, perhaps by way of IMPIBK if output is active)
1251 IMPLI3: MOVEI A,%ISIIL          ; Say reading IP type leader.
1252         MOVEM A,IMPIS
1253 IFN KAIMP,CONO IMP,IMI32S+IMPCHN        ; Set further input to 32-bit mode
1254 IFN DMIMP,CONO FI,FII32S+NETCHN_3+IMPCHN
1255         DATAI IMP,IMPILB+3      ; Store the 4th 36-bit word immediately; this
1256                                 ; also starts interface reading the 5th word.
1257 IFN KAIMP,[
1258         MOVE A,IMPLD6           ; Now must set up for next interrupt.
1259         MOVEM A,IMPLD4          ; Fake out the common code below
1260         JRST IMPLI4             ; Set up for next Input-Done interrupt
1261 ]
1262 IFN DMIMP,[
1263         MOVE A,[JSR IMPLD4]     ; Shouldn't need this, but just in case...
1264         EXCH A,IMPILC           ; Restore A, set int vector to safe rtn
1265         CONO FI,NETCHN*11       ; DM interface can simply set Input-Done PIA!
1266         JRST 12,@IMPLD6
1267 ] ;DMIMP
1268 ] ;INETP
1269
1270 EBLK            ; PI 1 Input Done interrupt (from IMPILC+1, runout)
1271 IMPLD4: 0       ; JSR here on BLKI runout after reading IMP leader
1272 BBLK            ; There is still one word to go, to be gotten at NETCHN level
1273 IFN KAIMP,[
1274         MOVEM A,IMPILC          ; Save A
1275                                 ; Drop through to common code
1276
1277 IMPLI4: SETZM IMPIH             ; Say input no longer needs PI 1
1278         MOVEI A,NETCHN          ; Make PI 2 (NETCHN) the exit PIA,
1279         SKIPL IMPOH             ; unless output side needs PI 1.
1280          MOVEM A,IMPPIA         ; Set desired PIA channel on exit
1281         CONO IMP,@IMPPIA        ; Set PIA to whatever it was!
1282         MOVE A,[JSR IMPIBK]     ; Reset PI 1 Input-Done vector back to std.
1283         EXCH A,IMPILC           ; and restore A.
1284 ];DMIMP
1285 IFN DMIMP, CONO FI,NETCHN*11    ; DM interface can simply set Input-Done PIA!
1286         JRST 12,@IMPLD4
1287
1288 IMPBCM: BUG INFO,[NCP: CTL MSG BS NOT 8 OR CT>120. HST ],OCT,IMPHTN(H),[BS ],DEC,IMPCBS,[BC ],DEC,IMPCBC
1289         JRST IMPIRT
1290 \f
1291 ;;; IMP->Host Type 6 - Host Down Status
1292 ;       H/ host index
1293
1294 IMPHDS: MOVE A,IMPILB+1         ;1.8-1.1 AND 4.9-4.2 ARE THE INFO
1295         MOVE B,IMPILB+2
1296         LSHC A,8
1297         ANDI A,177777
1298         HRRM A,IMPHTB(H)        ;STORE, HOPE USER READ RFC 611
1299         JRST IMPIRT
1300
1301 ;;; IMP->Host Type 1 - Error in leader (msg-id not given)
1302 ;;; IMP->Host Type 8 - Error in data  (msg-id given)
1303
1304 IMPBE1: LDB T,IMSTBP    ; Get subtype (4 bits)
1305         ANDI T,3        ; Only 2 bits should be used
1306         AOS IMPM1S(T)   ; Increment count of Type 1 subtype messages
1307 IMPBE8: MOVE T,TIME
1308         SUB T,LNETIM
1309         CAIL T,60.      ;IGNORE ERROR DURING INITIAL SYNCHRONIZATION
1310          BUG INFO,[IMP: Type ],DEC,A,[err msg, leader],OCT,IMPILB,OCT,IMPILB+1,OCT,IMPILB+2
1311 IFN INETP,[
1312         MOVE B,IMPCLN
1313         CAIN B,233
1314          AOS IMNIP8
1315 ]
1316         CAIN A,8.
1317          JRST IMPBEB    ; Process "Error in data" (decrement RFNM wait cnt)
1318         JRST IMPIRT
1319
1320 IMPBER: SKIPGE IMPUP    ;SKIP IF UP, OR THOUGHT TO BE BROKEN
1321          JRST IMPBE2    ;ALREADY DOWN, LET IT COME UP IN PEACE
1322         MOVSI J,SCLNET  ;THINKS IT'S UP, RESET IT
1323         IORM J,SUPCOR
1324         CONI IMP,IMERCN ;RECORD IF IMP ERROR FLIP/FLOP SET
1325         SETOM IMPUP     ;IMP IS DOWN
1326         SETZM IMPTCU    ;AND NOT TRYING TO COME UP
1327 IFN INETP,.ERR IP/TCP code needs handling for IMP crashing.
1328 IFN NCPP,[
1329         MOVSI T,200000  ;CLEAR ALL BUFFERS ACTIVE AT PI LEVEL
1330         MOVSI I,-IMPSTL ;SINCE CORE JOB MAY BE WAITING ON THIS
1331         ANDCAM T,IMSOC6(I)
1332         AOBJN I,.-1
1333 ] ;NCPP
1334 IMPBE2:
1335 IFN KAIMP,[
1336         SETZM IMPPIA
1337         CONO IMP,0
1338 ]
1339 IFN DMIMP,CONO FI,FIRSET
1340         JRST IMPEX
1341
1342 ;;; IMP->Host Type 2 - IMP going down
1343
1344 IMPGD:  LDB B,[060200,,IMPILB+1]        ;WHY
1345         MOVEM B,IMPDWN
1346         LDB B,[020400,,IMPILB+1]        ;HOW SOON GOING DOWN * 5 MINS
1347         MOVE H,B
1348         IMULI B,5*60.*30.       ;TICKS IN 5 MINS
1349         ADD B,TIME
1350         MOVEM B,IMPDWN+1
1351         MOVE C,IMPILB+1         ;HOW LONG TO BE DOWN, SPANS WORD BOUNDARY
1352         MOVE D,IMPILB+2
1353         LSHC C,8
1354         ANDI C,1777
1355         MOVE Q,C
1356         IMULI C,5*60.*30.
1357         ADD C,B                 ;ADD TO TIME DOWN
1358         MOVEM C,IMPDWN+2        ;STORE TIME WHEN WILL BE UP
1359         IMULI H,5               ;MINUTES
1360         IMULI Q,5
1361         BUG INFO,[IMP: Going down in ],DEC,H,[mins for ],DEC,Q,[mins, reason],DEC,IMPDWN
1362         JRST IMPIRT
1363 \f
1364 ;;; IMP Blockage avoidance
1365 ;       The current IMP software will not accept more than 8 active
1366 ; messages to a single host; attempting to send a 9th message will block
1367 ; ALL output to the interface, until the first message has been ack'd
1368 ; by means of one of the following message types:
1369 ;       Type 5, RFNM - Message delivered OK
1370 ;       Type 7, Host dead - transmit failed ("permanent")
1371 ;       Type 8, Error in data - interface spazzed
1372 ;       Type 9, Incomplete Transmission - temporary failure
1373 ; If for some reason the first message simply becomes lost, the IMP timeout
1374 ; (and blockage) can last for up to 30-45 seconds.
1375 ; More details in BBN Report 1822.
1376 ;       ITS attempts to fix this by keeping a count of active un-ACKed
1377 ; messages for each host it is communicating with.  A timeout is also
1378 ; associated with each host; if output to a given host is blocked by ITS
1379 ; because there are 8 active messages, trying to send a 9th message
1380 ; will check the last-RFNM-received time and if this was more than
1381 ; 30 or so seconds then the IMP is probably not giving us what it should
1382 ; and we should reset things for that host.
1383
1384 %IMPMA==:8.     ; # of maximum active IMP messages allowed
1385
1386 ; IMPBLI, IMPBLD - routines to hack active-message counts, called via JSP T,
1387 ;       IMPBLD decrements count.
1388 ;       IMPBLI increments count and skips if successful (else failed,
1389 ;               and must NOT output another message to this host!)
1390 ;               Also clobbers Q.
1391 IMPBLI: AOS Q,IMPHTC(H)
1392         CAIGE Q,%IMPMA  ; Trying to send max or more messages?
1393          JRST 1(T)      ; No, can return safely.
1394         CAIG Q,8.       ; Is this the maximum # allowed?
1395          JRST [ MOVE Q,TIME             ; Yes, set up blockage timeout
1396                 ADDI Q,60.*30.          ; for one minute.
1397                 MOVEM Q,IMPHTT(H)
1398                 JRST 1(T)]
1399
1400         ; Trying to send too many messages, block it (check for timeout though)
1401         SOS IMPHTC(H)   ; Restore original count
1402         AOS IMNBLK      ; Increment # of times softwarily blocked.
1403         MOVE Q,IMPHTT(H)
1404         CAML Q,TIME     ; See if timeout still in the future
1405          JRST (T)       ; Yes, just take failure-return to block.
1406         BUG INFO,[IMP: RFNM-wait timeout! Hst=],OCT,IMPHTN(H)
1407         SETZM IMPHTC(H) ; This may be dangerous... oh well.
1408         SETZM IMPHTT(H)
1409         JRST (T)        ; Block one last time, next try will win.
1410
1411 IMPBLD: SOSL Q,IMPHTC(H)
1412          JRST IMPBL2
1413         BUG INFO,[IMP: neg RFNM-wait cnt, Hst=],OCT,IMPHTN(H)
1414         SETZB Q,IMPHTC(H)
1415 IMPBL2: CAIL Q,8.-1     ; If we were blocking on this host,
1416          CALL IMPIOS    ; Ensure IMP output started up so blocked stuff
1417         JRST (T)        ; gets sent promptly.
1418
1419 ;;; IMP->Host Type 8 - Error in Data
1420 ;       Actually this is secondary routine that IMPBE1 jumps to.
1421
1422 IMPBEB: JSP T,IMPBLD    ; Decrement count of active messages
1423         JRST IMPIRT
1424
1425
1426
1427 ;;; IMP->Host Type 5 - RFNM (Ready For Next Message)
1428
1429 IFN INETP,.ERR INETP needs handling for RFNM on link 233
1430 IMPRFN:
1431 IFN BLIMPP,JSP T,IMPBLD ; Decrement count of active IMP messages for this host
1432         SKIPE IMPCLN    ;LINK NUMBER
1433          JRST IMRFN1    ;DATA LINK
1434 IMRFN6: SKIPL IMPHTB(H)
1435          JRST IMRFN7
1436         SKIPN IMPHTN(H)
1437          BUG HALT,[IMP: IMRFN6 sees free IMPHTB entry ],OCT,H
1438         MOVSI D,400000
1439         ANDCAM D,IMPHTB(H)      ;SET RFNM RECEIVED
1440         SOS IMRFCT
1441 IFN NCPP,[
1442         SKIPL IMPNCQ            ;SKIP IF NO PENDING CONTROL-LINK OUTPUT
1443          PUSHJ P,IMPIOS         ;START OUTPUT
1444 ];NCPP
1445         JRST IMPIRT
1446
1447 IMRFN7: AOS IMNSRC
1448         BUG INFO,[IMP: Spurious RFNM from ],OCT,IMPHTN(H),[LNK 0]
1449         JRST IMPIRT
1450
1451 ; RFNM on non-zero link message
1452 IMRFN1:
1453 IFN INETP,[
1454         MOVE A,IMPCLN   ; Get link #
1455         CAIE A,233      ; IP link number?
1456          JRST IMRFNX    ; No, skip IP code
1457         AOS IMNIPR      ; Bump count of IP RFNMs received
1458         JRST IMPIRT     ; and do nothing else about it, ugh.
1459 IMRFNX:
1460 ];INETP
1461 IFN NCPP,[
1462         MOVE A,IMPCSH
1463         LSH A,8
1464         IOR A,IMPCLN    ;HEADER
1465         MOVSI I,-IMPSTL
1466         MOVEI W,1
1467 IMRFN2: LDB D,IMSCHL    ;HEADER
1468         SKIPGE IMSOC1(I)        ;SKIP IF SLOT NOT IN USE
1469          CAME A,D       ;SKIP IF HEADER AGREES
1470           JRST IMRFN3
1471         HRRZ J,IMSOC4(I)        ;STATE
1472         MOVEI W,0
1473         CAIN J,%NSRFN
1474          SOJA J,IMRFN4  ;RFNM WAIT
1475         MOVSI J,20000   ;MIGHT BE EXPECTING RFNM AFTER CLOSE
1476         TDNE J,IMSOC5(I)
1477          JRST [ ANDCAM J,IMSOC5(I)
1478                 JRST IMPIRT ]
1479 IMRFN3: AOBJN I,IMRFN2
1480         BUG INFO,[IMP: Spurious RFNM from ],OCT,IMPHTN(H),[link],OCT,IMPCLN,SIXBIT,[(W)[SIXBIT/NOWAITNOLINK/]]
1481 ];NCPP
1482 .ELSE   BUG INFO,[IMP: Spurious RFNM from ],OCT,IMPHTN(H),[link],OCT,IMPCLN
1483         AOS IMNSRF
1484         JRST IMPIRT
1485
1486 IFN NCPP,[
1487 IMRFN4: HRRM J,IMSOC4(I)        ;CONNECTION OPEN
1488         MOVSI J,30000           ;TURN OFF CLOSE-AWAITING-RFNM BIT, AND
1489         ANDCAM J,IMSOC5(I)      ; RFNM-TIMEOUT-DURING-CLOSE BIT
1490         MOVE T,IMSPIP(I)
1491         CAME T,IMSMPP(I)        ;SKIP IF OUTPUT BUFFER EMPTY
1492          PUSHJ P,IMPIOS         ;START OUTPUT
1493         JRST IMPIRT
1494 ];NCPP
1495
1496
1497 ;;; IMP->Host Type 9 - Incomplete Transmission
1498
1499 IMPINC: LDB T,IMSTBP            ; Get subtype field (4 bit reason for failure)
1500         AOS IMPM9S(T)           ; Bump count of subtypes
1501         SKIPA E,[%NCINC]
1502
1503 ;;; IMP->Host Type 7 - Destination Host Dead
1504
1505 IMPDHD:  MOVEI E,%NCDED
1506 IFN BLIMPP,JSP T,IMPBLD ; Decrement count of active IMP messages for this host
1507 IFN INETP,[
1508         MOVE A,IMPCLN
1509         CAIN A,233
1510          JRST [ CAIN E,%NCINC
1511                  AOS IMNIP9
1512                 CAIN E,%NCDED
1513                  AOS IMNIP7
1514                 JRST IMPIRT]    ; Don't bother with NCP stuff or anything.
1515 ]
1516         MOVSI C,1000            ;RST SENT?
1517         TDNE C,IMPHTB(H)
1518          SOS IMRFCT             ;GOING TO CLEAR IT, DECREASE TIMEOUT RQ
1519         MOVSI C,3000
1520         ANDCAM C,IMPHTB(H)      ;CLEAR RST STATUS, RFNM SIMULATED LATER
1521 IFN NCPP,[
1522         MOVSI I,-IMPSTL
1523 IMDHD:  LDB T,IMSCFH
1524         SKIPGE C,IMSOC1(I)      ;SKIP IF NOT IN USE
1525          CAME T,IMPCSH
1526           JRST IMDHDA
1527         HRRZ T,IMSOC4(I)
1528         TLNN C,200000   ;THIS GUY IS CLOSING ANYWAY
1529          CAIG T,%NSLSN
1530           JRST IMDHDA   ;THIS SOCKET'S HOST NUMBER FIELD IS MEANINGLESS
1531         CAIGE T,%NSCLI .SEE %NSINP
1532          TDZA T,T .SEE %NSCLS
1533           MOVEI T,%NSCLI
1534         HRRM T,IMSOC4(I)
1535         DPB E,IMSCLS    ;CLS REASON
1536         PUSHJ P,IMPUIN
1537 IMDHDA: AOBJN I,IMDHD
1538 ];NCPP
1539         JRST IMRFN6     ;CONTROL LINK, TAKE AS RFNM SO AS NOT TO HANG THINGS
1540 \f
1541 IFN INETP,[
1542 ; IMPRMI - End of IP datagram, PI in progress on NETCHN, here from IMPBKX
1543 ;       A/ Last IMP word (32-bit)
1544 ;       TT/ CONI bits as of interrupt (note already returned to 36-bit mode)
1545
1546 IMPRMI: AOS B,IMBLKI    ; Get address to store last word in
1547         MOVEM A,(B)     ; Store it away
1548         SUB B,IMPIBS    ; Get # words read into datagram buffer
1549         MOVEI B,(B)
1550         MOVE A,IMPIDP   ; Get pointer to IP datagram buffer we were using
1551         SETZ C,         ; Say zero offset to IP header.
1552         MOVE J,IMPCSH   ; Set index to host-table entry dgm received from.
1553         PUSHJ P,IPRDGM  ; Call IP module to process received datagram at PI lvl
1554         SETZM IMPIDP    ; Clear PI level pointer
1555         JRST IMPIR1     ; Return from PI level, setting up for next msg
1556
1557 ] ;INETP
1558 \f
1559 SUBTTL  ARPANET OUTPUT INTERRUPT LEVEL
1560
1561 ; See comments at IMPINT for a description of the overall IMP interrupt
1562 ; structure.  Output is simpler than input, however.
1563 ; Each IMP message is output at PI level 1 except for the initial DATAO;
1564 ; the setup and takedown for each message is done at PI level 2.
1565 ; The code on this page is not referenced by anything outside the page
1566 ; except interrupt vector setup at IMPINI (to IMPOBK) and IMOB9 (to IMPCH1).
1567
1568 ; IMPCH1 - PI 1 Output-Done interrupt, from IMPOLC.
1569 ;       Comes here when last word DATAO'd has been sent to IMP.
1570 EBLK
1571 IMPCH1: 0
1572 BBLK
1573         MOVEM A,IMPOLC          ; Save A
1574         MOVE A,IMOPNT
1575 IMCH1A: SKIPGE A,IMOLST(A)      ; Get next "instruction"
1576          JRST IMCH1B            ; Jump if it's a BLKO pointer
1577         CAILE A,3               ; Ensure valid operation
1578          JRST 4,.
1579         XCT IMCH1I(A)           ; Do it
1580         AOS A,IMOPNT            ; Still here?  Point to next operation
1581         JRST IMCH1A             ; and loop to do it.
1582
1583 IMCH1I: JRST IMCH1C             ;0 Stop - end of output list
1584 IFN KAIMP,CONO IMP,IMPLHW+IMPCHN        ;1 Set Last Word
1585 IFN DMIMP,CONO FI,FILHW+11*NETCHN
1586 IFN KAIMP,CONO IMP,IMO32S+IMPCHN        ;2 Set 32-bit mode
1587 IFN DMIMP,CONO FI,FIO32S+10*NETCHN+IMPCHN
1588         JFCL                    ;3 NOP
1589
1590 IMCH1B: MOVEM A,IMBLKO          ; Set up BLKO - store the pointer
1591         MOVE A,[JSR IMCH1D]     ; Set dispatch for BLKO runout
1592         MOVEM A,IMPOLC+1
1593         MOVE A,[BLKO IMP,IMBLKO]
1594         EXCH A,IMPOLC           ; Store the BLKO and restore A
1595         AOS IMOPNT              ; Increment output list ptr past this op.
1596         JRST 12,@IMPCH1         ; Will interrupt immediately for first BLKO
1597                                 ; word, since Output-Done wasn't cleared.
1598
1599 ; PI 1 Output-Done, from IMPOLC+1 (BLKO runout)
1600 ;       Final word of the BLKO pointer is now in interface, being sent
1601 ;       to IMP, and Output-Done flag is off.
1602 EBLK
1603 IMCH1D: 0
1604 BBLK
1605         MOVEM A,IMPOLC
1606         MOVE A,[JSR IMPCH1]     ; Interrupt back when output of final word done
1607         EXCH A,IMPOLC
1608         JRST 12,@IMCH1D
1609
1610 ; Here from IMPCH1, PI 1 Output-Done interrupt
1611 ;       Output list has hit "stop" operation (previous op had better be
1612 ;       1 to set Last-Host-Word!)
1613 ;       This code reverts control back to PI level 2 (IMPOBK).
1614 IMCH1C:
1615 IFN DMIMP,[
1616         CONO FI,FIOUT+11*NETCHN ; Reset PIA to normal 2
1617         MOVE A,[JSR RINT1]      ; and ensure any further output PI 1 ints
1618 ]                               ; are classified as spurious.
1619
1620 IFN KAIMP,[                     ; Non-DM interface needs more hair.  
1621         SETZM IMPOH             ; Say output side doesn't need PI 1 anymore
1622         MOVEI A,NETCHN          ; And set exit PIA to 2,
1623         SKIPL IMPIH             ; unless input side still needs PI 1
1624          MOVEM A,IMPPIA         ; Set it.
1625         CONO IMP,NETCHN         ; Shouldn't this be CONO IMP,@IMPPIA??
1626         SETOM IMPO              ; Tell IMPINT we have output-done interrupt.
1627         MOVE A,[JSR IMPOBK]     ; Point PI 1 channel at switch-PIA routine,
1628 ]                               ; in case we interrupt on PI 1 again anyway.
1629         EXCH A,IMPOLC
1630         JRST 12,@IMPCH1
1631
1632 IFN KAIMP,[
1633
1634 ; PI 1 Output Done interrupt, when we should really be interrupting
1635 ;       at IMPINT on PI 2.
1636 EBLK
1637 IMPOBK: 0
1638 BBLK
1639         SETOM IMPO              ; Tell IMPINT what kind of interrupt
1640         CONO IMP,NETCHN         ; Reset PIA to 2
1641         JRST 12,@IMPOBK
1642 ]
1643 \f
1644 ; IMPOBZ - PI 2 (NETCHN) "Output Done" interrupt, via IMPINT.
1645 ;       Come here when we have finished sending stuff out at PI 1,
1646 ;       also when something wants output to start and tickled the "Done"
1647 ;       flag.
1648 ;       TT/ IMP CONI word.
1649
1650 IMPOBZ: AOS IMCT3
1651 IFN DMIMP,[
1652         TRC TT,IMPCHN_9 ;CHECK IF OUTPUT PIA=IMPCHN
1653         TRNN TT,7_9
1654          JRST IMPRET    ;IGNORE, ALREADY HANDLED BY IMPCHN
1655 ]
1656         SKIPL B,IMPOS
1657          CAIL B,IMPODL
1658           JRST 4,.
1659         JRST @IMPODT(B)
1660
1661 IMPODT: OFFSET -.
1662 %ISODL::        IMPOB1  ; 0 Idle, look for something to send
1663 %ISONC::        IMPOB6  ; 1 Finished NCP control message
1664 %ISOND::        IMPOBG  ; 2 Finished NCP data message
1665 IFN INETP,%ISOID::IMPOBI        ; 3 Finished IP datagram messge
1666 IMPODL::OFFSET 0
1667
1668 IFE NCPP,[
1669 IMPOB6: SETZM IMPOS
1670         SKIPN A,IMPSVQ
1671          JRST IMPRET            ;THAT WAS A NOP
1672 IMPOBG: JRST 4,.                ;Can't get here
1673 ];not NCPP
1674
1675 ; Idle - Look for output to send.  First ensure we can send stuff,
1676 ;       then try things in the order:
1677 ;       (1) Send NOP if net coming up
1678 ;       (2) Check NCP control queue, then (3) NCP data output queue
1679 ;       OR
1680 ;       (2) Check IP datagram queue
1681 ;
1682 ; Note that we alternate between checking the NCP and IP queues first,
1683 ; so that neither protocol can totally wedge the other up even if
1684 ; going at full blst.
1685
1686 IMPOB1: HRRZ T,IMPUP
1687         CAIE T,-2       ; Don't say it's up when it's still going down
1688          CAIN T,1       ; or when it is broken
1689           JRST IMPOB9
1690
1691         ; First check to see if NOP needs to be sent.
1692         AOSG IMNOPC     ; Check to see if sending NOPs
1693          JRST IMONOP    ; Output a NOP
1694         SETZM IMPUP     ; Say IMP is up
1695         SETZM IMPTCU    ; Say no longer trying to come up
1696
1697         ; Now see whether to check NCP or IP.
1698 IFN INETP,[
1699         SETCMB T,IMPPSW ; Complement IMP output protocol switch
1700         JUMPN T,IMOBNN  ; Jump for NCP
1701         PUSHJ P,IPGIOQ  ; Check IP! Get IP IMP output queue entry if any
1702          JRST IMOBN     ; Nothing there, go check NCP.
1703         ; Returns A/ ptr to IP dgm struct
1704         ;       B/ BLKO pointer to 32-bit words
1705         ;       C/ Arpanet address
1706         ; The output list should be set up as:
1707         ;IMOLST: -3,,IMOLDR
1708         ;IMOMOD: 2              ; switch to 32-bit mode
1709         ;IMOBK1: -1,,IMOLDR+3   ; Send 5th word of padding
1710         ;IMOBK2:output BLKO     ; Send datagram minus last word
1711         ;       1
1712         ;IMOBK3: -1,,lstwd-1    ; BLKO to last word of datagram
1713         ;       0
1714 IMOBI1:
1715         MOVEM A,IMPODP  ; Save ptr to datagram being output
1716         AOS IMNIPO      ; # of IP datagrams sent
1717         ADD B,[1,,]     ; Reduce BLKO count by one
1718         MOVEM B,IMOBK2  ; Store in output list
1719         HLRO D,B        ; Get -<# wds-1>
1720         MOVN D,D        ; Get <#wds-1>
1721         ADDI D,(B)      ; Get addr for last-word BLKO
1722         HRROM D,IMOBK3  ; Store -1,,lastwd-1
1723         MOVE B,[-3,,IMOLDR]
1724         MOVEM B,IMOLST
1725         MOVE B,[-1,,IMOLDR+3]
1726         MOVEM B,IMOBK1
1727
1728         ; Output list set up, now must put together the IMP leader
1729         ; in IMOLDR.
1730         MOVE B,[17_10.,,0]      ; Regular message
1731         MOVEM B,IMOLDR
1732         LSH C,8.                ; Move net address over
1733         IORI C,233              ; Get link # for IP
1734         MOVEM C,IMOLDR+1        ; Store 2nd word
1735         SETZM IMOLDR+2          ; 3rd word can be zero
1736         SETZM IMOLDR+3          ; rest is padding
1737         SETZM IMOLDR+4          ; ditto
1738
1739 IFN KAIMP,CONO IMP,IMO32C
1740 IFN DMIMP,CONO FI,FIO32C        ;SET 36 BIT MODE FOR LEADER, CLEAR PIA
1741         DATAO IMP,IMOLDR        ; Start it going!
1742         
1743         MOVEI C,%ISOID          ; State = outputting IP datagram.
1744         JRST IMOB9
1745
1746 IMOBN:  SKIPE IMPPSW            ; If no IP, check NCP only if havent already
1747          JRST IMOBI9            ; Skip NCP check, just return.
1748 IMOBNN:
1749 ] ;INETP
1750
1751 IFN NCPP,[
1752         ; Check NCP control message queue.
1753 IFN BLIMPP,[
1754         MOVEI C,IMPNCQ
1755 IMPOBV: SKIPGE A,(C)
1756          JRST IMPOBW
1757         HLRZ H,1(A)             ; Got one!  Go send NCP control msg,
1758         SKIPL IMPHTB(H)         ; unless control link waiting for RFNM
1759          JSP T,IMPBLI           ; or too many msgs active for that host.
1760           CAIA
1761            JRST [MOVEI T,(C) ? JRST IMPOB2]     ; Compat hack
1762         MOVEI C,(A)
1763         JRST IMPOBV
1764 ] ;BLIMPP
1765 .ELSE [
1766         MOVEI T,IMPNCQ
1767 IMPOBV: SKIPGE A,(T)
1768          JRST IMPOBW
1769         HLRZ B,1(A)             ;HOST TABLE INDEX
1770         SKIPL IMPHTB(B)         ;SKIP IF WAITING FOR RFNM
1771          JRST IMPOB2            ; Got one!  Go send NCP control message.
1772         MOVE T,A
1773         JRST IMPOBV
1774 ] ;IFE BLIMPP
1775
1776         ; Check NCP data output queue.  This simply runs through
1777         ; all the sockets to see if any want to output something.
1778 IMPOBW: MOVSI I,-IMPSTL
1779         MOVEI W,1
1780 IMPOBB: SKIPGE IMSOC1(I)        ;SKIP IF NOT IN USE
1781          TDNN W,IMSOC2(I)       ;SKIP IF SEND
1782           JRST IMOBA9
1783         HRRZ A,IMSOC4(I)
1784         CAIN A,%NSOPN           ;SKIP IF WRONG STATE
1785          SKIPGE IMSOC6(I)       ;SKIP IF NOT LOCKED BY CORE JOB
1786 IMOBA9:
1787 IFE BLIMPP,IMPOBA:
1788           AOBJN I,IMPOBB
1789 IFN BLIMPP,[
1790         JUMPGE I,IMPOB9
1791         LDB H,IMSCFH            ; Get fgn host index for this NCP conn
1792         JSP T,IMPBLI            ; Make sure not too many active msgs
1793          JRST IMOBA9            ; Sigh, too many, keep looking.
1794         JRST IMPOBD             ; OK, can send!
1795 IMPOBA: JSP T,IMPBLD            ; Couldn't send data msg after all, decr cnt
1796         JRST IMOBA9
1797 ]
1798 .ELSE   JUMPL I,IMPOBD          ; Got one!  Go send NCP data message.
1799 ];NCPP
1800
1801         ; No more NCP output for IMP.
1802 IMPOB9:
1803 IFN INETP,[
1804         SKIPN IMPPSW    ; If we didnt check IP queue yet,
1805          JRST IMOBI9
1806         PUSHJ P,IPGIOQ  ; then do it now, after NCP check.
1807          JRST IMOBI9    ; Nothing, really no more output.
1808         JRST IMOBI1     ; Aha, have stuff!  Go get it.
1809 IMOBI9:
1810 ]
1811         SETOM IMPOAC    ; No more output, couldn't find anything to send.
1812 IFN KAIMP,CONO IMP,IMPODC       ; Clear Output-Done interrupt bit
1813 IFN DMIMP,CONO FI,FIODC+NETCHN*11
1814         JRST IMPRET
1815
1816 \f
1817 ; IMONOP - Send a NOP, here from IMPOBZ only.
1818
1819 IMONOP: MOVEI A,IMPNOP-2
1820         SETZM IMPSVQ    ; Set flag => this msg not really from control queue
1821         MOVEI B,1       ; No text, but one extra wd (needed to make BLKO win)
1822         JRST IMPOB3
1823
1824         ; NOP Host-IMP leader
1825 IMPNOP: 17_10.,,4_4     ; New format, type 4 = NOP
1826         0
1827         5_10.,,0        ; 5 16-bit words of padding desired
1828
1829 ; IMPOB2 - Send a NCP control message, from IMPOBZ only
1830
1831 IMPOB2: HRL A,T
1832         MOVEM A,IMPSVQ  ;SAVE CTL MSG QUEUE PNTR
1833         HRRE B,1(A)     ;GET COUNT 
1834         JUMPG B,IMPOB3
1835          JRST 4,.       ;ERROR, COUNT NOT > 0
1836 IMPOB3:                 ; Entry pt from NOP sending code
1837 IFN KAIMP,CONO IMP,IMO32C
1838 IFN DMIMP,CONO FI,FIO32C        ;SET 36 BIT MODE FOR LEADER, CLEAR PIA
1839         DATAO IMP,2(A)  ;OUTPUT FIRST LEADER WORD
1840         MOVEI C,2(A)    ;SET UP BLKO POINTER FOR REST OF LEADER
1841         SKIPN IMPSVQ
1842          JRST [ HRLI C,-2       ;KLUDGE, SENDING NOP
1843                 JRST IMPOB4 ]
1844         HRLI C,-5
1845         AOS IMPMSS+0    ;COUNT REGULAR MSGS SENT
1846 IFN INETP,[
1847         MOVE T,IMPCLP           ; HACK!  Get specified # to use for ctl link
1848         DPB T,[001000,,3(A)]    ; Deposit in link field of leader.
1849 ];INETP
1850 IFN NCPP,[
1851         LDB T,[341000,,10(A)]   ;FIRST BYTE OF CONTROL MESSAGE
1852         CAIGE T,20
1853          AOS IMPCMS(T)
1854 ];NCPP
1855 IMPOB4: MOVEM C,IMOLST  ;STORE BLKO POINTER THAT SENDS LEADER
1856         MOVEI C,2       ;DO TEXT WORDS IN 32-BIT MODE
1857         MOVEM C,IMOMOD
1858 IFN DMIMP,MOVNI B,(B)   ;GET MINUS WORD COUNT
1859 IFN KAIMP,MOVNI B,-1(B) ;ALSO -1 FOR LAST WORD SENT SEPARATELY.
1860         HRLI B,7(A)     ;ADDR-1 FOR BLKO
1861         MOVSM B,IMOBK1  ;STORE FOR PI 1
1862 IFN KAIMP,[
1863         MOVNI B,(B)
1864         ADD B,IMOBK1    ;LAST WORD SENT SEPARATELY
1865         HRROM B,IMOBK3
1866         MOVEI B,3       ;CHECK FOR SCREW CASE, ONLY SENDING ONE WORD, IT'S THE
1867         SKIPL IMOBK1    ; LAST, SO NOP OUT THE MAIN BLKO
1868          MOVEM B,IMOBK1
1869 ]
1870 .ELSE   MOVEI B,3
1871         MOVEM B,IMOBK2  ;NO 2ND BLKO
1872         MOVEI C,%ISONC  ;STATE FOR CONTROL RETURN TO NETCHN
1873 IMOB9:  MOVEM C,IMPOS
1874         SETZM IMOPNT
1875         MOVE C,[JSR IMPCH1]
1876         MOVEM C,IMPOLC
1877 IFN KAIMP,[
1878         SETOM IMPOH     ;OUTPUT SIDE WANTS IMP TO RUN ON CHANNEL 1
1879         MOVEI A,IMPCHN
1880         MOVEM A,IMPPIA
1881 ]
1882 IFN DMIMP,CONO FI,FIOUT+NETCHN_3+IMPCHN ;SET PIA FOR OUTPUT
1883         JRST IMPRET
1884 \f
1885 IFN INETP,[
1886 ; Here when IP datagram transmission completed
1887
1888 IMPOBI: SETZM IMPOS     ; Reset output state
1889         MOVE A,IMPODP
1890         PUSHJ P,IPIODN  ; Tell IP level that datagram was output
1891         SETZM IMPODP
1892         JRST IMPRET
1893 ] ;INETP
1894 \f
1895 SUBTTL  ARPANET CLOCK LEVEL
1896
1897 OVHMTR IMP      ;NETWORK INTERRUPT LEVEL (NOT STYNET STUFF)
1898
1899 IMRSTO: SKIPN IMRFCT    ;CALLED AT 15 SEC CLK LEVEL TO UNHANG RFNM WAITS
1900 IFE NCPP,POPJ P,
1901 IFN NCPP,JRST IMFCT1
1902         MOVEI H,LIMPHT-1        ;SOME CONTROL LINKS WAITING FOR RFNM, CHECK FOR TIME OUT
1903         MOVSI TT,401000 ;4.9 AND 4.1 - RFNM AND RRP TIMEOUTS
1904         TDNN TT,IMPHTB(H)
1905 IMRS4:   SOJGE H,.-1
1906 IFN NCPP,JUMPL H,IMFCT1
1907 IFE NCPP,JUMPL H,CPOPJ
1908         CONO PI,NETOFF
1909         SKIPE IMPHTN(H)         ;MAKE SURE IT'S A REAL HOST, NOT A FREE ENTRY
1910          TDNN TT,IMPHTB(H)      ;AND THAT THE BITS DIDN'T TURN OFF DUE TO INTERRUPT
1911           JRST IMRS1
1912         LDB E,[221100,,IMPHTB(H)]
1913         LDB D,[051100,,TIME]    ;GET TIME IN SECONDS (APPROX)
1914         CAMLE E,D
1915          ADDI D,1_9
1916         SUB D,E
1917         CAIGE D,IMRFTO_<-5>
1918          JRST IMRS1     ;HASN'T TIMED OUT YET.
1919         LDB D,IMHSBT    ;TIMED OUT.  CHECK RST/RRP STATUS.
1920         SOJE D,IMRS2
1921         MOVSI D,400000
1922         ANDCAM D,IMPHTB(H)      ;RFNM SENT, CLEAR IT
1923         AOS IMNRFN
1924         SOS IMRFCT
1925         BUG INFO,[NET: CTL LNK RFNM TIMEOUT HST],OCT,IMPHTN(H)
1926 IMRS1:  CONO PI,NETON
1927         JRST IMRS4
1928
1929 IMRS2:  DPB D,IMHSBT    ;RST SENT, SET STATE TO DOWN
1930         BUG INFO,[NET: RST TIMEOUT HST=],OCT,IMPHTN(H)
1931         SOS IMRFCT
1932         JRST IMRS1
1933 \f
1934 ;NETHST (HOST INFO)
1935 ; ARG 1 - HOST => VAL 1 - STATUS, VAL 2 - HOST NUMBER
1936 ; ARG 1 - -1 => VAL 1 - (STATUS), VAL 2 - OUR HOST NUMBER
1937 ;NOT CURRENTLY IMPLEMENTED- ARG 1 - -1, ARG 2 - OUR GOING-DOWN REASON
1938
1939 ANETHST:HRRE T,A                ;LET IMMEDIATE -1 WIN (777777 NOT A VALID HOST)
1940         AOJE T,ANETH2           ;JUMP IF WANT LOCAL STATUS AND HOST NUMBER
1941         MOVE T,A
1942         JSP J,STDHST            ;STANDARDIZE AND ERROR-CHECK HOST NUMBER
1943         MOVE B,T                ;RETURN NEW FORMAT *******
1944         TLO B,(NW%ARP)
1945         MOVEI H,LIMPHT-1
1946         CONO PI,NETOFF          ;DO WE HAVE STATUS?
1947         CAME T,IMPHTN(H)
1948          SOJGE H,.-1
1949         JUMPGE H,ANETH1         ;YES, RETURN IT
1950         CONO PI,NETON           ;NO, HAVE TO GO GET IT
1951         MOVEM T,SRN3(U)
1952 IFN NCPP,[
1953         PUSHJ P,NETO00          ;GET IMSOC, RETURN WITH NETLST, IMSOC LOCKED
1954          POPJ P,                ;DEVICE FULL OR SOMETHING
1955         PUSHJ P,NETOR           ;OPEN COMMUNICATIONS WITH HOST
1956          JFCL                   ;IT'S DOWN, THAT'S OK
1957 ];NCPP
1958 .ELSE   POPJ P,                 ;OH, TOO BAD
1959 ANETH1: MOVE A,IMPHTB(H)        ;GET STATUS
1960         CONO PI,NETON
1961         EXCH A,B
1962         CALL CVH2NA             ; Convert to HOSTS2 for compat
1963         EXCH A,B
1964         JRST LSWCJ1             ;RETURN IMSOC, NETLST IF NOT DONE ALREADY
1965
1966 ANETH2: ;CAIL W,2               ;(THIS IS A CROCK)
1967          ;MOVEM B,NTHDSW        ;IF 2 ARGS, SET OUR REASON FOR GOING DOWN.
1968         SKIPE IMPUP             ;FAKE UP OUR STATUS
1969          TDZA A,A               ;WE'RE DOWN
1970           MOVSI A,2000          ;WE ARE UP
1971         MOVEI B,IMPUS           ;AND OUR HOST #.
1972         JRST POPJ1
1973
1974
1975 ;NETIMP (REASON,TIMEDOWN,TIMEUP)  READ/SET
1976
1977 ANETIMP:JUMPLE W,ANETM1 ;NO ARGS, RETURN
1978         CAIGE W,3       ;MUST HAVE 3 ARGS IF ANY
1979          JRST OPNL30
1980         MOVEM A,IMPDWN
1981         MOVEM B,IMPDWN+1
1982         MOVEM C,IMPDWN+2
1983         JRST POPJ1
1984
1985 ANETM1: MOVE A,IMPDWN
1986         MOVE B,IMPDWN+1
1987         MOVE C,IMPDWN+2
1988         SKIPE IMPUP
1989          TLO A,400000
1990         JRST POPJ1