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