2 ;;; Copyright (c) 1999 Massachusetts Institute of Technology
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 2 of the
7 ;;; License, or (at your option) any later version.
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.
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.
19 IMPVRS==.IFNM2 ; Version of IMP code
21 IFN NCPP,.FATAL IMP Code doesn't support NCP any more!
22 IFE KSIMP,.FATAL Wrong IMP driver file included!
26 ; IMP 1822 PROTOCOL INFORMATION (EXTENDED-LEADER VERSION)
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
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
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.
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.
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.
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)
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
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
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)
65 ; 3.2-1.5 Message length
66 ;------------------------------------------------------------------------
67 ;4: 4.9-1.5 First word of IP datagram
69 ;------------------------------------------------------------------------
71 ;In message types 2 and 6, the going-down status 16-bit word is
72 ;in word 3 bits 4.9-3.3.
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.
77 IMPLDS==3 ;IMP local leader size
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
91 SUBTTL ARPANET VARIABLES AND TABLES
95 %IMXLN==:<<8159.-96.>+31.>/32. ; Max # of 32-bit words in IMP regular msg,
96 ; exclusive of leader and leader padding. = 252.
98 ; ACTIVE HOST TABLE. Entries herein are allocated as needed, using garbage
99 ; collection. Most "host number" fields are really indices into this table.
101 LIMPHT==<XBL+10.> ; TCP conns plus a few extra
103 IMPHTF: -1 ;Host table free list, threaded through IMPHTB, end with -1
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:
111 ;4.2-4.1 STATUS OF HOST 0 DOWN, 1 RST SENT, 2 UP
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
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)
131 IMERCN: -1 ;CONI into here when net goes down
137 ;Input side variables
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
147 ;Output side variables
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
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
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
177 IMNSRF: 0 ;Number of spurious RFNMs on non-IP links
178 IMNBLK: 0 ;Number of times blockage avoided (output held up by ITS)
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
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
193 ;(Re)Start IMP. Called from SYSJOB to start IMP, or on error or
194 ; user requested cycle through LOCK
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
204 IOWRI A,%LHOCS ;Reset output side
205 IOWRI A,%LHICS ;Reset Input side
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
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
222 ;Wait one sec for IMP to notice rdy line drop
228 MOVNI A,30. ;Allow 15 seconds to come up
230 MOVE T,TIME ;Note when we last started IMP
232 PUSHJ P,IMPHRS ;Set host ready
233 PUSHJ P,IMPIST ;Start input
236 ADDI T,15. ;Wait 1/2 sec before we try to output
240 MOVEM A,IMNOPC ;Send 4 NOPs to start
241 ;Falls through to start output
246 IMPIOS: CONO PI,PIOFF ;Freeze.
247 AOSE IMPOAC ;Do nothing if output already active.
249 SETOM IMPBZY ;Note we want an IMP interrupt
250 CONO PI,NETRQ ;Force nonvectored IMP interrupt
253 ;Check if IMP ready line is set
254 ; Called from SYSJOB.
255 ; Return +1 if IMP not ready, +2 if so
257 IMPCKR: IORDI A,%LHICS ;Get input CSR
258 TRNN A,%LHINR ;Skip if IMP not ready
259 AOS (P) ;Return +2 if ready
262 ;Set HOST READY. From SYS job only, please, loops waiting.
264 IMPHRS: IORDI T,%LHICS
265 TRNN T,%LHRDY ;Can we mung?
267 IORI T,%LHHRC\%LHSE ;Turn on HR. SE prevents dropping messages
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
273 SOJG A,IMPHR1 ;Timed out yet?
274 BUG CHECK,[IMP: Timed out setting Host Ready]
277 SUBTTL HOST-TABLE MANAGEMENT
279 ;IMPHTI - Initialize host table
280 ; Performed whenever IMP announces that it has been reset
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]
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)
293 ; H/ host-table index
296 FNDHST: MOVEI H,LIMPHT-1 ;Search for an entry for this host
299 JUMPGE H,POPJ1 ;Found
300 SKIPGE H,IMPHTF ;Not found, cons one off free list
301 JRST FNDHS1 ;Oops, must garbage collect
303 CAIGE H,LIMPHT ;Make sure H is valid idx
304 CAIL W,LIMPHT ;ditto W
305 BUG HALT,[NET: FNDHST idx clobbered!!!]
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.
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)
318 ; GC mark phase - mark entries in use
320 MOVSI W,200000 ;Mark bit
321 MOVEI H,LIMPHT-1 ;Clear all mark bits
324 SKIPL H,IMPCSH ;Mark from IMPCSH
328 SKIPL H,XBNADR(I) ; See if TCP conn has a net addr specified
329 IORM W,IMPHTB(H) ; Yes, set the mark bit.
333 ; GC sweep phase - free all unmarked entries
334 SETO I, ;Free pointer
336 MOVSI W,601000 ;Protect if RFNM-WAIT, RST-WAIT, or marked
338 SKIPG IMPHTC(H) ;Also protect if any outstanding RFNMs
342 SETZM IMPHTN(H) ;Don't belong to any host
343 MOVEM I,IMPHTB(H) ;Cons onto free list
346 FNDHS5: MOVEM I,IMPHTF ;Free list
350 JRST FNDHST ;Try again, should win
352 ;See if IMP code is willing to handle a particular datagram right now.
354 ; C/ Immediate destination address
355 ; Returns +1, can't send right now, +2, OK to send
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.
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.
386 %IMPMA==:8. ; # of maximum active IMP messages allowed
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!)
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.
401 JRST 1(T)] ;And allow this one to be sent
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.
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.
412 JRST (T) ;Block one last time, next try will win.
414 ;Decrement block count on receipt of any kind of ACK
416 IMPBLD: SOSL Q,IMPHTC(H)
418 BUG INFO,[IMP: negative RFNM-wait cnt, Hst=],OCT,IMPHTN(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.
425 SUBTTL ARPANET INPUT INTERRUPT LEVEL
427 ;First level interrupt handling for input side. Here from UBA vector hardware.
429 IFN NETCHN-UTCCHN,.ERR NETCHN assumed == UTCCHN at IMPIBK
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
455 MOVEM A,IMPIBP ;Set pointer to available data words
456 JRST IMPLDD ;Go process input message
458 ;Here when finished processing current message.
459 IMPIRT: SETOM IMPCSH ;Note no current host
460 PUSHJ P,IMPIST ;Restart input listener
463 ;Message didn't fit in input buffer. Shouldn't ever get here, but
464 ;might if messages concatenated due to ready line randomness
466 IMPIB1: BUG INFO,[IMP: Huge message]
467 SETOM IMIFLS ;Say we are flushing output
468 JRST IMPIRT ;And go queue up another read
470 ;Here if error during IMP message transfer
471 ; Currently the only error handled is the IMP going non-ready
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
479 CAIG T,10. ;Huge number of errors while down?
480 JRST IMPIRT ;No, just ignore this input and start another
482 BUG INFO,[IMP: Excessive input errors while down]
483 JRST IMPRST ;Cycle the interface
485 IMPRST: IORDI T,%LHICS ;Record IMP status for sysjob
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
494 MOVEM T,IMPTCU ;But trying to come up (sysjob poked)
495 MOVSI J,SCLNET ;Ask SYSJOB to cycle the IMP
499 SUBTTL IMP leader dispatch handling
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
508 ADDM B,IMPIBP ;Increment buffer pointer,
510 ADDM C,IMPIBC ; and decrement count
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
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)
521 LDB T,IMSHBP ;Source host
522 LDB A,IMSIBP ;Source imp
523 DPB A,[112000,,T] ;Form host address
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
530 JRST IMPUN ;Unknown type?
531 AOS IMPMSR(A) ;Count IMP msgs rcvd
532 JRST @IMTDT(A) ;Dispatch
534 IMTDT: IMPRM ; 0 Regular Message
535 IMPBE1 ; 1 Error in Leader (no msg-id)
536 IMPGD ; 2 IMP Going Down
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
547 IMPLHE: BUG INFO,[IMP: Message discarded due to host table full],OCT,IMPILB,OCT,IMPILB+1,OCT,IMPILB+2
550 ;Here if leader is too short or of wrong format.
552 IMPLDE: SKIPE IMPUP ;If IMP is not up, we'll take anything.
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
566 JRST IMPIRT ;Ignore rest of message, if any
568 ;;; IMP->Host Type X (e.g. 3, 11-255) - bad type
570 IMPUN: BUG INFO,[IMP: Unknown msg type ],OCT,A,[ leader ],OCT,IMPILB,OCT,IMPILB+1,OCT,IMPILB+2
573 ;;; IMP->Host Type 1 - Error in leader (msg-id not given)
574 ;;; IMP->Host Type 8 - Error in data (msg-id given)
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
588 ;;; IMP->Host Type 2 - IMP going down
590 IMPGD: LDB B,[420200,,IMPILB+2] ;Reason (see 1822)
592 LDB B,[360400,,IMPILB+2] ;How soon going down * 5 mins
594 IMULI B,5*60.*30. ;Ticks in 5 mins
597 LDB C,[241200,,IMPILB+2] ;How long to be down * 5 minutes
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
604 BUG INFO,[IMP: Going down in ],DEC,H,[mins for ],DEC,Q,[mins, reason],DEC,IMPDWN
607 ;;; IMP->Host Type 4 - NOP
609 IMPIN: JRST IMPIRT ;One more NOP from IMP
611 ;;; IMP->Host Type 5 - RFNM (Ready For Next Message)
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.
620 IMRFNX: BUG INFO,[IMP: Spurious RFNM from ],OCT,IMPHTN(H),[link],OCT,IMPCLN
624 ;;; IMP->Host Type 6 - Host Down Status
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
631 ;;; IMP->Host Type 7 - Destination Host Dead
633 IMPDHD: MOVEI E,%NCDED
636 ;;; IMP->Host Type 9 - Incomplete Transmission
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
642 IMPHNR: JSP T,IMPBLD ;Decrement active IMP msg count for this host
643 MOVE A,IMPCLN ;Link for this message?
646 CAIN E,%NCINC ;Yes, count IP meters
652 IMPHN1: BUG INFO,[IMP: DHD or IT msg rcvd on non-IP link]
655 ;;; IMP->Host Type 10 - Interface Reset
657 IMPIRS: PUSHJ P,IMPHTI ;Initialize host table
658 BUG INFO,[IMP: Interface reset]
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.
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?
670 JRST IMPIRT ;No, ignore it
672 ;IP datagram. Copy into IP buffer and pass it up.
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
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
689 ;Start listening for new input from IMP
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
700 SUBTTL ARPANET OUTPUT INTERRUPT LEVEL
702 ;Here on unvectored interrupt caused by call to IMPIOS
704 IMPINT: AOS IMCT1 ;Count unvectored interrupts
705 JRST IMPOBZ ;Go try to start output
706 ;Returns directly to interrupt dispatcher
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.
713 IFN NETCHN-UTCCHN,.ERR NETCHN assumed == UTCCHN at IMPOBK
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?
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.
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.
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
743 ;Here if interface wasn't fully up.
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.
751 ;IMPOBZ - Toplevel output processing routing.
752 ; Called from output done interrupt handler or from MP/CLOCK level with
753 ; NETOFF to start output.
755 IMPOBZ: SKIPL B,IMPOS
757 BUG HALT,[IMP: Bad output state]
761 %ISODL:: IMPOB0 ; 0 Idle, look for something to send
762 %ISONP:: IMPOB1 ; 1 Finished NOP
763 %ISOID:: IMPOB2 ; 2 Finished IP datagram messge
766 ;Here when interrupt has finished processing a complete message.
767 ; Attempt to find something else to do.
770 ;JRST IMPOB0 ;Fall through to try for more
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
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
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
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.
792 ; Returns A/ ptr to IP dgm struct
793 ; B/ BLKO pointer to 32-bit words (unused)
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.
801 MOVEM A,IMPODP ;Save ptr to datagram being output
802 AOS IMNIPO ;# of IP datagrams sent
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
808 MOVSI B,233_10. ;IP link # in left 8 bits
809 MOVEM B,IMOLDR+2 ;Set up third word
811 LSH C,4. ;Move net address to correct field
812 MOVEM C,IMOLAD ;set up second word of leader
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.
821 PUSHJ P,IMPSOH ;Go start hardware
822 MOVEI C,%ISOID ;Remember we are outputting IP leader
828 ;Here if nothing to output.
829 ; Flag output inactive and disable interface
831 IMPOBN: SETOM IMPOAC ;No more output
833 TRZ TT,%LHIE\%LHGO ;Deactivate interface for a bit
837 ;IMONOP - Send a NOP, here from IMPOBZ only.
839 IMONOP: MOVEI A,IMPNOS ;Length of NOP message
840 MOVE B,[IMPNOP,,IMPOBF] ;BLT (and reformat) NOP to output buffer
842 PUSHJ P,IMPSOH ;Start output of (A) words from IMPOBF to IMP
843 MOVEI C,%ISONP ;Set correct output FSM state
847 ;Prefabricated NOP Host-IMP leader
848 IMPNOP: 17_10.,,4_4 ;New format, type 4 = NOP
850 0 ;No padding required on regular messages
853 ;Finished sending NOP, from IMPOBZ
855 IMPOB1: SETZM IMPOS ;Reset state
856 JRST IMORET ;Go look for something else to do.
858 ;Was sending IP datagram, from IMPOBZ
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.
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.
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.
879 SUBTTL ARPANET CLOCK LEVEL
881 OVHMTR IMP ;NETWORK INTERRUPT LEVEL (NOT STYNET STUFF)
883 IMRSTO: RET ;Nothing to do any more?
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
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
893 JSP J,STDHST ;Standardize and error-check host number
894 MOVE B,T ;Return new format
897 CONO PI,NETOFF ;Do we have status for this host?
898 CAME T,IMPHTN(H) ;Scan table
900 JUMPGE H,ANETH1 ;Yes, return it
901 CONO PI,NETON ;No, have to go get it
905 ;Here to return status of foreign ARPAnet host
906 ANETH1: MOVE A,IMPHTB(H) ;Get status
909 CALL CVH2NA ;Convert to HOSTS2 for compat
911 JRST LSWCJ1 ;Return IMSOC, NETLST if not done already
913 ;Here to return our status, host
916 CAIL W,2 ;(This is a crock)
917 MOVEM B,NTHDSW ;If 2 args, set our reason for going down.
919 SKIPE IMPUP ;Fake up our status
921 MOVSI A,2000 ;We are up
922 MOVEI B,IMPUS ;And our host umber
926 ;NETIMP (REASON,TIMEDOWN,TIMEUP) READ/SET
928 ANETIM: JUMPLE W,ANETM1 ;No args, return current data
929 CAIGE W,3 ;Must have 3 args if any
931 MOVEM A,IMPDWN ;Set data
936 ANETM1: MOVE A,IMPDWN ;Get data to return
939 SKIPE IMPUP ;Note current condition of IMP, too