;;; -*- Mode:MIDAS -*- ;;; Copyright (c) 1999 Massachusetts Institute of Technology ;;; ;;; This program is free software; you can redistribute it and/or ;;; modify it under the terms of the GNU General Public License as ;;; published by the Free Software Foundation; either version 3 of the ;;; License, or (at your option) any later version. ;;; ;;; This program is distributed in the hope that it will be useful, ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ;;; General Public License for more details. ;;; ;;; You should have received a copy of the GNU General Public License ;;; along with this program; if not, write to the Free Software ;;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 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) ];DMIMP 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 ] ; 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==+ ; 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 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. ];DMIMP 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 MOVEI B,IMPUS ;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