Consolidate license copies
[its.git] / system / imp.364
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
19 IMPVRS==.IFNM2  ; Version of IMP code
20
21 IFN NCPP,.FATAL IMP Code doesn't support NCP any more!
22 IFE KSIMP,.FATAL Wrong IMP driver file included!
23
24 OVHMTR IMP      ;Charge all this stuff to the IMP
25
26 $INSRT LHDH
27
28 ; IMP 1822 PROTOCOL INFORMATION (EXTENDED-LEADER VERSION)
29
30 ; The IMP leader is 96 bits long, usually organized as 3 words of 32 bits.
31 ; For further details, these documents are available from the Network
32 ; Information Center:
33 ;       IMP-HOST protocol: BBN Report No. 1822
34 ;       NCP protocol: NIC 8246, Host-to-Host Protocol for the ARPANET
35 ;       IP, TCP: Internet Protocol Transition Workbook, and
36 ;                Internet Protocol Implementor's Guide
37 ;
38 ; Here is the leader format used by the IMP code. This format uses
39 ; no IMP padding, assumes IP only, and expects all IMP<->HOST data
40 ; transfers in 32-bit mode.
41 ;
42 ; Previous versions of this code which supported NCP used a much more
43 ; complicated leader formatting scheme based on 36 bit transfers and
44 ; IMP padding. That scheme is dead, see SYSTEM;IMPOLD WTHNCP for details.
45 ;
46 ; All data from the IMP interface ends up in the -10 as left-justified
47 ; 32-bit words. Objects of less than 32 bits length, such as IP octets,
48 ; are stored in PDP10 ILDB byte order.
49 ;
50 ;------------------------------------------------------------------------
51 ;1:  4.9-4.6 not used (0)
52 ;    4.5-4.2 all 1's for new format, else old msg type (4=old nop)
53 ;    4.1-3.3 network number (0)
54 ;    3.2-2.8 not used (0)
55 ;        2.7 trace (ignored)
56 ;    2.6-2.4 leader flags (2.6 is to be ignored, 2.5-2.4 are not used!)
57 ;    2.3-1.5 message type
58 ;
59 ;2:  4.9-4.2 Handling type (7 for big buffers, 4 for small buffers,
60 ;                           0 for the control link)
61 ;    4.1-3.3 Host number on IMP
62 ;    3.2-1.5 IMP number
63 ;
64 ;3:  4.9-4.2 Link Number (High 8 bits of Message ID)
65 ;    4.1-3.7 Low 4 bits of Message ID (0) 
66 ;    3.6-3.3 Sub-type
67 ;    3.2-1.5 Message length
68 ;------------------------------------------------------------------------
69 ;4:  4.9-1.5 First word of IP datagram
70 ;    ....
71 ;------------------------------------------------------------------------
72 ;
73 ;In message types 2 and 6, the going-down status 16-bit word is
74 ;in word 3 bits 4.9-3.3.
75
76 ;3.6-3.3 of word 3 are the padding count for type 4 (nop) from host.
77 ;This is currently 0 (none).  Padding is only put on type-0 messages.
78 \f
79 IMPLDS==3                       ;IMP local leader size
80
81                                 ;Byte pointers to fields of input leader
82 IMOTBP: 340400,,IMPILB+0        ;Message format type
83 IMTBP:  041000,,IMPILB+0        ;Message type field
84 IMSABP: 043000,,IMPILB+1        ;Source address field (host+IMP)
85 IMSHBP: 241000,,IMPILB+1        ;Source host field
86 IMSIBP: 042000,,IMPILB+1        ;Source IMP field
87 IMLNBP: 341000,,IMPILB+2        ;Link number field
88 IMSTBP: 240400,,IMPILB+2        ;Subtype field
89 IMMLBP: 042000,,IMPILB+2        ;Message length field
90 \f
91
92
93 SUBTTL  ARPANET VARIABLES AND TABLES
94
95 EBLK
96
97 %IMXLN==:<<8159.-96.>+31.>/32.  ; Max # of 32-bit words in IMP regular msg,
98                 ; exclusive of leader and leader padding.  = 252.
99
100 %IMMTU==:251.*4 ; Used by IP/TCP. Driver currently rounds to PDP10 words,
101                 ; forcing this to be 1004 instead of 1007.
102
103 ; ACTIVE HOST TABLE.  Entries herein are allocated as needed, using garbage
104 ; collection.  Most "host number" fields are really indices into this table.
105 ;
106 LIMPHT==<XBL+10.>       ; TCP conns plus a few extra
107
108 IMPHTF: -1      ;Host table free list, threaded through IMPHTB, end with -1
109
110 IMPHTS:                 ;Start of table area
111 IMPHTN: BLOCK LIMPHT    ; Host number.  1.1-1.8 HOST, 2.1-3.7 IMP
112 IMPHTB: BLOCK LIMPHT    ;Bits:
113                         ;4.9            UNUSED
114                         ;4.8            GC MARK BIT
115                         ;4.7-4.3        UNUSED
116                         ;4.2-4.1        STATUS OF HOST 0 DOWN, 1 RST SENT, 2 UP
117                         ;3.9-3.1        UNUSED
118         .SEE IMPHDS     ;RH   Last message from IMP about "host dead status"
119 IMPHTC: BLOCK LIMPHT    ; # active messages outstanding for host (8 max)
120 IMPHTT: BLOCK LIMPHT    ; Time of last RFNM received
121 IMPHTE==.-1             ;Last location in table
122
123 ;Status variables
124 ;
125 IMPUP:  -1      ;0 => IMP up  ;-1 => down  ;-2 => coming up, PI  still off
126                 ;1 => down for good, until next time IMP ready line changes
127 IMPTCU: 0       ;0 IMP up/down status not changing
128                 ;>0 Trying to reinitialize, SYSJOB hasn't done so yet
129                 ;-1 Has been reinitialized, haven't exchanged NOPs yet
130 IMPUCT: 0       ;IMP coming up timeout, if 4 NOPs don't go through promptly.
131 IMPDWN: BLOCK 3 ;Last message from IMP that it is going down
132                 ;WD0: "Reason" claimed by IMP (see ch 3 of BBN report 1822)
133                 ;WD1: Time when expected down
134                 ;WD2: Time when expected up (SYS time=1/30 sec since up)
135
136 IMERCN: -1      ;CONI into here when net goes down
137
138 BBLK
139 \f
140 EBLK
141
142 ;Input side variables
143 ;
144 IMPILB: BLOCK IMPLDS    ;Input leader buffer
145 IMPCSH: -1      ;Current source host (IMPHTB index).  -1 when idle.
146 IMPCLN: 0       ;Current link number
147 IMIFLS: 0       ;Flushing output at interrupt handler
148 IMPIEC: 0       ;Count of input errors while down.
149 IMPIBC: 0       ;Count of words available in DMA input buffer
150 IMPIBP: 0       ;Pointer into DMA input buffer
151
152 ;Output side variables
153 ;
154                 ;Output leader buffer
155 IMOLDR: <17_10.>,,0     ;Regular new-format message
156 IMOLAD: 0               ;Filled in with destination IMP address
157         <233_10.>,,0    ;IP link field
158
159 IMNOPC: 0       ;< 0 => Send NOPs
160 IMPOAC: -1      ;>= 0 => Output active, don't restart
161 IMPBZY: 0       ;-1 == Waiting for output interrupt
162 IMPODP: 0       ;Pointer to IP datagram being output at PI level
163 IMPOS:  0       ;Output state
164  %ISODL==:0     ; Not expecting output done (i.e. between messages)
165  %ISONP==:1     ; Sending NOP
166  %ISOID==:2     ; Sending IP Datagram
167
168 ;Meters
169
170 ;IP meters
171 IMNIPI: 0       ; # of IP datagrams input (rcvd)
172 IMNIPF: 0       ; # of IP datagrams flushed (input threw away)
173 IMNIPO: 0       ; # of IP datagrams output (sent)
174 IMNIPR: 0       ; # of IP RFNMs received
175 IMNIP7: 0       ; # of IP Type 7 (Dest Host Dead) messages received
176 IMNIP8: 0       ; # of IP Type 8 (Error) msgs rcvd
177 IMNIP9: 0       ; # of IP Type 9 (Incomplete Transmission) msgs rcvd
178 IMNWIG: 0       ; # words ignored by "Ignore" state (%ISIGN)
179 IMNWIF: 0       ; # words flushed by IMPRM5
180
181 ;IMP meters
182 IMNSRF: 0       ;Number of spurious RFNMs on non-IP links
183 IMNBLK: 0       ;Number of times blockage avoided (output held up by ITS)
184
185 IMPMSR: BLOCK 20;Count of IMP messages rcvd
186 IMPM1S: BLOCK 4 ; # Type 1 (Error in Leader) subtype msgs
187 IMPM9S: BLOCK 2 ; # Type 9 (Incomplete Transmission) subtype msgs
188 IMPMSS: BLOCK 1 ;Count of IMP msg sent (we only send regular msgs)
189 IMCT1:  0       ;# Unvectored interrupts
190 IMCT2:  0       ;# Valid input interrupts
191 IMCT3:  0       ;# Valid output interrupts
192 BBLK
193 \f
194 SUBTTL  ARPANET MAIN-PROGRAM LEVEL
195 ;IMPIBF, IMPOBF defined as low-memory buffer page in ITS
196 IF2,IFN IMPIBF&777,.FATAL IMPIBF not on DEC page boundary
197
198 ;(Re)Start IMP. Called from SYSJOB to start IMP, or on error or
199 ; user requested cycle through LOCK
200 ;
201 IMPINI: SETOM IMPUP             ;Not up yet,
202         SETOM IMPTCU            ; but thinking about it.
203         MOVEI A,IMPIBF_-9.      ;DEC page # of IMP buffer page
204         TRO A,%UQ16B\%UQVAL     ;Valid mapping, 16 bit device
205         IOWRI A,UBAPAG+IUIMPG_1 ;Set up 1 DEC page of UBA mapping. Note that
206                                 ; the second half of IUIMPG isn't mapped at all
207         CONO PI,NETOFF          ;Freeze things while IMP bashing occurs
208         MOVEI A,%LHRST
209         IOWRI A,%LHOCS          ;Reset output side
210         IOWRI A,%LHICS          ;Reset Input side
211
212         ;IMP now shut down. Reset variables
213         SKIPE A,IMPODP          ;Have an output datagram ?
214          PUSHJ P,IPIODN         ;Yep, release it.
215         SETZM IMPODP            ;No output datagram
216         SETZM IMPOS             ;Output idle
217         SETOM IMPOAC            ;Output interrupt level inactive
218         SETZM IMPBZY            ;No pending output interrupt
219
220         SETZM IMPIBC            ;No input available
221         SETZM IMPIEC            ;No input errors yet
222         SETZM IMIFLS            ;Not flushing input at interrupt level
223         SETOM IMPCSH            ;No current host table index
224         SETOM IMPDWN+1          ;Time for IMP to go down, not known
225         CONO PI,NETON           ;Allow interrupts again
226
227         ;Wait one sec for IMP to notice rdy line drop
228         MOVE T,TIME
229         ADDI T,30.
230         CAMLE T,TIME
231          PUSHJ P,UFLS
232
233         MOVNI A,30.             ;Allow 15 seconds to come up
234         MOVEM A,IMPUCT
235         MOVE T,TIME             ;Note when we last started IMP
236         MOVEM T,LNETIM
237         PUSHJ P,IMPHRS          ;Set host ready
238         PUSHJ P,IMPIST          ;Start input
239
240         MOVE T,TIME
241         ADDI T,15.              ;Wait 1/2 sec before we try to output
242         CAMLE T,TIME
243          PUSHJ P,UFLS
244         MOVNI A,4
245         MOVEM A,IMNOPC          ;Send 4 NOPs to start
246         ;Falls through to start output
247 \f
248 ;Start IMP output
249 ;
250 IMPOST:
251 IMPIOS: CONO PI,PIOFF           ;Freeze.
252         AOSE IMPOAC             ;Do nothing if output already active.
253          JRST PIONJ
254         SETOM IMPBZY            ;Note we want an IMP interrupt
255         CONO PI,NETRQ           ;Force nonvectored IMP interrupt
256          JRST PIONJ
257
258 ;Check if IMP ready line is set
259 ; Called from SYSJOB.
260 ; Return +1 if IMP not ready, +2 if so
261 ;
262 IMPCKR: IORDI A,%LHICS          ;Get input CSR
263         TRNN A,%LHINR           ;Skip if IMP not ready
264          AOS (P)                ;Return +2 if ready
265         POPJ P,                 ;That's all
266
267 ;Set HOST READY. From SYS job only, please, loops waiting.
268 ;
269 IMPHRS: IORDI T,%LHICS
270         TRNN T,%LHRDY           ;Can we mung?
271          BUG
272         IORI T,%LHHRC\%LHSE     ;Turn on HR. SE prevents dropping messages
273         IOWRI T,%LHICS
274         MOVEI A,777777          ;I don't know why this takes so long.
275 IMPHR1: IORDI T,%LHICS          ;Get the bits back
276         TRNE T,%LHHR            ;LHDH thinks host ready is ready
277          RET                    ;HR line set
278         SOJG A,IMPHR1           ;Timed out yet?
279          BUG CHECK,[IMP: Timed out setting Host Ready]
280         RET
281 \f
282 SUBTTL  HOST-TABLE MANAGEMENT
283
284 ;IMPHTI - Initialize host table
285 ; Performed whenever IMP announces that it has been reset
286 ;
287 IMPHTI: SETOM IMPHTF            ;Force GC of IMPHTB on first reference
288         SETZM IMPHTS            ;Clear table of old information
289         MOVE A,[IMPHTS,,IMPHTS+1]
290         BLT A,IMPHTE
291         POPJ P,
292
293 ; FNDHST - Look up host-table index for a given IMP host address.
294 ;       Call with NETOFF or NETCHN PI in progress.
295 ;       T/ IMP host address (maybe someday other nets?)
296 ; Returns .+1 if failed (no room in table)
297 ; Returns .+2
298 ;       H/ host-table index
299 ; Smashes W.
300
301 FNDHST: MOVEI H,LIMPHT-1        ;Search for an entry for this host
302         CAME T,IMPHTN(H)
303          SOJGE H,.-1
304         JUMPGE H,POPJ1          ;Found
305         SKIPGE H,IMPHTF         ;Not found, cons one off free list
306          JRST FNDHS1            ;Oops, must garbage collect
307         MOVE W,IMPHTB(H)
308         CAIGE H,LIMPHT          ;Make sure H is valid idx
309          CAIL W,LIMPHT          ;ditto W
310           BUG HALT,[NET: FNDHST idx clobbered!!!]
311         MOVEM W,IMPHTF
312         MOVEM T,IMPHTN(H)
313         SETZM IMPHTB(H)         ;Nothing is known about this host
314         SETZM IMPHTC(H)         ;Assume no RFNMs outstanding
315         SETZM IMPHTT(H)         ;Clear out time of last RFNM.
316         JRST POPJ1
317
318 ; Host-Table full, attempt to GC it and flush unused entries, by
319 ; scanning all possible pointers into table.
320 ;       IMP pointers are IMPCSH and IMPHTC(H)
321 ;       TCP pointers are XBNADR(I)
322
323 ; GC mark phase - mark entries in use
324 FNDHS1: PUSH P,I
325         MOVSI W,200000          ;Mark bit
326         MOVEI H,LIMPHT-1        ;Clear all mark bits
327         ANDCAM W,IMPHTB(H)
328         SOJGE H,.-1
329         SKIPL H,IMPCSH          ;Mark from IMPCSH
330          IORM W,IMPHTB(H)
331 IFN TCPP,[
332         MOVEI I,XBL-1
333         SKIPL H,XBNADR(I)       ; See if TCP conn has a net addr specified
334          IORM W,IMPHTB(H)       ; Yes, set the mark bit.
335         SOJGE I,.-2
336 ] ;IFN TCPP
337 \f
338 ; GC sweep phase - free all unmarked entries
339         SETO I,                 ;Free pointer
340         MOVEI H,LIMPHT-1
341         MOVSI W,601000          ;Protect if RFNM-WAIT, RST-WAIT, or marked
342 FNDHS4:
343         SKIPG IMPHTC(H)         ;Also protect if any outstanding RFNMs
344          TDNE W,IMPHTB(H)
345           SOJGE H,FNDHS4
346         JUMPL H,FNDHS5
347         SETZM IMPHTN(H)         ;Don't belong to any host
348         MOVEM I,IMPHTB(H)       ;Cons onto free list
349         MOVE I,H
350         SOJGE H,FNDHS4
351 FNDHS5: MOVEM I,IMPHTF          ;Free list
352         POP P,I
353         SKIPGE IMPHTF
354          POPJ P,                ;GC-overflow
355         JRST FNDHST             ;Try again, should win
356
357 ;See if IMP code is willing to handle a particular datagram right now.
358 ; A/ IP DGM pointer
359 ; C/ Immediate destination address
360 ; Returns +1, can't send right now, +2, OK to send
361 ;
362 IMPCTS: MOVE T,C                ;Set up for FNDHST
363         AND T,[<377_16.>+377]   ;Mask out all but host and IMP field
364         CALL FNDHST             ;Get host index in H
365          POPJ P,                ;No host entry, don't send
366         JSP T,IMPBLI            ;See if OK to send
367          POPJ P,                ;IMP wants to block, no send
368         JRST POPJ1              ;Skip return if OK to send.
369
370 \f
371 ;;; IMP Blockage avoidance
372 ;       The current IMP software will not accept more than 8 active
373 ; messages to a single host; attempting to send a 9th message will block
374 ; ALL output to the interface, until the first message has been ack'd
375 ; by means of one of the following message types:
376 ;       Type 5, RFNM - Message delivered OK
377 ;       Type 7, Host dead - transmit failed ("permanent")
378 ;       Type 8, Error in data - interface spazzed
379 ;       Type 9, Incomplete Transmission - temporary failure
380 ; If for some reason the first message simply becomes lost, the IMP timeout
381 ; (and blockage) can last for up to 30-45 seconds.
382 ; More details in BBN Report 1822.
383 ;       ITS attempts to fix this by keeping a count of active un-ACKed
384 ; messages for each host it is communicating with.  A timeout is also
385 ; associated with each host; if output to a given host is blocked by ITS
386 ; because there are 8 active messages, trying to send a 9th message
387 ; will check the last-RFNM-received time and if this was more than
388 ; 30 or so seconds then the IMP is probably not giving us what it should
389 ; and we should reset things for that host.
390
391 %IMPMA==:8.     ; # of maximum active IMP messages allowed
392
393 ; IMPBLI, IMPBLD - routines to hack active-message counts, called via JSP T,
394 ;       IMPBLD decrements count.
395 ;       IMPBLI increments count and skips if successful (else failed,
396 ;               and must NOT output another message to this host!)
397 ;               Also clobbers Q.
398 ;
399 IMPBLI: AOS Q,IMPHTC(H)
400         CAIGE Q,%IMPMA          ;Trying to send max or more messages?
401          JRST 1(T)              ;No, can return safely.
402         CAIG Q,%IMPMA           ;Is this the maximum # allowed?
403          JRST [ MOVE Q,TIME     ;Yes, set up blockage timeout
404                 ADDI Q,60.*30.  ; for one minute.
405                 MOVEM Q,IMPHTT(H)
406                 JRST 1(T)]      ;And allow this one to be sent
407
408         ; Trying to send too many messages, block it (check for timeout though)
409         SOS IMPHTC(H)           ;Restore original count
410         AOS IMNBLK              ;Increment # of times softwarily blocked.
411         MOVE Q,IMPHTT(H)
412         CAML Q,TIME             ;See if timeout still in the future
413          JRST (T)               ;Yes, just take failure-return to block.
414         BUG INFO,[IMP: RFNM-wait timeout! Hst=],OCT,IMPHTN(H)
415         SETZM IMPHTC(H)         ;This may be dangerous... oh well.
416         SETZM IMPHTT(H)
417         JRST (T)                ;Block one last time, next try will win.
418
419 ;Decrement block count on receipt of any kind of ACK
420 ;
421 IMPBLD: SOSL Q,IMPHTC(H)
422          JRST IMPBL2
423         BUG INFO,[IMP: negative RFNM-wait cnt, Hst=],OCT,IMPHTN(H)
424         SETZB Q,IMPHTC(H)
425 IMPBL2: CAIL Q,%IMPMA-1         ;If we were blocking on this host,
426          PUSHJ P,IMPIOS         ;Ensure IMP output started up so blocked stuff
427         JRST (T)                ; gets sent promptly.
428
429 \f
430 SUBTTL  ARPANET INPUT INTERRUPT LEVEL
431
432 ;First level interrupt handling for input side. Here from UBA vector hardware.
433
434 IFN NETCHN-UTCCHN,.ERR NETCHN assumed == UTCCHN at IMPIBK
435
436         EBLK
437 IMPIBK: 0
438         BBLK
439         JSR UTCSAV              ;Save AC's, get a stack
440         AOS IMCT2               ;Count input interrupts
441         IORDI TT,%LHICS         ;Get CS register
442         TRNE TT,%LHERR\%LHNXM
443          JRST IMPRST            ;Try resetting the IMP
444         TRNE TT,%LHMRE          ;Ready line flapped
445          JRST IMPIER            ;Go directly to error routine
446         TRNN TT,%LHRDY          ;Device ready for new operation?
447          JRST IMPRST            ;Try resetting. 
448         TRNN TT,%LHEOM          ;Saw EOM from IMP?
449          JRST IMPIB1            ;No, word count ran out before message
450         SKIPGE IMIFLS           ;Flushing output?
451          JRST [ SETZM IMIFLS    ;Not any more!
452                 JRST IMPIRT ]   ;But flush last piece by queueing new request
453         IORDI A,%LHIWC          ;End of message. Get remaining UB word count
454         SKIPE A                 ;This would be a surprise, really
455          TDO A,[-1,,600000]     ;36bit number of UBA words remaining in bfr
456         IDIVI A,2               ;Number of PDP10 words (cleverly rounded)
457         ADDI A,IMPBFS           ;Number of PDP10 words of message
458         MOVEM A,IMPIBC          ;Set current count of available data words
459         MOVEI A,IMPIBF
460         MOVEM A,IMPIBP          ;Set pointer to available data words
461         JRST IMPLDD             ;Go process input message
462
463 ;Here when finished processing current message.
464 IMPIRT: SETOM IMPCSH            ;Note no current host
465         PUSHJ P,IMPIST          ;Restart input listener
466         JRST IMPEX
467
468 ;Message didn't fit in input buffer. Shouldn't ever get here, but
469 ;might if messages concatenated due to ready line randomness
470 ;
471 IMPIB1: BUG INFO,[IMP: Huge message]
472         SETOM IMIFLS            ;Say we are flushing output
473         JRST IMPIRT             ;And go queue up another read
474
475 ;Here if error during IMP message transfer
476 ; Currently the only error handled is the IMP going non-ready
477
478 IMPIER: SKIPE IMPUP             ;Is the IMP supposed to be up?
479          JRST IMPIE1            ;No, handle errors differently
480         BUG INFO,[IMP: Input Ready Error]
481         JRST IMPRST             ;Ready line flapped while up, cycle interface
482
483 IMPIE1: AOS T,IMPIEC
484         CAIG T,10.              ;Huge number of errors while down?
485          JRST IMPIRT            ;No, just ignore this input and start another
486         SETZM IMPIEC            ;Reset
487         BUG INFO,[IMP: Excessive input errors while down]
488         JRST IMPRST             ;Cycle the interface
489 \f
490 IMPRST: IORDI T,%LHICS          ;Record IMP status for sysjob
491         HRLZM T,IMERCN
492         IORDI T,%LHOCS
493         HRRM T,IMERCN
494         MOVEI A,%LHRST          ;Avoid randomness by resetting HW now.
495         IOWRI A,%LHOCS          ;Reset output side
496         IOWRI A,%LHICS          ;Reset Input side
497         SETOM IMPUP             ;IMP is down
498         MOVEI T,1
499         MOVEM T,IMPTCU          ;But trying to come up (sysjob poked)
500         MOVSI J,SCLNET          ;Ask SYSJOB to cycle the IMP
501         IORM J,SUPCOR
502         JRST IMPEX
503 \f
504         SUBTTL IMP leader dispatch handling
505
506 IMPLDD: SKIPG B,IMPIBC          ;Get count of available data
507          POPJ P,                ;None, nothing to do.
508         CAILE B,IMPLDS          ;More than a leader worth?
509          MOVEI B,IMPLDS         ;Yep, only want leader now
510         MOVS A,IMPIBP           ;Copy and reformat leader to IMPILB
511         HRRI A,IMPILB
512         BLTUB A,IMPILB-1(B)
513         ADDM B,IMPIBP           ;Increment buffer pointer,
514         MOVN C,B
515         ADDM C,IMPIBC           ; and decrement count
516
517         LDB T,IMOTBP            ;Examine new-format flag bits of leader
518         CAIL B,IMPLDS           ;Large enough to be a valid leader?
519          CAIE T,17              ;Verify that leader is "new" 96-bit fmt.
520           JRST IMPLDE           ;Go process error in leader
521
522         LDB T,IMLNBP            ;Extract link number (high 8 bits of msg-id)
523         MOVEM T,IMPCLN          ;Save link message arrived on
524         LDB T,IMSABP            ;Get arpanet address (source host+imp)
525 IFN 0,[ 
526         LDB T,IMSHBP            ;Source host
527         LDB A,IMSIBP            ;Source imp
528         DPB A,[112000,,T]       ;Form host address
529 ];IFN 0
530         PUSHJ P,FNDHST          ;H gets host table index
531          JRST IMPLHE            ;Host table full
532         MOVEM H,IMPCSH          ;Save current host
533         LDB A,IMTBP             ;Get message type in A
534         CAIL A,IMTDTS
535          JRST IMPUN             ;Unknown type?
536         AOS IMPMSR(A)           ;Count IMP msgs rcvd
537         JRST @IMTDT(A)          ;Dispatch
538
539 IMTDT:  IMPRM   ; 0 Regular Message
540         IMPBE1  ; 1 Error in Leader (no msg-id)
541         IMPGD   ; 2 IMP Going Down
542         IMPUN   ; 3  -
543         IMPIN   ; 4 NOP
544         IMPRFN  ; 5 RFNM - Ready For Next Message (transmit succeeded)
545         IMPHDS  ; 6 Host Dead Status (general info)
546         IMPDHD  ; 7 Destination Host Dead (transmit failed)
547         IMPBE8  ; 8 Error in Data (has msg-id)
548         IMPINC  ; 9 Incomplete Transmission (transmit failed temporarily)
549         IMPIRS  ;10 Interface Reset - IMP dropped its ready line
550 IMTDTS==.-IMTDT
551
552 IMPLHE: BUG INFO,[IMP: Message discarded due to host table full],OCT,IMPILB,OCT,IMPILB+1,OCT,IMPILB+2
553         JRST IMPIRT
554 \f
555 ;Here if leader is too short or of wrong format.
556 ; B/ Leader length
557 IMPLDE: SKIPE IMPUP             ;If IMP is not up, we'll take anything.
558          JRST IMPIRT
559         CAIGE B,IMPLDS          ;Announce short leader if so.
560          BUG INFO,[IMP: Short leader, ],DEC,B,[wds. WD1=],OCT,IMPILB,[WD2=],OCT,IMPILB+1
561         LDB A,IMOTBP            ;Get message format type
562         CAIN A,4                ;Old-type NOP?
563          JRST IMPIRT            ; Just ignore it.
564 IFN 0,[ ;;For the moment this is a problem because the IMP is marked
565         ;;up too soon, before all incoming NOPS are received.
566         CAIN A,16               ;Is it 1822L format?
567          BUG INFO,[IMP: 1822L leader],OCT,IMPILB
568         CAIE A,17               ;Is it not the long-leader format?
569          BUG INFO,[IMP: Old-type leader],OCT,IMPILB
570 ]
571         JRST IMPIRT             ;Ignore rest of message, if any
572
573 ;;; IMP->Host Type X (e.g. 3, 11-255) - bad type
574
575 IMPUN:  BUG INFO,[IMP: Unknown msg type ],OCT,A,[ leader ],OCT,IMPILB,OCT,IMPILB+1,OCT,IMPILB+2
576         JRST IMPIRT
577
578 ;;; IMP->Host Type 1 - Error in leader (msg-id not given)
579 ;;; IMP->Host Type 8 - Error in data  (msg-id given)
580
581 IMPBE1: LDB T,IMSTBP            ;Get subtype (4 bits)
582         ANDI T,3                ;Only 2 bits should be used
583         AOS IMPM1S(T)           ;Increment count of Type 1 subtype messages
584 IMPBE8: SKIPN IMPUP             ;Ignore error during initial syncronization
585          BUG INFO,[IMP: Type ],DEC,A,[err msg, leader],OCT,IMPILB,OCT,IMPILB+1,OCT,IMPILB+2
586         MOVE B,IMPCLN           ;Get link msg came in on
587         CAIN B,233              ;Internet link?
588          AOS IMNIP8             ;Yes, count IP meter
589         CAIN A,8.               ;Error identified with a particular message?
590          JSP T,IMPBLD           ;Decrement count of active messages
591         JRST IMPIRT
592
593 ;;; IMP->Host Type 2 - IMP going down
594
595 IMPGD:  LDB B,[420200,,IMPILB+2]        ;Reason (see 1822)
596         MOVEM B,IMPDWN
597         LDB B,[360400,,IMPILB+2]        ;How soon going down * 5 mins
598         MOVE H,B
599         IMULI B,5*60.*30.       ;Ticks in 5 mins
600         ADD B,TIME
601         MOVEM B,IMPDWN+1
602         LDB C,[241200,,IMPILB+2]        ;How long to be down * 5 minutes
603         MOVE Q,C
604         IMULI C,5*60.*30.       ;Downtime in ticks
605         ADD C,B                 ;Add to time down
606         MOVEM C,IMPDWN+2        ;Store time when will be up
607         IMULI H,5               ;Minutes
608         IMULI Q,5
609         BUG INFO,[IMP: Going down in ],DEC,H,[mins for ],DEC,Q,[mins, reason],DEC,IMPDWN
610         JRST IMPIRT
611
612 ;;; IMP->Host Type 4 - NOP
613
614 IMPIN:  JRST IMPIRT             ;One more NOP from IMP
615 \f
616 ;;; IMP->Host Type 5 - RFNM (Ready For Next Message)
617
618 IMPRFN: JSP T,IMPBLD            ;Decrement outstanding message count for host
619         MOVE A,IMPCLN           ;Get link #
620         CAIE A,233              ;IP link number?
621          JRST IMRFNX            ;No, skip IP code
622         AOS IMNIPR              ;Bump count of IP RFNMs received
623         JRST IMPIRT             ; and do nothing else about it, ugh.
624
625 IMRFNX: BUG INFO,[IMP: Spurious RFNM from ],OCT,IMPHTN(H),[link],OCT,IMPCLN
626         AOS IMNSRF
627         JRST IMPIRT
628
629 ;;; IMP->Host Type 6 - Host Down Status
630 ;       H/ host index
631
632 IMPHDS: LDB A,[301400,,IMPILB+2];Bits 65-76 of leader, 4.9-3.7 3rd word
633         HRRM A,IMPHTB(H)        ;Store, hope user read RFC 611
634         JRST IMPIRT
635
636 ;;; IMP->Host Type 7 - Destination Host Dead
637
638 IMPDHD: MOVEI E,%NCDED
639         JRST IMPHNR
640
641 ;;; IMP->Host Type 9 - Incomplete Transmission
642
643 IMPINC: LDB T,IMSTBP            ;Get subtype field (4 bit reason for failure)
644         AOS IMPM9S(T)           ;Bump count of subtypes
645         MOVEI E,%NCINC          ;This is an incomplete msg response
646
647 IMPHNR: JSP T,IMPBLD            ;Decrement active IMP msg count for this host
648         MOVE A,IMPCLN           ;Link for this message?
649         CAIE A,233              ;IP Link?
650          JRST IMPHN1
651         CAIN E,%NCINC           ;Yes, count IP meters
652          AOS IMNIP9
653         CAIN E,%NCDED
654          AOS IMNIP7
655         JRST IMPIRT
656
657 IMPHN1: BUG INFO,[IMP: DHD or IT msg rcvd on non-IP link]
658         JRST IMPIRT
659
660 ;;; IMP->Host Type 10 - Interface Reset
661
662 IMPIRS: PUSHJ P,IMPHTI          ;Initialize host table
663         BUG INFO,[IMP: Interface reset]
664         JRST IMPIRT
665
666 \f
667 ;;; IMP->Host Type 0 - Regular Host-Host message
668 ; Unless the source host screwed up and sent a dataless message,
669 ; there is at least one word waiting to be read in the buffer.
670 ;
671 IMPRM:  SKIPG A,IMPIBC          ;Get available input word count
672          JRST IMPIRT            ;None left, just ignore message
673         MOVE B,IMPCLN           ;Is link number the magic cookie for IP?
674         CAIE B,233
675          JRST IMPIRT            ;No, ignore it
676
677 ;IP datagram. Copy into IP buffer and pass it up.
678 ;
679         AOS IMNIPI              ;Bump count of IP datagrams received
680         PUSHJ P,IPGIPT          ;Ask IP for buffer of size (A)
681          JRST [ AOS IMNIPF      ;Punted, bump cnt of datagrams lost
682                 JRST IMPIRT ]   ;Flush this message (err msg already printed)
683         MOVE B,PK.BUF(A)        ;Destination
684         HRL B,IMPIBP            ;Source
685         MOVE C,IMPIBC           ;Input words available
686         ADDI C,-1(B)            ;Last destination address
687         BLTUB B,(C)             ;Copy and reformat data to IP buffer
688         MOVE B,IMPIBC           ;Get word count back to B
689         SETZB C,IMPIBC          ;Say zero offset to IP header, and clear count.
690         MOVE J,IMPCSH           ;Set idx to host-table entry dgm received from.
691         PUSHJ P,IPRDGM          ;Hand off rcvd datagram to IP
692         JRST IMPIRT             ;Return from PI level, setting up for next msg
693
694 ;Start listening for new input from IMP
695 ;
696 IMPIST: HRREI T,-IMPBFS*2
697         IOWRI T,%LHIWC          ;Read up to a buffer full of data
698         MOVEI T,<IUIMPG_12.>+<4*<IMPIBF&777>>
699         IOWRI T,%LHICA          ;Read data to here
700         MOVEI T,%LHIE\%LHHRC\%LHSE\%LHGO ;Interrupt, store data, go
701         IOWRI T,%LHICS          ;Start read
702         RET
703
704 \f
705 SUBTTL  ARPANET OUTPUT INTERRUPT LEVEL
706
707 ;Here on unvectored interrupt caused by call to IMPIOS
708
709 IMPINT: AOS IMCT1               ;Count unvectored interrupts
710         JRST IMPOBZ             ;Go try to start output
711                                 ;Returns directly to interrupt dispatcher
712
713 ;First-level interrupt handling, from hardware dispatch.
714 ; Crash on severe interface errors
715 ; Restart IMP on ready line flappage.
716 ; Else, go look for more output to send.
717
718 IFN NETCHN-UTCCHN,.ERR NETCHN assumed == UTCCHN at IMPOBK
719
720         EBLK
721 IMPOBK: 0
722         BBLK
723         JSR UTCSAV              ;Save AC's, get a stack
724         AOS IMCT3               ;Count output interrupts
725         IORDI TT,%LHOCS         ;Get CS register
726         TRNE TT,%LHERR\%LHNXM   ;Interface lost?
727          JRST IMPOEC            ;Try cycling
728         TRNE TT,%LHMRE          ;Somebody bounce a ready line?
729          JRST IMPOER
730 IMPOBE: TRNN TT,%LHRDY          ;Device ready for new operation?
731          JRST IMPOEC            ;Try cycling
732         PUSHJ P,IMPOBZ          ;No IMP error. Perform planned action.
733         JRST IMPEX              ;Dismiss interrupt.
734
735 ;Error while outputting datagram. Currently, just means ready line flapped.
736 ; If IMP was up, finish up IP output if necessary to free buffer, then
737 ;  cycle the interface.
738 ; If trying to send NOPS to come up, just send a few more to resynch.
739 ;
740 IMPOER: SKIPE IMPUP             ;IMP up?
741          JRST IMPOE1            ;Not running normally, maybe OK.
742         BUG INFO,[IMP: Output RDY error]
743 IMPOEC: SKIPE A,IMPODP          ;Have an output datagram ?
744          PUSHJ P,IPIODN         ;Yep, release it.
745         SETZM IMPOS             ;Doing nothing useful
746         JRST IMPRST             ;Go poke SYSJOB to cycle the IMP
747
748 ;Here if interface wasn't fully up. 
749 IMPOE1: MOVE T,IMPOS
750         CAIE T,%ISONP           ;Were we sending a NOP?
751          BUG CHECK,[IMP: Confusing output error]
752         SOS IMNOPC              ;Add another NOP to make up for this one
753         SETZM IMPOS             ;NOt doing anything anymore
754         JRST IMPOBE             ;Go continue processing.
755
756 ;IMPOBZ - Toplevel output processing routing.
757 ; Called from output done interrupt handler or from MP/CLOCK level with
758 ; NETOFF to start output.
759
760 IMPOBZ: SKIPL B,IMPOS
761          CAIL B,IMPODL
762           BUG HALT,[IMP: Bad output state]
763         JRST @IMPODT(B)
764
765 IMPODT: OFFSET -.
766 %ISODL::        IMPOB0  ; 0 Idle, look for something to send
767 %ISONP::        IMPOB1  ; 1 Finished NOP
768 %ISOID::        IMPOB2  ; 2 Finished IP datagram messge
769 IMPODL::OFFSET 0
770 \f
771 ;Here when interrupt has finished processing a complete message.
772 ; Attempt to find something else to do.
773 ;
774 IMORET: 
775         ;JRST IMPOB0            ;Fall through to try for more
776
777 ; Idle - Look for output to send.  First ensure we can send stuff,
778 ;       then try things in the order:
779 ;       (1) Send NOP if net coming up
780 ;       (2) Check IP datagram queue
781 ;
782 IMPOB0: HRRZ T,IMPUP            ;Get current IMP state.
783         CAIE T,-2               ;Don't say it's up when it's still going down
784          CAIN T,1               ;or when it is broken
785           JRST IMPOBN
786
787         ; First check to see if NOP needs to be sent.
788         AOSG IMNOPC             ;Check to see if sending NOPs
789          JRST IMONOP            ;Output a NOP
790         SETZM IMPUP             ;Say IMP is up
791         SETZM IMPTCU            ;Say no longer trying to come up
792
793         ; Now see if there is any real traffic to send
794         PUSHJ P,IPGIOQ          ;Check IP. Get IP IMP output queue entry if any
795          JRST IMPOBN            ;Nothing there, we're done.
796
797         ; Returns A/ ptr to IP dgm struct
798         ;         B/ BLKO pointer to 32-bit words (unused)
799         ;         C/ Arpanet address
800         ;
801         ;Build an IMP-format datagram at IMPOBF.
802         ; Set correct address in prototype leader.
803         ; BLT and reformat leader to IMPOBF.
804         ; BLT and reformat datagram to IMPOBF + leader size.
805
806         MOVEM A,IMPODP          ;Save ptr to datagram being output
807         AOS IMNIPO              ;# of IP datagrams sent
808
809         ;Put together the IMP leader in IMOLDR.
810 IFN 0,[ ;First and third word initialized at assembly time
811         MOVE B,[17_10.,,0]      ;Regular message
812         MOVEM B,IMOLDR
813         MOVSI B,233_10.         ;IP link # in left 8 bits
814         MOVEM B,IMOLDR+2        ;Set up third word
815 ]
816         LSH C,4.                ;Move net address to correct field
817         MOVEM C,IMOLAD          ;set up second word of leader
818         
819         ;Copy leader and datagram to IMPOBF
820         MOVE B,[IMOLDR,,IMPOBF]
821         BLTBU B,IMPOBF+IMPLDS-1 ;Move IMP leader into place
822         MOVS B,PK.BUF(A)        ;SOURCE,,COUNT
823         MOVEI A,IMPLDS(B)       ;Size including leader to A
824         HRRI B,IMPOBF+IMPLDS    ;Put d'gram immediately after leader.
825         BLTBU B,IMPOBF-1(A)
826         PUSHJ P,IMPSOH          ;Go start hardware
827         MOVEI C,%ISOID          ;Remember we are outputting IP leader
828         MOVEM C,IMPOS
829         POPJ P,
830
831 \f
832
833 ;Here if nothing to output.
834 ; Flag output inactive and disable interface
835 ;
836 IMPOBN: SETOM IMPOAC            ;No more output
837         IORDI TT,%LHOCS
838         TRZ TT,%LHIE\%LHGO      ;Deactivate interface for a bit
839         IOWRI TT,%LHOCS
840         POPJ P,
841
842 ;IMONOP - Send a NOP, here from IMPOBZ only.
843 ;
844 IMONOP: MOVEI A,IMPNOS          ;Length of NOP message
845         MOVE B,[IMPNOP,,IMPOBF] ;BLT (and reformat) NOP to output buffer
846         BLTBU B,IMPOBF-1(A)
847         PUSHJ P,IMPSOH          ;Start output of (A) words from IMPOBF to IMP
848         MOVEI C,%ISONP          ;Set correct output FSM state
849         MOVEM C,IMPOS
850         POPJ P,
851
852 ;Prefabricated NOP Host-IMP leader
853 IMPNOP: 17_10.,,4_4             ;New format, type 4 = NOP
854         0
855         0                       ;No padding required on regular messages
856 IMPNOS==.-IMPNOP
857
858 ;Finished sending NOP, from IMPOBZ
859 ;
860 IMPOB1: SETZM IMPOS             ;Reset state
861         JRST IMORET             ;Go look for something else to do.
862
863 ;Was sending IP datagram, from IMPOBZ
864 ;
865 IMPOB2: SETZB A,IMPOS           ;Reset output state.
866         EXCH A,IMPODP           ;Get active datagram and reset pointer
867         PUSHJ P,IPIODN          ;Tell IP level that datagram was output
868         JRST IMORET             ;Go see if there is anything else to do.
869
870 ;Start output hardware.
871 ; A/ Count of PDP10 words to write to net.
872 ; Data to output in IMPOBF.
873 ; Must be NETOFF or at NETCHN interrupt level. Bashes A only.
874
875 IMPSOH: ASH A,1                 ;Convert PDP10 word count to...
876         MOVNS A                 ; negative unibus word count.
877         IOWRI A,%LHOWC          ;Tell the interface
878         MOVEI A,<IUIMPG_12.>+<4*<IMPOBF&777>>
879         IOWRI A,%LHOCA          ;Unibus address of output buffer
880         MOVEI A,%LHIE\%LHELB\%LHGO ;Enable interrupts, send EOM, GO
881         IOWRI A,%LHOCS          ;Start DMA transfer
882         POPJ P,                 ;And forget it.
883 \f
884 SUBTTL  ARPANET CLOCK LEVEL
885
886 IMRSTO: RET                     ;Nothing to do any more?
887 \f
888 OVHMTR UUO
889
890 ;NETHST (HOST INFO)
891 ; ARG 1 - HOST => VAL 1 - STATUS, VAL 2 - HOST NUMBER
892 ; ARG 1 - -1 => VAL 1 - (STATUS), VAL 2 - OUR HOST NUMBER
893 ;NOT CURRENTLY IMPLEMENTED- ARG 1 - -1, ARG 2 - OUR GOING-DOWN REASON
894 ;
895 ANETHST:HRRE T,A                ;Let immediate -1 win (777777 not a valid host)
896         AOJE T,ANETH2           ;Jump if want local status and host number
897         MOVE T,A
898         JSP J,STDHST            ;Standardize and error-check host number
899         MOVE B,T                ;Return new format
900         TLO B,(NW%ARP)
901         MOVEI H,LIMPHT-1
902         CONO PI,NETOFF          ;Do we have status for this host?
903         CAME T,IMPHTN(H)        ;Scan table
904          SOJGE H,.-1
905         JUMPGE H,ANETH1         ;Yes, return it
906         CONO PI,NETON           ;No, have to go get it
907         MOVEM T,SRN3(U)
908         POPJ P,                 ;Oh, too bad
909
910 ;Here to return status of foreign ARPAnet host
911 ANETH1: MOVE A,IMPHTB(H)        ;Get status
912         CONO PI,NETON
913         EXCH A,B
914         CALL CVH2NA             ;Convert to HOSTS2 for compat
915         EXCH A,B
916         JRST LSWCJ1             ;Return IMSOC, NETLST if not done already
917
918 ;Here to return our status, host
919 ANETH2:
920 REPEAT 0,[
921         CAIL W,2                ;(This is a crock)
922          MOVEM B,NTHDSW         ;If 2 args, set our reason for going down.
923 ]
924         SKIPE IMPUP             ;Fake up our status
925          TDZA A,A               ;We're down
926           MOVSI A,2000          ;We are up
927         MOVEI B,IMPUS           ;And our host umber
928         JRST POPJ1
929
930
931 ;NETIMP (REASON,TIMEDOWN,TIMEUP)  READ/SET
932 ;
933 ANETIM: JUMPLE W,ANETM1         ;No args, return current data
934         CAIGE W,3               ;Must have 3 args if any
935          JRST OPNL30
936         MOVEM A,IMPDWN          ;Set data
937         MOVEM B,IMPDWN+1
938         MOVEM C,IMPDWN+2
939         JRST POPJ1
940
941 ANETM1: MOVE A,IMPDWN           ;Get data to return
942         MOVE B,IMPDWN+1
943         MOVE C,IMPDWN+2
944         SKIPE IMPUP             ;Note current condition of IMP, too
945          TLO A,400000
946         JRST POPJ1