1
0
mirror of https://github.com/PDP-10/its.git synced 2026-01-11 23:53:12 +00:00
PDP-10.its/src/system/impold.ncp3
2026-01-07 15:06:26 +01:00

1995 lines
64 KiB
Plaintext
Executable File
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

;;; -*- Mode:MIDAS -*-
;;; Copyright (c) 1999 Massachusetts Institute of Technology
;;; See the COPYING file at the top-level directory of this project.
SUBTTL ARPANET HARDWARE DEFINITIONS
IFNDEF BLIMPP,BLIMPP==INETP ; Use IMP blockage avoidance code
IMPVRS==.IFNM2 ; Version of IMP/NCP code
IFN KAIMP,[
; Hardware description of AI-KA/ML/MC IMP interface, device "IMP".
; For a more detailed description, see AI Hardware Memo #10,
; "ARPA Network Interface".
; In particular, the "channel 1 multiplexing" feature of the ITS KA's
; is used, so that:
; When PI level 2 (NETCHN) is assigned, the IMP interface takes
; all interrupts on the normal channel (goes to IMPINT).
; When PI level 1 (IMPCHN) is assigned,
; IMPID+(-IMPLIW) => Pseudo channel 4, location 70 (IMPILC)-> various
; IMPOD => Pseudo channel 5, location 72 (IMPOLC)-> various
; else normal PI channel 1 (PI0LOC+2)-> IMPBRK
; CONI bits - starred items cause interrupt on PIA channel
; 1.1-1.3 => PIA
IMPID==10 ;* INPUT DONE - Turned on when interface has word for DATAI
IMPI32==20 ; Input in 32 bit mode
;IMPIB==40 ; Input Busy
IMPOD==100 ;* OUTPUT DONE - Interface has finished giving word to IMP
;IMPO32==200 ; Output in 32 bit mode
;IMPOB==400 ; Output Busy
IMPERR==1000 ;* Imp Error (interrupt if IMPIC zero)
IMPR==2000 ;* Imp Ready (interrupt if IMPIC set)
;IMPIC==4000 ; Imp interrupt condition (0 = int on IMPERR, 1= int on IMPR)
IMPHER==10000 ;* Host Error (interrupt if IMPIHE zero)
;IMPHR==20000 ; Host Ready
;IMPIHE==40000 ; Inhibit interrupt on Host Error (IMPHER)
IMPLW==100000 ;* Last Imp Word
; CONO bits - starred flags are always copied directly to set states
;* 1.1-1.3 => PIA set from these bits
IMPIDC==10 ; Clear Input Done
IMI32S==20 ; Set input to 32 bit mode
IMI32C==40 ; Clear input in 32 bit mode
IMPODC==100 ; Clear Output Done
IMO32S==200 ; Set output to 32 bit mode
IMO32C==400 ; Clear output in 32 bit mode
IMPODS==1000 ; Set Output Done
IMPIR==4000 ;* Copied to IMPIC; 1= Enable int on imp ready
IMPHEC==10000 ; Clear Host Error
;IMIIHE==40000 ;* Copied to IMPIHE; 1= Inhibit int on host error
IMPLHW==200000 ; Set Last Host Word (do this before last DATAO of msg)
];KAIMP
IFN DMIMP,[ ;HARDWARE DESCRIPTION OF DM IMP INTERFACE (PER RMM)
; Note that all PI level 2 interrupts go to normal ITS location
; and thence vectored to IMPINT.
; However, PI 1 interrupts go to different places:
; Input Done -> loc 70 (IMPILC)
; Output Done -> loc 72 (IMPOLC)
; Control -> Should never get control interrupt at PI 1.
; Thus for example "Last Imp Word" interrupts go to
; IMPINT even though input side PIA is 1, because LIW is
; a control interrupt and control ints are always kept at PI 2.
;IMP INTERFACE CONO FLAG DESCRIPTION
;COMMON FLAG BITS TO CONTROLLER
;18-> 0 FOR INPUT SIDE, 1 FOR OUTPUT SIDE
;19->CLEAR TEST MODE (200000)
;20->SET TEST MODE (100000)
;21->CLEAR HOST READY
;22->SET HOST READY (20000)
;23->CLEAR IMP-WAS-DOWN (10000)
;24->FI DEVICE RESET (CLEAR ALL INPUT AND OUTPUT FLAGS) (4000)
;CONO FI (424) TO OUTPUT SIDE
;BIT ;18->IS '1' INDICATING TO OUTPUT
;25->CLEAR OUTPUT 32-BIT MODE
;26->SET OUTPUT 32-BIT MODE
;27->SET OUTPUT EOT (CLEAR DONE, SET BUSY) (400)
;28->SET OUTPUT DONE (200)
;29->RESET OUTPUT (CLEAR ALL OUTPUT FLAGS) (100)
;30-32->CONTROL PI ASSIGNMENT
;33-35->OUTPUT DONE PI ASSIGNMENT
;CONO FI (424) TO INPUT SIDE
;BIT ;18->IS '0' INDICATING TO INPUT
;25->CLEAR 32-BIT MODE (2000)
;26->SET 32-BIT MODE (1000)
;27->SUSPEND INPUT (400) DATAI WONT SET BUSY NOW
;28->SET INPUT BUSY (LISTENING TO NETWORK) (200)
;29->RESET INPUT (CLEAR ALL INPUT FLAGS!) (100)
;30-32->CONTROL PI ASSIGNMENT
;33-35->INPUT DONE PI ASSIGNMENT
;FI CONI FLAG DESCRIPTION
;BIT ;00->TEST MODE IS ENABLED
;08->OUTPUT IS IN 32-BIT MODE
;17->INPUT IS IN 32-BIT MODE
;18->IMP IS DOWN
;19->IMP WAS DOWN
;20->HOST READY (?)
;21->OUTPUT EOT ON
;22->OUTPUT BUSY
;23->OUTPUT DONE
;24-26->OUTPUT-DONE PI ASSIGNMENT
;27->INPUT EOT ON
;28->INPUT BUSY
;29->INPUT DONE
;30-32->CONTROL INTERRUPT PI ASSIGNMENT
;33-35->INPUT DONE PI ASSIGNMENT
; SYMBOL ASSIGNMENTS FOR DM HARDWARE
; CONO BITS
FIIN==000000 ;(SIC) SPECIFY CONO FOR INPUT
FIOUT==400000 ;SPECIFY CONO FOR OUTPUT SIDE
;FITSTC==200000 ;CLEAR TEST MODE
;FITSTS==100000 ;SET TEST MODE
;FIHSTC==040000 ;CLEAR HOST READY
FIHSTS==020000 ;SET HOST READY
FIIWDC==010000 ;CLEAR "IMP WAS DOWN"
FIRSET==004000 ;DO LOCAL IOB RESET FOR FI DEVICE
;INPUT SIDE ONLY
FII32C==002000 ;CLEAR 32 BIT MODE, INPUT
FII32S==001000 ;SET 32 BIT MODE, INPUT
FISUSP==000400 ;"SUSPEND INPUT" CLEAR FLAG, NOT SET BUSY
FIIBSY==000200 ;SET INPUT BUSY, ALLOWS BITS IN FROM IMP
FIIDC==000100 ;CLEAR INPUT DONE
; 0000X0 ;CONTROL PIA
; 00000X ;INPUT DONE PIA
;OUTPUT SIDE ONLY
FIO32C==402000 ;CLEAR 32 BIT MODE, OUTPUT
FIO32S==401000 ;SET 32 BIT MODE, OUTPUT
FILHW==400400 ;SET "LAST HOST BIT TO IMP"
FIODS==400200 ;SET OUTPUT DONE
FIODC==400100 ;CLR OUTPUT DONE
; 0000X0 ;CONTROL PIA
; 40000X ;OUTPUT DONE PIA
; CONI BITS
; LEFT HALF OF CONI WORD FOR FOLLOWING 3 BITS
;FITSTM==400000 ;TEST MODE IS ON
;FIO32==001000 ;OUTPUT IS IN 32 BIT MODE
FII32==000001 ;INPUT IS IN 32 BIT MODE
; RIGHT HALF OF CONI
FIDOWN==400000 ;IMP IS DOWN
FIWASD==200000 ;IMP WAS DOWN (OR IS) SINCE LAST RESET
;FIHSTR==100000 ;HOST READY IS SET ON
;FIOEOT==040000 ;OUTPUT LAST IMP BIT IS ON
;FIOBSY==020000 ;OUTPUT IS BUSY AFTER DATAO
FIOD==010000 ;OUTPUT IS DONE, (INTERRUPTING)
; 00X000 ;OUTPUT DONE PIA
FILW==000400 ;LAST BIT SET FROM IMP
FIIBSY==000200 ;INPUT IS BUSY, WORD BEING ASSEMBLED FROM IMP
FIID==000100 ;INPUT IS DONE (INTERRUPTING) TO DO DATAI
; 0000X0 ;CONTROL PIA
; 00000X ;INPUT PIA
IMPLW==FILW ;USEFUL TO TEST IN AC
IMP==FI ;USEFUL FOR BLKO, DATAO INSTR
];DMIMP
; IMP 1822 PROTOCOL INFORMATION (EXTENDED-LEADER VERSION)
; The IMP leader is 96 bits long, usually organized as 3 words of 32 bits.
; For further details, these documents are available from the Network
; Information Center:
; IMP-HOST protocol: BBN Report No. 1822
; NCP protocol: NIC 8246, Host-to-Host Protocol for the ARPANET
; IP, TCP: Internet Protocol Transition Workbook, and
; Internet Protocol Implementor's Guide
;
; For the benefit of the NCP code, ITS reads in the leader as 36-bit words
; with sufficient IMP padding (5 16-bit wds) to cause NCP data to be aligned
; on a word boundary. The first 4 words of the leader are read
; in 36-bit mode:
;------------------------------------------------------------------------
;1: 4.9-4.6 not used (0)
; 4.5-4.2 all 1's for new format, else old msg type (4=old nop)
; 4.1-3.3 network number (0)
; 3.2-2.8 not used (0)
; 2.7 trace (ignored)
; 2.6-2.4 leader flags (2.6 is to be ignored, 2.5-2.4 are not used!)
; 2.3-1.5 message type (as of yore, but more bits) (see IMTDT)
; 1.4-1.1 high 4 bits of handling type (0)
;
;2: 4.9-4.6 Low bits of handling type (7 for big buffers, 4 for small buffers,
; 4.5-3.7 host number and 0 for the control link)
; 3.6-1.9 Imp number
; 1.8-1.1 Link number (high 8 bits of message-id)
;
;3: 4.9-4.6 Low 4 bits of message-id (0)
; 4.5-4.2 Sub-type
; 4.1-2.4 Message length (ignored)
; 2.3-1.1 Padding
;------------------------------------------------------------------------
; All non-regular messages (ie Host-Imp, not Host-Host)
; stop here, since padding and data only exist for regular
; messages (Type 0).
;------------------------------------------------------------------------
;4: 4.9-1.1 Padding
;------------------------------------------------------------------------
; At this point there are still 32 bits of padding left. The
; Internet Protocol messages are vectored off here (they are
; identified by a message-type of 0 and a link-number of 233).
;------------------------------------------------------------------------
; HOST-HOST REGULAR MESSAGES
; NETWORK CONTROL PROTOCOL (NCP) - read in 36-bit mode
;5: 4.9-1.5 Padding
; 1.4-1.1 M1 Host-host padding
;
;6: 4.9-4.6 M1 Host-host padding ; NCP leader contained in this word.
; 4.5-3.7 S Byte size
; 3.6-1.9 C Byte count
; 1.8-1.1 M2 Host-host padding
;------------------------------------------------------------------------
; HOST-HOST REGULAR MESSAGES
; INTERNET PROTOCOL (IP) - read in 32-bit mode
;5: 4.9-1.5 Padding
;6: 4.9-1.5 First word of IP datagram
;------------------------------------------------------------------------
;In message types 2 and 6, the going-down status 16-bit word is
;in word 2 1.8-1.1 and word 3 4.9-4.2.
;4.5-4.2 of word 3 are the padding count for type 4 (nop) from host.
;This is 5. Padding is only put on type-0 messages.
IMTBP: 041000,,IMPILB+0 ;BYTE POINTER FOR MESSAGE TYPE FIELD
IMOTBP: 340400,,IMPILB+0 ; Byte ptr for message format type
IMLNBP: 001000,,IMPILB+1 ;BYTE POINTER FOR LINK NUMBER FIELD
IMSABP: 103000,,IMPILB+1 ; Byte ptr for source address field (host+imp)
IMSHBP: 301000,,IMPILB+1 ;BYTE POINTER FOR SOURCE HOST FIELD
IMSIBP: 102000,,IMPILB+1 ;BYTE POINTER FOR SOURCE IMP FIELD
IMSTBP: 340400,,IMPILB+2 ; Byte ptr for subtype field
IMCBBP: 301000,,IMPILB+5 ;BYTE POINTER FOR CONNECTION BYTE SIZE FIELD
IMBCBP: 102000,,IMPILB+5 ;BYTE POINTER FOR BYTE COUNT FIELD
SUBTTL ARPANET VARIABLES AND TABLES
IFN NCPP,[
IMPSTL==NNETCH ;SOCKET TABLE LENGTH (MUST BE .LE. 70)
IFG NNETCH-70,.ERR NNETCH SHOULD BE LESS THAN 70 OCTAL, PER BBN SPECS
];NCPP
IFN INETP,[
IMPCLP: 0 ; HACK!! # to use for control-link link field.
]
EBLK
IMPN:: ;IMP DATA AREA CLEARED WHEN IMPUP
IFN INETP,[
%IMXLN==:<<8159.-96.>+31.>/32. ; Max # of 32-bit words in IMP regular msg,
; exclusive of leader and leader padding. = 252.
IMPIBS: 0 ; Saved initial BLKI pointer for IP datagram read
IMPIDP: 0 ; Pointer to IP datagram being input at PI level
IMPODP: 0 ; Pointer to IP datagram being output at PI level
IMPPSW: 0 ; Flip-flop to alternate output of IP and NCP msgs
]
IFN KAIMP,[
IMPI: 0 ;-1 => IMPCHN INPUT INTERRUPT OCCURRED
IMPO: 0 ;-1 => IMPCHN OUTPUT INTERRUPT OCCURRED
IMPB: 0 ;-1 => IMPCHN FLAG INTERRUPT OCCURRED
IMPIH: 0 ;-1 => INPUT WANTS PIA = IMPCHN
IMPOH: 0 ;-1 => OUTPUT WANTS PIA = IMPCHN
]
IMPIS: 0 ;INPUT STATE
%ISIDN==:-1 ; Network shut off
%ISIDL==:0 ; Normal - idle, not expecting input (i.e. between msgs)
%ISIGN==:1 ; Ignore input until end of current message (36 bit mode)
%ISIML==:2 ; Reading IMP initial leader (36 bit mode)
%ISINC==:3 ; Reading NCP control message (32 bit mode)
%ISIND==:4 ; Reading NCP data message (32 or 36 bit mode)
%ISINL==:5 ; Reading NCP-type IMP leader (36 bit mode)
%ISIIL==:6 ; Reading IP-type IMP leader (32 bit mode)
%ISIID==:7 ; Reading IP datagram (32 bit mode)
IMPOS: 0 ;OUTPUT STATE
%ISODL==:0 ; Not expecting output done (i.e. between messages)
%ISONC==:1 ; Sending NCP control message
%ISOND==:2 ; Sending NCP data message
%ISOID==:3 ; Sending IP Datagram
IMPHI: 0 ;-1 TO HOLD UP INPUT
;-2 INPUT IS SUCCESSFULLY HELD UP
IMRFCT: 0 ;NUMBER OF HOST TABLE ENTRIES WITH PENDING
;TIMEOUTS FOR CONTROL-LINK RFNM OR RST-RRP.
; ACTIVE HOST TABLE. Entries herein are allocated as needed, using garbage
; collection. Most "host number" fields are really indices into
; this table.
LIMPHT==<NNETCH/2+3>+<XBL+5> ; NCP conns plus TCP conns plus a few extra
IMPHTN: BLOCK LIMPHT ; Host number. 1.1-1.8 HOST, 2.1-3.7 IMP
IMPHTB: BLOCK LIMPHT ;BITS:
;4.9 1=RFNM WAIT ON LINK 0 (NCP)
;4.8 GC MARK BIT
;4.7-4.3 UNUSED
;4.2-4.1 STATUS OF HOST 0 DOWN, 1 RST SENT, 2 UP
;3.9-3.1 TIME (MOD 2**9) LAST RFNM SENT ON LINK 0 (NCP)
.SEE IMPHDS ;RH LAST MESSAGE FROM IMP ABOUT "HOST DEAD STATUS"
IMPHTC: BLOCK LIMPHT ; # active messages outstanding for host (8 max)
IMPHTT: BLOCK LIMPHT ; Time of last RFNM received
IMNCS: 0 ;NUMBER OF CHANNELS BEING CLOSED
IMNAS: 0 ;NUMBER OF CHANNELS WITH 4.8 IN IMSOC5 SET
LIMPN==.-1 ;LAST LOCATION BLT'ED TO ZERO WHEN INITIALIZED
IMNBLK: 0 ; Number of times blockage avoided (output held up by ITS)
IMPHTF: -1 ;HOST TABLE FREE LIST, THREADED THROUGH IMPHTB, END WITH -1
IMPUP: -1 ;0 => IMP UP ;-1 => DOWN ;-2 => COMING UP, PI LVL STILL OFF
;1 => DOWN FOR GOOD, UNTIL NEXT TIME IMP READY LINE CHANGES
IMPTCU: 0 ;0 IMP UP/DOWN STATUS NOT CHANGING
;>0 TRYING TO REINITIALIZE, SYS JOB HASN'T DONE SO YET
;-1 HAS BEEN REINITIALIZED, HAVEN'T EXCHANGED NOPS YET
IMPUCT: 0 ;IMP COMING UP TIMEOUT, IF 4 NOOPS DON'T GO THROUGH PROMPTLY.
IMPDWN: BLOCK 3 ;LAST MESSAGE FROM IMP THAT IT IS GOING DOWN
;WD0 "REASON" CLAIMED BY IMP (SEE CH 3 OF BBN REPORT 1822)
;WD1 TIME WHEN EXPECTED DOWN
;WD2 TIME WHEN EXPECTED UP (SYS TIME=1/30 SEC SINCE UP)
IFN KAIMP,IMPPIA: 0 ;CURRENT IMP PIA
IMPCNI: 0 ;CONI INTO HERE AT SLOW CLOCK LEVEL
IMERCN: -1 ;CONI INTO HERE WHEN NET GOES DOWN
IMNOPC: 0 ;< 0 => SEND NOPS
IMPA: 0 ;SAVE A AT IMPCHN PI LEVEL
IMPOAC: -1 ;-1 => OUTPUT INACTIVE
IMPERB: BLOCK 5 ;LAST "ERR" MESSAGE FROM A HOST
;WD 0 TIME WHEN RCVD, WD 1 HOST, WD2-4 11. 9-BIT BYTES OF DATA
IFN DMIMP,IMPSUS: 0 ;HOLDS INPUT WORD WHILE INPUT IS HELD UP
IMPILB: BLOCK 6 ;INPUT LEADER BUFFER
IMPINB: BLOCK 30.+5 ;30. WORDS @ 32 BITS/WD = 120. 8 BIT BYTES
;+5 WORDS FOR GOOD MEASURE
;THIS BUFFER IS FOR CONTROL-LINK MESSAGES
BBLK
IMHSBT: 330200,,IMPHTB(H) ;RST/RRP STATUS
EBLK
IMPCSH: -1 ;CURRENT SOURCE HOST (IMPHTB INDEX). -1 WHEN IDLE.
IMPCLN: 0 ;CURRENT LINK NUMBER
IMPCBS: 0 ;CURRENT BYTE SIZE
IMPCBC: 0 ;CURRENT BYTE COUNT
IMPNIW: 0 ;EXPECTED LAST BLKI ADDRESS
IMNWSI: 0 ;SECOND BLKI POINTER, ZERO IF NONE
IMPSVP: 0 ;SAVE PIA AT IMPRMP
IMPSVQ: 0 ;SAVE CONTROL MESSAGE QUEUE POINTER AT IMPOB2
IMBLKI: 0 ;PLACE TO STORE BLKI POINTER
IMBLKO: 0 ;PLACE TO STORE BLKO POINTER
IMPNBI: 0 ;AMOUNT TO INCREMENT IMSMPC(I) BY, I.E. # OF DATA BYTES
; IN MESSAGE CURRENTLY COMING IN AT P.I. LEVEL
IMPNBO: 0 ;AMOUNT TO INCREMENT IMSMPC(I) BY, I.E. # OF DATA BYTES THAT WILL BE
; MADE FREE IN BUFFER BY MESSAGE CURRENTLY GOING OUT AT P.I. LEVEL
IMPNBT: 0 ;# BITS ACTUALLY BEING SENT, USED TO ADJUST ALLOCATION
IMPNPT: 0 ;NEW VALUE FOR IMSPIP(I) AFTER MSG IS SENT
IMPIPI: -1 ;IMSOC INDEX ACTIVE FOR INPUT AT P.I. LEVEL, OR -1 IF NONE
IMPOPI: -1 ;IMSOC INDEX ACTIVE FOR OUTPUT AT P.I. LEVEL, OR -1 IF NONE
IMOB0Z: 0 ;IMSMPP AT IMOBD1, FOR DEBUGGING
;IMP OUTPUT LIST. EXECUTED AT PI LEVEL 1.
;NEGATIVE = BLKO POINTER, 0=STOP, 1=SET LAST WORD, 2=32-BIT MODE, 3=NOP
IMOPNT: 0 ;INDEX OF NEXT "INSTRUCTION" IN IMP OUTPUT LIST:
IMOLST: 0 ;BLKO FOR SECOND THROUGH SIXTH LEADER WORDS (FIRST IS DATAO'ED)
IMOMOD: 2 ;SWITCH TO 32-BIT MODE IF NECESSARY
IMOBK1: 0 ;FIRST BLKO POINTER
IMOBK2: 0 ;SECOND BLKO POINTER
1 ;SET LAST WORD
IMOBK3: 0 ;THIRD BLKO POINTER (SEND LAST WORD, NOT USED WITH DM INTERFACE)
0 ;STOP
IMOLDR: BLOCK 6 ;BUILD PREAMBLE HERE FOR DATA MESSAGES
IMPNEA: 0 ;NUMBER OF ECOS IN COMMAND MESSAGE THAT HAVE BEEN ANSWERED
IMPNRA: 0 ;NUMBER OF RSTS ANSWERED
;METERS
IFN INETP,[
IMNIPI: 0 ; # of IP datagrams input (rcvd)
IMNIPF: 0 ; # of IP datagrams flushed (input threw away)
IMNIPO: 0 ; # of IP datagrams output (sent)
IMNIPR: 0 ; # of IP RFNMs received
IMNIP7: 0 ; # of IP Type 7 (Dest Host Dead) messages received
IMNIP8: 0 ; # of IP Type 8 (Error) msgs rcvd
IMNIP9: 0 ; # of IP Type 9 (Incomplete Transmission) msgs rcvd
IMNWIG: 0 ; # words ignored by "Ignore" state (%ISIGN)
IMNWIF: 0 ; # words flushed by IMPRM5
] ;INETP
IFN NCPP,[
IMNOSH: 0 ;# OF SHUFFLES OF NET OUTPUT BUFFERS
IMNISH: 0 ;# OF SHUFFLES OF NET INPUT BUFFERS
IMNSCM: 0 ;NUMBER OF SHORT CONTROL LINK MESSAGES
IMPNEI: 0 ;NUMBER OF ERPS NOT SENT
IMPNRI: 0 ;NUMBER OF RRPS NOT SENT
IMNRFC: 0 ;NUMBER OF RFCS CLSED
IMNRFI: 0 ;NUMBER OF RFCS IGNORED
IMNCLI: 0 ;NUMBER OF CLS IGNORED
IMNALI: 0 ;NUMBER OF ALLS IGNORED
IMNPIL: 0 ;NUMBER OF TIMES PI CONTROL QUEUE EXCEEDED
IMNCNS: 0 ;NUMBER OF CLS NOT SENT
IMNANS: 0 ;NUMBER OF ALLS NOT SENT
IMNMNC: 0 ;NUMBER OF REGULAR MESSAGES FOR NON-EXISTANT CONNECTIONS
IMNMAE: 0 ;NUMBER OF TIMES MSG ALL EXCEEDED
IMNMSS: 0 ;NUMBER OF TIMES MSG SHORT
IMNBAE: 0 ;NUMBER OF TIMES BIT ALL EXCEEDED
] ;IFN NCPP
IMPNPE: 0 ;NUMBER OF PROTOCOL ERRORS
IMNSRC: 0 ;NUMBER OF SPURIOUS RFNMS ON CONTROL LINK
IMNSRF: 0 ;NUMBER OF SPURIOUS RFNMS ON REG CONNECTIONS
IMNRFN: 0 ;NUMBER OF RFNMS NOT SENT
IMSTAS: 0 ;STATUS OF INPUT AT TIME HELD UP
IMPNIH: 0 ;NUMBER OF TIMES INPUT SUCCESSFULLY HELD UP
IMPNUH: 0 ;NUMBER OF TIMES INPUT HOLDUP UNDONE
IMRFTO==60.*30. ;RFNM WAIT TIME OUT
IFN NCPP,[
IMNORH: 0 ;NUMBER OF STYNET OUTPUT RESETS DELAYED
;IMPRTO==30.*60. ;RESET TIME OUT (IDENTICALLY = IMRFTO)
IMPCTO==30.*30. ;CLS TIME OUT
IMFCTO==55.*30. ;RFC QUEUE TIME OUT - SHOULD BE LESS THAN 2*IMPCTO
IMPCMR: BLOCK 20 ;COUNT OF CONTROL MESSAGES RCD
IMPCMS: BLOCK 20 ;COUNT OF CTL MSG SENT
] ;IFN NCPP
IMPMSR: BLOCK 20 ;COUNT OF IMP MESSAGES RCD
IMPM1S: BLOCK 4 ; # Type 1 (Error in Leader) subtype msgs
IMPM9S: BLOCK 20 ; # Type 9 (Incomplete Transmission) subtype msgs
IMPMSS: BLOCK 1 ;COUNT OF IMP MSG SENT (WE ONLY SEND REGULAR MSGS)
IMCT1: 0 ;# TIMES AT IMPBKZ
IMCT2: 0 ;# TIMES AT IMPIBZ
IMCT3: 0 ;# TIMES AT IMPOBZ
BBLK
SUBTTL ARPANET MAIN-PROGRAM LEVEL
IMPINI:
IFN KAIMP,[
CONO IMP,IMI32C
DATAI IMP,A
CONO IMP,IMPODC ;CLEAR OUTPUT DONE AND PIA
CONSZ IMP,IMPOD+7 ;CHECK OUTPUT DONE, PIA, CAUSE HOST READY
JRST 4,. ;CONO DIDN'T CLEAR SOME BITS?
CONO IMP,IMPIR+IMPHEC ;CLEAR HOST ERR, ENABLE INT ON IMP READY
]
IFN DMIMP,[
CONO FI,FIRSET ;RESET IMP INTERFACE, SET HOST READY
CONO FI,FIHSTS
]
SETOM IMPIPI
SETOM IMPOPI
MOVE T,TIME
ADDI T,15.
CAMLE T,TIME
PUSHJ P,UFLS ;WAIT FOR HALF SECOND
IFN KAIMP,[
CONO IMP,0 ;CLEAR "ENABLE IMP READY" INT (TURNS OFF IMP ERROR)
MOVEI A,NETCHN ;IDLE PIA
MOVEM A,IMPPIA
MOVE A,[JSR IMPIBK]
MOVEM A,IMPILC
MOVE A,[JSR IMPOBK]
MOVEM A,IMPOLC
]
IFN DMIMP,CONO FI,FIIWDC ;CLEAR "IMP WAS DOWN"
IFN NCPP,[
MOVSI I,-IMPSTL
IMPINA: SKIPE IMSOC6(I)
JRST 4,.
SETZM IMSOC1(I)
AOBJN I,IMPINA
] ;IFN NCPP
SETZM IMPILC+1
SETZM IMPOLC+1
SETOM IMPOAC
SETOM IMPUP ;NOT UP YET
MOVNI A,20. ;ALLOW 10 SECONDS TO COME UP
MOVEM A,IMPUCT
SETOM IMPTCU ;TRYING TO COME UP
SETOM IMPHTF ;WILL GC IMPHTB ON FIRST REFERENCE
IFN NCPP,[
SETOM IMPMPU
SETOM IMPMPL
SETOM IMPNCQ
SETOM IMPLCQ
MOVEI I,IMNPIC
MOVEM I,IMFCQL
MOVEI A,IMPCQ
MOVEM A,IMFFCQ
JRST IMPIN1
IMPIN2: ADDI A,IMPMQS+1
MOVEM A,-IMPMQS-1(A)
IMPIN1: SOJG I,IMPIN2
SETOM (A)
SETOM IMPBPQ
SETOM IMPEPQ
MOVEI A,IMPPQ
MOVEM A,IMFFPQ
MOVEI I,IMNPQ
JRST IMPIN4
IMPIN3: ADDI A,4
MOVEM A,-4(A)
IMPIN4: SOJG I,IMPIN3
SETOM (A)
MOVEI A,NETSRS
MOVEM A,NRSOC
];NCPP
MOVE A,[IMPN,,IMPN+1]
SETZM IMPN
BLT A,LIMPN
SETOM IMPIS ; Say IMP shut off
MOVE T,TIME
MOVEM T,LNETIM
IFN KAIMP,CONO IMP,NETCHN
IFN DMIMP,[
CONSZ FI,FIDOWN+FIWASD ;SKIP IF STILL UP
POPJ P, ;LOSE IF NOT IMP UP
CONO FI,FIIN\FIIBSY+NETCHN*11
CONO FI,FIOUT+NETCHN*11
]
SETOM IMPDWN+1 ;TIME FOR IMP TO GO DOWN, NOT KNOWN
;MOVE T,TIME
ADDI T,15.
CAMLE T,TIME
PUSHJ P,UFLS
SETZM IMPIS ; Say up but idle
MOVNI A,4
MOVEM A,IMNOPC ;SEND 4 NOPS
IMPOST: CONO PI,NETOFF
IFN DMIMP,[
CONSO FI,70 ;SKIP IF PIA NON-ZERO
JRST NETONJ ;IF NO PIA, THEN DONT SET INT
]
IFN KAIMP,MOVE TT,IMPPIA ;MAIN PROGRAM OUTPUT START
AOSN IMPOAC ;SKIP IF OUTPUT ALREADY ACTIVE
IFN KAIMP, CONO IMP,IMPODS(TT) ;GENERATE OUTPUT INTERRUPT
IFN DMIMP, CONO FI,FIODS+NETCHN*11
JRST NETONJ
IMPIOS:
IFN KAIMP,[
AOSE IMPOAC ;PI LEVEL OUTPUT START
POPJ P,
PUSH P,TT
CONO PI,400 ;TURN PI OFF, IMP MAY HAVE PIA = 1
MOVE TT,IMPPIA
CONO IMP,IMPODS(TT)
CONO PI,200
POP P,TT
]IFN DMIMP,[
AOSN IMPOAC
CONO FI,FIODS+NETCHN*11
]
POPJ P,
;Check if IMP ready line is set
; Called from SYSJOB.
; Return +1 if IMP not ready, +2 if so
;
IMPCKR:
IFN DMIMP,[
.ERR IMPCKR Missing for DMIMP!
]
IFN KAIMP,[
CONSZ IMP,IMPR ;Skip if IMP not ready
AOS (P) ;Return +2 if ready
POPJ P,
]
SUBTTL HOST-TABLE MANAGEMENT
; FNDHST - Look up host-table index for a given IMP host address.
; Call with NETOFF or NETCHN PI in progress.
; T/ IMP host address (maybe someday other nets?)
; Returns .+1 if failed (no room in table)
; Returns .+2
; H/ host-table index
; Smashes W.
FNDHST: MOVEI H,LIMPHT-1 ;SEARCH FOR AN ENTRY FOR THIS HOST
CAME T,IMPHTN(H)
SOJGE H,.-1
JUMPGE H,POPJ1 ;FOUND
SKIPGE H,IMPHTF ;NOT FOUND, CONS ONE OFF FREE LIST
JRST FNDHS1 ;OOPS, MUST GARBAGE COLLECT
MOVE W,IMPHTB(H)
IFN INETP,[ ; Later make this check standard!
CAIGE H,LIMPHT ; Make sure H is valid idx
CAIL W,LIMPHT ; ditto W
BUG HALT,[NET: FNDHST idx clobbered!!!]
]
MOVEM W,IMPHTF
MOVEM T,IMPHTN(H)
SETZM IMPHTB(H) ;NOTHING IS KNOWN ABOUT THIS HOST
SETZM IMPHTC(H) ; Assume no RFNMs outstanding
SETZM IMPHTT(H) ; Clear out time of last RFNM.
JRST POPJ1
; Host-Table full, attempt to GC it and flush unused entries, by
; scanning all possible pointers into table.
; IMP pointers are IMPCSH and IMPHTC(H)
; NCP pointers are IMSOC4<3.9-4.7>, RFC queue, PI ctl msg queue,
; and the RFNM-wait and RST-sent bits in table.
; TCP pointers are XBNADR(I)
; GC mark phase - mark entries in use
FNDHS1: PUSH P,I
MOVSI W,200000 ;MARK BIT
MOVEI H,LIMPHT-1 ;CLEAR ALL MARK BITS
ANDCAM W,IMPHTB(H)
SOJGE H,.-1
SKIPL H,IMPCSH ;MARK FROM IMPCSH
IORM W,IMPHTB(H)
IFN TCPP,[
MOVEI I,XBL-1
SKIPL H,XBNADR(I) ; See if TCP conn has a net addr specified
IORM W,IMPHTB(H) ; Yes, set the mark bit.
SOJGE I,.-2
] ;IFN TCPP
IFN NCPP,[
MOVEI I,IMPSTL-1 ;MARK FROM IMSOC4
FNDHS2: SKIPN IMSOC1(I) ;SKIP IF IMSOC4 IS BEING USED BY ANYONE
SOJGE I,FNDHS2
JUMPL I,FNDHS3
LDB H,IMSCFH
CAIE H,377
IORM W,IMPHTB(H)
SOJGE I,FNDHS2
FNDHS3: MOVE I,IMPBPQ ;MARK RFC PENDING QUEUE
JUMPGE I,[ LDB H,[101000,,3(I)]
IORM W,IMPHTB(H)
MOVE I,(I)
JRST . ]
MOVE I,IMPNCQ ;MARK CONTROL QUEUE
JUMPGE I,[ HLRZ H,1(I)
IORM W,IMPHTB(H)
MOVE I,(I)
JRST . ]
] ;NCPP
; GC sweep phase - free all unmarked entries
SETO I, ;FREE POINTER
MOVEI H,LIMPHT-1
MOVSI W,601000 ;PROTECT IF RFNM-WAIT, RST-WAIT, OR MARKED
FNDHS4:
SKIPG IMPHTC(H) ; Also protect if any outstanding RFNMs
TDNE W,IMPHTB(H)
SOJGE H,FNDHS4
JUMPL H,FNDHS5
SETZM IMPHTN(H) ;DON'T BELONG TO ANY HOST
MOVEM I,IMPHTB(H) ;CONS ONTO FREE LIST
MOVE I,H
SOJGE H,FNDHS4
FNDHS5: MOVEM I,IMPHTF ;FREE LIST
POP P,I
SKIPGE IMPHTF
POPJ P, ;GC-OVERFLOW
JRST FNDHST ;TRY AGAIN, SHOULD WIN
;See if IMP code is willing to handle a particular datagram right now.
; A/ IP DGM pointer
; C/ Immediate destination address
; Returns +1, can't send right now, +2, OK to send
;
IMPCTS:
IFN 0,[
MOVE T,C ;Set up for FNDHST
AND T,[<377_16.>+377] ;Mask out all but host and IMP field
CALL FNDHST ;Get host index in H
POPJ P, ;No host entry, don't send
JSP T,IMPBLI ;See if OK to send
POPJ P, ;IMP wants to block, no send
]
JRST POPJ1 ;Skip return if OK to send.
SUBTTL ARPANET INPUT INTERRUPT LEVEL
COMMENT |
The IMP interrupt level structure is fairly complicated and
deserves some explanation. Because the IMP interface is not a DMA
device, all I/O is done "by hand", a word at a time; for this reason
all I/O is done at PI level IMPCHN=1 (the highest) whenever possible.
However, to prevent general IMP processing from taking complete
precedence over everything else, all non-I/O handling is done at
PI level NETCHN=2, which is the same level as disk devices.
The MIT-DMS interface (DMIMP) is much more complicated than the
AI-KA/ML/MC interface and was designed to facilitate this dual-level
interrupt processing by providing different PI channel assignments
for each of 3 possible conditions:
Input Done (must usually read next word)
Output Done (must usually output next word)
Control Int (some unusual condition, including Last-IMP-Word)
Because the non-DM interface only has one PI assignment available,
the software to switch levels is much more complicated. For either
case, the code will not make sense unless you understand the channel 1
multiplexing feature (see interface CONI bit descriptions).
|
; Here when IMP interface is interrupting at PI level 2 (NETCHN)
; TT has CONI bits. Can clobber most ACs
IMPINT:
IFN KAIMP,[
AOSN IMPB ; PI 1 control interrupt?
JRST IMPBKZ ; Yes
AOSN IMPI ; PI 1 Input Done interrupt?
JRST IMPIBZ ; Yes
AOSN IMPO ; PI 1 Output Done interrupt?
JRST IMPOBZ ; Yes already
TRNE TT,IMPLW+IMPHER+IMPERR ; No PI 1 ints, check status bits
JRST IMPBKZ ; PI 2 Control interrupt (error or Last Imp Word)
TRNE TT,IMPID
JRST IMPIBZ ; PI 2 Input Done
TRNE TT,IMPOD
JRST IMPOBZ ; PI 2 Output Done
]IFN DMIMP,[
TRNE TT,FILW+FIWASD+FIDOWN
JRST IMPBKZ ; PI 2 Control interrupt (error or Last Imp Word)
TRNE TT,FIID
JRST IMPIBZ ; PI 2 Input Done
TRNE TT,FIOD
JRST IMPOBZ ; PI 2 Output Done
]
JRST 4,. ; Must be one of above!!
IFN KAIMP,[
; IMPIBK - Default PI 1 Input Done routine, called from IMPILC.
; We're idling, switch to PI 2 to handle the input
; (normally 1st word of new IMP message)
EBLK
IMPIBK: 0
BBLK
SETOM IMPI ; Set flag saying PI 1 Input Int seen
CONO IMP,NETCHN ; Switch PIA to 2
JRST 12,@IMPIBK ; Go re-interrupt, will get to IMPINT->IMPIBK
]
IFN KAIMP,[
; IMPBRK - PI 1 Control interrupt, called from PI0LOC+2 (= 42 on KA's)
; which is the standard PI 1 vector location.
; Again, switch to PI 2 to handle the condition
; (typically Last Imp Word seen on input)
EBLK
IMPBRK: 0 ; This interrupt is to 42, may not be the IMP
BBLK
CONSO IMP,IMPLW+IMPHER+IMPERR ; This really from the IMP?
IFE NEWDTP,JRST RC1INT
IFN NEWDTP,JRST IMPBR1
SETOM IMPB ; Yes, re-interrupt and handle at NETCHN level
CONO IMP,NETCHN ; Switch PIA to 2 (NETCHN)
JRST 12,@IMPBRK ; Go re-interrupt, will get to IMPINT->IMPBKZ
IFN NEWDTP,[
IMPBR1: CONSZ DTC,70 ; Allow for non-IMP interrupt on PI chan 1
JRST 12,@IMPBRK
]
RC1INT: MOVEM 17,R1NTAC+17
MOVEI 17,R1NTAC
BLT 17,R1NTAC+16
MOVEI J,1
JSP E,SPUR
MOVSI 17,R1NTAC
BLT 17,17
JRST 12,@IMPBRK
];IFN KAIMP
; IMPRM4 - PI 1 Input-Done handler during readin of IMP data (not leader)
; BLKI has run out but haven't yet gotten Last Imp Word!
; Either read more (if 2nd ptr specifed) or ignore following data.
EBLK
IMPRM4: 0
BBLK
MOVEM A,IMPA ; Save A
SKIPL A,IMNWSI ; Second BLKI pointer exists?
JRST IMPRM6 ; Nope, none now
MOVEM A,IMBLKI ; Yes, store it!
SETZM IMNWSI ; Clear this flag so don't do it again
MOVE A,IMPA ; Restore A
JRST 12,@IMPRM4 ; Return, continuing BLKI.
IMPRM6: MOVE A,[JSR IMPRM5] ; Ugh! Ignore additional input
MOVEM A,IMPILC ; Set up new vector to "ignore" routine
MOVE A,IMPA
JRST 12,@IMPRM4
; IMPRM5 - PI 1 Input-Done handler while ignoring IMP data, only
; set up by IMPRM6 above.
; Just reads a word and ignores it. This loop is broken
; by a control interrupt when Last-Imp-Word is seen.
EBLK
IMPRM5: 0 ; Hmm? Flush input at PI 1
BBLK
DATAI IMP,IMPA
IFN INETP,AOS IMNWIF ; See how often we come here.
JRST 12,@IMPRM5
; IMPIBZ - PI 2 (NETCHN) "Input Done" interrupt, via IMPINT.
; Note there is one input word waiting in the IMP interface,
; but it is NOT the last IMP word (if it was, we would get a
; control interrupt and go to IMPBKZ instead). This situation
; should only happen while reading the IMP leader and there is
; more input than just the leader, i.e. it is a NCP or IP message.
; This is also where we come after being in idle state.
; TT/ IMP CONI word
IMPIBZ: AOS IMCT2
IFN DMIMP,[
TRC TT,IMPCHN ;FIND IF INPUT PIA=IMPCHN
TRNN TT,7
JRST IMPRET ;YES, ALREADY HANDLED BY IMPCHN
];DMIMP
IFE INETP,[ ; Note IP datagram is read in 32-bit mode!
IFN DMIMP,TLNE TT,FII32
IFN KAIMP,TRNE TT,IMPI32
JRST 4,. ; NCP-only, leader should always be read in 36-bit mode
] ;IFE INETP
MOVE C,IMPHI
SKIPN B,IMPIS ; Skip hold-up check unless at start of msg (idle)
AOJE C,IMPBKW ; Jump if input needs to be held up (can only do at start or end of msg)
IFE INETP,CAILE B,%ISIML
IFN INETP,CAILE B,%ISIID
JRST 4,. ; Unknown input state
JRST @.+2(B) ; Dispatch, note data not read yet
IMPIGN ;-1 Supposed to be shut off, go ignore message.
OFFSET -.
%ISIDL:: IMSTR1 ; 0 Was idle, this is start of a message!
%ISIGN:: IMPIGN ; 1 Ignoring this message.
IFE INETP,%ISIML:: IMPLD2 ; 2 Reading IMP leader, see what we got.
IFN INETP,[
%ISIML:: [JRST 4,.] ; 2 Should only see %ISINL or %ISIIL
%ISINC:: [JRST 4,.] ; 3 Was reading control msg! Runout is error.
%ISIND:: [JRST 4,.] ; 4 Was reading NCP data msg! Runout is error.
%ISINL:: IMPLD2 ; 5 Was reading NCP IMP leader
%ISIIL:: IMPLD2 ; 6 Was reading IP IMP leader.
%ISIID:: [JRST 4,.] ; 7 Was reading IP datagram! Runout is error.
] ;INETP
OFFSET 0
IMPIGN: DATAI IMP,A ; Ignore input (only come here via table above)
IFN INETP,AOS IMNWIG ; See how often we come here.
;JRST IMPRET
; All routines dispatched to from IMPIBZ should return via IMPRET.
IMPRET:
IFN DMIMP,CONI FI,A
SKIPN IMPIS ; Skip if input not in normal (idle) state
IFN KAIMP, CONSO IMP,IMPI32 ; It is, see if input is in 32-bit mode
IFN DMIMP, TLNN A,FII32
JRST .+2
JRST 4,. ; Shouldn't be in 32 bit mode in normal state
IFN KAIMP,CONO IMP,@IMPPIA ; Switch to desired exit PIA
JRST IMPEX
; IMPBKZ - PI 2 (NETCHN) Control interrupt, via IMPINT.
; Error or Last Imp Word on input.
; TT/ IMP CONI word
IMPBKZ: AOS IMCT1 ; Bump count of control interrupts
IFN KAIMP,TRNE TT,IMPERR+IMPHER ; See if error or last-imp-word.
IFN DMIMP,TRNE TT,FIWASD+FIDOWN
JRST IMPBER ; Jump if IMP Error or Host Error
; Not an error, interface has Last Imp Word ready for DATAI'ing!
MOVE B,IMPHI ; Check here to see if input should be held up
AOJN B,IMPBKX ; Jump if not.
; Input must be held up. Also enter here from IMPIBZ if
; at start of message (only other time input can be held up).
IMPBKW:
IFN KAIMP,CONO IMP,IMPIDC ; Clear Input Done so we don't re-interrupt
IFN DMIMP,[
CONO FI,FISUSP ; Suspend input, no bits accepted after DATAI
DATAI FI,IMPSUS ; Have to read word now
CONO FI,FIIDC+NETCHN_3 ; Have to do this to clear IMP Last Word
] ; (also to clear Input-Done PIA)
SOS IMPHI ; Set -2 to indicate successfully held up
MOVEM TT,IMSTAS ; Save status (CONI bits)
AOS IMPNIH ; Bump meter - count of times input was held up.
JRST IMPRET
; IMPBKX - Auxiliary to IMPBKZ, PI 2 Control Interrupt
; Have got Last Imp Word and not holding up input, so go
; handle end of IMP message.
IMPBKX:
IFN KAIMP,[
MOVE A,[JSR IMPIBK] ; Get rid of input BLKI
MOVEM A,IMPILC ; Replace with default switch-PIA vector
SETZM IMPIH ; Say don't need PI 1 for input any more.
MOVEI A,NETCHN ; And change exit PIA to 2
SKIPL IMPOH ; Unless output side still needs PI 1.
MOVEM A,IMPPIA ; Set value of PI level desired on exit.
CONO IMP,IMI32C ; Put back in 36 bit mode to start next msg
DATAI IMP,A ; Get the last input word for processing
]IFN DMIMP,[
CONO FI,FII32C+FISUSP ; Hold up bits for following clear
DATAI FI,A ; Get last input word
CONO FI,FIIDC+FIIBSY+NETCHN*11 ; Now clear Last-Imp-Word
]
; Enter here from IMOB6 if input had been held up.
IMPBKV: SKIPGE B,IMPIS ; Unless network has been shut off
JRST IMPRET ; (in which case ignore input)
JRST @IMSDT2(B) ; then go process end of IMP message.
IMSDT2: OFFSET -.
%ISIDL:: IMPBKN ; 0 Was idle - leader only 1 word long??
%ISIGN:: IMPIRT ; 1 Ignore input
%ISIML:: IMPLD1 ; 2 End of IMP leader - can't be regular msg
%ISINC:: IMPBK3 ; 3 End of NCP control message
%ISIND:: IMPRMB ; 4 End of NCP data input
IFN INETP,[
%ISINL:: IMPLD1 ; 5 End of NCP IMP leader?? Probably error.
%ISIIL:: IMPLD1 ; 6 End of IP IMP leader?? Probably error.
%ISIID:: IMPRMI ; 7 End of IP datagram
] ;INETP
OFFSET 0
; Here from table above for old-type leader (1 word)
; IMPBN1 is used by IMPLD2 if long leader has wrong format.
IMPBKN: MOVEM A,IMPILB ; Store first (and only) word of leader
IMPBN1: LDB A,IMOTBP ; Get message format type
CAIN A,4 ; Old-type NOP?
JRST IMPIRT ; Just ignore it.
CAIN A,16 ; Is it 1822L format?
BUG INFO,[IMP: 1822L leader],OCT,IMPILB
CAIE A,17 ; Is it not the long-leader format?
BUG INFO,[IMP: Old-type leader],OCT,IMPILB
JRST IMPIRT ; Ignore rest of message, if any
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; IMP LEADER READING/DISPATCH ;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Code on this page handles the initial processing of
;;; IMP messages and dispatches to the appropriate
;;; routines for each message type. Only Type 0 ("Regular")
;;; messages carry Host-Host traffic.
; Here from IMPIBZ only, to handle first word of an IMP message.
; (It's not the last word or IMPBKZ would complain about it)
; Set up a BLKI to get the rest of the leader.
IMSTR1: DATAI IMP,A ; Get 1st word from interface
; Entry point from IMPOB6 only to restart input from "held-up" state
; First word already in A
IMSTRT: MOVEM A,IMPILB ; Store first word of leader
MOVEI C,%ISIML ; Set new state = reading rest of IMP leader
IFE INETP,MOVE B,[-4,,IMPILB] ; If not diverting IP, ask for it all.
IFN INETP,MOVE B,[-2,,IMPILB] ; Must vector IP, ask for max 36-bit wds
JRST IMPRM9 ; Go read the leader.
; The code at IMPLD5 will switch to 32-bit mode at right place if
; the message turns out to be an IP datagram. Otherwise the message
; is either a NCP Host-Host message, or an IMP-to-Host note of some kind;
; both stay in 36-bit mode.
; Here from IMPBKX only for a leader not followed by any data.
; Last word in A, IMPLW flag in TT.
IMPLD1: AOS B,IMBLKI ; Update pointer to buffer
MOVEM A,(B) ; and store last word in right place.
; Fall through to handle what should be an IMP-Host note.
; The IMPLW flag distinguishes this entry point from IMPLD2,
; so we know there isn't a data word in the interface.
; Here from IMPIBZ only, for an IMP leader with more data following;
; almost certainly a "Regular" host-host message. The 2 possible
; states are:
; %ISINL - NCP, in 36-bit mode, have read 5 wds and 6th awaits.
; %ISIIL - IP, in 32-bit mode, have read 4 wds and 5th awaits.
; We can't DATAI the current word from the interface until we know
; what mode the remaining data should be read in.
IMPLD2:
IFN KAIMP,TRNE TT,IMPI32
IFN DMIMP,TLNE TT,FII32
IFE INETP, JRST 4,. ; Input was in 32 bit mode when shouldn't!
IFN INETP,[JRST [MOVE B,IMPIS ; If reading IP IMP leader then 32 bit OK.
CAIE B,%ISIIL ; Leader read in 32-bit mode, must be IP.
JRST 4,. ; It isn't???
JRST .+1]
] ;INETP
LDB T,IMOTBP ; Examine new-format flag bits of leader
CAIN A,16 ; Is it 1822L format?
BUG INFO,[IMP: 1822L leader],OCT,IMPILB
CAIE T,17 ; to verify that leader is "new" 96-bit fmt.
JRST IMPBN1 ; Something else?? Go discard.
HRRZ B,IMBLKI ;-> LAST WORD READ
CAIGE B,IMPILB+2 ;MUST BE AT LEAST 3 WORDS TO BE VALID
JRST IMPLD3
LDB T,IMLNBP ; Extract link number (high 8 bits of msg-id)
IFN INETP,[
CAMN T,IMPCLP ; HACK! If it matches our specified ctl link
SETZ T, ; number, then make it look like ctl link!
]
MOVEM T,IMPCLN
LDB T,IMSABP ; Get arpanet address (source host+imp)
IFN 0,[ LDB T,IMSHBP ;SOURCE HOST
LDB A,IMSIBP ;SOURCE IMP
DPB A,[112000,,T] ;FORM HOST ADDRESS
] ;ifn 0
PUSHJ P,FNDHST ;H GETS HOST TABLE INDEX
JRST IMPLD9 ;HOST TABLE FULL
MOVEM H,IMPCSH ;SAVE CURRENT HOST
LDB A,IMTBP ;GET MESSAGE TYPE IN A
CAILE A,10.
JRST IMPUN ;UNKNOWN TYPE
AOS IMPMSR(A) ;COUNT IMP MSGS RCD
JRST @IMTDT(A) ;DISPATCH
IMTDT: IMPRM ; 0 Regular Message
IMPBE1 ; 1 Error in Leader (no msg-id)
IMPGD ; 2 IMP Going Down
IMPUN ; 3 -
IMPIN ; 4 NOP
IMPRFN ; 5 RFNM - Ready For Next Message (transmit succeeded)
IMPHDS ; 6 Host Dead Status (general info)
IMPDHD ; 7 Destination Host Dead (transmit failed)
IMPBE8 ; 8 Error in Data (has msg-id)
IMPINC ; 9 Incomplete Transmission (transmit failed temporarily)
IMPIRS ;10 Interface Reset - IMP dropped its ready line
IMPLD9: BUG INFO,[IMP: Message discarded due to host table full],OCT,IMPILB,OCT,IMPILB+1,OCT,IMPILB+2
JRST IMPIRT
; Here from IMPLD2 if leader is too short
IMPLD3: SUBI B,IMPILB-1 ;# WDS READ
BUG INFO,[IMP: Short leader, ],DEC,B,[wds. WD1=],OCT,IMPILB,[WD2=],OCT,IMPILB+1
;JRST IMPIRT ;FLUSH REST OF MESSAGE
;;; IMP->Host Type 4 - NOP
IMPIN: JRST IMPIRT ; One more nop from IMP
;;; IMP->Host Type 10 - Interface Reset
IMPIRS: BUG INFO,[IMP: Interface-reset msg]
JRST IMPIRT ; Probably nothing useful to do about it.
;;; IMP->Host Type X (e.g. 3, 11-255) - bad type
IMPUN: BUG INFO,[IMP: Unknown msg type ],OCT,A,[ leader ],OCT,IMPILB,OCT,IMPILB+1,OCT,IMPILB+2
;JRST IMPIRT
IFE NCPP,[
IMPBK3:: ;Ignore NCP messages
IMPRMB::
];NCPP
; Here from all over, to flush rest of this message.
; All non-regular messages (not type 0) return here, as well as some
; errors with regular msgs.
; TT says whether there is any more data to read from this message.
IMPIRT: SETZM IMPIS ; Assume end of message, reset to normal state
TRNN TT,IMPLW ; But if we haven't yet read the last word,
AOSA IMPIS ; then change state to "Ignore" and flush input.
; Note skip over following SETZM.
; Regular messages (type 0) return here, when we already know this message
; was completely read. TT isn't valid.
IMPIR1: SETZM IMPIS ; Reset to normal idle state
SETOM IMPCSH ; Say no current host
IFN KAIMP,CONO IMP,IMI32C ; Put world back in 36 bit input mode
IFN DMIMP,CONO FI,FII32C+NETCHN*11
JRST IMPRET
;;; IMP->Host Type 0 - Regular Host-Host message
; Unless the source host screwed up and sent a dataless message,
; there is a word waiting to be read from the interface.
; For IP this is the 5th word and we are in 32-bit mode.
; For NCP it's the 6th (the NCP leader) and we're in 36-bit mode.
; TT/ IMP CONI bits,
; B/ addr of last wd input (counted-out BLKI pointer)
IMPRM: TRNE TT,IMPLW
JRST IMPRM3 ; Foo, message shouldn't end so soon. Go barf.
IFE INETP,[
CAIE B,IMPILB+4 ; Check that host-host leader word is next in
JRST IMPLD3 ; Barf
SKIPE IMPCLN ; Skip if link 0 - NCP control msg
JRST IMPRMD ; Data message, go read into user buffer.
]
IFN INETP,[
SKIPN A,IMPCLN ; Skip unless NCP control link message
JRST IMPRM1 ; NCP control message, go handle it.
CAIE A,233 ; Is link number the magic cookie for IP?
IFN NCPP, JRST IMPRMD ; No, go handle as NCP data message.
IFE NCPP, JRST IMPIRT ; No, ignore it if we don't have NCP
; This is an Internet Protocol datagram. Make sure we are
; in right mode for reading.
AOS IMNIPI ; Bump count of IP datagrams received
IFN KAIMP,TRNN TT,IMPI32 ; Should already be in 32-bit mode
IFN DMIMP,TLNN TT,FII32
BUG PAUSE,[IMP: Reading IP dgm in 36-bit mode]
DATAI IMP,IMPILB+4 ; Okay, read in the padding and get going.
MOVEI A,%IMXLN ; Specify max size of IMP message
; (we can't trust msg-len leader field)
PUSHJ P,IPGIPT ; Call IP module - get input buffer pointer
JRST [ AOS IMNIPF ; Punted, bump cnt of datagrams lost
JRST IMPIRT] ; Flush this message (err msg already printed)
MOVEM A,IMPIDP ; Save datagram pointer
MOVEM B,IMPIBS ; Save input BLKI pointer for later check
MOVEI C,%ISIID ; Set state = reading IP datagram
JRST IMPRM9 ; Go do it.
IMPRM1: CAIE B,IMPILB+4 ; NCP control message, check that NCP leader is next
JRST IMPLD3 ; Barf, short message??
] ;INETP
IFN KAIMP,CONO IMP,IMI32S ; NCP control message, set 32-bit mode
IFN DMIMP,CONO FI,FII32S+NETCHN*11
DATAI IMP,IMPILB+5 ; Get NCP leader word
LDB A,IMCBBP
MOVEM A,IMPCBS ; Byte size
LDB B,IMBCBP
MOVEM B,IMPCBC ; Byte count
CAIN A,8 ; Byte size should be 8 for control link
CAILE B,120. ; Byte count shouldn't be > 120.
JRST IMPBCM
ADDI B,3
LSH B,-2 ; Number of words necessary
MOVEM B,IMPNIW ; Number of input words expected
HRLOI B,-1(B)
EQVI B,IMPINB-1 ; BLKI pointer
MOVEI C,%ISINC ; New state = reading NCP control message
; Set up BLKI. Pointer in B, state in C.
; This place is jumped to by several things that initiate IMP input,
; specifically IMSTRT, IMPRMT, and IMPRM.
IMPRM9: MOVEM C,IMPIS
MOVEM B,IMBLKI
MOVE B,[BLKI IMP,IMBLKI]
MOVEM B,IMPILC
MOVE B,IMPBRO(C) ; Get BLKI runout instruction and set vector;
MOVEM B,IMPILC+1 ; will execute when ptr counts out.
IFN KAIMP,[
SETOM IMPIH ; Say that input wants high pri
MOVEI B,IMPCHN ; And set our exit PIA to it (IMP)
MOVEM B,IMPPIA
]
IFN DMIMP,CONO FI,NETCHN_3+IMPCHN ; Set control PIA = NET, input done = IMP
JRST IMPRET
; This table holds the instruction to execute after the input
; BLKI has counted out the ptr and stored the current input word.
; Note that if the IMP message ends during the BLKI, a control
; interrupt will happen instead and control goes to IMPBKZ->IMPBKX
; where there is another state dispatch table.
; Normally only %ISIML and %ISINL actually use these instructions;
; the other states are impossible or expect to read the entire
; remaining message.
IMPBRO: OFFSET -.
%ISIDL:: JRST 4,IMPBRO ; 0 Idle - shouldn't be BLKI'ing.
%ISIGN:: JRST 4,IMPBRO+1 ; 1 Ignore - shouldn't be BLKI'ing.
%ISIML::
IFE INETP,JSR IMPLD4 ; 2 Reading IMP leader (5 wds partial msg)
IFN INETP,JSR IMPLD5 ; 2 Reading IMP leader (4 wds partial msg)
%ISINC:: JSR IMPRM4 ; 3 Reading NCP control message (get all)
%ISIND:: JSR IMPRM4 ; 4 Reading NCP data (get all)
IFN INETP,[
%ISINL:: JSR IMPLD4 ; 5 Reading NCP IMP leader (partial msg)
%ISIIL:: JSR IMPLD4 ; 6 Reading IP IMP leader (partial msg)
%ISIID:: JSR IMPRM4 ; 7 Reading IP datagram (get all)
] ;INETP
OFFSET 0
IMPRM3: LDB B,IMBCBP ;BYTE COUNT OF EMPTY CONTROL LINK MESSAGE
JUMPE B,IMPIRT
AOS IMPNPE ;NO TEXT BUT BYTE COUNT NOT ZERO
BUG INFO,[NCP: CTL MSG NO TXT, BC NOT 0. HST ],OCT,IMPHTN(H),[BC],DEC,B
JRST IMPIRT
IFN INETP,[
EBLK ; PI 1 Input Done interrupt (from IMPILC+1, runout)
IMPLD5: 0 ; JSR here on BLKI runout after reading 3rd wd of IMP leader.
BBLK ; Input Done is not set, because BLKI just turned it off.
MOVEM A,IMPILC ; Save A
MOVE A,[JSR IMPLD6] ; Make very next input word interrupt to IMPLD6
EXCH A,IMPILC ; Do it, restore A
JRST 12,@IMPLD5
EBLK ; PI 1 Input Done interrupt (from IMPILC)
IMPLD6: 0 ; JSR here with 4th wd of leader in interface.
BBLK ; Must decide whether to continue reading leader in
; 36-bit mode (NCP) or 32-bit mode (IP).
MOVEM A,IMPILC ; Save A
MOVE A,IMPILB+1 ; Get word with link number in it
ANDI A,377 ; Mask off
CAIN A,233 ; Internet Protocol "link"?
JRST IMPLI3 ; Yes! Go handle it.
; NCP read will immediately store current 36-bit word (4th),
; store another 36-bit word (5th), and then run out to IMPLD4.
MOVE A,[-2,,IMPILB+2] ; Reading NCP message.
MOVEM A,IMBLKI
MOVEI A,%ISINL ; Reading NCP leader, set state thereto.
MOVEM A,IMPIS
MOVE A,[JSR IMPLD4] ; And change dispatch vector.
MOVEM A,IMPILC+1
MOVE A,[BLKI IMP,IMBLKI]
EXCH A,IMPILC ; Set up BLKI and restore A
JRST 12,@IMPLD6 ; Return. Note current input word is still waiting.
; IP read will immediately store current 36-bit word (4th),
; then set up so next input-done interrupt (on 5th, 32-bit word)
; goes directly to IMPIBZ->IMPLD2 with NETCHN PI.
; (For AI-KA/MC/ML, perhaps by way of IMPIBK if output is active)
IMPLI3: MOVEI A,%ISIIL ; Say reading IP type leader.
MOVEM A,IMPIS
IFN KAIMP,CONO IMP,IMI32S+IMPCHN ; Set further input to 32-bit mode
IFN DMIMP,CONO FI,FII32S+NETCHN_3+IMPCHN
DATAI IMP,IMPILB+3 ; Store the 4th 36-bit word immediately; this
; also starts interface reading the 5th word.
IFN KAIMP,[
MOVE A,IMPLD6 ; Now must set up for next interrupt.
MOVEM A,IMPLD4 ; Fake out the common code below
JRST IMPLI4 ; Set up for next Input-Done interrupt
]
IFN DMIMP,[
MOVE A,[JSR IMPLD4] ; Shouldn't need this, but just in case...
EXCH A,IMPILC ; Restore A, set int vector to safe rtn
CONO FI,NETCHN*11 ; DM interface can simply set Input-Done PIA!
JRST 12,@IMPLD6
] ;DMIMP
] ;INETP
EBLK ; PI 1 Input Done interrupt (from IMPILC+1, runout)
IMPLD4: 0 ; JSR here on BLKI runout after reading IMP leader
BBLK ; There is still one word to go, to be gotten at NETCHN level
IFN KAIMP,[
MOVEM A,IMPILC ; Save A
; Drop through to common code
IMPLI4: SETZM IMPIH ; Say input no longer needs PI 1
MOVEI A,NETCHN ; Make PI 2 (NETCHN) the exit PIA,
SKIPL IMPOH ; unless output side needs PI 1.
MOVEM A,IMPPIA ; Set desired PIA channel on exit
CONO IMP,@IMPPIA ; Set PIA to whatever it was!
MOVE A,[JSR IMPIBK] ; Reset PI 1 Input-Done vector back to std.
EXCH A,IMPILC ; and restore A.
];KAIMP
IFN DMIMP, CONO FI,NETCHN*11 ; DM interface can simply set Input-Done PIA!
JRST 12,@IMPLD4
IMPBCM: BUG INFO,[NCP: CTL MSG BS NOT 8 OR CT>120. HST ],OCT,IMPHTN(H),[BS ],DEC,IMPCBS,[BC ],DEC,IMPCBC
JRST IMPIRT
;;; IMP->Host Type 6 - Host Down Status
; H/ host index
IMPHDS: MOVE A,IMPILB+1 ;1.8-1.1 AND 4.9-4.2 ARE THE INFO
MOVE B,IMPILB+2
LSHC A,8
ANDI A,177777
HRRM A,IMPHTB(H) ;STORE, HOPE USER READ RFC 611
JRST IMPIRT
;;; IMP->Host Type 1 - Error in leader (msg-id not given)
;;; IMP->Host Type 8 - Error in data (msg-id given)
IMPBE1: LDB T,IMSTBP ; Get subtype (4 bits)
ANDI T,3 ; Only 2 bits should be used
AOS IMPM1S(T) ; Increment count of Type 1 subtype messages
IMPBE8: MOVE T,TIME
SUB T,LNETIM
CAIL T,60. ;IGNORE ERROR DURING INITIAL SYNCHRONIZATION
BUG INFO,[IMP: Type ],DEC,A,[err msg, leader],OCT,IMPILB,OCT,IMPILB+1,OCT,IMPILB+2
IFN INETP,[
MOVE B,IMPCLN
CAIN B,233
AOS IMNIP8
]
CAIN A,8.
JRST IMPBEB ; Process "Error in data" (decrement RFNM wait cnt)
JRST IMPIRT
IMPBER: SKIPGE IMPUP ;SKIP IF UP, OR THOUGHT TO BE BROKEN
JRST IMPBE2 ;ALREADY DOWN, LET IT COME UP IN PEACE
MOVSI J,SCLNET ;THINKS IT'S UP, RESET IT
IORM J,SUPCOR
CONI IMP,IMERCN ;RECORD IF IMP ERROR FLIP/FLOP SET
SETOM IMPUP ;IMP IS DOWN
SETZM IMPTCU ;AND NOT TRYING TO COME UP
IFN INETP,.ERR IP/TCP code needs handling for IMP crashing.
IFN NCPP,[
MOVSI T,200000 ;CLEAR ALL BUFFERS ACTIVE AT PI LEVEL
MOVSI I,-IMPSTL ;SINCE CORE JOB MAY BE WAITING ON THIS
ANDCAM T,IMSOC6(I)
AOBJN I,.-1
] ;NCPP
IMPBE2:
IFN KAIMP,[
SETZM IMPPIA
CONO IMP,0
]
IFN DMIMP,CONO FI,FIRSET
JRST IMPEX
;;; IMP->Host Type 2 - IMP going down
IMPGD: LDB B,[060200,,IMPILB+1] ;WHY
MOVEM B,IMPDWN
LDB B,[020400,,IMPILB+1] ;HOW SOON GOING DOWN * 5 MINS
MOVE H,B
IMULI B,5*60.*30. ;TICKS IN 5 MINS
ADD B,TIME
MOVEM B,IMPDWN+1
MOVE C,IMPILB+1 ;HOW LONG TO BE DOWN, SPANS WORD BOUNDARY
MOVE D,IMPILB+2
LSHC C,8
ANDI C,1777
MOVE Q,C
IMULI C,5*60.*30.
ADD C,B ;ADD TO TIME DOWN
MOVEM C,IMPDWN+2 ;STORE TIME WHEN WILL BE UP
IMULI H,5 ;MINUTES
IMULI Q,5
BUG INFO,[IMP: Going down in ],DEC,H,[mins for ],DEC,Q,[mins, reason],DEC,IMPDWN
JRST IMPIRT
;;; IMP Blockage avoidance
; The current IMP software will not accept more than 8 active
; messages to a single host; attempting to send a 9th message will block
; ALL output to the interface, until the first message has been ack'd
; by means of one of the following message types:
; Type 5, RFNM - Message delivered OK
; Type 7, Host dead - transmit failed ("permanent")
; Type 8, Error in data - interface spazzed
; Type 9, Incomplete Transmission - temporary failure
; If for some reason the first message simply becomes lost, the IMP timeout
; (and blockage) can last for up to 30-45 seconds.
; More details in BBN Report 1822.
; ITS attempts to fix this by keeping a count of active un-ACKed
; messages for each host it is communicating with. A timeout is also
; associated with each host; if output to a given host is blocked by ITS
; because there are 8 active messages, trying to send a 9th message
; will check the last-RFNM-received time and if this was more than
; 30 or so seconds then the IMP is probably not giving us what it should
; and we should reset things for that host.
%IMPMA==:8. ; # of maximum active IMP messages allowed
; IMPBLI, IMPBLD - routines to hack active-message counts, called via JSP T,
; IMPBLD decrements count.
; IMPBLI increments count and skips if successful (else failed,
; and must NOT output another message to this host!)
; Also clobbers Q.
IMPBLI: AOS Q,IMPHTC(H)
CAIGE Q,%IMPMA ; Trying to send max or more messages?
JRST 1(T) ; No, can return safely.
CAIG Q,8. ; Is this the maximum # allowed?
JRST [ MOVE Q,TIME ; Yes, set up blockage timeout
ADDI Q,60.*30. ; for one minute.
MOVEM Q,IMPHTT(H)
JRST 1(T)]
; Trying to send too many messages, block it (check for timeout though)
SOS IMPHTC(H) ; Restore original count
AOS IMNBLK ; Increment # of times softwarily blocked.
MOVE Q,IMPHTT(H)
CAML Q,TIME ; See if timeout still in the future
JRST (T) ; Yes, just take failure-return to block.
BUG INFO,[IMP: RFNM-wait timeout! Hst=],OCT,IMPHTN(H)
SETZM IMPHTC(H) ; This may be dangerous... oh well.
SETZM IMPHTT(H)
JRST (T) ; Block one last time, next try will win.
IMPBLD: SOSL Q,IMPHTC(H)
JRST IMPBL2
BUG INFO,[IMP: neg RFNM-wait cnt, Hst=],OCT,IMPHTN(H)
SETZB Q,IMPHTC(H)
IMPBL2: CAIL Q,8.-1 ; If we were blocking on this host,
CALL IMPIOS ; Ensure IMP output started up so blocked stuff
JRST (T) ; gets sent promptly.
;;; IMP->Host Type 8 - Error in Data
; Actually this is secondary routine that IMPBE1 jumps to.
IMPBEB: JSP T,IMPBLD ; Decrement count of active messages
JRST IMPIRT
;;; IMP->Host Type 5 - RFNM (Ready For Next Message)
IFN INETP,.ERR INETP needs handling for RFNM on link 233
IMPRFN:
IFN BLIMPP,JSP T,IMPBLD ; Decrement count of active IMP messages for this host
SKIPE IMPCLN ;LINK NUMBER
JRST IMRFN1 ;DATA LINK
IMRFN6: SKIPL IMPHTB(H)
JRST IMRFN7
SKIPN IMPHTN(H)
BUG HALT,[IMP: IMRFN6 sees free IMPHTB entry ],OCT,H
MOVSI D,400000
ANDCAM D,IMPHTB(H) ;SET RFNM RECEIVED
SOS IMRFCT
IFN NCPP,[
SKIPL IMPNCQ ;SKIP IF NO PENDING CONTROL-LINK OUTPUT
PUSHJ P,IMPIOS ;START OUTPUT
];NCPP
JRST IMPIRT
IMRFN7: AOS IMNSRC
BUG INFO,[IMP: Spurious RFNM from ],OCT,IMPHTN(H),[LNK 0]
JRST IMPIRT
; RFNM on non-zero link message
IMRFN1:
IFN INETP,[
MOVE A,IMPCLN ; Get link #
CAIE A,233 ; IP link number?
JRST IMRFNX ; No, skip IP code
AOS IMNIPR ; Bump count of IP RFNMs received
JRST IMPIRT ; and do nothing else about it, ugh.
IMRFNX:
];INETP
IFN NCPP,[
MOVE A,IMPCSH
LSH A,8
IOR A,IMPCLN ;HEADER
MOVSI I,-IMPSTL
MOVEI W,1
IMRFN2: LDB D,IMSCHL ;HEADER
SKIPGE IMSOC1(I) ;SKIP IF SLOT NOT IN USE
CAME A,D ;SKIP IF HEADER AGREES
JRST IMRFN3
HRRZ J,IMSOC4(I) ;STATE
MOVEI W,0
CAIN J,%NSRFN
SOJA J,IMRFN4 ;RFNM WAIT
MOVSI J,20000 ;MIGHT BE EXPECTING RFNM AFTER CLOSE
TDNE J,IMSOC5(I)
JRST [ ANDCAM J,IMSOC5(I)
JRST IMPIRT ]
IMRFN3: AOBJN I,IMRFN2
BUG INFO,[IMP: Spurious RFNM from ],OCT,IMPHTN(H),[link],OCT,IMPCLN,SIXBIT,[(W)[SIXBIT/NOWAITNOLINK/]]
];NCPP
.ELSE BUG INFO,[IMP: Spurious RFNM from ],OCT,IMPHTN(H),[link],OCT,IMPCLN
AOS IMNSRF
JRST IMPIRT
IFN NCPP,[
IMRFN4: HRRM J,IMSOC4(I) ;CONNECTION OPEN
MOVSI J,30000 ;TURN OFF CLOSE-AWAITING-RFNM BIT, AND
ANDCAM J,IMSOC5(I) ; RFNM-TIMEOUT-DURING-CLOSE BIT
MOVE T,IMSPIP(I)
CAME T,IMSMPP(I) ;SKIP IF OUTPUT BUFFER EMPTY
PUSHJ P,IMPIOS ;START OUTPUT
JRST IMPIRT
];NCPP
;;; IMP->Host Type 9 - Incomplete Transmission
IMPINC: LDB T,IMSTBP ; Get subtype field (4 bit reason for failure)
AOS IMPM9S(T) ; Bump count of subtypes
SKIPA E,[%NCINC]
;;; IMP->Host Type 7 - Destination Host Dead
IMPDHD: MOVEI E,%NCDED
IFN BLIMPP,JSP T,IMPBLD ; Decrement count of active IMP messages for this host
IFN INETP,[
MOVE A,IMPCLN
CAIN A,233
JRST [ CAIN E,%NCINC
AOS IMNIP9
CAIN E,%NCDED
AOS IMNIP7
JRST IMPIRT] ; Don't bother with NCP stuff or anything.
]
MOVSI C,1000 ;RST SENT?
TDNE C,IMPHTB(H)
SOS IMRFCT ;GOING TO CLEAR IT, DECREASE TIMEOUT RQ
MOVSI C,3000
ANDCAM C,IMPHTB(H) ;CLEAR RST STATUS, RFNM SIMULATED LATER
IFN NCPP,[
MOVSI I,-IMPSTL
IMDHD: LDB T,IMSCFH
SKIPGE C,IMSOC1(I) ;SKIP IF NOT IN USE
CAME T,IMPCSH
JRST IMDHDA
HRRZ T,IMSOC4(I)
TLNN C,200000 ;THIS GUY IS CLOSING ANYWAY
CAIG T,%NSLSN
JRST IMDHDA ;THIS SOCKET'S HOST NUMBER FIELD IS MEANINGLESS
CAIGE T,%NSCLI .SEE %NSINP
TDZA T,T .SEE %NSCLS
MOVEI T,%NSCLI
HRRM T,IMSOC4(I)
DPB E,IMSCLS ;CLS REASON
PUSHJ P,IMPUIN
IMDHDA: AOBJN I,IMDHD
];NCPP
JRST IMRFN6 ;CONTROL LINK, TAKE AS RFNM SO AS NOT TO HANG THINGS
IFN INETP,[
; IMPRMI - End of IP datagram, PI in progress on NETCHN, here from IMPBKX
; A/ Last IMP word (32-bit)
; TT/ CONI bits as of interrupt (note already returned to 36-bit mode)
IMPRMI: AOS B,IMBLKI ; Get address to store last word in
MOVEM A,(B) ; Store it away
SUB B,IMPIBS ; Get # words read into datagram buffer
MOVEI B,(B)
MOVE A,IMPIDP ; Get pointer to IP datagram buffer we were using
SETZ C, ; Say zero offset to IP header.
MOVE J,IMPCSH ; Set index to host-table entry dgm received from.
PUSHJ P,IPRDGM ; Call IP module to process received datagram at PI lvl
SETZM IMPIDP ; Clear PI level pointer
JRST IMPIR1 ; Return from PI level, setting up for next msg
] ;INETP
SUBTTL ARPANET OUTPUT INTERRUPT LEVEL
; See comments at IMPINT for a description of the overall IMP interrupt
; structure. Output is simpler than input, however.
; Each IMP message is output at PI level 1 except for the initial DATAO;
; the setup and takedown for each message is done at PI level 2.
; The code on this page is not referenced by anything outside the page
; except interrupt vector setup at IMPINI (to IMPOBK) and IMOB9 (to IMPCH1).
; IMPCH1 - PI 1 Output-Done interrupt, from IMPOLC.
; Comes here when last word DATAO'd has been sent to IMP.
EBLK
IMPCH1: 0
BBLK
MOVEM A,IMPOLC ; Save A
MOVE A,IMOPNT
IMCH1A: SKIPGE A,IMOLST(A) ; Get next "instruction"
JRST IMCH1B ; Jump if it's a BLKO pointer
CAILE A,3 ; Ensure valid operation
JRST 4,.
XCT IMCH1I(A) ; Do it
AOS A,IMOPNT ; Still here? Point to next operation
JRST IMCH1A ; and loop to do it.
IMCH1I: JRST IMCH1C ;0 Stop - end of output list
IFN KAIMP,CONO IMP,IMPLHW+IMPCHN ;1 Set Last Word
IFN DMIMP,CONO FI,FILHW+11*NETCHN
IFN KAIMP,CONO IMP,IMO32S+IMPCHN ;2 Set 32-bit mode
IFN DMIMP,CONO FI,FIO32S+10*NETCHN+IMPCHN
JFCL ;3 NOP
IMCH1B: MOVEM A,IMBLKO ; Set up BLKO - store the pointer
MOVE A,[JSR IMCH1D] ; Set dispatch for BLKO runout
MOVEM A,IMPOLC+1
MOVE A,[BLKO IMP,IMBLKO]
EXCH A,IMPOLC ; Store the BLKO and restore A
AOS IMOPNT ; Increment output list ptr past this op.
JRST 12,@IMPCH1 ; Will interrupt immediately for first BLKO
; word, since Output-Done wasn't cleared.
; PI 1 Output-Done, from IMPOLC+1 (BLKO runout)
; Final word of the BLKO pointer is now in interface, being sent
; to IMP, and Output-Done flag is off.
EBLK
IMCH1D: 0
BBLK
MOVEM A,IMPOLC
MOVE A,[JSR IMPCH1] ; Interrupt back when output of final word done
EXCH A,IMPOLC
JRST 12,@IMCH1D
; Here from IMPCH1, PI 1 Output-Done interrupt
; Output list has hit "stop" operation (previous op had better be
; 1 to set Last-Host-Word!)
; This code reverts control back to PI level 2 (IMPOBK).
IMCH1C:
IFN DMIMP,[
CONO FI,FIOUT+11*NETCHN ; Reset PIA to normal 2
MOVE A,[JSR RINT1] ; and ensure any further output PI 1 ints
] ; are classified as spurious.
IFN KAIMP,[ ; Non-DM interface needs more hair.
SETZM IMPOH ; Say output side doesn't need PI 1 anymore
MOVEI A,NETCHN ; And set exit PIA to 2,
SKIPL IMPIH ; unless input side still needs PI 1
MOVEM A,IMPPIA ; Set it.
CONO IMP,NETCHN ; Shouldn't this be CONO IMP,@IMPPIA??
SETOM IMPO ; Tell IMPINT we have output-done interrupt.
MOVE A,[JSR IMPOBK] ; Point PI 1 channel at switch-PIA routine,
] ; in case we interrupt on PI 1 again anyway.
EXCH A,IMPOLC
JRST 12,@IMPCH1
IFN KAIMP,[
; PI 1 Output Done interrupt, when we should really be interrupting
; at IMPINT on PI 2.
EBLK
IMPOBK: 0
BBLK
SETOM IMPO ; Tell IMPINT what kind of interrupt
CONO IMP,NETCHN ; Reset PIA to 2
JRST 12,@IMPOBK
]
; IMPOBZ - PI 2 (NETCHN) "Output Done" interrupt, via IMPINT.
; Come here when we have finished sending stuff out at PI 1,
; also when something wants output to start and tickled the "Done"
; flag.
; TT/ IMP CONI word.
IMPOBZ: AOS IMCT3
IFN DMIMP,[
TRC TT,IMPCHN_9 ;CHECK IF OUTPUT PIA=IMPCHN
TRNN TT,7_9
JRST IMPRET ;IGNORE, ALREADY HANDLED BY IMPCHN
]
SKIPL B,IMPOS
CAIL B,IMPODL
JRST 4,.
JRST @IMPODT(B)
IMPODT: OFFSET -.
%ISODL:: IMPOB1 ; 0 Idle, look for something to send
%ISONC:: IMPOB6 ; 1 Finished NCP control message
%ISOND:: IMPOBG ; 2 Finished NCP data message
IFN INETP,%ISOID::IMPOBI ; 3 Finished IP datagram messge
IMPODL::OFFSET 0
IFE NCPP,[
IMPOB6: SETZM IMPOS
SKIPN A,IMPSVQ
JRST IMPRET ;THAT WAS A NOP
IMPOBG: JRST 4,. ;Can't get here
];not NCPP
; Idle - Look for output to send. First ensure we can send stuff,
; then try things in the order:
; (1) Send NOP if net coming up
; (2) Check NCP control queue, then (3) NCP data output queue
; OR
; (2) Check IP datagram queue
;
; Note that we alternate between checking the NCP and IP queues first,
; so that neither protocol can totally wedge the other up even if
; going at full blst.
IMPOB1: HRRZ T,IMPUP
CAIE T,-2 ; Don't say it's up when it's still going down
CAIN T,1 ; or when it is broken
JRST IMPOB9
; First check to see if NOP needs to be sent.
AOSG IMNOPC ; Check to see if sending NOPs
JRST IMONOP ; Output a NOP
SETZM IMPUP ; Say IMP is up
SETZM IMPTCU ; Say no longer trying to come up
; Now see whether to check NCP or IP.
IFN INETP,[
SETCMB T,IMPPSW ; Complement IMP output protocol switch
JUMPN T,IMOBNN ; Jump for NCP
PUSHJ P,IPGIOQ ; Check IP! Get IP IMP output queue entry if any
JRST IMOBN ; Nothing there, go check NCP.
; Returns A/ ptr to IP dgm struct
; B/ BLKO pointer to 32-bit words
; C/ Arpanet address
; The output list should be set up as:
;IMOLST: -3,,IMOLDR
;IMOMOD: 2 ; switch to 32-bit mode
;IMOBK1: -1,,IMOLDR+3 ; Send 5th word of padding
;IMOBK2:output BLKO ; Send datagram minus last word
; 1
;IMOBK3: -1,,lstwd-1 ; BLKO to last word of datagram
; 0
IMOBI1:
MOVEM A,IMPODP ; Save ptr to datagram being output
AOS IMNIPO ; # of IP datagrams sent
ADD B,[1,,] ; Reduce BLKO count by one
MOVEM B,IMOBK2 ; Store in output list
HLRO D,B ; Get -<# wds-1>
MOVN D,D ; Get <#wds-1>
ADDI D,(B) ; Get addr for last-word BLKO
HRROM D,IMOBK3 ; Store -1,,lastwd-1
MOVE B,[-3,,IMOLDR]
MOVEM B,IMOLST
MOVE B,[-1,,IMOLDR+3]
MOVEM B,IMOBK1
; Output list set up, now must put together the IMP leader
; in IMOLDR.
MOVE B,[17_10.,,0] ; Regular message
MOVEM B,IMOLDR
LSH C,8. ; Move net address over
IORI C,233 ; Get link # for IP
MOVEM C,IMOLDR+1 ; Store 2nd word
SETZM IMOLDR+2 ; 3rd word can be zero
SETZM IMOLDR+3 ; rest is padding
SETZM IMOLDR+4 ; ditto
IFN KAIMP,CONO IMP,IMO32C
IFN DMIMP,CONO FI,FIO32C ;SET 36 BIT MODE FOR LEADER, CLEAR PIA
DATAO IMP,IMOLDR ; Start it going!
MOVEI C,%ISOID ; State = outputting IP datagram.
JRST IMOB9
IMOBN: SKIPE IMPPSW ; If no IP, check NCP only if havent already
JRST IMOBI9 ; Skip NCP check, just return.
IMOBNN:
] ;INETP
IFN NCPP,[
; Check NCP control message queue.
IFN BLIMPP,[
MOVEI C,IMPNCQ
IMPOBV: SKIPGE A,(C)
JRST IMPOBW
HLRZ H,1(A) ; Got one! Go send NCP control msg,
SKIPL IMPHTB(H) ; unless control link waiting for RFNM
JSP T,IMPBLI ; or too many msgs active for that host.
CAIA
JRST [MOVEI T,(C) ? JRST IMPOB2] ; Compat hack
MOVEI C,(A)
JRST IMPOBV
] ;BLIMPP
.ELSE [
MOVEI T,IMPNCQ
IMPOBV: SKIPGE A,(T)
JRST IMPOBW
HLRZ B,1(A) ;HOST TABLE INDEX
SKIPL IMPHTB(B) ;SKIP IF WAITING FOR RFNM
JRST IMPOB2 ; Got one! Go send NCP control message.
MOVE T,A
JRST IMPOBV
] ;IFE BLIMPP
; Check NCP data output queue. This simply runs through
; all the sockets to see if any want to output something.
IMPOBW: MOVSI I,-IMPSTL
MOVEI W,1
IMPOBB: SKIPGE IMSOC1(I) ;SKIP IF NOT IN USE
TDNN W,IMSOC2(I) ;SKIP IF SEND
JRST IMOBA9
HRRZ A,IMSOC4(I)
CAIN A,%NSOPN ;SKIP IF WRONG STATE
SKIPGE IMSOC6(I) ;SKIP IF NOT LOCKED BY CORE JOB
IMOBA9:
IFE BLIMPP,IMPOBA:
AOBJN I,IMPOBB
IFN BLIMPP,[
JUMPGE I,IMPOB9
LDB H,IMSCFH ; Get fgn host index for this NCP conn
JSP T,IMPBLI ; Make sure not too many active msgs
JRST IMOBA9 ; Sigh, too many, keep looking.
JRST IMPOBD ; OK, can send!
IMPOBA: JSP T,IMPBLD ; Couldn't send data msg after all, decr cnt
JRST IMOBA9
]
.ELSE JUMPL I,IMPOBD ; Got one! Go send NCP data message.
];NCPP
; No more NCP output for IMP.
IMPOB9:
IFN INETP,[
SKIPN IMPPSW ; If we didnt check IP queue yet,
JRST IMOBI9
PUSHJ P,IPGIOQ ; then do it now, after NCP check.
JRST IMOBI9 ; Nothing, really no more output.
JRST IMOBI1 ; Aha, have stuff! Go get it.
IMOBI9:
]
SETOM IMPOAC ; No more output, couldn't find anything to send.
IFN KAIMP,CONO IMP,IMPODC ; Clear Output-Done interrupt bit
IFN DMIMP,CONO FI,FIODC+NETCHN*11
JRST IMPRET
; IMONOP - Send a NOP, here from IMPOBZ only.
IMONOP: MOVEI A,IMPNOP-2
SETZM IMPSVQ ; Set flag => this msg not really from control queue
MOVEI B,1 ; No text, but one extra wd (needed to make BLKO win)
JRST IMPOB3
; NOP Host-IMP leader
IMPNOP: 17_10.,,4_4 ; New format, type 4 = NOP
0
5_10.,,0 ; 5 16-bit words of padding desired
; IMPOB2 - Send a NCP control message, from IMPOBZ only
IMPOB2: HRL A,T
MOVEM A,IMPSVQ ;SAVE CTL MSG QUEUE PNTR
HRRE B,1(A) ;GET COUNT
JUMPG B,IMPOB3
JRST 4,. ;ERROR, COUNT NOT > 0
IMPOB3: ; Entry pt from NOP sending code
IFN KAIMP,CONO IMP,IMO32C
IFN DMIMP,CONO FI,FIO32C ;SET 36 BIT MODE FOR LEADER, CLEAR PIA
DATAO IMP,2(A) ;OUTPUT FIRST LEADER WORD
MOVEI C,2(A) ;SET UP BLKO POINTER FOR REST OF LEADER
SKIPN IMPSVQ
JRST [ HRLI C,-2 ;KLUDGE, SENDING NOP
JRST IMPOB4 ]
HRLI C,-5
AOS IMPMSS+0 ;COUNT REGULAR MSGS SENT
IFN INETP,[
MOVE T,IMPCLP ; HACK! Get specified # to use for ctl link
DPB T,[001000,,3(A)] ; Deposit in link field of leader.
];INETP
IFN NCPP,[
LDB T,[341000,,10(A)] ;FIRST BYTE OF CONTROL MESSAGE
CAIGE T,20
AOS IMPCMS(T)
];NCPP
IMPOB4: MOVEM C,IMOLST ;STORE BLKO POINTER THAT SENDS LEADER
MOVEI C,2 ;DO TEXT WORDS IN 32-BIT MODE
MOVEM C,IMOMOD
IFN DMIMP,MOVNI B,(B) ;GET MINUS WORD COUNT
IFN KAIMP,MOVNI B,-1(B) ;ALSO -1 FOR LAST WORD SENT SEPARATELY.
HRLI B,7(A) ;ADDR-1 FOR BLKO
MOVSM B,IMOBK1 ;STORE FOR PI 1
IFN KAIMP,[
MOVNI B,(B)
ADD B,IMOBK1 ;LAST WORD SENT SEPARATELY
HRROM B,IMOBK3
MOVEI B,3 ;CHECK FOR SCREW CASE, ONLY SENDING ONE WORD, IT'S THE
SKIPL IMOBK1 ; LAST, SO NOP OUT THE MAIN BLKO
MOVEM B,IMOBK1
]
.ELSE MOVEI B,3
MOVEM B,IMOBK2 ;NO 2ND BLKO
MOVEI C,%ISONC ;STATE FOR CONTROL RETURN TO NETCHN
IMOB9: MOVEM C,IMPOS
SETZM IMOPNT
MOVE C,[JSR IMPCH1]
MOVEM C,IMPOLC
IFN KAIMP,[
SETOM IMPOH ;OUTPUT SIDE WANTS IMP TO RUN ON CHANNEL 1
MOVEI A,IMPCHN
MOVEM A,IMPPIA
]
IFN DMIMP,CONO FI,FIOUT+NETCHN_3+IMPCHN ;SET PIA FOR OUTPUT
JRST IMPRET
IFN INETP,[
; Here when IP datagram transmission completed
IMPOBI: SETZM IMPOS ; Reset output state
MOVE A,IMPODP
PUSHJ P,IPIODN ; Tell IP level that datagram was output
SETZM IMPODP
JRST IMPRET
] ;INETP
SUBTTL ARPANET CLOCK LEVEL
OVHMTR IMP ;NETWORK INTERRUPT LEVEL (NOT STYNET STUFF)
IMRSTO: SKIPN IMRFCT ;CALLED AT 15 SEC CLK LEVEL TO UNHANG RFNM WAITS
IFE NCPP,POPJ P,
IFN NCPP,JRST IMFCT1
MOVEI H,LIMPHT-1 ;SOME CONTROL LINKS WAITING FOR RFNM, CHECK FOR TIME OUT
MOVSI TT,401000 ;4.9 AND 4.1 - RFNM AND RRP TIMEOUTS
TDNN TT,IMPHTB(H)
IMRS4: SOJGE H,.-1
IFN NCPP,JUMPL H,IMFCT1
IFE NCPP,JUMPL H,CPOPJ
CONO PI,NETOFF
SKIPE IMPHTN(H) ;MAKE SURE IT'S A REAL HOST, NOT A FREE ENTRY
TDNN TT,IMPHTB(H) ;AND THAT THE BITS DIDN'T TURN OFF DUE TO INTERRUPT
JRST IMRS1
LDB E,[221100,,IMPHTB(H)]
LDB D,[051100,,TIME] ;GET TIME IN SECONDS (APPROX)
CAMLE E,D
ADDI D,1_9
SUB D,E
CAIGE D,IMRFTO_<-5>
JRST IMRS1 ;HASN'T TIMED OUT YET.
LDB D,IMHSBT ;TIMED OUT. CHECK RST/RRP STATUS.
SOJE D,IMRS2
MOVSI D,400000
ANDCAM D,IMPHTB(H) ;RFNM SENT, CLEAR IT
AOS IMNRFN
SOS IMRFCT
BUG INFO,[NET: CTL LNK RFNM TIMEOUT HST],OCT,IMPHTN(H)
IMRS1: CONO PI,NETON
JRST IMRS4
IMRS2: DPB D,IMHSBT ;RST SENT, SET STATE TO DOWN
BUG INFO,[NET: RST TIMEOUT HST=],OCT,IMPHTN(H)
SOS IMRFCT
JRST IMRS1
;NETHST (HOST INFO)
; ARG 1 - HOST => VAL 1 - STATUS, VAL 2 - HOST NUMBER
; ARG 1 - -1 => VAL 1 - (STATUS), VAL 2 - OUR HOST NUMBER
;NOT CURRENTLY IMPLEMENTED- ARG 1 - -1, ARG 2 - OUR GOING-DOWN REASON
ANETHST:HRRE T,A ;LET IMMEDIATE -1 WIN (777777 NOT A VALID HOST)
AOJE T,ANETH2 ;JUMP IF WANT LOCAL STATUS AND HOST NUMBER
MOVE T,A
JSP J,STDHST ;STANDARDIZE AND ERROR-CHECK HOST NUMBER
MOVE B,T ;RETURN NEW FORMAT *******
TLO B,(NW%ARP)
MOVEI H,LIMPHT-1
CONO PI,NETOFF ;DO WE HAVE STATUS?
CAME T,IMPHTN(H)
SOJGE H,.-1
JUMPGE H,ANETH1 ;YES, RETURN IT
CONO PI,NETON ;NO, HAVE TO GO GET IT
MOVEM T,SRN3(U)
IFN NCPP,[
PUSHJ P,NETO00 ;GET IMSOC, RETURN WITH NETLST, IMSOC LOCKED
POPJ P, ;DEVICE FULL OR SOMETHING
PUSHJ P,NETOR ;OPEN COMMUNICATIONS WITH HOST
JFCL ;IT'S DOWN, THAT'S OK
];NCPP
.ELSE POPJ P, ;OH, TOO BAD
ANETH1: MOVE A,IMPHTB(H) ;GET STATUS
CONO PI,NETON
EXCH A,B
CALL CVH2NA ; Convert to HOSTS2 for compat
EXCH A,B
JRST LSWCJ1 ;RETURN IMSOC, NETLST IF NOT DONE ALREADY
ANETH2: ;CAIL W,2 ;(THIS IS A CROCK)
;MOVEM B,NTHDSW ;IF 2 ARGS, SET OUR REASON FOR GOING DOWN.
SKIPE IMPUP ;FAKE UP OUR STATUS
TDZA A,A ;WE'RE DOWN
MOVSI A,2000 ;WE ARE UP
MOVE B,NIFIPA ;AND OUR HOST #.
JRST POPJ1
;NETIMP (REASON,TIMEDOWN,TIMEUP) READ/SET
ANETIMP:JUMPLE W,ANETM1 ;NO ARGS, RETURN
CAIGE W,3 ;MUST HAVE 3 ARGS IF ANY
JRST OPNL30
MOVEM A,IMPDWN
MOVEM B,IMPDWN+1
MOVEM C,IMPDWN+2
JRST POPJ1
ANETM1: MOVE A,IMPDWN
MOVE B,IMPDWN+1
MOVE C,IMPDWN+2
SKIPE IMPUP
TLO A,400000
JRST POPJ1