1
0
mirror of https://github.com/PDP-10/its.git synced 2026-04-27 12:39:26 +00:00
Files
PDP-10.its/src/system/chaos.289

2787 lines
79 KiB
Plaintext
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.
;;; Copyright (c) 1999 Massachusetts Institute of Technology
;;; See the COPYING file at the top-level directory of this project.
IFE IMPP, IFE CH11P, .ERR NOT EVERYTHING IN CHAOS WILL WORK WITHOUT IMP
IFNDEF FTRCHK, FTRCHK==0 ;PROBABLY FOUND ALL THE BUGS THIS WAS GOOD FOR
; LONG AGO
IFN FTRCHK, .ERR REDUNDANT CHECKING ENABLED IN CHAOS ROUTINES
;NOTES:
; WINDOW SIZE ADJUSTMENT STUFF
; ROUND TRIP TIME MEASUREMENT & OTHER METERING
; BETTER METERING, SOME METERS ARE CURRENTLY MISSING
SUBTTL CH-10 HARDWARE DEFINITIONS
IFN CH10P,[
CHX==470 ;I/O DEVICE NUMBER
;CONI/CONO BITS
;1.1-1.3 PIA
CHXTEN==10 ;1.4 TRANSMIT INTERRUPT ENABLE
CHXREN==20 ;1.5 RECEIVE INTERRUPT ENABLE
CHXSPY==40 ;1.6 MATCH ANY DESTINATION
CHXLUP==100 ;1.7 LOOP BACK
CHXSWB==200 ;1.8 SWAP BYTES
CHXHLF==400 ;1.9 HALFWORD DATAO
CHXXMT==1000 ;2.1 TRANSMIT DONE (CONI)
; TRANSMIT OR RETRANSMIT PACKET (CONO)
CHXRCV==2000 ;2.2 RECEIVE DONE (CONI)
; ENABLE TO RECEIVE NEXT PACKET (CONO)
CHXABT==4000 ;2.3 TRANSMIT ABORTED (CONI)
; RESET TRANSMITTER (CONO)
$CHXLC==140400 ;2.4-2.7 LOST COUNT (CONI)
CHXRST==10000 ;2.4 RESET (CONO)
CHXCRC==200000 ;2.8 CRC ERROR (CONI)
CHXWLE==400000 ;2.9 WORD LENGTH ERROR (CONI)
CHXPLE==1,, ;3.1 PACKET LENGTH ERROR (CONI)
CHXOVR==2,, ;3.2 OVERRUN (CONI)
$CHXAD==242000 ;3.3-4.9 CHAOSNET ADDRESS (CONI)
];CH10P
IFN CH11P,[
$INSRT KSNET
];CH11P
SUBTTL CHAOS NET VARIABLES
EBLK
$CHXRI==001200 ;REAL INDEX PART (LOW TEN BITS) - IS IN LH(IOCHNM)
$CHXUN==120600 ;UNIQUIZATION PART (TOP SIX BITS)
CHXMUN==1_6-1 ;MAXIMUM VALUE OF UNIQUIZER
MXWIND==100 ;MAXIMUM WINDOW SIZE (8K WORDS)
.SEE MYCHAD ;SUBNET AND HOST OF MYSELF
.SEE DLCP ;1 MEANS USE DL10 TO GET TO CHAOS NET
.SEE T11CHP ;1 MEANS USE TEN-11 INTERFACE TO GET TO CHAOS NET
.SEE CH10P ;1 MEANS USE CH10 HARDWARE TO GET TO CHAOS NET
.SEE CH11P ;1 MEANS USE UNIBUS CHAOSNET HARDWARE ON KS10
;Internet address of my Chaosnet Interface
.SEE IMPUS4 ; Should now be defined in CONFIG >
;IMPUS4==<.BYTE 4 ? 0 ? .BYTE 8 ? 128. ? 31. ? .BYTE 16. ? MYCHAD>
;PER-INDEX VARIABLES
CHSUSR: REPEAT NINDX,-1 ;-1 INDEX NOT IN USE
;OTHERWISE RH USER
$CHSUO==220600 ;3.1-3.6 OUTPUT CHANNEL NUMBER (77=IOPUSHED)
$CHSUI==300600 ;3.7-4.3 INPUT CHANNEL NUMBER (77=IOPUSHED)
;4.9 ZERO IF IN USE
CHSSTA: REPEAT NINDX,-1 ;RH STATE, LH FLAGS
%CF==525252(1)
%CFOFF==400000 ;SIGN BIT MEANS TURNED OFF AT PI LEVEL, NO TALKING TO NETWORK
%CFSTS==200000 ;SEND STS PACKET AS SOON AS POSSIBLE (1/2 SECOND CLOCK)
%CFCLS==100000 ;HALF-CLOSED FLAG
%CFSTY==040000 ;DIRECT-CONNECTED TO STTY FLAG
$CFTTN==220600 ;TTY NUMBER OF STTY CONNECTED TO
%CS==,,-1
.SEE %CSCLS ;FOR SYMBOLS FOR STATES
CHSNBF: BLOCK NINDX ;LH LENGTH(CHSPBF), RH LENGTH(CHSIBF)
CHSNOS: BLOCK NINDX ;NUMBER OF FREE OUTPUT SLOTS IN THE WINDOW
CHSIBF: BLOCK NINDX ;RECEIVE BUFFER POINTERS FIRST,,LAST
CHSPBF: BLOCK NINDX ;OUT OF ORDER RECEIVE BUFFER POINTERS FIRST,,LAST
CHSOBF: BLOCK NINDX ;TRANSMIT BUFFER POINTERS FIRST,,LAST
CHSITM: BLOCK NINDX ;TIME OF LAST INPUT FROM NET
CHSWIN: BLOCK NINDX ;WINDOW SIZE RECEIVE,,TRANSMIT
CHSPKN: BLOCK NINDX ;LAST PACKET# GIVEN TO USER,,LAST PACKET# SENT BY USER
CHSACK: BLOCK NINDX ;LAST PACKET# ACKNOWLEDGED RECEIVE,,TRANSMIT (START OF WINDOW)
CHSLCL: REPEAT NINDX,<.BYTE 16. ? MYCHAD ? 100000+.RPCNT>
;BYTE (16) LOCAL HOST, LOCAL INDEX (4) 0
;NOTE THIS SAVES THE UNIQUIZER BITS FOR THIS INDEX
CHSFRN: BLOCK NINDX ;BYTE (16) FOREIGN HOST, FOREIGN INDEX (4) 0
;THESE FOUR ARE FOR BYTE-STREAM I/O
CHSOBP: BLOCK NINDX ;BYTE PNTR TO OUTPUT BUFFER, 0 IF NONE
CHSOBC: BLOCK NINDX ;BYTE COUNT, NUMBER OF BYTE SPACES LEFT IN OUTPUT BUFFER
CHSIBP: BLOCK NINDX ;BYTE PNTR TO INPUT BUFFER, 0 IF NONE
CHSIBC: BLOCK NINDX ;BYTE COUNT, NUMBER OF VALID BYTES REMAINING IN INPUT BUFFER
CHAOSW: -1 ? 0 ;SWITCH FOR ALLOCATING INDICES
CHALCP: 0 ;LAST INDEX ALLOCATED, USED TO CIRCULARIZE ALLOCATION
CHIRFJ: SIXBIT/CHAOS/ ? 0 ;AGENT OF CHAOS
.SEE NETUSW ;NON-ZERO ENABLES RFC'S FROM HOSTS OTHER THAN SELF.
;METERS
CHNPI: 0 ;NUMBER OF PACKETS INPUT (REALLY TO 10)
CHNPO: 0 ;NUMBER OF PACKETS OUTPUT (ALL CAUSES)
CHNPF: 0 ;NUMBER OF PACKETS FORWARDED
CHNSTS: 0 ;NUMBER OF STS PACKETS OUTPUT
CHNSNS: 0 ;NUMBER OF SNS PACKETS OUTPUT
CHNRTR: 0 ;NUMBER OF RETRANSMITTED PACKETS OUTPUT
CHNPFL: 0 ;NUMBER OF PACKETS DISCARDED (FORWARDING LOOP)
CHNPD: 0 ;NUMBER OF PACKETS DISCARDED (DUPLICATES)
CHNIPI: 0 ;NUMBER OF INTERNET PACKETS IN FROM CHAOSNET
CHNIPO: 0 ;NUMBER OF INTERNET FRAGMENTS OUT TO CHAOSNET
;BUFFER QUEUES. EACH HAS A ONE-WORD HEADER, WHICH IS ZERO
;IF IT IS EMPTY, OR CONTAINS FIRST,,LAST BUFFER ADDRESS.
CHQFRE: 0 ;FREE LIST
CHQRFC: 0 ;PENDING RFCS
CHQLSN: 0 ;PENDING LISTENS
CHCLNQ: 0 .SEE CHCLN
CHFRBF: 0 ;NUMBER OF FREE BUFFERS
CHTTBF: 0 ;TOTAL NUMBER OF BUFFERS
IF2 CHMXBF==50.*<1024./<%CPMXW+2>> ;MAX CORE FOR CHAOS NET 50K
CHMXTM: 0 ;TIME OF LAST COMPLAINT ABOUT USING TOO MUCH CORE
IFN T11CHP,[
;VARIABLES FOR TEN-11 INTERFACE CONNECTING TO CHAOS NET
.SEE T11CHS ;EXEC ADDRESS OF PDP11 COMMUNICATION AREA
T11VER=T11CHS ;VERSION NUMBER
T11I10=T11CHS+1 ;INIT 10
T11I11=T11CHS+2 ;INIT 11
T11PRM=T11CHS+3 ;.WORD BUFFER SIZE, # BUFFERS
;THEN 4 SPARE DOUBLEWORDS
T11IBB: T11CHS+8 ;BEGINNING OF INPUT BUFFERS
T11IBE: 0 ;END OF INPUT BUFFERS
T11IBP: 0 ;POINTER TO NEXT INPUT BUFFER
T11OBB: 0 ;BEGINNING OF OUTPUT BUFFERS
T11OBE: 0 ;END OF OUTPUT BUFFERS
T11OBP: 0 ;POINTER TO NEXT OUTPUT BUFFER
T11BSZ: 0 ;BUFFER SIZE IN PDP10 WORDS
T11WIN: 0 ;1 WINNING, -1 HAVE TOLD 11 TO INIT, 0 NOT WINNING
T11XMQ: 0 ;QUEUED TRANSMISSION QUEUE
T11CKE: 0 ;COUNT OF CHECKSUM ERRORS
;THE FIRST 32-BIT WORD OF A BUFFER IS 0 IF IDLE, OR
;NON-ZERO IF BUFFER IS TO BE SENT TO OTHER MACHINE.
;THE SECOND 32-BIT WORD IS THE CHECKSUM, WHICH IS
;COMPUTED BY ADDING ALL THE 32-BIT WORDS, IGNORING OVERFLOW,
; AND LOGICALLY SHIFTING RIGHT ONE BIT AFTER EACH ADD; BITS SHIFTED
; OUT ON THE RIGHT ARE BROUGHT BACK IN ON THE LEFT.
;IF THE NUMBER OF 16-BIT WORDS IS ODD, THE LEFT-OVER ONE BETTER BE 0.
];T11CHP
IFN DLCP,[
;VARIABLES FOR INTERFACE TO CHAOS NET ON PDP11 ON DL10
;.SEE INDICATES A VARIABLE SHARED BETWEEN 10 AND 11
;NOTE THAT THE DL10 HARDWARE LIMITS PACKET LENGTH TO 256 WORDS (1K BYTES)
.SEE DLCINI ;WHEN THE 11 SEES THIS NON-ZERO, IT KNOWS ITS HAS
; BEEN RELOADED AND RESETS ITS PACKET POINTER TO 0
; AND CLEARS DLCINI.
DLCSBF: 0 ;CURRENT BUFFER, 10 SEND SIDE (1 OR 0)
DLCSA1: 0 ;ADDRESS OF PACKET BEING SENT
DLCSA2: 0 ;DITTO, SECOND BUFFER
.SEE DLCSP1 ;POINTER USED BY PDP11 TO COPY PACKET (16-BIT BYTES)
.SEE DLCSP2 ;DITTO, SECOND BUFFER
.SEE DLCSS1 ;STATE FOR BUFFER 1, 0 IDLE, 1 SENT TO 11, 2 11 DONE
.SEE DLCSS2 ;STATE FOR BUFFER 2
DLCRA1: 0 ;ADDRESS OF PACKET BUFFER RECEIVING A PACKET
DLCRA2: 0 ;DITTO, SECOND BUFFER
.SEE DLCRP1 ;POINTER USED BY PDP11 TO COPY PACKET (16-BIT BYTES)
.SEE DLCRP2 ;DITTO, SECOND BUFFER
.SEE DLCRS1 ;STATE FOR BUFFER 1, 0 IDLE, 1 AWAITING 11, 2 CONTAINS A PACKET
.SEE DLCRS2 ;STATE FOR BUFFER 2
DLCXMQ: 0 ;TRANSMIT BUFFER LIST FOR DL10
;NOTE THAT THIS IS NOT A REGULAR BUFFER LIST SINCE
;IT IS THREADED THROUGH LH INSTEAD OF RH. WE DO MAINTAIN
;POINTERS TO FIRST,,LAST HOWEVER
];DLCP
IFN CH10P,[
;VARIABLES FOR CH10 INTERFACE ONLY
CHXCNO: CHXREN+CHXTEN+CHXCHN ;CONO BITS CURRENTLY IN EFFECT
];CH10P
IFN CH11P,[
;VARIABLES FOR CH11 INTERFACE ONLY
CHXCSR: %CAREN+%CATEN ;CURRENT BITS WANTED IN CSR
];CH11P
IFN CH10P+CH11P,[
;VARIABLES THAT WOULD OTHERWISE BE IN THE FRONT-END
CHXXMQ: 0 ;HEAD,,TAIL OF TRANSMIT QUEUE
CHOSTA: 0 ;OUTPUT STATUS: 0 IDLE, ELSE NUMBER OF TRANSMISSIONS
NCHRTR==4 ;TRANSMIT UP TO 4 TIMES IN FACE OF COLLISIONS
;ROUTING STUFF
NSUBNT==122. ;122 is maximum possible
SBNRUT: REPEAT NSUBNT, 1000,,3040 ;COST,,GATEWAY ADDRESS
;EXTRA METERS
CHNABT: 0 ;NUMBER OF TRANSMIT ABORTS
CHNCRC: 0 ;NUMBER OF CRC ERRORS BEFORE READING PACKET
CHNCR2: 0 ;NUMBER OF CRC ERRORS AFTER READING PACKET
CHNWLE: 0 ;NUMBER OF WORD LENGTH ERRORS (NOT MULTIPLE OF 16 BITS)
CHNPLE: 0 ;NUMBER OF PACKET LENGTH ERRORS (DISAGREES WITH LENGTH IN HEADER)
CHNLOS: 0 ;NUMBER OF PACKETS LOST DUE TO RECEIVER BUSY
];CH10P+CH11P
IFN CH11P,[
CHNSPZ: 0 ;NUMBER OF TIMERS BIT COUNTER SPAZZED
];CH11P
BBLK
;Get definitions of packet format
IF1,[
$INSRT CHSDEF
PKTBSZ==%CPMXW+2 ;PACKET BUFFER IS 2 HEADER WORDS + MAX SIZE PACKET
IFN <PKTBSZ&<-PKTBSZ>>-PKTBSZ, .ERR PKTBSZ IS SUPPOSED TO BE A POWER OF 2
$CPKSX==$CHXRI+40000,,2 ;REAL PART OF SOURCE INDEX
$CPKDX==$CHXRI+40000,,1 ;REAL PART OF DESTINATION INDEX
];IF1
;;; Debugging Info
;;; This contains the last N headers received from the network
NRECHD==20
EBLK
RECHDP: RECHDR ;POINTER TO NEXT
RECHDR: BLOCK NRECHD*%CPKDT
BBLK
SUBTTL CHAOS NET OPEN (.CALL CHAOSO)
;.CALL CHAOSO,RCVCHN,XMTCHN,<RECEIVE,,TRANSMIT>
CHASO: JRST OPNL12 ; Say "mode not avail"
CHAOSO: HRRZS A
HRRZS B
CAIGE A,20
CAIL B,20
JRST OPNL14 ;BAD CHANNEL NUMBER ARGUMENT
CAMN A,B
JRST OPNL33 ;BOTH CHANNELS SAME IS ILLEGAL
PUSH P,A ;SAVE ARGS, CLOSE THE SPECIFIED CHANNELS
PUSH P,B
PUSH P,C
MOVE R,A
ADDI R,IOCHNM(U)
PUSHJ P,CCLOSE
MOVE R,-1(P) ;B
ADDI R,IOCHNM(U)
PUSHJ P,CCLOSE
POP P,C
POP P,B
POP P,A
MOVE U,USER ;TO SAVE ULCERS
HRRZM A,UUAC(U) ;REMEMBER INPUT CHNL # FOR ERRS
PUSHJ P,SWTL ;LOCK CHAOS INDEX ASSIGNMENT SWITCH
CHAOSW
MOVE I,CHALCP ;ALLOCATE AN INDEX
SOJL I,CHASO2
CHASO1: SKIPL CHSUSR(I)
SOJGE I,CHASO1
JUMPGE I,CHASO3
CHASO2: MOVEI I,NINDX ;REACHED BEGINNING, WRAP AROUND TO END
CAMN I,CHALCP
JRST OPNL6 ;ALL INDICES IN USE
MOVEM I,CHALCP
SOJA I,CHASO1
CHASO3: MOVEM I,CHALCP ;SAVE SCAN POINTER FOR NEXT TIME
PUSHJ P,CHASO4 ;INIT VARIOUS STUFF
CAILE C,MXWIND ;SET UP WINDOW SIZE
MOVEI C,MXWIND ;DON'T LET USER USE UP TOO MUCH WIRED CORE
HRLZM C,CHSWIN(I)
HRRZM U,CHSUSR(I) ;VARIABLES INITIALIZED, MAKE INDEX IN USE.
DPB A,[$CHSUI,,CHSUSR(I)]
DPB B,[$CHSUO,,CHSUSR(I)]
HRLZ T,I ;SET UP USER'S IOCHNM WORDS
HRRI T,CHAIDN
ADDI A,IOCHNM(U)
MOVEM T,(A)
HRRI T,CHAODN
ADDI B,IOCHNM(U)
MOVEM T,(B)
JRST LSWPJ1 ;SUCCESS RETURN
;INITIALIZE CONNECTION IN I
CHASO4: SETZM CHSNBF(I)
SETZM CHSNOS(I)
SETZM CHSIBF(I)
SETZM CHSPBF(I)
SETZM CHSOBF(I)
SETZM CHSACK(I)
SETZM CHSPKN(I) ;START PACKET NUMBERING AT ONE
SETZM CHSOBP(I)
SETZM CHSOBC(I)
SETZM CHSIBP(I)
SETZM CHSIBC(I)
MOVSI T,%CFOFF .SEE %CSCLS
MOVEM T,CHSSTA(I)
LDB TT,[$CHXUN+40000,,CHSLCL(I)]
CAIE TT,CHXMUN ;INCREMENT THE UNIQUIZER
AOSA TT
MOVEI TT,1 ;BUT MAKE SURE IT ISN'T ZERO
DPB TT,[$CHXUN+40000,,CHSLCL(I)]
SETZM CHSFRN(I)
POPJ P,
SUBTTL CHAOS NET CLOSE, FINISH, WHYINT, NETBLK, CHAOSQ
;CLOSE A CHAOS CHANNEL.
CHACLS: HLRZ I,(R) ;GET VARIABLES INDEX
MOVSI A,%CFCLS
TDNN A,CHSSTA(I) ;ONLY REALLY CLOSE WHEN BOTH CHANNELS CLOSED
JRST CHACS7
PUSHJ P,CHACS1 ;FLUSH ALL BUFFERS OF THIS CONNECTION
HRRZ T,CHSSTA(I)
CAIN T,%CSOPN
PUSHJ P,CHABGI ;SEND A CLS IF OPEN AND MEM AVAIL
JRST CHACS4
MOVE T,CHSFRN(I)
MOVEM T,%CPKS(A)
MOVE T,CHSLCL(I)
MOVEM T,%CPKD(A)
MOVEI B,[ASCIZ/Channel closed/]
PUSHJ P,CHIRF2
CHACS4: CONO PI,NETOFF
SETZM (R) ;CLOSE THIS CHANNEL
SETOM CHSUSR(I) ;RETURN INDEX
MOVE W,CHQLSN ;FLUSH ANY PENDING LSN PACKET
SETZM CHQLSN
CHACS5: MOVEI Q,W ;GET NEXT PACKET OFF OLD LIST
PUSHJ P,CHAQGF
JUMPE A,NETONJ ;EXHAUSTED
LDB B,[$CPKSX(A)] ;GET OWNER
CAME B,I
JRST [ MOVEI Q,CHQLSN ;NOT THIS INDEX, PUT BACK
PUSHJ P,CHAQPL
JRST CHACS5 ]
PUSHJ P,CHABRT ;FREE
JRST CHACS5
CHACS7: IORM A,CHSSTA(I) .SEE %CFCLS
HRRZ B,(R) ;GET DIRECTION
CAIN B,CHAIDN ;AS A BYTE POINTER TO CHANNEL NUMBER
SKIPA B,[$CHSUI,,CHSUSR(I)]
MOVE B,[$CHSUO,,CHSUSR(I)]
MOVEI T,77 ;CLOSE THAT CHANNEL
DPB T,B
SETZM (R)
POPJ P,
;THIS FLUSHES ALL BUFFERS FOR CONNECTION IN I
CHACS1: MOVSI A,%CFOFF ;INHIBIT RETRANSMISSIONS
IORB A,CHSSTA(I)
LDB E,[$CFTTN,,CHSSTA(I)]
EXCH E,I
TLNE A,%CFSTY
PUSHJ P,NSTYN0 ;DISCONNECT FROM STY
JFCL
EXCH E,I
IFN DLCP,[
MOVEI Q,DLCXMQ ;REMOVE THIS INDEX'S BUFFERS FROM DL10 TRANSMIT LIST
PUSHJ P,CFLXMQ
];DLCP
IFN T11CHP,[
MOVEI Q,T11XMQ ;REMOVE THIS INDEX'S BUFFERS FROM TEN11 TRANSMIT LIST
PUSHJ P,CFLXMQ
];T11CHP
IFN CH10P+CH11P,[
MOVEI Q,CHXXMQ ;REMOVE THIS INDEX'S BUFFERS FROM CH10 TRANSMIT LIST
PUSHJ P,CFLXMQ
];CH10P+CH11P
MOVEI Q,CHSIBF(I) ;RETURN RECEIVE BUFFERS
PUSHJ P,CHALFR
MOVEI Q,CHSPBF(I) ;RETURN OUT OF ORDER RECEIVE BUFFERS
PUSHJ P,CHALFR
MOVEI Q,CHSOBF(I) ;RETURN TRANSMIT BUFFERS
PUSHJ P,CHALFR
IFE FTRCHK,[
SKIPE A,CHSOBP(I) ;RETURN STREAM I/O BUFFERS
PUSHJ P,CHBPFR
SKIPE A,CHSIBP(I)
PUSHJ P,CHBPFR
];FTRCHK
IFN FTRCHK,[
SKIPN A,CHSOBP(I)
JRST .+3
SETZM CHSOBP(I)
PUSHJ P,CHBPFR
SKIPN A,CHSIBP(I)
JRST .+3
SETZM CHSIBP(I)
PUSHJ P,CHBPFR
];FTRCHK
POPJ P,
;.CALL FORCE ON A CHAOS OUTPUT CHANNEL.
CHAFRC: HLRZ I,(R)
SKIPGE CHSSTA(I) .SEE %CFOFF
JRST OPNL7 ;DEVICE NOT READY
AOS (P) ;WILL TAKE SUCCESS RETURN
CHAFC1: SKIPN A,CHSOBP(I)
POPJ P, ;NO BUFFERED OUTPUT TO BE FORCED
SUBI A,1 ;SIOKT LIKES TO POINT BP AT NEXT BUFFER
ANDI A,-PKTBSZ ;GET PACKET POINTER
ADDI A,2
MOVSI T,(SETZ) ;DATA OPCODE
MOVEM T,(A) .SEE $CPKOP
MOVEI T,%CPMXC ;SET BYTE COUNT
SUB T,CHSOBC(I)
DPB T,[$CPKNB(A)]
PUSHJ P,[JUMPN T,CHODT1 ;IF THERE IS ANYTHING IN THE BUFFER, TRANSMIT IT
JRST CHABRT ] ;OTHERWISE, JUST THROW IT AWAY
SETZM CHSOBP(I) ;NOW THERE IS NO BUFFER
SETZM CHSOBC(I)
POPJ P,
;.CALL FINISH ON A CHAOS OUTPUT CHANNEL. WAIT FOR ALL BUFFERS
;ON SEND LIST TO GET SENT AND ACKNOWLEDGED.
;HANGS FOREVER IF SOCKET GETS INTO AN IMPROPER STATE, BUT YOU SHOULD GET AN INTERRUPT
CHAFIN: HLRZ T,(R)
PUSHJ P,[HRRZ A,CHSWIN(T)
CAMG A,CHSNOS(T)
AOS (P)
POPJ P, ]
PUSHJ P,UFLS
JRST POPJ1
;.CALL WHYINT ON A CHAOS CHANNEL.
;RESULTS ARE: A/ %WYCHA
; B/ STATE
; C/ LH NUMBER OF INPUT PACKETS AVAILABLE
; RH NUMBER OF OUTPUT SLOTS AVAILABLE
; D/ WINDOW SIZE (RECEIVE,,TRANSMIT)
; E/ INPUT CHNL#,,OUTPUT CHNL#
CHAWHY: HLRZ I,(R)
MOVEI A,%WYCHA
HRRZ B,CHSSTA(I)
HRLZ C,CHSNBF(I) ;NUMBER OF PACKETS AVAILABLE
SKIPE CHSIBP(I)
ADD C,[1,,] ;ADD 1 IF PARTIALLY-READ INPUT BUFFER EXISTS
MOVSI D,%CFSTY
TDNE D,CHSSTA(I)
MOVEI C,0 ;NO INPUT AVAILABLE IF DIRECT-CONNECTED
SKIPLE CHSNOS(I)
HRR C,CHSNOS(I)
MOVE D,CHSWIN(I)
LDB E,[$CHSUO,,CHSUSR(I)]
CAIN E,77
MOVEI E,-1
LDB T,[$CHSUI,,CHSUSR(I)]
CAIN T,77
TLOA E,-1
HRL E,T
JRST POPJ1
;.CALL RFNAME on a CHAOS channel. A contains index.
;Returns results analogous to RFNAME on TCP: and (almost) RFNAME on NET:.
;"FN1" is local index, "FN2" is foreign index, "SNAME" is foreign host
;number in HOSTS3 format.
CHARCH: LDB B,[042000,,CHSLCL(A)]
LDB C,[042000,,CHSFRN(A)]
LDB D,[242000,,CHSFRN(A)]
TLO D,(NW%CHS)
POPJ P,
;IOPDL ROUTINES. I IS 0 FOR IOPUSH, 1 FOR IOPOP. R POINTS AT IOCHNM WORD.
;C(R) IS SET UP TO THIS DEVICE IN EITHER CASE.
CHAIOP: HRRZ T,R ;DISCOVER CHANNEL NUMBER
SUBI T,IOCHNM(U)
SKIPN I
MOVEI T,77 ;IOPUSH, USE 77
HLRZ I,(R) ;GET CHAOS INDEX
HRRZ B,(R) ;GET DIRECTION
CAIN B,CHAIDN ;AS A BYTE POINTER TO CHANNEL NUMBER
SKIPA B,[$CHSUI,,CHSUSR(I)]
MOVE B,[$CHSUO,,CHSUSR(I)]
DPB T,B ;ADJUST SAVED CHANNEL NUMBER
POPJ P,
;.CALL NETBLK ON A CHAOS CHANNEL.
;ARG 1 - CHANNEL (COMES IN IN R)
;ARG 2 - UNDESIRED STATE
;ARG 3 - OPTIONAL TIMEOUT, WRITTEN BACK UNLESS IMMEDIATE
;VAL 1 - NEW STATE
;VAL 2 - TIME LEFT
CHANBK: HRRZ T,(R)
CAIL T,CHAIDN
CAILE T,CHAODN
IFN NCPP, JRST ANETBL ;NOT A CHAOS CHANNEL, TRY ARPANET
IFE NCPP, JRST OPNL34
HLRZ I,(R)
MOVE T,I ;SAVE INDEX IN T FOR FLSINS
CAIGE W,3
JRST [ HRLOI D,377777 ;NO TIME GIVEN, USE INFINITY
JRST CHANB4 ]
TLNE C,1000 ;SKIP IF POINTER RATHER THAN IMMEDIATE
JRST [ HRRZ D,C ;GET IMMEDIATE TIME
ADD D,TIME
JRST CHANB4 ]
XCTR XRW,[MOVES D,(C)] ;GET TIME, CHECK WRITEABILITY
JUMPGE D,[ MOVNS D ;RELATIVE TIME, MAKE NEGATIVE ABSOLUTE
SUB D,TIME
JRST .+1 ]
UMOVEM D,(C) ;STORE BACK ABSOLUTE TIME
MOVNS D ;MAKE POSITIVE
CHANB4: MOVEM D,AC0S+D(U) ;SAVE ABSOLUTE TIME TO WAIT UNTIL
MOVEM B,AC0S+B(U) ;SAVE UNDESIRED STATE
PUSHJ P,CHANB2 ;SKIP IF STATE CHANGE OR TIMEOUT
PUSHJ P,UFLS
MOVE B,D
SUB B,TIME ;HOW MUCH USED?
HRRZ A,CHSSTA(I) ;NEW STATE
JRST POPJ1
CHANB2: HRRZ A,CHSSTA(T) ;CURRENT STATE
CAME A,AC0S+B(U) ;SKIP IF STILL MATCH
JRST POPJ1
MOVE A,AC0S+D(U) ;TIMEOUT TIME
CAMG A,TIME
AOS (P)
POPJ P,
;.CALL CHAOSQ
;ARG 1 - ADDRESS OF A %CPMXW-WORD PACKET BUFFER
;FINDS THE FIRST PACKET ON THE PENDING-RFC QUEUE, COPIES IT
;INTO THE USER'S BUFFER, AND RETURNS IT TO THE QUEUE.
CHAOSQ: MOVE C,A ;SAVE POINTER TO USER'S BUFFER
HRL A,A ;MAKE SURE USER'S BUFFER IS SWAPPED IN
XCTR XBRW,[BLT A,%CPMXW-1(C)] ;AND NO MAR BREAK SET
MOVEI Q,CHQRFC ;GET FIRST PACKET ON RFC QUEUE
PUSHJ P,CHAQGF
JUMPE A,OPNL4 ;QUEUE IS EMPTY
PUSHJ P,CHAQPL ;PUT BACK AT END OF QUEUE
HRL C,A ;COPY PACKET TO USER
MOVE T,C
XCTR XBW,[BLT T,%CPMXW-1(C)]
JRST POPJ1
SUBTTL CHAOS NET IOT ROUTINES
;.CALL PKTIOT. ARG1 CHANNEL, ARG2 ADDRESS OF %CPMXW-WORD BUFFER
PKTIOT: HRRZ A,(R)
CAIN A,CHAODN
JRST CHPKO
CAIE A,CHAIDN
JRST OPNL34 ;WRONG TYPE DEVICE
;CHAOSNET INPUT PKTIOT
;B POINTS TO %CPMXW-WORD PACKET BUFFER
CHPKI: PUSHJ P,CHAIOS ;SET UP I, E
HLRZ A,CHSIBF(I) ;GET FIRST RECEIVE BUFFER
JUMPE A,[PUSHJ P,CHPKI0 ;LIST EMPTY
JRST CHPKI ]
HRL B,A ;COPY TO USER BEFORE REMOVING FROM LISTS
LDB T,[$CPKNB(A)] ;GET SIZE OF PACKET
ADDI T,4*%CPKDT+3 ;HEADER PLUS ROUND-UP TO NEXT WORD BOUNDARY
LSH T,-2 ;CONVERT BYTES TO WORDS
ADDI T,-1(B) ;ADDRESS OF LAST DESTINATION WORD
XCTR XBW,[BLT B,(T)]
LDB TT,[$CPKOP(A)] ;GET OPCODE
CAIGE TT,%CODAT ;ACKNOWLEDGE IF DATA
CAIN TT,%COEOF ;OR EOF MARK
PUSHJ P,CHPKIA
SOS CHSNBF(I) ;NOW REMOVE BUFFER FROM RECEIVE LIST
MOVEI Q,CHSIBF(I)
PUSHJ P,CHAQGF
PUSHJ P,CHABRT ;AND RETURN TO FREE
JRST POPJ1 ;SUCCESS
;INPUT WITH INPUT BUFFER EMPTY. MUSTN'T BASH B,C,E.
CHPKI0: SKIPGE CHSSTA(I) .SEE %CFOFF
JRST [ HRRZ T,CHSSTA(I)
CAIE T,%CSFRN ;CHAOSNET OR FOREIGN PROTOCOL?
JRST IOCR10 ;IOT WITH CHANNEL IN IMPROPER STATE
JRST .+1 ] ;WAIT BUT DON'T TRY TO TOUCH WINDOW SIZE
;HERE CONSIDER INCREASING WINDOW SIZE
SKIPN CHSIBF(I) ;AWAIT INPUT
PUSHJ P,UFLS
POPJ P, ;RETRY
;ACKNOWLEDGE DATA PACKET IN A. ITS OPCODE IN TT.
CHPKIA: LDB T,[$CPKPN(A)] ;GET PACKET #
HRLM T,CHSPKN(I) ;IT NOW NEEDS TO BE ACKNOWLEDGED
CAIN TT,%COEOF ;ALWAYS ACKNOWLEDGE EOF RIGHT AWAY
JRST CHASTO
HLRZ TT,CHSACK(I) ;GET LAST ONE REALLY ACKNOWLEDGED
SUB T,TT ;GET NUMBER OF PACKETS AWAITING ACK
SKIPGE T
ADDI T,200000
IMULI T,3 ;MORE THAN ONE THIRD THE WINDOW SIZE?
IFN FTRCHK,[
MOVE TT,-1(A)
CAMN TT,[ASCII/LUNCH/]
BUG PAUSE,[CHAOS BUFFER ADDRESS TRASHED],OCT,A
];FTRCHK
HLRZ TT,CHSWIN(I)
CAML T,TT
PUSHJ P,CHASTO ;YES, SEND ACK (CAN'T PCLSR)
POPJ P,
;SET UP FOR CHAOS IOT
CHAIOS: HLRZ I,(R) ;GET INDEX
MOVE E,CHSSTA(I)
TLNE E,%CFSTY+%CFCLS
JRST IOCR10 ;CAN'T DO I/O WHILE DIRECT-CONNECTED OR HALF-CLOSED
HRRZS E ;RETURN STATE IN E
POPJ P,
;UNIT-MODE INPUT.
;1.4 IN CTLBTS IS DON'T-HANG MODE
SKIPA T,[SIOKT]
CHAUI: MOVEI T,CHRKT
PUSHJ P,CHAIOS ;SET UP I, E
MOVE E,[440800,,4]
JSP B,(T)
CHSIBP(I)
CHSIBC(I)
CHAIBG
CHAIBD
0
TRNA
;CHAOS INPUT BUFFER DISCARD
CHAIBD: SKIPN A,CHSIBP(I)
POPJ P,
SETZM CHSIBP(I)
SETZM CHSIBC(I)
JRST CHBPFR
;CHAOS INPUT BUFFER GET
CHAIBG: HLRZ A,CHSIBF(I) ;GET FIRST RECEIVE BUFFER
JUMPE A,CHAIB2 ;NONE
LDB TT,[$CPKOP(A)] ;IS IT NORMAL DATA?
CAIE TT,%CODAT
JRST CHAIB1 ;NO
PUSHJ P,CHAIB3 ;YES, ACKNOWLEDGE AND REMOVE FROM LIST
LDB J,[$CPKNB(A)] ;SET UP FOR BYTE STREAM INPUT
MOVEI TT,%CPKDT(A)
JRST SIOBG1
CHAIB3: PUSH P,B
PUSH P,C
PUSH P,E
PUSHJ P,CHPKIA ;SEND ACKNOWLEDGEMENT
POP P,E
POP P,C
POP P,B
SOS CHSNBF(I) ;REMOVE BUFFER FROM RECEIVE LIST
MOVEI Q,CHSIBF(I)
JRST CHAQGF
CHAIB1: CAIE TT,%COEOF
JRST CHAIB2
PUSHJ P,CHAIB3 ;EOF PACKET, ACKNOWLEDGE IT
PUSHJ P,CHABRT ;RETURN IT TO FREE
JRST POPJ2 ;AND SIGNAL EOF
CHAIB2: MOVE TT,CTLBTS(U) ;CHECK DON'T-HANG MODE
TRNE TT,10
JRST POPJ2 ;YES, EOF
JUMPN A,IOCR10 ;NO, ABNORMAL PACKET, BARF
PUSHJ P,CHPKI0 ;AWAIT INPUT
JRST CHAIBG ;RETRY
;UNIT-MODE OUTPUT.
;1.4 IN CTLBTS IS DON'T-HANG MODE
SKIPA T,[SIOKT]
CHAUO: MOVEI T,CHRKT
PUSHJ P,CHAIOS ;SET UP I, E
CAIE E,%CSOPN
JRST IOCR10 ;NOT OPEN, ERROR
MOVE E,[440800,,4]
JSP B,(T)
SETZ CHSOBP(I)
CHSOBC(I)
CHAOBG
CHAOBW
0
TRNA
;GET NEW OUTPUT BUFFER
CHAOBG: SKIPG CHSNOS(I) ;WINDOW FULL
PUSHJ P,[ MOVE TT,CTLBTS(U)
TRNN TT,10
JRST UFLS
SUB P,[1,,1]
JRST POPJ2 ] ;DON'T HANG MODE, RETURN "EOF"
PUSH P,B
PUSHJ P,CHABGT ;SET UP AN OUTPUT BUFFER
POP P,B
MOVEI TT,%CPKDT(A)
MOVEI J,%CPMXC
JRST SIOBG1
;WRITE OUTPUT BUFFER
CHAOBW: PUSH P,B
PUSH P,C
PUSH P,E
PUSHJ P,CHAFC1
POP P,E
JRST POPCBJ
;CHAOSNET OUTPUT PKTIOT.
;B POINTS TO %CPMXW-WORD PACKET BUFFER
CHPKO: PUSHJ P,CHAIOS ;SET UP I, E
UMOVE H,(B) ;GET HEADER WORD OF USER'S PACKET BUFFER
LDB D,[$CPKNB H] ;GET BYTE COUNT
CAIG D,%CPMXC
TLNE H,(.BM $CPKMV) ;WE DON'T SUPPORT MUPPETS ANY MORE
JRST IOCER3 ;BYTE LENGTH OUT OF BOUNDS
ADDI D,4*%CPKDT+3 ;CONVERT BYTES TO WORDS, INCLUDING HEADER WDS
LSH D,-2
MOVSI J,1(B) ;SAVE ADDRESS+1 OF USER'S PACKET
PUSHJ P,CHABGT ;GET A BUFFER
PUSHJ P,LOSSET ;RETURN IT IF PCLSR
CHPKO2
MOVEM H,(A) ;STORE PACKET HEADER, NOT STORED WITH BLT
HRRI J,1(A) ; BECAUSE MIGHT HAVE CHANGED AFTER ERROR CHECK
ADDI D,-1(A)
XCTR XBR,[BLT J,(D)] ;COPY USER'S PACKET INTO SYSTEM
AOS (P) ;GOING TO SUCCEED
SKIPGE (A) ;SKIP IF CONTROL PACKET
JRST CHODAT ;DATA
LDB D,[$CPKOP(A)] ;GET OPCODE
CAIGE D,%COMAX ;DISPATCH ON IT
JRST @.+1(D)
OFFSET -.
JRST IOCER3 ;OPCODE OUT OF BOUNDS
%CORFC::JRST CHORFC
%COOPN::JRST CHOOPN
%COCLS::JRST CHOCLS
%COFWD::JRST CHOFWD
%COANS::JRST CHOFWD
%COSNS::JRST IOCER3
%COSTS::JRST IOCER3
%CORUT::JRST IOCER3
%COLOS::JRST IOCER3
%COLSN::JRST CHOLSN
%COMNT::JRST IOCER3
%COEOF::JRST CHOEOF
%COUNC::JRST CHOUNC
%COBRD::JRST IOCER9 ;UNTIL I IMPLEMENT IT
%COMAX::OFFSET 0
;LOSSET ROUTINE TO RETURN BUFFER A POINTS TO.
CHPKO2: MOVE A,AC0S+A(U)
PUSH P,Q ;MAY CLOBBER ONLY A AND T
PUSHJ P,CHABRT
JRST POPQJ
;SENDING %COEOF (END-FILE MARK)
CHOEOF: CAIE E,%CSOPN ;CONNECTION MUST BE OPEN
JRST IOCR10
SKIPG CHSNOS(I)
PUSHJ P,UFLS ;WINDOW FULL, WAIT
JRST CHOOP1 ;SEND RETRANSMITTABLE CONTROL PACKET
;SENDING REQUEST FOR CONNECTION
CHORFC: PUSHJ P,CHORF1 ;RE-INITIALIZE CONNECTION
MOVSI B,777774 ;SAVE DESTINATION HOST, CLEAR OTHER BITS
ANDB B,%CPKD(A)
MOVEM B,CHSFRN(I)
MOVEI E,%CSRFS ;PUT INTO RFC-SENT STATE
JRST CHOOP1 ;GO SEND
;RE-INITIALIZE CONNECTION WHEN USER OUTPUTS RFC OR LSN
;FLUSHES ANY OLD PACKET BUFFERS, CHANGES UNIQUIZER IN INDEX#
CHORF1: JUMPN E,IOCR10 .SEE %CSCLS ;CONNECTION MUST BE CLOSED
PUSH P,A
PUSH P,B
PUSHJ P,CHACS1 ;FLUSH BUFFERS FROM CONNECTION
PUSHJ P,CHASO4 ;REINITIALIZE VARIABLES
JRST POPBAJ
;"SENDING" LISTEN
CHOLSN: PUSHJ P,CHORF1
PUSHJ P,LSWDEL ;GOING TO USE PACKET
MOVEI E,%CSLSN ;PUT INTO LISTENING STATE
HRRM E,CHSSTA(I)
MOVEI Q,CHQRFC ;NOW SEARCH PENDING-RFC QUEUE
CONO PI,NETOFF
PUSHJ P,CHAQSR
JRST [ CONO PI,NETON ;NO MATCH, PUT ONTO LISTENING QUEUE
MOVEI Q,CHQLSN
MOVE T,CHSLCL(I)
MOVEM T,%CPKS(A)
JRST CHAQPL ]
PUSHJ P,CHIRF0 ;MATCH, JOIN INTERRUPT LEVEL CODE
JRST NETONJ
;SENDING OPEN
CHOOPN: CAIE E,%CSRFC ;CONNECTION MUST BE RFC-RECEIVED
JRST IOCR10
MOVEI TT,4 ;SET BYTE COUNT TO 4
DPB TT,[$CPKNB(A)]
PUSHJ P,DPBRCP ;INCLUDE RECEIPT
HLRZ B,CHSWIN(I) ;INCLUDE WINDOW SIZE
DPB B,[042000,,%CPKDT(A)]
MOVEI E,%CSOPN ;MAKE IT OPEN
;HERE TO SEND A RETRANSMITTABLE CONTROL PACKET (RFC OR OPN), NEW STATE IN E
;THIS PACKET WILL GET TAKEN OFF THE CHSOBF LIST BY RECEIPT IN THE NORMAL WAY
;THIS CODE COPIED FROM CHODAT WITH SOME MODIFICATIONS
CHOOP1: MOVE T,TIME ;UPDATE CHSITM SO WON'T THINK HOST IS DOWN
MOVEM T,CHSITM(I)
MOVEM E,CHSSTA(I) ;AND CLEAR %CFOFF (NO OTHER LH FLAGS CAN BE ON)
PUSHJ P,LSWDEL ;BUFFER WILL BE USED
HRRZ B,CHSPKN(I) ;ASSIGN PACKET NUMBER
CAIL B,177777
TDZA B,B
ADDI B,1
HRRM B,CHSPKN(I)
DPB B,[$CPKPN(A)]
HLRZ B,CHSPKN(I) ;GET PACKET NUMBER TO ACKNOWLEDGE
HRLM B,CHSACK(I) ;REMEMBER IT HAS BEEN
DPB B,[$CPKAN(A)] ;PIGGY-BACK THIS ACKNOWLEDGE
MOVE B,[<.BM $CPKOP>+<.BM $CPKNB>]
ANDM B,(A) ;CLEAR FORWARDING COUNT AND UNUSED FIELD
MOVE B,CHSLCL(I) ;SET UP SOURCE
MOVEM B,%CPKS(A)
MOVE D,CHSFRN(I) ;SET UP DESTINATION
MOVEM D,%CPKD(A)
SETOM -2(A) ;NOTE NOT ON TRANSMIT LIST YET
CONI PI,E ;SUPER KLUDGERY REQUIRED HERE! FOREIGN HOST MIGHT RECEIPT
CONO PI,NETOFF ;THIS PACKET JUST AS WE START TO TRANSMIT IT. THIS IS A
;VIOLATION OF PROTOCOL, BUT SHOULDN'T CRASH I.T.S. BECAUSE THE
;PACKET ABOUT TO BE GIVEN TO CHAXMT HAS BEEN FREED ALREADY.
MOVEI Q,CHSOBF(I) ;PUT ON END OF SEND LIST
PUSHJ P,CHAQPL
JRST CHAXM0 ;GO TRANSMIT
;SENDING CLOSE
CHOCLS: CAIE E,%CSOPN ;CONNECTION MUST BE OPEN
;SEND FWD OR ANS
CHOFWD: CAIN E,%CSRFC ; OR RFC-RECEIVED
TLOA E,%CFOFF ;PUT IT INTO THE CLOSED STATE
JRST IOCR10
HLLZM E,CHSSTA(I) .SEE %CSCLS
PUSHJ P,LSWDEL ;BUFFER WILL BE USED
JRST CHODT2 ;GO TRANSMIT
;Here for transmitting an UNC packet. It could be part of a connection
;or it could be foreign-protocol mode. In any case transmit it without
;munging the header very much.
CHOUNC: CAIN E,%CSFRN
JRST CHOUN1 ;Okay to transmit UNC now
CAIN E,%CSOPN
JRST CHOUN2
JUMPN E,IOCR10 .SEE %CSCLS ;Bad state
SKIPE CHSPBF(I) ;I guess out of order packets would
JRST IOCR10 ; cause some confusion in the NCP.
MOVE E,[%CFOFF,,%CSFRN] ;Put into foreign-protocol state
MOVEM E,CHSSTA(I)
CHOUN1: MOVE D,%CPKD(A) ;Save destination
MOVEM D,CHSFRN(I)
CHOUN3: MOVE B,CHSLCL(I) ;Set up source
MOVEM B,%CPKS(A)
PUSHJ P,LSWDEL
SETOM -2(A)
JRST CHAXMT
CHOUN2: MOVE D,CHSFRN(I) ;Set up destination
MOVEM D,%CPKD(A)
JRST CHOUN3
OVHMTR CHX
;SENDING REGULAR PACKET
CHODAT: CAIE E,%CSOPN ;CONNECTION MUST BE OPEN
JRST IOCR10
SKIPG CHSNOS(I)
PUSHJ P,UFLS ;WINDOW FULL, WAIT
PUSHJ P,LSWDEL ;BUFFER WILL BE USED
CHODT1: HRRZ B,CHSPKN(I) ;ASSIGN PACKET NUMBER
CAIL B,177777
TDZA B,B
ADDI B,1
HRRM B,CHSPKN(I)
DPB B,[$CPKPN(A)]
CHODT2: HLRZ B,CHSPKN(I) ;GET PACKET NUMBER TO ACKNOWLEDGE
HRLM B,CHSACK(I) ;REMEMBER IT HAS BEEN
DPB B,[$CPKAN(A)] ;PIGGY-BACK THIS ACKNOWLEDGE
MOVE B,[<.BM $CPKOP>+<.BM $CPKNB>]
ANDM B,(A) ;CLEAR FORWARDING COUNT AND UNUSED FIELD
MOVE B,CHSLCL(I) ;SET UP SOURCE
MOVEM B,%CPKS(A)
MOVE D,CHSFRN(I) ;SET UP DESTINATION
MOVEM D,%CPKD(A)
SETOM -2(A) ;NOTE NOT ON TRANSMIT LIST YET
SKIPL (A) ;SKIP IF DATA PACKET
JRST CHAXMT
CONI PI,E ;SUPER KLUDGERY REQUIRED HERE! FOREIGN HOST MIGHT RECEIPT
CONO PI,NETOFF ;THIS PACKET JUST AS WE START TO TRANSMIT IT. THIS IS A
;VIOLATION OF PROTOCOL, BUT SHOULDN'T CRASH I.T.S. BECAUSE THE
;PACKET ABOUT TO BE GIVEN TO CHAXMT HAS BEEN FREED ALREADY.
MOVEI Q,CHSOBF(I) ;PUT ON END OF SEND LIST
PUSHJ P,CHAQPL
SOSA CHSNOS(I) ;USE UP WINDOW, SKIP
;SKIPS THROUGH INTO CHAXMT
;SKIPS IN
SUBTTL CHAOS NET PACKET TRANSMIT ROUTINE
;CALL WITH PACKET IN A, SMASHES B, C, D, E, T, TT, Q, J
;USES E TO SAVE THE PI STATUS, NOTHING BETTER CLOBBER THIS, OR, BOY, WILL IT EVER LOSE!
;YOU BETTER SETOM -2(A) BEFORE CALLING THIS, AND IF YOU'RE
;PUTTING IT ON A SEND LIST, DO THAT FIRST ALSO.
;THIS CODE ASSUMES THERE IS ONLY ONE INTERFACE, AND IT IS ON A
;PDP11 WHICH WILL TAKE CARE OF THE ROUTING.
;;THIS ROUTINE IS SKIPPED INTO FROM THE PREVIOUS PAGE!
CHAXMT: CONI PI,E ;SAVE PI STATUS BEFORE TURNING NETOFF; CALLED FROM MANY LEVELS
CHAXM0: ANDI E,177
AOS CHNPO
MOVE T,TIME
MOVEM T,-1(A) ;SET TIME OF LAST TRANSMISSION
CONO PI,NETOFF ;ONE PROCESS AT A TIME, TO PROTECT INTERFACE VARIABLES
IFN FTRCHK,[
HLRZ J,-2(A) ;I TOLD YOU TO SETOM -2(A)
CAIE J,-1
BUG PAUSE,[CHAOS BUFFER THREAD TRASHED],OCT,A,OCT,-2(A)
];FTRCHK
IFN DLCP,[
;FOR NOW, JUST ALWAYS SHIP IT OUT THE DL10
IFN FTRCHK,[
HLRZ J,DLCXMQ ;MAKE SURE NOT PUTTING ON LIST TWICE
JUMPE J,.+7
CAMN J,A
BUG PAUSE,[CHAOS BUFFER ALREADY ON DLCXMQ],OCT,A
HLRZ J,-2(J)
CAIN J,-1
BUG PAUSE,[DLCXMQ THREAD TRASHED]
JUMPN J,.-5
MOVEI J,1 ;MAKE SURE NOT ACTIVE TO 11
HRRZ T,DLCSA1(J)
CAMN T,A
BUG PAUSE,[CHAOS BUFFER ALREADY ACTIVE TO 11],OCT,A
SOJGE J,.-3
];FTRCHK
HRRZS -2(A) ;PUT END-LIST INDICATOR IN LH (FLAGS TRANSMIT ACTIVE)
MOVE J,DLCSBF ;SEE IF SEND BUFFER IS FREE
SKIPE DLCSS1(J)
JRST CHXMD1
PUSHJ P,DLCXMT ;YES, SEND THE PACKET NOW
JRST CHXMD2
CHXMD1: HRRZ B,DLCXMQ ;NO BUFFERS FREE RIGHT NOW, QUEUE
JUMPE B,[ HRLZM A,DLCXMQ ? JRST .+2 ]
HRLM A,-2(B)
HRRM A,DLCXMQ
CHXMD2: CONO PI,PICON(E) ;RESTORE PI
POPJ P,
];DLCP
IFN T11CHP,[
;FOR NOW, JUST ALWAYS SHIP IT OUT THE TEN11
PUSHJ P,T11CHK ;SEE IF TEN-11 IS READY
JRST CHXME3 ;NO
SKIPE @T11OBP ;SEE IF HAVE AVAILABLE OUTPUT BUFFER
JRST CHXME1 ;NO
PUSHJ P,T11XMT ;SEND THE PACKET NOW
JRST CHXME2
CHXME3: HRROS T,-2(A) ;TEN11 DOWN, DISCARD PACKET
AOJN T,CHXME2
PUSHJ P,CHABRT
JRST CHXME2
CHXME1: HRRZ B,T11XMQ ;NO BUFFERS FREE RIGHT NOW, QUEUE
JUMPE B,[ HRLZM A,T11XMQ ? JRST .+2 ]
HRLM A,-2(B)
HRRM A,T11XMQ
HRRZS -2(A) ;PUT END-LIST INDICATOR IN LH
CHXME2: CONO PI,PICON(E) ;RESTORE PI
POPJ P,
];T11CHP
IFN CH10P,[
;FOR NOW, JUST ALWAYS SHIP IT OUT THE CH10
HRRZ B,CHXXMQ ;ADD TO END OF TRANSMIT QUEUE
JUMPE B,[ HRLZM A,CHXXMQ ? JRST .+2 ]
HRLM A,-2(B)
HRRM A,CHXXMQ
HRRZS -2(A) ;PUT END-LIST INDICATOR IN LH
MOVEI B,CHXTEN ;ENABLE TRANSMIT-DONE INTERRUPT
IORM B,CHXCNO
CONO CHX,@CHXCNO
CONO PI,PICON(E) ;RESTORE PI
POPJ P,
];CH10P
IFN CH11P,[
;FOR NOW, JUST ALWAYS SHIP IT OUT THE CH11
HRRZ B,CHXXMQ ;ADD TO END OF TRANSMIT QUEUE
JUMPE B,[ HRLZM A,CHXXMQ ? JRST .+2 ]
HRLM A,-2(B)
HRRM A,CHXXMQ
HRRZS -2(A) ;PUT END-LIST INDICATOR IN LH
MOVEI B,%CATEN ;ENABLE TRANSMIT-DONE INTERRUPT
IORB B,CHXCSR
IOWRI B,CAICSR
CONO PI,PICON(E) ;RESTORE PI
POPJ P,
];CH11P
SUBTTL CHAOS NET DIRECT CONNECT TO STY
OVHMTR CHS
;CALLED AT CLOCK LEVEL FROM STYNTC WHEN A CHAOS STY IS ENCOUNTERED
;TTY NUMBER IN I & R
STYCHA: MOVE I,STYNTI-NFSTTY(R) ;GET CHAOS INDEX
MOVE TT,CHSSTA(I)
TLNN TT,%CFSTY
JRST 4,. ;CHAOS CONNECTION CLAIMS NOT BE CONNECTED?
JUMPL TT,STYCH9 .SEE %CFOFF ;OK TO USE? IF NOT, DISCONNECT
SKIPGE TTYOAC(R) ;ANY OUTPUT?
JRST STYCH1 ;NO, CHECK FOR INPUT
SKIPN D,CHSOBP(I) ;IF BUFFER ALLOCATED, USE IT
JRST [ SKIPG CHSNOS(I) ;OTHERWISE ALLOCATE ONE
JRST STYCH1 ;WINDOW FULL, WAIT UNTIL REACTIVATED
PUSHJ P,CHABGI
JRST STYCH3 ;NO CORE, WAIT ONE CLOCK TICK
MOVEI D,%CPKDT(A)
HRLI D,440800
MOVEM D,CHSOBP(I)
MOVEI E,%CPMXC
MOVEM E,CHSOBC(I)
JRST .+3 ]
SKIPG E,CHSOBC(I)
JRST STYCH4 ;BUFFER FULL, FORCE IT
EXCH R,I ;I GETS TTY, R GETS CHAOS
CONO PI,TTYOFF
MOVEM D,DBBBP ;SET UP BUFFER FOR TTY OUTPUT INTERRUPT LEVEL
MOVEM E,DBBCC
MOVEM E,DBBCC1
PUSH P,R
SETOM TYPNTF
PUSHJ P,TYP ;GENERATE OUTPUT
SETZM TYPNTF
POP P,R
EXCH R,I ;I GETS CHAOS, R GETS TTY
MOVE D,DBBBP ;ADVANCE POINTERS
MOVEM D,CHSOBP(I)
MOVE E,DBBCC
SUB E,DBBCC1 ;MINUS # CHARS OUTPUT GENERATED
CONO PI,TTYON
ADDM E,CHSOBC(I)
STYCH4: PUSHJ P,CHAFC1 ;FORCE THE BUFFER
JRST STYCHA ;CHECK FOR MORE OUTPUT
STYCH3: PUSHJ P,CHINTI ;REACTIVATE SO WILL COME BACK ON NEXT CLOCK TICK
STYCH1: SOSGE CHSIBC(I) ;GET INPUT, IF ANY
JRST [ PUSHJ P,CHAIBD ;DISCARD EXHAUSTED INPUT BUFFER, IF ANY
HLRZ A,CHSIBF(I)
JUMPE A,STYNT8 ;NONE, RETURN TO STYNTC
LDB TT,[$CPKOP(A)]
CAIE TT,%CODAT
JRST STYCH9 ;RANDOM PACKET, DISCONNECT
PUSHJ P,CHPKIA ;ACKNOWLEDGE GOBBLING OF THIS PACKET
SOS CHSNBF(I) ;REMOVE BUFFER FROM RECEIVE LIST
MOVEI Q,CHSIBF(I)
PUSHJ P,CHAQGF
LDB E,[$CPKNB(A)] ;SET UP FOR BYTE STREAM INPUT
MOVEM E,CHSIBC(I)
MOVEI D,%CPKDT(A)
HRLI D,440800
MOVEM D,CHSIBP(I)
JRST STYCH1 ]
ILDB A,CHSIBP(I) ;GET CHARACTER OF INPUT
TRNE A,200
JRST [ AOS CHSIBC(I) ;WOOPS, SPECIAL CHARACTER, NEEDS USER ATTENTION
MOVSI A,8_14 ;SO PUT IT BACK AND DISCONNECT
ADDM A,CHSIBP(I)
JRST STYCH9 ]
EXCH R,I ;I GETS TTY, R GETS CHAOS
PUSH P,R
PUSH P,I
CONO PI,TTYOFF
PUSHJ P,NTYI5 ;GIVE CHARACTER TO TTY INPUT INTERRUPT LEVEL
CONO PI,TTYON
POP P,R
POP P,I ;I GETS CHAOS, R GETS TTY ((POP IN REVERSE ORDER))
JRST STYCH1 ;TRY FOR MORE INPUT
STYCH9: PUSH P,I
MOVE I,R ;I GETS TTY
PUSHJ P,NSTYN0 ;DISCONNECT THE STY
JRST 4,.
POP P,I ;I GETS CHAOS
PUSHJ P,CHINTI ;WAKE UP THE TELNET SERVER
JRST STYNT8 ;GO HANDLE OTHER STYS
SUBTTL CHAOS NET CLOCK LEVEL STUFF
OVHMTR CHC
;HERE FROM 1/2 SECOND CLOCK. DO RETRANSMISSIONS AND DELAYED STS'S
CHACLK:
IFN DLCP,[
CONO PI,NETOFF
PUSHJ P,DLCIBG ;GET MEMORY FOR INPUT BUFFERS IF NEEDED
CONO PI,NETON
];DLCP
MOVEI I,NINDX-1 ;SCAN ALL INDICES
CHACL0: SKIPL CHSUSR(I) ;SKIP THIS ONE IF NOT IN USE
SKIPGE CHSSTA(I) .SEE %CFOFF ;OR INHIBITED FROM PI LEVEL
SOJGE I,CHACL0
JUMPL I,CPOPJ ;JUMP IF ALL INDICES DONE
PUSHJ P,CHARTR ;RETRANSMIT IF NEEDED
MOVSI B,%CFSTS
TDNE B,CHSSTA(I) ;SEND STS IF NEEDED
PUSHJ P,CHASTO
SOJGE I,CHACL0
POPJ P,
;HERE EVERY 5 SECONDS, TO DO PROBES
CHA5CL: MOVEI I,NINDX-1 ;SCAN ALL INDICES
CHA5C0: SKIPL CHSUSR(I) ;SKIP IF THIS ONE NOT IN USE
SKIPGE CHSSTA(I) .SEE %CFOFF ;OR INHIBITED FROM PI LEVEL
CHA5C1: SOJGE I,CHA5C0
JUMPL I,CHA5C4 ;JUMP IF ALL INDICES DONE
MOVE T,TIME
SUB T,CHSITM(I) ;TIME SINCE LAST COMMUNICATION FROM OTHER END
CAILE T,90.*30.
JRST [ MOVEI W,%CSINC ;TOO LONG, CONNECTION BROKEN
PUSHJ P,CHINT
JRST CHA5C1 ]
HRRZ B,CHSSTA(I) ;ONLY PROBE IF OPEN (COULD BE RFC-SENT)
CAIE B,%CSOPN
JRST CHA5C1
HRRZ B,CHSWIN(I) ;SEE IF NO TRANSMIT WINDOW (LOST STS DURING OPEN)
JUMPE B,CHA5C2
HRRZ B,CHSACK(I) ;SEE IF AWAITING ACK (WINDOW NOT EMPTY)
HRRZ C,CHSPKN(I)
CAMN B,C
CAIL T,60.*30.
CHA5C2: PUSHJ P,CHABGI ;AWAITING ACK OR IDLE FOR 1 MINUTE, PROBE
JRST CHA5C1 ;NO PROBE, OR NO BUFFER AVAILABLE
MOVSI T,(.DPB %COSNS,($CPKOP),0) ;SENSE PACKET, BYTE-COUNT=0
MOVEM T,(A)
AOS CHNSNS
PUSHJ P,CHODT2
JRST CHA5C1
CHA5C4: MOVEI B,[ASCIZ/Timeout/]
MOVEI Q,CHQRFC ;TIME-OUT FIRST RFC ON LIST
PUSHJ P,CHAQGF
JUMPE A,CHA5C5
MOVE T,-1(A)
ADDI T,60.*30. ;TIME-OUT IS ONE MINUTE
PUSHJ P,[ CAMG T,TIME
JRST CHIRF2
JRST CHAQPF ]
CHA5C5:
IFN CH10P,[
MOVEI T,CHXREN+CHXTEN ;WAKE UP IN CASE OF TIMING ERROR
IORM T,CHXCNO ;IN DEALING WITH CHXCNO
CONO CHX,@CHXCNO
MOVSI T,-NSUBNT ;DECAY ROUTING COSTS
CONO PI,NETOFF ;PREVENT RUT PACKET FROM COMING IN
CHA5C6: HLRZ TT,SBNRUT(T)
ADDI TT,1
CAIG TT,1000
HRLM TT,SBNRUT(T)
AOBJN T,CHA5C6
CONO PI,NETON
];CH10P
IFN CH11P,[
MOVEI T,%CAREN+%CATEN ;WAKE UP IN CASE OF TIMING ERROR
IORB T,CHXCSR ;IN DEALING WITH CHXCSR
IOWRI T,CAICSR
MOVSI T,-NSUBNT ;DECAY ROUTING COSTS
CONO PI,NETOFF ;PREVENT RUT PACKET FROM COMING IN
CHA5C6: HLRZ TT,SBNRUT(T)
ADDI TT,1
CAIG TT,1000
HRLM TT,SBNRUT(T)
AOBJN T,CHA5C6
CONO PI,NETON
];CH11P
MOVEI T,5*60.
MOVEI C,CHA5CK
JRST CLQREE
OVHMTR CHR
;RETRANSMIT FOR INDEX IN I
CHARTR: CONI PI,W ;SAVE PI CHANNELS ACTIVE
ANDI W,177 ;CHAXMT BETTER NOT CLOBBER W!
CONO PI,NETOFF ;PI BETTER BE OFF THROUGHOUT THIS ZONE
; SO WE DON'T GET INTO CHIACK
HLRZ A,CHSOBF(I) ;SCAN DOWN OUTPUT BUFFER LIST
JUMPE A,CHART2 ;EMPTY
CHART1: MOVE T,-1(A) ;DON'T RETRANSMIT IF DONE TOO RECENTLY
HLRZ TT,-2(A) ;OR IF ALREADY ON ITS WAY OUT (DON'T LINK TWICE ON XMIT LIST)
CAME T,TIME
CAIE TT,-1
JRST CHART2 ;ANYTHING AFTER THIS IS LIKELY TO LOSE ALSO
AOS CHNRTR
PUSHJ P,CHAXMT ;RETRANSMIT THIS
; HRRZ A,-2(A) ;THREAD TO NEXT
; JUMPN A,CHART1
CHART2: CONO PI,PICON(W)
POPJ P,
;THIS ROUTINE SENDS A STS PACKET, OR TRIES TO. FAILURE => SLOW CLOCK WILL TRY AGAIN.
;CANNOT PCLSR NOR WAIT, CALLABLE FROM INTERRUPT LEVEL.
;INDEX IN I, CLOBBERS A,B,C,D,E,T,TT,Q,J
CHASTO: MOVSI D,%CFSTS
IORM D,CHSSTA(I)
PUSHJ P,CHABGI ;GET A BUFFER, WITHOUT WAITING
POPJ P, ;CAN'T GET ONE, WILL RETRY AT CLOCK LEVEL
ANDCAM D,CHSSTA(I) ;OK, A STS WILL BE SENT, CLEAR NEED-STS FLAG
MOVE T,[.DPB %COSTS,($CPKOP),<.DPB 4,($CPKNB),0>]
MOVEM T,(A) ;SEND A STS WITH 4 DATA BYTES
PUSHJ P,DPBRCP ;FIRST PAIR IS RECEIPT
HLRZ B,CHSWIN(I) ;SECOND PAIR IS WINDOW SIZE
DPB B,[042000,,%CPKDT(A)]
AOS CHNSTS
JRST CHODT2 ;FIRE IT OFF
DPBRCP: HLRZ B,CHSPKN(I)
SKIPE T,CHSIBF(I)
LDB B,[$CPKPN(T)]
DPB B,[242000,,%CPKDT(A)]
POPJ P,
SUBTTL CHAOS NET INTERRUPT-LEVEL INPUT PROCESSING
OVHMTR CHI
;PROCESS A PACKET RECEIVED AT INTERRUPT LEVEL. BY THE TIME WE GET HERE
; A BUFFER HAS BEEN ALLOCATED AND FILLED WITH THE DATA FROM THE DEVICE.
; ITS ADDRESS IS IN A. RETURN VIA POPJ P, WITH ALL REGISTERS CLOBBERED.
CHAPII: MOVE B,RECHDP ;SAVE HEADER FOR DEBUGGING IN RING BUFFER
MOVEI D,%CPKDT(B)
HRL B,A
BLT B,-1(D)
CAIN D,RECHDR+<NRECHD*%CPKDT>
MOVEI D,RECHDR
MOVEM D,RECHDP
;END OF DEBUGGING CODE
LDB D,[$CPKMV(A)] ;MUPPET?
JUMPN D,CHABRT ;FLUSH, NOT SUPPORTED
LDB D,[$CPKOP(A)] ;GET OPCODE
LDB B,[$CPKDA(A)] ;CHECK DESTINATION
CAIE B,MYCHAD ;IF FOR ME,
SKIPN B ;OR FOR ME BY VIRTUE OF BROADCAST
AOSA CHNPI ;ACCEPT IT
JRST CHAPFW ;NOT ME, FORWARD
LDB C,[$CPKNB(A)] ;PASS LENGTH IN C TO OP ROUTINES
MOVEI B,[ASCIZ/Illegal byte count/]
CAILE C,%CPMXC
JRST CHALOS
SKIPGE (A) ;TEST OPCODE
JRST CHIDAT ;DATA PACKET
MOVEI B,[ASCIZ/Illegal opcode/]
CAIGE D,%COMAX
JRST @.+1(D)
OFFSET -.
JRST CHALOS ;ILLEGAL, FLUSH
%CORFC::JRST CHIRFC
%COOPN::JRST CHIOPN
%COCLS::JRST CHICLS
%COFWD::JRST CHIANS
%COANS::JRST CHIANS
%COSNS::JRST CHISNS
%COSTS::JRST CHISTS
%CORUT::
IFE CH10P+CH11P,JRST CHABRT ;IGNORE
IFN CH10P+CH11P,JRST CHIRUT
%COLOS::JRST CHILOS
%COLSN::JRST CHALOS ;ILLEGAL, FLUSH
%COMNT::JRST CHABRT ;IGNORE
%COEOF::JRST CHIDAT
%COUNC::JRST CHIUNC
%COBRD::JRST CHIBRD
%COMAX::OFFSET 0
;FORWARDING
CHAPFW: LDB B,[$CPKDA(A)] ;CHECK DESTINATION HOST
TRNN B,377_8 ;SUBNET 0?
JRST CHABRT ;FLUSH IT, XX-NETWORK-11 IS TRYING TO MAKE US CRASH
LDB B,[$CPKFC(A)] ;INCREMENT FORWARDING COUNT
ADDI B,1
CAIL B,20
JRST [ AOS CHNPFL ? JRST CHABRT ] ;LOOP, DISCARD
DPB B,[$CPKFC(A)]
SETOM -2(A) ;NOT ON SEND LIST
AOS CHNPF
JRST CHAXMT
IFN CH10P+CH11P,[ ;INCOMING ROUTING INFO
CHIRUT: LSH C,-2 ;NUMBER OF SUBNET ENTRIES
JUMPE C,CHABRT ;COULD BE ZERO-LENGTH
MOVEI D,%CPKDT(A)
HRLI D,442000
LDB E,[$CPKSA(A)] ;SOURCE HOST IS GATEWAY
CHIRU1: ILDB T,D ;SUBNET
ILDB TT,D ;COST
HLRZ B,SBNRUT(T) ;COST OF EXISTING ROUTE
CAIGE T,NSUBNT
CAMLE TT,B
JRST CHIRU2
HRLM TT,SBNRUT(T) ;THIS IS BEST ROUTE NOW
HRRM E,SBNRUT(T)
CHIRU2: SOJG C,CHIRU1
JRST CHABRT
];CH10P+CH11P
;INTERRUPT-LEVEL PROCESSING OF SNS PACKET
;NOTE THAT WE DO NOT BARF AT SNS'S TO EXISTENT NON-OPEN CONNECTIONS. IF IT
;WAS AN RFC-SENT CONNECTION, THIS COULD BREAK IT PREMATURELY IF AN OPN WAS
;LOST AND THEN A SNS WAS NOT.
CHISNS: MOVEI E,%CSOPN
PUSHJ P,CHFNDX
JRST [ CAIE E,%CSOPN
JRST CHABRT ;CONNECTION EXISTS AND IS NOT OPEN, IGNORE PACKET
JRST CHALOS ] ;CONNECTION DOES NOT EXIST, COMPLAIN
PUSHJ P,CHABRT ;CONNECTION DOES EXIST
CAIE E,%CSOPN
POPJ P, ;NOT OPEN, IGNORE
JRST CHASTO ;REPLY WITH STS
;INTERRUPT LEVEL PROCESSING OF RECEIVED FWD OR ANS
CHIANS: PUSHJ P,CHFNDX ;FIND CONNECTION
JRST CHABRT ;NOBODY AT OTHER END TO RECEIVE A LOS ANYWAY
CAIE E,%CSRFS
JRST CHABRT ;NOT IN RFC-SENT STATE, LOSS
; JRST CHICL1 ;CLOSE THE CONNECTION BUT GIVE TO USER AS INPUT
;DROPPING THROUGH WILL DO
;INTERRUPT LEVEL PROCESSING OF RECEIVED CLS PACKET
CHICLS: PUSHJ P,CHFNDX ;FIND CONNECTION BEING CLOSED
JRST CHALOS ;NONE, LOSS
CHICL1: MOVEI W,%CSCLS ;CLOSE THE CONNECTION
CHICL2: PUSHJ P,CHINT ;SET TO STATE IN W, INTERRUPT
PUSH P,A
MOVEI Q,CHSPBF(I) ;DISCARD OUT-OF-ORDER PACKETS
PUSHJ P,CHALFR
HRRZS CHSNBF(I)
CHIC2A: MOVEI Q,CHSOBF(I) ;DISCARD TRANSMIT PACKETS, E.G. RFC WHICH RECEIVED
PUSHJ P,CHAQGF ;AN ANS OR FWD, DON'T WANT TO TRANSMIT AGAIN
JUMPE A,CHIC2B
PUSHJ P,CHABR1
JRST CHIC2A
CHIC2B: POP P,A
JRST CHIDT1 ;GIVE PACKET TO USER AS DATA
;INTERRUPT LEVEL PROCESSING OF RFC PACKET
CHIRFC: MOVE T,%CPKDT(A) ;CHECK FOR STATUS REQUEST
CAMN T,[.BYTE 8 ? "S ? "T ? "A ? "T]
CAIE C,6
JRST CHIRF7
MOVS TT,%CPKDT+1(A)
XORI TT,(<.BYTE 8 ? "U ? "S>)
TRNN TT,(<.BYTE 8 ? -1 ? -1>)
JRST CHIRF3
CHIRF7: MOVEI Q,CHQLSN ;SEARCH LISTENING QUEUE
PUSHJ P,CHAQSR
JRST CHIRF1 ;NOT FOUND, LOAD SERVER
EXCH A,B ;A LSN, B RFC
LDB I,[$CPKSX(A)] ;GET CORRESPONDING INDEX
HRRZ E,CHSSTA(I)
CAIE E,%CSLSN
JRST 4,.
CHIRF0: PUSHJ P,CHABRT ;FOUND, DISCARD LISTEN PACKET
MOVE A,B ;GET OTHER HOST'S RFC
LDB B,[$CPKPN(A)] ;INITIALIZE RECEIVER'S PACKET NUMBER
HRLM B,CHSPKN(I)
MOVE B,%CPKS(A)
MOVEM B,CHSFRN(I) ;HOOK 'EM UP
MOVEI W,%CSRFC ;PUT INTO RFC-RECEIVED STATE
MOVE T,TIME ;AND ENGAGE PI LEVEL
MOVEM T,CHSITM(I)
JRST CHICL2
;RFC RECEIVED AND NOT IMMEDIATELY MATCHED TO A LSN. QUEUE AND LOAD SERVER JOB.
;BUT FIRST CHECK WHETHER THIS IS A DUPLICATE WHICH SHOULD BE DISCARDED.
CHIRF1: MOVE C,%CPKS(A) ;SEARCH PENDING RFC QUEUE FOR RFC FROM
HLRZ T,CHQRFC ;THE SAME SOURCE AS THIS.
JUMPE T,CHIRD1
CHIRD0: CAMN C,%CPKS(T)
JRST CHABRT ;THIS RFC IS A DUPLICATE, IGNORE IT
HRRZ T,-2(T)
JUMPN T,CHIRD0
CHIRD1: MOVSI T,-NINDX ;SEARCH OPEN AND RFC-RECEIVED CONNECTIONS
CHIRD2: SKIPL CHSUSR(T) ;FOR ONE CONNECTED TO SAME GUY AS SENT RFC
CAME C,CHSFRN(T)
AOBJN T,CHIRD2
JUMPGE T,CHIRD3 ;NO DUPLICATE OF THIS RFC, QUEUE IT
HRRZ TT,CHSSTA(T)
CAIE TT,%CSOPN
CAIN TT,%CSRFC
JRST CHABRT ;REALLY A DUPLICATE, DISCARD
AOBJN T,CHIRD2
CHIRD3: MOVEI B,[ASCIZ/System not up/]
SKIPL SYSDBG ;REFUSE INCOMING CONNECTIONS IF LOGINS REFUSED
SKIPE NETUSW ;ALLOWING INCOMING NET CONNECTIONS?
JRST CHIRF2 ;NO, REFUSE (EVEN IF FROM OURSELVES)
HRROI T,CHIRFJ ;LOAD JOB
CONI PI,Q ;MUST TURN UTCOFF TO CALL NUJBST
ANDI Q,177 ;SINCE THIS MAY RUN AT OTHER INT LEVELS
CONO PI,NETOFF
PUSHJ P,NUJBST
JRST [ CONO PI,PICON(Q)
JRST CHABRT ] ;RING BUFFER FULL, IGNORE, RETRY WILL CATCH
CONO PI,PICON(Q)
MOVE T,TIME ;REMEMBER WHEN THIS RFC WAS QUEUED
MOVEM T,-1(A)
MOVEI Q,CHQRFC
JRST CHAQPF ;PUT ON FRONT OF QUEUE
;COME HERE TO SEND A LOS PACKET IN RESPONSE TO CRUFTY INPUT IN A
;B SHOULD POINT TO AN ASCIZ STRING FOR WHY.
CHALOS: SKIPA T,[%COLOS]
;HERE TO REFUSE AN RFC. TURN IT INTO A CLS AND SEND IT BACK.
;B SHOULD POINT TO AN ASCIZ STRING FOR WHY.
CHIRF2: MOVEI T,%COCLS
HRLI B,440700 ;BP TO MESSAGE
SETZB C,(A) .SEE $CPKFC
DPB T,[$CPKOP(A)]
MOVE T,%CPKS(A) ;EXCHANGE SOURCE AND DESTINATION
EXCH T,%CPKD(A)
MOVEM T,%CPKS(A)
MOVE D,[440800,,%CPKDT(A)]
CHIRF4: ILDB T,B
JUMPE T,CHIRF5
IDPB T,D
AOJA C,CHIRF4
CHIRF5: DPB C,[$CPKNB(A)]
SETOM -2(A) ;NOT ON ANY SEND LIST
JRST CHAXMT ;SEND IT
;HERE FOR RFC TO "STATUS"
EXPUNGE FOO,BAR
DEFINE FOO NAME
BAR==0
.BYTE 8
IRPC CH,,NAME
"CH
BAR==BAR+1
TERMIN
IFG BAR-4, .ERR NAME MORE THAN 4 CHARACTERS
REPEAT 4-BAR, 0
.BYTE
TERMIN
CHIRF3: MOVE B,[MNAME FOO ,,] ;NAME OF MACHINE IN 8-BIT ASCII
EXPUNGE FOO,BAR
MOVEM B,%CPKDT(A)
SETZM %CPKDT+1(A)
MOVSI B,%CPKDT+1(A)
HRRI B,%CPKDT+2(A)
BLT B,%CPKDT+7(A)
MOVE B,[.BYTE 8 ? MYCHAD/400 ? 1 ? 4+IFN CH10P+CH11P,[10.] ? 0 ]
MOVEM B,%CPKDT+10(A)
MOVEI B,%CPKDT+11(A)
HRLI B,441000
MOVE T,CHNPI
PUSHJ P,CHRF3A
MOVE T,CHNPO
PUSHJ P,CHRF3A
IFN CH10P+CH11P,[
MOVE T,CHNABT
PUSHJ P,CHRF3A
MOVE T,CHNLOS
PUSHJ P,CHRF3A
MOVE T,CHNCRC
PUSHJ P,CHRF3A
MOVE T,CHNCR2
PUSHJ P,CHRF3A
MOVE T,CHNPLE
ADD T,CHNWLE
PUSHJ P,CHRF3A
];CH10P+CH11P
MOVEI T,%COANS
SETZM (A) .SEE $CPKFC
DPB T,[$CPKOP(A)]
MOVE T,%CPKS(A) ;EXCHANGE SOURCE AND DESTINATION
EXCH T,%CPKD(A)
MOVEM T,%CPKS(A)
MOVEI C,13*4+IFN CH10P+CH11P,[20.] ;BYTE COUNT
JRST CHIRF5 ;SEND
CHRF3A: MOVEI TT,4
IDPB T,B
LSH T,-8
SOJG TT,.-2
POPJ P,
;HERE TO CONVERT A BRD INTO AN RFC
CHIBRD: LDB T,[$CPKAN(A)] ;NUMBER OF BITMAP BYTES
LDB TT,[$CPKNB(A)] ;NUMBER OF TOTAL DATA BYES (INCLUDES BITMAP)
CAIG T,32. ;ACK NUMBER NO GREATER THAN 32.
TRNE T,3 ; MUST BE MULTIPLE OF 4
JRST CHABRT ; FREE THE PACKET IF NO GOOD
CAMG TT,T ;MUST BE SOME TEXTUAL RFC DATA AS WELL
JRST CHABRT ; IF NOT, FREE PACKET
MOVE C,TT ;GET NUMBER OF BYTES (CHIRFC WANTS COUNT IN C)
SUB C,T ;WITHOUT BITMAP
DPB C,[$CPKNB(A)] ;NEW BYTE COUNT
LSH T,-2 ;CONVERT BITMAP BYTE COUNT TO WORD COUNT
ADDI TT,3 ;CONVERT BYTE COUNT TO...
LSH TT,-2 ;... WORD COUNT
MOVEI D,%CPKDT(A) ;GET POINTER TO BEGINNING OF DATA
HRL D,D ;IN UPPER AND LOWER HALVES (ALMOST BLT POINTER)
HRLZ T,T ;BITMAP WORD COUNT,,0
ADD D,T ;RFC-STRING,,DATA-FIELD
ADDI TT,%CPKDT-1(A) ;LAST LOCATION FOR BLT
BLT D,(TT)
SETZI TT,
DPB TT,[$CPKAN(A)] ;ZERO THE ACK FIELD
MOVE TT,MYCHAD
DPB TT,[$CPKDA(A)] ;PRETEND IT WAS FOR ME
JRST CHIRFC ;AND HANDLE IT AS AN RFC
;ROUTINE TO FIND INDEX PACKET CORRESPONDS TO, SKIP IF FOUND, INDEX IN I.
;ALSO RETURNS STATE IN E SINCE THAT'S OFTEN HANDY.
;ALSO SETS B FOR CHALOS
CHFNDX: MOVEI B,[ASCIZ/Connection does not exist at this end/]
LDB I,[$CPKDX(A)] ;GET REAL-INDEX PART OF DESTINATION INDEX
CAIGE I,NINDX
SKIPGE CHSUSR(I)
POPJ P, ;NO MATCH
SKIPGE CHSSTA(I) .SEE %CFOFF
POPJ P, ;NOT TALKING TO NETWORK
HRRZ E,CHSSTA(I)
MOVE TT,%CPKD(A)
MOVE T,%CPKS(A)
CAIN E,%CSRFS ;IF IN RFC-SENT STATE, ONLY
AND T,[.BYTE 16. ? -1 ? 0] ;THE SOURCE HOST HAS TO MATCH
CAMN TT,CHSLCL(I) ;COMPARE LOCAL ADDRESS
CAME T,CHSFRN(I) ; AND FOREIGN ADDRESS
POPJ P, ;NO MATCH
MOVE T,TIME
MOVEM T,CHSITM(I)
JRST POPJ1 ;SUCCEED, CALLER CHECKS THE STATE
;INTERRUPT LEVEL PROCESSING OF RECEIVED OPN PACKET
CHIOPN: PUSHJ P,CHFNDX ;FIND CONNECTION TO BE OPENED
JRST CHALOS
CAIE E,%CSRFS ;NOT IN RFC-SENT STATE,
JRST CHABRT ; MUST BE DUPLICATE, DISCARD.
LDB B,[$CPKPN(A)] ;GET ITS PACKET NUMBER
HRLM B,CHSPKN(I) ;INITIALIZE PACKET NUMBERING OF RECEIVED MESSAGES
MOVE B,%CPKS(A)
MOVEM B,CHSFRN(I) ;HOOK 'EM UP
PUSHJ P,CHIST1 ;PROCESS AS A STS, DISCARD
PUSHJ P,CHASTO ;RESPOND WITH A STS
MOVEI W,%CSOPN
;DROP INTO CHINT
;COME HERE WITH INDEX IN I AND NEW STATE IN W, TO CHANGE STATE AND INTERRUPT
CHINT: HRRM W,CHSSTA(I)
MOVE T,TIME
MOVEM T,CHSITM(I) ;IN CASE GOT HERE FROM CHOLSN
MOVSI T,%CFOFF
CAIE W,%CSOPN
IORM T,CHSSTA(I) ;DISENGAGE PI LEVEL
CAIN W,%CSOPN
ANDCAM T,CHSSTA(I) ;NOW OPEN, ENGAGE PI LEVEL
;COME HERE TO INTERRUPT ON THE INPUT CHANNEL. SMASHES T,TT,W
CHINTI: LDB T,[$CHSUI,,CHSUSR(I)]
CHINT2: MOVE TT,CHSSTA(I) ;SIGNAL USER OR STY?
TLNN TT,%CFSTY
JRST CHINT4 ;USER
LDB T,[$CFTTN,,TT] ;STY, GET TTY NUMBER
CONO PI,PIOFF ;PROTECT LIST MODIFICATION
SKIPL STYNTL-NFSTTY(T) ;DON'T PUT ON LIST TWICE
JRST PIONJ
MOVE TT,STYNTA ;ADD TO LIST
MOVEM TT,STYNTL-NFSTTY(T)
MOVEM T,STYNTA
JRST PIONJ
CHINT4: SKIPGE TT,CHSUSR(I)
JRST 4,.
MOVSI W,(SETZ) ;PCLSR THE JOB SO IT GETS AN IOC ERROR IF NEEDFUL
IORM W,PIRQC(TT) ;EVEN IF NORMAL INTERRUPTS ARE NOT ENABLED
CAIN T,77
POPJ P, ;IOPUSH'D, NO INTERRUPT
MOVE T,CHNBIT(T)
AND T,MSKST2(TT)
IORM T,IFPIR(TT)
POPJ P,
OVHMTR CHD
;INTERRUPT LEVEL PROCESSING OF RECEIVED DATA PACKET
CHIDAT: PUSHJ P,CHFNDX ;FIND ASSOCIATED CONNECTION
JRST CHALOS ;NONE, LOSS
CAIE E,%CSOPN ;STATE MUST BE OPEN
JRST CHALOS ;BAD, LOSS
PUSHJ P,CHIACK ;PROCESS ACKNOWLEDGEMENT FIELD
;NOW DECIDE WHETHER IT GOES ON CHSIBF(I), OR ON CHSPBF(I), OR GETS DISCARDED.
HLRZ B,CHSPKN(I) ;LAST PACKET NUMBER GIVEN TO USER
LDB C,[$CPKPN(A)] ;GET PACKET NUMBER OF THE NEW PACKET
HLRZ T,CHSWIN(I) ;RECEIVE WINDOW SIZE
ADDI T,(B) ;HIGHEST LEGAL PACKET NUMBER
SUB T,C
TRNE T,100000 ;SKIP IF T >= C
JRST CHABRT ;FOO ON YOU, OVER WINDOW SIZE
HRRZ T,CHSIBF(I) ;COMPUTE NEXT IN-ORDER PACKET EXPECTED
JUMPE T,CHIDT6 ;BASED ON LAST IN-ORDER PACKET
LDB TT,[$CPKOP(T)]
CAIE TT,%COUNC
JRST [ LDB B,[$CPKPN(T)]
JRST CHIDT6 ]
HLRZ T,CHSIBF(I) ;IF IT'S AN UNC, HAVE TO GO FIND CORRECT PACKET
CHIDT5: LDB TT,[$CPKOP(T)]
CAIE TT,%COUNC
LDB B,[$CPKPN(T)]
HRRZ T,-2(T)
JUMPN T,CHIDT5
CHIDT6: ADDI B,1
ANDI B,177777 ;NEXT IN-ORDER PACKET EXPECTED
CAMN B,C
JRST CHIDT1 ;EQUAL, IT GOES ON THE END OF CHSIBF(I) LIST.
SUB B,C ;NOT EQUAL, COMPARE THEM MODULO 2^16.
TRNN B,100000
JRST CHIDTD ;B GREATER, THIS IS AN OLD PACKET, DISCARD IT
;PUT ON CHSPBF(I) IN PROPER ORDER
;A IS THIS PACKET, C IS HIS NUMBER, B IS PREDECESSOR, D IS NEXT, E IS HIS #
MOVEI B,0 ;SIGNIFY AT FRONT OF LIST
HLRZ D,CHSPBF(I) ;GET FIRST PACKET ON OUT-OF-ORDER LIST
JUMPE D,CHIDT4 ;LIST IS EMPTY
CHIDT3: LDB E,[$CPKPN(D)]
SUB E,C ;COMPARE PACKET NUMBERS
JUMPE E,CHIDTD ;DUPLICATE, DISCARD
TRNE E,100000
JRST [ MOVE B,D ;E IS LESS, KEEP LOOPING
HRRZ D,-2(B)
JUMPN D,CHIDT3
JRST .+1 ] ;REACHED END PUT IT HERE
SKIPE B
HRRM A,-2(B) ;THREAD ONTO PREVIOUS PACKET
SKIPN D
CHIDT4: HRRM A,CHSPBF(I) ;THREAD ONTO BACK OF LIST
SKIPN B
HRLM A,CHSPBF(I) ;THREAD ONTO FRONT OF LIST
HRRM D,-2(A) ;THREAD IN BEFORE PACKET IN D
MOVSI B,1
ADDM B,CHSNBF(I)
POPJ P,
;HERE IT GOES ON CHSIBF(I). A HAS PACKET, C HAS ITS PACKET NUMBER.
;IF GETTING HERE FROM CHICL1, C HAS GARBAGE BUT IT WILL NEVER BE USED.
CHIDT1: SKIPN CHSIBF(I)
PUSHJ P,CHINTI ;THERE WAS NO INPUT, BUT THERE IS NOW, COME AND GET IT
AOS CHSNBF(I)
MOVEI Q,CHSIBF(I)
PUSHJ P,CHAQPL ;PUT ON END OF RECEIVE LIST
HLRZ A,CHSPBF(I) ;GET FIRST OUT-OF-ORDER PACKET
JUMPE A,CPOPJ ;NONE
LDB B,[$CPKPN(A)] ;SEE IF THIS PACKET IS NOW IN-ORDER
CAIL C,177777 ;BY COMPARING AGAINST C+1 MODULO 2^16.
TDZA C,C
ADDI C,1
CAME B,C
POPJ P, ;NO
MOVEI Q,CHSPBF(I)
PUSHJ P,CHAQGF ;YES, PULL PACKET OF OUT-OF-ORDER LIST
MOVSI B,-1
ADDM B,CHSNBF(I)
JRST CHIDT1 ;AND GO PUT ONTO IN-ORDER LIST
;HERE IF PACKET IS A DUPLICATE AND IS TO BE DISCARDED. MUST SEND
;RECEIPT TO SHUT OFF EXCESS RETRANSMISSION.
CHIDTD: PUSHJ P,CHABRT
AOS CHNPD
JRST CHASTO
;HERE FOR RECEIVING AN UNC PACKET
CHIUNC: LDB I,[$CPKDI(A)] ;Destination index zero?
JUMPE I,CHIUN2
LDB I,[$CPKDX(A)] ;GET REAL-INDEX PART OF DESTINATION INDEX
CAIGE I,NINDX
SKIPGE CHSUSR(I)
JRST CHALOS ;NO MATCH
MOVE TT,%CPKD(A) ;DESTINATION ADDRESS MATCHES?
CAME TT,CHSLCL(I)
JRST CHALOS
HRRZ E,CHSSTA(I) ;IN FOREIGN PROTOCOL MODE?
CAIN E,%CSFRN
JRST CHIUN1
MOVE TT,%CPKS(A) ;NORMAL PROTOCOL, SOURCE ADDRESS MUST MATCH
CAMN TT,CHSFRN(I)
CAIE E,%CSOPN ;AND STATE MUST BE OPEN
JRST CHALOS
CHIUN1: MOVE TT,TIME
MOVEM TT,CHSITM(I)
SKIPE T,CHSIBF(I) ;DISCARD PACKET IF OVER WINDOW SIZE
JRST [ LDB TT,[$CPKOP(T)] ; AND ALREADY HAVE AN UNC
HRRZ T,CHSNBF(I)
HLRZ Q,CHSWIN(I)
CAML T,Q
CAIE TT,%COUNC
JRST .+2
JRST CHABRT ]
PUSHJ P,CHINTI ;THERE WAS NO INPUT, BUT THERE IS NOW, COME AND GET IT
AOS CHSNBF(I) ;PUT ON END OF RECEIVE LIST.
MOVEI Q,CHSIBF(I) ;PACKET NUMBER IS RANDOM, NOTHING LOOKS AT IT
JRST CHAQPL
CHIUN2:
IFE INETP,JRST CHALOS ;No comprendo internet
IFN INETP,[
LDB I,[$CPKAN(A)] ;Protocol number
CAIE I,8_8 ;DOD Internet #x0800
JRST CHALOS
AOS CHNIPI ;Meter Internet packets in from Chaosnet
MOVE J,A ;Save Chaosnet packet
LDB A,[$CPKNB(A)] ;Compute size of Internet datagram in words
ADDI A,3
LSH A,-2
MOVE C,A ;Save word count
CALL IPGIPT ;Get buffer to copy datagram into
JRST CHIUN3 ;No buffers available, discard packet
MOVSI T,%CPKDT(J) ;Make BLT pointer
HRRI T,1(B)
ADDI B,(C) ;Address of last destination word
BLT T,(B)
EXCH A,J ;Free the Chaosnet packet
CALL CHABRT
MOVE A,J ;Datagram structure
MOVE B,C ;Word count
MOVEI C,0 ;Offset to start of IP header
CALRET IPRDGM ;Dispose of datagram
CHIUN3: MOVE A,J ;Discard Chaosnet packet
CALRET CHABRT
];INETP
OVHMTR CHJ
;INTERRUPT LEVEL PROCESSING OF LOS
CHILOS: PUSHJ P,CHFNDX ;FIND CONNECTION TO BE BROKEN
JRST CHABRT ;NONE, IGNORE
MOVEI W,%CSLOS ;PUT INTO LOST STATE
JRST CHICL2 ;GIVE PACKET TO USER AS DATA, DISENGAGE, AND INTERRUPT
;INTERRUPT LEVEL PROCESSING OF STS
CHISTS: PUSHJ P,CHFNDX
JRST CHALOS
CAIE E,%CSOPN ;CONNECTION MUST BE OPEN
JRST CHALOS
CHIST1: LDB B,[042000,,%CPKDT(A)] ;GET NEW WINDOW SIZE
CAILE B,MXWIND
MOVEI B,MXWIND
HRRM B,CHSWIN(I)
LDB B,[242000,,%CPKDT(A)] ;PROCESS RECEIPT
PUSHJ P,CHIAK0
PUSHJ P,CHABRT
JRST CHARTR ;RETRANSMIT
OVHMTR CHA
;INTERRUPT LEVEL PROCESSING OF RECEIVED ACKNOWLEDGEMENT.
;REMOVE THE ACKNOWLEDGED PACKETS FROM THE INDEX'S SEND LIST AND UPDATE CHSNOS(I).
;NOTE THAT THE LIST IS ASSUMED TO BE SORTED SO WE ONLY
;REMOVE PACKETS FROM THE FRONT. CLOBBERS B,C,D,T,TT,Q.
CHIACK: LDB B,[$CPKAN(A)] ;PACKET NUMBER BEING RECEIPTED
CHIAK0: LDB T,[$CPKAN(A)] ;ENTER HERE FROM CHISTS
HRRZ D,CHSACK(I) ;GET MAX OF THIS ACKNOWLEDGE AND PREVIOUS
SUB D,T
TRNE D,100000
HRRM T,CHSACK(I) ;ACKNOWLEDGED PACKET NUMBER IS NEW START OF WINDOW
PUSH P,A
HLRZ A,CHSOBF(I) ;MAP DOWN SEND LIST
JUMPE A,CHIAK2 ;LIST EMPTY
CHIAK1: LDB D,[$CPKPN(A)]
SUBM B,D
TRNE D,100000
JRST CHIAK2 ;RCP# LESS THAN PKT#
HRRZ C,-2(A) ;GET NEXT PACKET
HLLOS D,-2(A) ;MARK NOT ON SEND LIST
AOJE D,CHIAK3 ;AND JUMP IF NOT ON TRANSMIT LIST
IFN DLCP,[
MOVEI Q,DLCXMQ ;ON TRANSMIT LIST, TRY TO TAKE OFF
PUSHJ P,CHIAKF
];DLCP
IFN T11CHP,[
MOVEI Q,T11XMQ
PUSHJ P,CHIAKF
];T11CHP
IFN CH10P+CH11P,[
MOVEI Q,CHXXMQ
PUSHJ P,CHIAKF
];CH10P+CH11P
CAIA ;AND DON'T FREE IT
CHIAK3: PUSHJ P,CHABRT
HRLM C,CHSOBF(I)
SKIPE A,C
JRST CHIAK1
SETZM CHSOBF(I) ;SEND LIST NOW EMPTY
CHIAK2: MOVE D,CHSNOS(I) ;COMPUTE NEW VALUE OF CHSNOS
HRRZ T,CHSACK(I) ;START OF WINDOW
HRRZ C,CHSPKN(I) ;LAST PACKET SENT
SUB T,C
SKIPLE T
SUBI T,200000 ;T GETS NEGATIVE AMOUNT OF WINDOW OCCUPIED
ADD T,CHSWIN(I) ;RH(T) GETS AVAILABLE PORTION OF WINDOW
HRREM T,CHSNOS(I) ;WHICH IS NUMBER OF OUTPUT SLOTS
JUMPG D,POPAJ ;IF FORMERLY THERE WERE NO OUTPUT SLOTS,
LDB T,[$CHSUO,,CHSUSR(I)]
SKIPLE CHSNOS(I) ;AND NOW THERE ARE,
PUSHJ P,CHINT2 ;INTERRUPT ON THE OUTPUT CHANNEL
JRST POPAJ
;TRY TO TAKE PACKET IN A OFF OF TRANSMIT LIST IN Q.
;CLOBBER T,Q,D. CALLED WITH INTERRUPTS OFF.
;MAY RETURN WITH A POINTING TO FREE BUT THAT IS OK AT THIS TIME.
CHIKF1: SKIPA D,T
CHIAKF: MOVEI D,2(Q) ;LH[-2(D)] POINTS TO (T)
HLRZ T,-2(D)
JUMPE T,CPOPJ ;NOT FOUND
CAIE T,(A)
JRST CHIKF1
HLRZ T,-2(A) ;LINK OUT
HRLM T,-2(D)
JUMPN T,CHABRT ;JUMP IF DIDN'T DELETE LAST PACKET IN LIST
HRRM D,(Q) ;NEW LAST PACKET IN LIST
CAIN D,2(Q)
SETZM (Q) ;FOO, TRANSMIT LIST NOW EMPTY
JRST CHABRT
SUBTTL CHAOS NET DL10 INTERRUPT ROUTINE
OVHMTR CHH
IFN DLCP,[
;COME HERE FROM EACH DL10 INTERRUPT AT TTY LEVEL. SMASH ALL REGISTERS EXCEPT P AND 0.
DLCWAK: CONI PI,E ;SAVE PI STATUS AND SWITCH TO NETWORK INTERRUPT LEVEL
ANDI E,177
PUSH P,E
CONO PI,NETOFF
DLCWK1: MOVEI J,1 ;ALWAYS CHECK BOTH BUFFERS SO WE CAN'T GET OUT OF PHASE WITH 11
MOVEI R,2 ;CHECK FOR INPUT AVAILABLE
CAME R,DLCRS1(J)
SOJGE J,.-1
JUMPL J,DLCWK2
MOVE A,DLCRA1(J) ;GOT INPUT, PROCESS IT
SETZM DLCRS1(J) ;BUFFER SLOT NOT OCCUPIED NOW
IFN KS10P, CLRCSH
IFN KL10P, PUSHJ P,DLCSWP ;SWEEP CACHE IN CASE ANYONE HAPPENED TO TOUCH BUFFER
SKIPE A ;THIS CAN HAPPEN IF PDP11 WAS JUST STUFFED
PUSHJ P,CHAPII ;PROCESS THE PACKET
PUSHJ P,DLCIBG ;SUPPLY A NEW INPUT BUFFER TO 11
JRST DLCWK1 ;TRY FOR MORE INPUT
DLCWK2: MOVEI J,1 ;SCAN CHANNELS FOR OUTPUT DONE
CAME R,DLCSS1(J)
DLCWK3: SOJGE J,.-1
JUMPL J,DLCWK4
MOVE A,DLCSA1(J) ;FOUND AN OUTPUT DONE BUFFER
HRROS B,-2(A) ;MARK IT NOT ON TRANSMIT LIST
AOJN B,.+2 ;AND UNLESS IT IS ON SEND LIST
PUSHJ P,CHABRT ;RETURN IT TO FREE
SETZM DLCSA1(J) ;IDLE THIS BUFFER
SETZM DLCSS1(J)
JRST DLCWK3
DLCWK4: MOVE J,DLCSBF ;TRY TO SEND SOME OUTPUT
SKIPE DLCSS1(J)
JRST DLCWK9 ;BUFFER BUSY
HLRZ A,DLCXMQ ;GET ANOTHER OFF TRANSMIT QUEUE
JUMPE A,DLCWK9 ;QUEUE EMPTY
HLRZ T,-2(A)
IFN FTRCHK,[
CAIN T,-1
BUG PAUSE,[CHAOS LIST THREAD TRASHED],OCT,A,OCT,-2(A)
];FTRCHK
HRLM T,DLCXMQ
IFN FTRCHK,[
JUMPN T,.+4
CAME A,DLCXMQ ;REACHED END OF LIST, END IN RIGHT PLACE?
BUG PAUSE,[DCLXMQ THREAD TRASHED]
SETZM DLCXMQ
];FTRCHK
IFE FTRCHK,[
SKIPN T
SETZM DLCXMQ
];FTRCHK
PUSHJ P,DLCXMT ;SEND IT ON THIS BUFFER
JRST DLCWK4 ;GO TRY TO SEND ON OTHER BUFFER
DLCWK9: POP P,E
CONO PI,PICON(E) ;RESTORE PI
POPJ P,
;THIS ROUTINE SUPPLIES AN INPUT BUFFER TO THE 11 ON ALL BUFFERS THAT NEED IT
;CALL WITH INTERRUPTS OFF OR IN PROGRESS
DLCIBG: MOVEI J,1
SKIPE DLCRS1(J)
DLCIB1: SOJGE J,.-1
JUMPL J,CPOPJ
PUSHJ P,CHABGI ;GET A BUFFER
JRST [ SETZM DLCRA1(J) ;NO MEMORY, WILL TRY AGAIN AT CLOCK LEVEL
SETZM DLCRS1(J)
POPJ P, ]
SETZM (A) ;CLEAR THE BUFFER SINCE THE DL10 DOESN'T TOUCH LOW 4 BITS
HRLZ T,A
HRRI T,1(A)
BLT T,%CPMXW-1(A)
MOVEM A,DLCRA1(J) ;MAKE AVAILABLE TO PDP11
HRLI A,120000
MOVEM A,DLCRP1(J)
SOS DLCRP1(J)
IFN KS10P, .ERR CLRCSH not needed here?
IFN KL10P, PUSHJ P,DLCSWP ;SWEEP CACHE BEFORE SIGNALLING 11
MOVEI T,1
MOVEM T,DLCRS1(J)
CONO DLC,100040+TTYCHN ;INTERRUPT 11
JRST DLCIB1 ;TRY FOR OTHER BUFFER ALSO
;THIS ROUTINE SENDS PACKET IN A TO DL10 (CALL WITH NETOFF OR IN PROGRESS)
;SWITCHES BUFFERS, LEAVES NEW ONE IN J
DLCXMT: MOVE J,DLCSBF
MOVEM A,DLCSA1(J)
HRLI A,120000
MOVEM A,DLCSP1(J) ;GIVE 11 POINTER TO NEW PACKET
SOS DLCSP1(J)
IFN KS10P, .ERR CLRCSH not needed here?
IFN KL10P, PUSHJ P,DLCSWP ;SWEEP CACHE, PUTTING PACKET INTO CORE
MOVEI T,1
MOVEM T,DLCSS1(J) ;ACTIVATE PDP11
CONO DLC,100040+TTYCHN
XORI J,1 ;NEXT BUFFER
MOVEM J,DLCSBF
POPJ P,
IFN KL10P,[
;THIS ROUTINE SWEEPS PACKET IN A OUT OF THE CACHE,
;CLOBBERING B, C, AND D.
IFG PKTBSZ-1000, .ERR PKTBSZ BIGGER THAN HARDWARE PAGE SIZE, CACHE SWEEP LOSES
DLCSWP: LDB D,[111100,,A] ;SWEEP ONE PAGE OF CACHE
SWPUO (D) ;STORING PACKET INTO CORE
MOVE B,[CONSZ 200000] ;AWAIT COMPLETION IN ACS
MOVE C,[JRST B] ;TO MINIMIZE CACHE INTERFERENCE
MOVSI D,(POPJ P,)
JRST B
];KL10P
];DLCP
SUBTTL CHAOS NET TEN-11 INTERFACE STUFF
IFN T11CHP,[
;THIS ROUTINE CHECKS FOR TEN-11 INITIALIZATION, SKIP-RETURNS IF OK TO USE
;CLOBBERS T,TT
T11CHK: SKIPE TEN11F
JRST T11LUZ ;NOT SUPPOSED TO USE TEN11
MOVE T,T11VER ;CHECK VERSION TO MAKE SURE RIGHT PROGRAM, ETC.
CAME T,[.BYTE 8 ? "H ? "C ? 0 ? 1]
JRST T11LUZ ;PROBABLY TURNED OFF OR WRONG PROGRAM
SKIPE T11I10 ;SHOULD WE REINIT?
JRST T11CK1 ;YES, GO DO SO
SKIPLE T,T11WIN ;ARE WE WINNING?
JRST POPJ1 ;YES, FINE
JUMPE T,[SETOM T11WIN ;NOW THAT VERSION IS OK, TELL 11 TO INIT
MOVSI T,-1
MOVEM T,T11I11
JRST T11CK1 ] ;AND INIT OURSELVES
SKIPE T11I11 ;WAITING FOR 11 TO REINIT?
POPJ P, ;YES, WAIT
;HERE TO REINIT. FIRST, PICK UP PARAMETERS.
T11CK1: LDB TT,[242000,,T11PRM] ;BYTES PER PACKET BUFFER
CAIGE TT,<%CPMXW+1>*4 ;BETTER BE RIGHT SIZE
JRST T11LUZ ;TOO SMALL (ASSUME IF TOO BIG, PACKETS WON'T BE)
LSH TT,-2
MOVEM TT,T11BSZ ;SAVE BUFFER SIZE IN PDP10 WORDS
LDB T,[042000,,T11PRM] ;NUMBER OF BUFFERS IN EACH DIRECTION
IMULB T,TT ;NUMBER OF PDP10 WORDS IN EACH DIRECTION
ADD TT,T11IBB
MOVEM TT,T11IBE ;INIT POINTERS
MOVEM TT,T11OBB
MOVEM TT,T11OBP
ADD TT,T
MOVEM TT,T11OBE
HRREI T,-T11CHS-2000(TT)
JUMPG T,T11LUZ ;COMMUNICATION AREA LONGER THAN 1K
MOVE T,T11IBB
MOVEM T,T11IBP
T11CK2: SETZM (T) ;CLEAR BUFFER HEADERS
ADD T,T11BSZ
CAMGE T,TT
JRST T11CK2
MOVEM T,T11WIN ;WE'RE WINNING (MAKE T11WIN POSITIVE NON-ZERO)
SETZM T11I10 ;INIT DONE
JRST POPJ1
;HERE IF PDP11 PARAMETERS DON'T MATCH WHAT WE EXPECT
T11LUZ: SETZM T11WIN ;NOT WINNING
POPJ P,
;HERE FROM CLOCK LEVEL TO CHECK ON TEN-11 CHAOS NET CHANNEL
T11WAK: PUSHJ P,T11CHK ;IS EVERYTHING OK?
POPJ P, ;NO.
T11WK0: MOVE C,T11IBP ;CHECK INPUT
SKIPN (C)
JRST T11WK1 ;NONE AVAILABLE
MOVSI J,2(C) ;POINT TO PACKET
LDB D,[$CPKNB+2(C)] ;GET SIZE OF PACKET
ADDI D,4*%CPKDT+3 ;CONVERT BYTES TO WORDS INCLUDING HEADER
LSH D,-2
CAILE D,%CPMXW ;DON'T GET FAKED OUT BY CLOBBERED COUNT
MOVEI D,%CPMXW
PUSHJ P,CHABGI ;GET PLACE TO PUT IT
JRST T11WK1 ;NONE AVAILABLE
HRLOI E,-1(D)
EQVI E,(A) ;AOBJN POINTER TO PACKET BUFFER
HRRI J,(A) ;BLT POINTER TO COPY PACKET
ADDI D,-1(A) ;LAST WORD
BLT J,(D) ;COPY PACKET FROM 11 TO 10
MOVEI H,0 ;COMPUTE CHECKSUM
T11WK4: ADD H,(E)
LSH H,-1
TRZE H,10
TLO H,(SETZ)
AOBJN E,T11WK4
MOVE TT,1(C) ;GET PDP11'S CHECKSUM
SETZM (C) ;GIVE THE 11 BACK THE BUFFER
ADD C,T11BSZ ;ADVANCE THE POINTER
CAML C,T11IBE
MOVE C,T11IBB
MOVEM C,T11IBP
CAME H,TT
JRST [ AOS T11CKE ;COUNT CHECKSUM ERRORS
PUSHJ P,CHABRT ;AND DISCARD PACKET
JRST T11WK0 ]
CONO PI,NETOFF
PUSHJ P,CHAPII ;PROCESS THE INPUT
CONO PI,NETON
JRST T11WK0
T11WK1: CONO PI,NETOFF
SKIPE T11XMQ ;ANY OUTPUT?
SKIPE @T11OBP ;AND OUTPUT BUFFER SPACE AVAILABLE?
JRST NETONJ ;NO, RETURN FROM T11WAK
HLRZ A,T11XMQ ;GET PACKET OFF TRANSMIT QUEUE
HLRZ B,-2(A) ;GET NEXT AFTER THAT
HRLM B,T11XMQ ;BECOMES NEW HEAD OF QUEUE
SKIPN B
SETZM T11XMQ
PUSHJ P,T11XMT ;COPY PACKET INTO 11
CONO PI,NETON
JRST T11WK1 ;LOOK FOR MORE OUTPUT
;SEND PACKET A-> TO 11. SMASHES B,C,T,TT,Q. CALL WITH NETOFF.
T11XMT: LDB C,[$CPKNB(A)] ;GET BYTE COUNT
MOVE Q,C ;MUST CLEAR UNUSED BYTES AT END OF LAST WORD
ANDI Q,3 ;TO MAKE THE CHECKSUM COME OUT RIGHT
ADDI C,4*%CPKDT+3
LSH C,-2 ;CONVERT TO WORD COUNT
MOVE Q,(Q)[ -1 ;MASK FOR BYTES TO RETAIN IN LAST WORD
<.BYTE 8 ? -1>
<.BYTE 8 ? -1 ? -1>
<.BYTE 8 ? -1 ? -1 ? -1> ]
MOVEI TT,-1(C)
ADD TT,A
ANDM Q,(TT) ;MASK OFF LAST WORD
HRLOI C,-1(C)
EQVI C,(A) ;AOBJN PTR
MOVEI TT,0 ;COMPUTE XOR CHECKSUM IN TT
SKIPA B,T11OBP ;-> CURRENT OUTPUT BUFFER IN 11
T11XM1: ADDI B,1
MOVE T,(C)
TRZ T,17 ;CLEAR BITS 10-11 TREATS SPECIALLY
ADD TT,T ;COMPUTE CHECKSUM
LSH TT,-1
TRZE TT,10
TLO TT,(SETZ)
MOVEM T,2(B)
AOBJN C,T11XM1
MOVE B,T11OBP
MOVEM TT,1(B) ;GIVE CHECKSUM TO 11
MOVSI TT,-1
MOVEM TT,0(B) ;GIVE PACKET TO 11
ADD B,T11BSZ ;ADVANCE BUFFER POINTER
CAML B,T11OBE
MOVE B,T11OBB
MOVEM B,T11OBP
HRROS T,-2(A) ;TAKE PACKET OFF TRANSMIT LIST
AOJN T,.+2
PUSHJ P,CHABRT ;NOT ON SEND LIST, FREE IT
POPJ P,
];T11CHP
SUBTTL CH-10 INTERRUPT ROUTINES
;THE GENERAL IDEA IS THAT WE INTERRUPT ON A LOW-PRIORITY INTERRUPT LEVEL,
;AND DO THE TIME-INTENSIVE PACKET COPYING AT THAT LEVEL. THE GENERAL
;CHAOS ROUTINES ARE THEN CALLED WITH NETOFF.
IFN CH10P,[
EBLK
CHXACS: BLOCK 20
CHXPDL: -60,,.
BLOCK 60
CHXBRK: 0
BBLK
MOVEM 17,CHXACS+17
MOVEI 17,CHXACS
BLT 17,CHXACS+16
MOVE P,CHXPDL
CONSO CHX,CHXRCV ;PACKET RECEIVED?
JRST CHXBK5
PUSHJ P,CHABGI ;GET PLACE TO PUT PACKET
JRST [ MOVEI T,CHXREN ;NONE AVAILABLE, DISABLE INTR
ANDCAM T,CHXCNO
CONO CHX,@CHXCNO
JRST CHXBK5 ]
CONSZ CHX,CHXCRC+CHXWLE ;CHECK FOR ERRORS
JRST [ CONSZ CHX,CHXCRC
AOSA CHNCRC
AOS CHNWLE
JRST CHXBK4 ] ;IGNORE PACKET
DATAI CHX,T ;FIRST DATAI YIELDS GARBAGE
MOVEI T,CHXSWB ;DISABLE BYTE SWAPPING
ANDCAM T,CHXCNO
CONO CHX,@CHXCNO
HRLI A,-%CPKDT ;READ HEADER
DATAI CHX,(A)
AOBJN A,.-1
HRRZI A,-%CPKDT(A)
PUSHJ P,CHSWAB ;ENABLE BYTE SWAPPING IF NEEDED
LDB T,[$CPKNB(A)] ;GET SIZE OF PACKET
CAILE T,%CPMXC ;DON'T RUN OFF END OF BUFFER
JRST CHXBK4
ADDI T,3 ;ROUND UP TO NEXT WORD BOUNDARY
LSHC T,-2 ;CONVERT BYTES TO WORDS, TT GETS REMAINDER
HRLOI D,-1(T) ;MAKE AOBJN POINTER
EQVI D,%CPKDT(A)
JUMPGE D,.+3 ;EMPTY PACKET BOUNDARY CASE
DATAI CHX,(D)
AOBJN D,.-1
DATAI CHX,T ;NOW READ AND IGNORE HARDWARE HEADER
TLNE T+1,400000
DATAI CHX,T ;THIRD HALFWORD
CONI CHX,T ;CHECK FOR ERRORS
TDNE T,[CHXPLE+CHXCRC+CHXOVR]
JRST [ TLNE T,(CHXOVR)
JRST CHXBKZ ;OVERRRUN CAN'T HAPPEN UNLESS HARDWARE BROKEN
TLNE T,(CHXPLE)
AOSA CHNPLE
TRNN T,CHXCRC
JRST CHXBK4
AOS CHNCR2
JRST CHXBK4 ]
CONO PI,NETOFF-1
PUSHJ P,CHAPII ;PROCESS THE INPUT
CONO PI,NETON-1
CAIA
CHXBK4: PUSHJ P,CHABRT ;DIDN'T USE BUFFER AFTER ALL
CONI CHX,T ;COUNT LOST PACKETS
LDB T,[$CHXLC,,T]
ADDM T,CHNLOS
MOVEI T,CHXREN ;ENABLE RECEIVER FOR NEXT PACKET
IORB T,CHXCNO
CONO CHX,CHXRCV(T)
CHXBK5: CONSO CHX,CHXXMT ;TRANSMIT DONE?
JRST CHXBK9
SKIPE T,CHOSTA ;TRANSMIT IN PROGRESS?
CONSO CHX,CHXABT ;AND WAS ABORTED?
JRST CHXBK7 ;NO TO EITHER, LOOK FOR MORE WORK
AOS CHNABT ;METER TRANSMIT ABORTS
CAIL T,NCHRTR ;ABORTED TOO MANY TIMES?
JRST CHXBK7 ;DONE WITH PACKET
AOS CHOSTA ;COUNT RETRANSMISSIONS
MOVEI T,CHXTEN
IORB T,CHXCNO
CONO CHX,CHXXMT(T) ;RETRANSMIT PACKET
JRST CHXBK9
CHXBK7: SETZM CHOSTA ;TRANSMITTER IDLE, LOOK FOR NEXT PACKET
CONO PI,PIOFF
HLRZ A,CHXXMQ ;ANYTHING QUEUED FOR TRANSMISSION?
JUMPE A,[ MOVEI T,CHXTEN ;DISABLE INTERRUPTS
ANDCAM T,CHXCNO
CONO CHX,@CHXCNO
CONO PI,PION
JRST CHXBK9 ]
HLRZ B,-2(A) ;CDR TRANSMIT QUEUE
HRLM B,CHXXMQ
SKIPN B
SETZM CHXXMQ ;QUEUE EMPTY NOW
CONO PI,PION
AOS CHOSTA ;NOW SEND THIS PACKET
MOVEI T,CHXHLF+CHXSWB ;CLEAR HALFWORD, BYTE-SWAP MODES
ANDCAM T,CHXCNO
CONO CHX,@CHXCNO
HRLI A,-%CPKDT ;TRANSMIT HEADER
DATAO CHX,(A)
AOBJN A,.-1
HRRZI A,-%CPKDT(A)
PUSHJ P,CHSWAB ;ENABLE BYTE SWAPPING IF NEEDED
LDB T,[$CPKNB(A)] ;GET SIZE OF PACKET
ADDI T,1 ;ROUND UP TO NEXT HALF WORD BOUNDARY
LSHC T,-2 ;CONVERT BYTES TO WORDS, T+1 GETS REMAINDER
HRLOI D,-1(T) ;MAKE AOBJN POINTER
EQVI D,%CPKDT(A)
JUMPGE D,.+3 ;EMPTY PACKET BOUNDARY CASE
DATAO CHX,(D)
AOBJN D,.-1
MOVEI T,CHXHLF+CHXTEN ;SWITCH TO HALFWORD MODE, ENABLE DONE INTR
IORM T,CHXCNO
CONO CHX,@CHXCNO
TLNE T+1,400000 ;SEND EXTRA HALFWORD IF NEEDED
DATAO CHX,(D)
MOVEI T,CHXSWB ;DISABLE SWAP BYTES MODE
ANDCAM T,CHXCNO
CONO CHX,@CHXCNO
LDB T,[$CPKDN(A)] ;GET DESTINATION SUBNET
HRRZ D,SBNRUT(T) ;GATEWAY TO THAT SUBNET
CAIGE T,NSUBNT
CAIN T,MYCHAD_-8 ;IF ON LOCAL CABLE
LDB D,[$CPKDA(A)] ;GO DIRECT
LSH D,16.+4
DATAO CHX,D ;STORE HARDWARE DESTINATION ADDRESS
MOVE T,CHXCNO ;TRANSMIT PACKET
CONO CHX,CHXXMT(T)
CONI CHX,T
TLNE T,(CHXOVR) ;CAN'T HAPPEN UNLESS HARDWARE BROKEN
CHXBKZ: BUG HALT,[CHAOS: I/O BUS OVERRUN]
HRROS B,-2(A) ;MARK IT NOT ON TRANSMIT LIST
AOJN B,.+2 ;AND UNLESS IT IS ON SEND LIST
PUSHJ P,CHABRT ;RETURN IT TO FREE
CHXBK9: MOVSI 17,CHXACS ;DISMISS INTERRUPT
BLT 17,17
JRST 12,@CHXBRK
CHSWAB: LDB T,[$CPKOP(A)] ;DOES THIS PACKET NEED BYTE SWAPPING?
TRNE T,200
JRST [ TRNE T,100
POPJ P, ;BINARY DATA
JRST CHSWB1 ] ;CHARACTER DATA
IDIVI T,40
MOVE T,CHSWBT(T)
LSH T,(T+1)
JUMPL T,CPOPJ ;BINARY CONTROL PACKET
CHSWB1: MOVEI T,CHXSWB ;CHARACTER, SWAP DEM BYTES
IORM T,CHXCNO
CONO CHX,@CHXCNO
POPJ P,
CHSWBT: 1_<35.-%COOPN>+1_<35.-%COSTS>+1_<35.-%CORUT>
0 ? 0 ? 0
];CH10P
SUBTTL CH-11 INTERRUPT ROUTINES
;The Unibus Chaosnet board interrupts on the same level as TTYs,
;and comes to CHXBKH via vectored interrupt. We use a programmed
;interrupt request to drop down to a lower interrupt level for the
;slow packet-copying operation, so as not to interfere with the TTYs,
;then turn NETOFF when we call into the Chaosnet NCP.
;(We actually use NETOFF-1 and NETON-1 so as not to interfere with
;CLKOFF. This assumes that interrupt levels between CLKCHN and
;CHXCHN are never turned off.)
IFN CH11P,[
;;; Macros that will eventually be instructions
DEFINE PACK16 AC,E ;AC,AC+1 right-aligned and zero-filled
LSH AC,16.
IOR AC,AC+1
LSH AC,4
MOVEM AC,E
TERMIN
DEFINE PACK8 AC,E ;AC: ...B2B1 AC+1: ...B4B3 zero-filled!!
ROTC AC,-8 ;B3...B2 B1...B4
ROT AC,-16. ;B1,B2,B3 in position, B4 right-aligned
ADDI AC+1,(AC+1) ;Shift RH(AC+1) left 4 bits
ADDI AC+1,(AC+1)
ADDI AC+1,(AC+1)
ADDI AC+1,(AC+1) ;B1,B4 in position in AC+1
IOR AC,AC+1
MOVEM AC,E
TERMIN
DEFINE UNPK16 AC,E ;Doesn't bother masking off garbage bits
MOVE AC,E
MOVE AC+1,AC
ROT AC,16. ;First halfword right-aligned
LSH AC+1,-4 ;Second halfword right-aligned
TERMIN
DEFINE UNPK8 AC,E
MOVE AC,E ;B1B2B3B4...
ROT AC,8 ;B2B3B4...B1
MOVE AC+1,AC
AND AC,[377_2,,377] ;...B3...B1 zero-filled
ROT AC+1,16. ;B4...B1B2B3
AND AC+1,[377_12,,377_8];B4...B2... zero-filled
IORB AC,AC+1 ;B4B3...B2B1
ROT AC+1,16. ;...B4B3, garbage in high bits
TERMIN
EBLK
CHXACS: BLOCK 20
CHXSVH: 0
CHXPDL: -60,,.
BLOCK 60
CHXBKH: 0 ;Hardware interrupt on TTYCHN comes here
BBLK
CONO PI,CHXRQ ;Redirect to lower interrupt level
MOVEM T,CHXSVH ;Clear hardware interrupt enable
MOVEI T,%CAREN+%CATEN ; so the Chaos board will stop interrupting
ANDCAB T,CHXCSR
IOWRI T,CAICSR
MOVE T,CHXSVH
JRST 12,@CHXBKH
EBLK
CHXBRK: 0 ;Software interrupt on CHXCHN comes here
BBLK
CONO PI,020000+200_<-CHXCHN> ;BAG-BITING DEC LOSERS
MOVEM 17,CHXACS+17
MOVEI 17,CHXACS
BLT 17,CHXACS+16
MOVE P,CHXPDL
IORDI T,CAICSR ;Check for received packet
TRNN T,%CARDN
JRST CHXBK3 ;No incoming packet yet
TRNE T,%CAERR ;Check for error in received packet
JRST [ AOS CHNCRC
JRST CHXBK1 ] ;Ignore packet
IORDI R,CAIRBC ;Number of bits in packet - 1
SUBI R,31. ;Exclude the three extra hardware words
TRNE R,17
JRST [ AOS CHNWLE ;Length not a multiple of 16
JRST CHXBK1 ]
ASH R,-5 ;32-bit word count, rounded up
PUSHJ P,CHABGI ;Get place to put packet
JRST [ AOS CHNLOS ;No buffers, lose this packet
JRST CHXBK1 ]
HRLI A,-%CPKDT ;Copy out the packet header
CHSRC1: IORDI B,CAIRBF
IORDI C,CAIRBF
PACK16 B,(A)
AOBJN A,CHSRC1
PUSHJ P,CHSHDR ;Decode the header
JRST CHSRC4 ;No byte swapping
JUMPGE D,CHSRC3
CHSRC2: IORDI B,CAIRBF ;Read out the data, byte-swapped
IORDI C,CAIRBF
PACK8 B,(D)
AOBJN D,CHSRC2
CHSRC3: JUMPGE H,CHSRC7 ;Jump if even packet length
IORDI B,CAIRBF ;Residual halfword
SETZ C, ;Somebody depends on zero here
PACK8 B,(D)
AOJA D,CHSRC7
CHSRC4: JUMPGE D,CHSRC6
CHSRC5: IORDI B,CAIRBF ;Read out the data, halfwords
IORDI C,CAIRBF
PACK16 B,(D)
AOBJN D,CHSRC5
CHSRC6: JUMPL H,[ IORDI B,CAIRBF ;Residual halfword
SETZ C, ;Somebody depends on zero here
PACK16 B,(D)
AOJA D,CHSRC7 ]
CHSRC7: SUB D,R ;AOBJN pointer minus number of words in packet
CAIE A,(D)
JRST [ AOS CHNPLE ;Packet length disagrees with hardware length
JRST CHXBK2 ]
IORDI T,CAIRBF ;Read the three hardware header words
IORDI T,CAIRBF
IORDI T,CAIRBF
IORDI T,CAICSR
TRNE T,%CAERR ;Make sure packet came out of RAM okay
JRST [ AOS CHNCR2 ;Garbage, try again
JRST CHXBK2 ]
IORDI T,CAIRBC ;Make sure counter didn't spazz
CAIE T,7777
JRST [ AOS CHNSPZ
JRST CHXBK2 ]
CONO PI,NETOFF-1 ;Get to network interrupt level
PUSHJ P,CHAPII ;Process the input
CONO PI,NETON-1
CHXBK1: IORDI T,CAICSR ;Count lost packets
LDB TT,[$CALOS,,T]
ADDM TT,CHNLOS
MOVE TT,CHXCSR
IORI TT,%CARCL ;Enable receiver for next packet
IOWRI TT,CAICSR
CHXBK3: TRNN T,%CATDN ;Transmit done?
JRST CHXBK8 ;No, dismiss
SKIPN TT,CHOSTA ;Transmit in progress?
JRST CHXBK7 ;No, look for something to transmit
TRNN T,%CATAB ;Yes, was it aborted?
JRST CHXBK5 ;No, we're done with that packet
AOS CHNABT ;Meter transmit aborts
CAIGE TT,NCHRTR ;Aborted too many times?
JRST CHXBK7 ;No, retransmit it
CHXBK5: CONO PI,PIOFF ;Lock transmit list
HLRZ A,CHXXMQ ;Get packet probably being transmitted now
JUMPE A,[ CONO PI,PION ;It vanished?
JRST CHXBK6 ]
HLRZ B,-2(A) ;CDR transmit queue
HRLM B,CHXXMQ
SKIPN B
SETZM CHXXMQ ;Queue empty now
CONO PI,PION
HRROS B,-2(A) ;Mark it not on transmit list
AOJN B,CHXBK6 ;And unless it is on send list
PUSHJ P,CHABRT ;Return it to free
CHXBK6: SETZM CHOSTA ;Transmitter idle, look for next packet
CHXBK7: HLRZ A,CHXXMQ ;Anything queued for transmission?
JUMPE A,CHXBK9 ;No, leave interrupts disabled
AOS CHOSTA ;Count retransmissions
MOVE T,CHXCSR ;Reset transmitter
IORI T,%CATDN
IOWRI T,CAICSR
HRLI A,-%CPKDT ;Transmit header
CHXXM1: UNPK16 B,(A)
IOWRI B,CAIWBF
IOWRI C,CAIWBF
AOBJN A,CHXXM1
PUSHJ P,CHSHDR ;Decode the header
JRST CHXXM4 ;No byte swapping
JUMPGE D,CHXXM3
CHXXM2: UNPK8 B,(D) ;Transmit data with byte swapping
IOWRI B,CAIWBF
IOWRI C,CAIWBF
AOBJN D,CHXXM2
CHXXM3: JUMPGE H,CHXXM7 ;Jump if even packet length
UNPK8 B,(D) ;Transmit residual bytes
IOWRI B,CAIWBF
JRST CHXXM7
CHXXM4: JUMPGE D,CHXXM6
CHXXM5: UNPK16 B,(D) ;Transmit data with byte swapping
IOWRI B,CAIWBF
IOWRI C,CAIWBF
AOBJN D,CHXXM5
CHXXM6: JUMPGE H,CHXXM7 ;Jump if even packet length
UNPK16 B,(D) ;Transmit residual bytes
IOWRI B,CAIWBF
CHXXM7: LDB T,[$CPKDN(A)] ;Get destination subnet
HRRZ D,SBNRUT(T) ;Gateway to that subnet
CAIGE T,NSUBNT
CAIN T,MYCHAD_-8 ;If on local cable,
LDB D,[$CPKDA(A)] ; go direct
IOWRI D,CAIWBF ;Store hardware destination address
IORDI T,CAIXMT ;Transmit packet
CHXBK8: MOVEI A,%CATEN ;Enable transmit-done interrupt if xmitting
CHXBK9: IORI A,%CAREN ;Enable receive-done interrupt always
IORB A,CHXCSR
IOWRI A,CAICSR
MOVSI 17,CHXACS ;Dismiss software interrupt
BLT 17,17
JRST 12,@CHXBRK
CHXBK2: PUSHJ P,CHABRT ;Packet no good, discard it
JRST CHXBK1
;Examine packet in A, return AOBJN pointer to data in D,
; H is negative if there is an extra halfword after that.
; W gets number of full words of data (same as LH D).
; T,U get clobbered
; Returns:
; +1 16-bit data
; +2 8-bit data
CHSHDR: HRRZI A,-%CPKDT(A) ;Restore packet address
LDB W,[$CPKNB(A)] ;Get size of packet in bytes
CAILE W,%CPMXC
MOVEI W,%CPMXC ;Self-defense
ADDI W,1 ;Round up to next word boundary
LSHC W,-2 ;Convert bytes to words, H gets remainder
HRLOI D,-1(W) ;Make AOBJN pointer
EQVI D,%CPKDT(A)
LDB T,[$CPKOP(A)] ;Does this packet need byte swapping?
TRNE T,200
JRST [ TRNN T,100
AOS (P) ;Character data
POPJ P, ] ;Binary data
IDIVI T,40
MOVE T,CHSWBT(T)
LSH T,(T+1)
JUMPL T,CPOPJ ;Binary control packet
JRST POPJ1 ;Characters
CHSWBT: 1_<35.-%COOPN>+1_<35.-%COSTS>+1_<35.-%CORUT>
0 ? 0 ? 0
];CH11P
SUBTTL CHAOS NET BUFFER LIST STUFF
OVHMTR CHL
;BUFFERS ARE PKTBSZ WORDS LONG; 2 HEADER WORDS AND %CPMXW PACKET WORDS.
;PKTBSZ IS A POWER OF 2 AND LESS THAN 1K (MEMORY PAGE SIZE).
;NOTE THAT A BUFFER ADDRESS POINTS AT THE FIRST PACKET WORD
;AND THE HEADER WORDS ARE AT NEGATIVE ADDRESSES.
;FIRST HEADER WORD: -2(A)
; RH LIST THREAD FOR MOST LISTS, 0=END, -1=NOT ON LIST
; LH LIST THREAD FOR TRANSMIT LIST
;SECOND HEADER WORD: -1(A)
; TIME RECEIVED OR TIME PUT ON TRANSMIT LIST
; OR VALUE OF I FOR A PACKET ON THE LSN QUEUE
; ASCII/LUNCH/ FOR A PACKET ON THE FREE LIST
;I DO IT THIS WAY (PIOFF) TO AVOID HAVING TO PUSH AND POP PI STATUS,
;CONO PI,NETOFF CAN LOSE AT INTERRUPT LEVEL (MAINLY THE NETON LOSES)
;THESE ROUTINES TURN OFF INTERRUPTS MOMENTARILY SO THAT
;LISTS MAY BE SAFELY MANIPULATED.
;Q POINTS TO THE HEADER WORD OF A QUEUE, REMOVE THE FIRST
;THING AND RETURN IN A. (ZERO IF NONE) CLOBBERS T
CHAQGF: CONO PI,PIOFF
HLRZ A,(Q) ;GET FIRST
JUMPE A,PIONJ ;EMPTY
HRRZ T,-2(A) ;GET SECOND
HRLM T,(Q) ;MAKE FIRST
IFN FTRCHK,[
JUMPN T,PIONJ
HRRZ T,(Q)
CAIE T,(A)
BUG PAUSE,[CHAOS LIST TRASHED],OCT,Q
SETZM (Q) ;IS NOW EMPTY
];FTRCHK
IFE FTRCHK,[
SKIPN T
SETZM (Q) ;IS NOW EMPTY
];FTRCHK
CONO PI,PION
POPJ P,
;RETURN BUFFER INTO WHICH THE BYTE POINTER IN A POINTS. CLOBBERS A,T,Q
CHBPFR: SUBI A,1 ;SIOKT LIKES TO MAKE BP POINT AT NEXT BUFFER
ANDI A,-PKTBSZ
ADDI A,2
JRST CHABRT
;RETURN BUFFER POINTED TO BY A TO FREE UNLESS ON TRANSMIT LIST.
CHABR1: HLLOS T,-2(A) ;RH GETS -1, NO LONGER ON REGULAR LIST
AOJN T,CPOPJ ;EXIT IF STILL ON TRANSMIT LIST
;DROPS THROUGH
;RETURN BUFFER POINTED BY A TO FREE STORAGE. CLOBBERS T, Q.
CHABRT: MOVEI Q,CHQFRE
IFN FTRCHK,[
SKIPN A
BUG PAUSE,[FREEING 0]
];FTRCHK
MOVE T,[ASCII/LUNCH/] ;TANSTAAFL
MOVEM T,-1(A)
SETOM -2(A) ;NOT ON TRANSMIT LIST NOW (THIS IS WHAT INITS
AOS CHFRBF ; LH[-2(A)] WHEN BUFFER FIRST CREATED)
;JRST CHAQPL ;DROPS THROUGH
;A POINTS TO A BUFFER, Q TO A QUEUE. PUT IT ON AS THE LAST THING. BASHES T.
CHAQPL: HLLZS -2(A) ;PUT ENDLIST IN RH
CONO PI,PIOFF
HRRZ T,(Q) ;GET LAST
HRRM A,(Q) ;MAKE NEW LAST
JUMPN T,[HRRM A,-2(T) ;MAKE A COME AFTER IT
JRST PIONJ ]
HRLM A,(Q) ;WAS EMPTY, ALSO IS NEW FIRST
CONO PI,PION
POPJ P,
;A POINTS TO A BUFFER, Q TO A QUEUE. PUT IT ON AS THE FIRST THING. SMASHES T.
CHAQPF: CONO PI,PIOFF
HLRZ T,(Q) ;GET FIRST
HRRM T,-2(A) ;MAKE SECOND
HRLM A,(Q) ;MAKE NEW FIRST
SKIPN T
HRRM A,(Q) ;WAS EMPTY, ALSO MAKE NEW LAST
CONO PI,PION
POPJ P,
;ALLOCATE A BUFFER AT MAIN PROGRAM LEVEL, TO A, MASHES T, TT, Q, B.
CHABG0: PUSHJ P,UDELAY ;WAIT FOR MEMORY
CHABGT: PUSHJ P,CHABGI
JRST CHABG0
POPJ P, ;WIN
;ALLOCATE A BUFFER, RETURN POINTER TO IT IN A, SKIP. BLOWS AWAY T, TT, Q.
;NON-SKIP IF NO BUFFERS AVAILABLE. (DOESN'T MAKE NEW ONES IF FREE LIST EMPTY)
CHABAL: MOVEI Q,CHQFRE
PUSHJ P,CHAQGF
JUMPE A,CPOPJ
SETZM -1(A) ;NO LUNCH
SOS CHFRBF
JRST POPJ1
;ALLOCATE A BUFFER TO A, MAKE NEW IF NONE FREE. OBLITERATES T,Q,B.
;NON-SKIP IF CAN'T GET MEMORY. (SUITABLE FOR CALLING FROM INT LEVEL)
CHABGI: PUSHJ P,CHABAL ;TRY TO ALLOCATE A BUFFER FROM FREE LIST
CAIA
JRST POPJ1 ;WON, RETURN
CONI PI,Q ;SAVE PI CHANNELS ON STATUS
ANDI Q,177
CONO PI,UTCOFF ;MAKE THE WORLD SAFE FOR IOMQ
MOVE B,CHTTBF
CAIL B,CHMXBF ;MAKE SURE NOT TO USE UP ALL CORE
JRST CHABG4
PUSHJ P,IOMQ ;GET 1K OF MEMORY
JRST CHABG3 ;MEM NOT AVAILABLE, FAIL
CONO PI,PICON(Q) ;WON, RESTORE PI STATUS
MOVEI B,MUCHA
DPB B,[MUR,,MEMBLT(A)]
LSH A,10. ;ADDRESS OF 1K OF ALLOCATED MEMORY
ADD A,[-<2000/PKTBSZ>,,2] ;-BUFFERS PER 1K,,OFFSET TO HEADER
CHABG2: PUSHJ P,CHABRT ;PUT THEM ALL ON FREE LIST
ADDI A,PKTBSZ-1
AOBJN A,CHABG2
MOVEI B,<2000/PKTBSZ> ;THIS MANY MORE BUFFERS HAVE BEEN CREATED
ADDM B,CHTTBF
JRST CHABGI ;NOW GO ALLOCATE ONE
;HERE IF CHAOS NET TRYING TO USE UP TOO MUCH CORE
CHABG4: MOVE B,CHMXTM ;DON'T COMPLAIN TOO OFTEN
ADDI B,60.*30. ;JUST ONCE A MINUTE
CAMLE B,TIME
JRST CHABG3
IFE CH10P, BUG CHECK,[CHAOS NET ATTEMPTING TO USE TOO MUCH CORE]
IFN CH10P,[
CONI CHX,B
BUG CHECK,[CHAOS NET ATTEMPTING TO USE TOO MUCH CORE, CONI=],OCT,B,[CONO=],OCT,CHXCNO,[CHOSTA=],OCT,CHOSTA
];CH10P
MOVE B,TIME
MOVEM B,CHMXTM
CHABG3: CONO PI,PICON(Q) ;LOST, RESTORE PI STATUS
POPJ P, ;AND TAKE ERROR RETURN
;FREE A WHOLE LIST OF BUFFERS, Q-> HEAD. DESTROYS A,T
CHALFR: PUSHJ P,CHAQGF
JUMPE A,CPOPJ
PUSH P,Q
PUSHJ P,CHABR1 ;FREE UNLESS STILL ON TRANSMIT LIST
POP P,Q
JRST CHALFR
;Q -> A TRANSMIT QUEUE, FLUSH ALL BUFFERS BELONGING TO INDEX I.
;CLOBBERS A,B,C,T
CFLXMQ: PUSH P,Q
CONO PI,NETOFF ;DON'T LET TRANSMIT LIST CHANGE (AT ALL)
HLRZ A,(Q) ;HEAD OF TRANSMIT LIST
JUMPE A,CFLXM3
MOVEI B,2(Q) ;B PREVIOUS PACKET, A CURRENT, C NEXT
CFLXM1: HLRZ C,-2(A) ;GET THREAD TO NEXT
IFN FTRCHK,[
CAIN C,-1
JRST 4,. ;CLAIMS NOT TO BE ON LIST?
];FTRCHK
LDB T,[$CPKSX(A)] ;GET THIS PACKET'S INDEX
CAME T,I
JRST CFLXM2
HRLM C,-2(B) ;THREAD PREVIOUS TO NEXT
HRROS T,-2(A) ;IF THIS BUFFER IS NOT ALSO ON SEND LIST,
AOJN T,.+2
PUSHJ P,CHABRT ;RETURN IT
SKIPA Q,(P)
CFLXM2: MOVE B,A
SKIPE A,C
JRST CFLXM1
HRRM B,(Q) ;LAST PACKET ON LIST MAY HAVE CHANGED
CAIN B,2(Q)
SETZM (Q) ;TRANSMIT QUEUE IS NOW EMPTY
CFLXM3: POP P,Q
JRST NETONJ
;SEARCH LIST IN Q FOR PACKET WHOSE CONTACT NAME MATCHES THAT
;OF PACKET IN A, RETURN IT IN B, SKIPPING IF WINNING. CLOBBERS T,TT,C,D,E,H,J.
;THE PACKET RETURNED IN B IS DE-LINKED FROM THE SEARCHED QUEUE.
;HAS TO BE CALLED WITH NETOFF OR IN PROGRESS, SO LIST CAN'T GET MUNGED.
;I HOPE IT'S NOT TOO BLETCHEROUSLY SLOW.
CHAQSR: HLRZ B,(Q) ;GET START OF LIST TO SEARCH
JUMPE B,CPOPJ ;EMPTY, LOSE
MOVEI J,0 ;PACKET PREVIOUS TO B
CHAQS1: LDB C,[$CPKNB(A)] ;SET UP STRING COMPARE LOOP
LDB H,[$CPKNB(B)] ;THIS ASSUMES NO ZERO-LENGTH STRINGS
MOVEI D,%CPKDT(A)
HRLI D,440800
MOVEI E,%CPKDT(B)
HRLI E,440800
CHAQS2: ILDB T,D
ILDB TT,E ;DON'T IGNORE CASE, THAT WOULD JUST SLOW THIS
CAME T,TT ;BAG-BITER DOWN EVEN MORE. EVERYONE SHOULD
JRST CHAQS4 ;PUT THEIR CONTACT NAMES IN UPPER-CASE.
CAIN T,40 ;TERMINATE ON SPACE
JRST CHAQS5
SOJLE C,CHAQS3
SOJG H,CHAQS2
ILDB T,D
CAIE T,40
JRST CHAQS4
CHAQS5: HRRZ C,-2(B) ;WON, DELINK PACKET FROM LIST
JUMPE J,[ HRLM C,(Q)
JUMPN C,POPJ1
IFN FTRCHK,[
HRRZ C,(Q) ;CHECK LIST ENDING IN RIGHT PLACE
CAIE C,(B)
JRST 4,.
];FTRCHK
SETZM (Q)
JRST POPJ1 ]
HRRM C,-2(J)
JUMPN C,POPJ1
HRRM J,(Q) ;TOOK LAST PACKET, STORE NEW LAST
JRST POPJ1
CHAQS3: SOJLE H,CHAQS5
ILDB TT,E
CAIN TT,40
JRST CHAQS5
CHAQS4: MOVE J,B ;THIS ONE DOESN'T MATCH, TRY NEXT
HRRZ B,-2(B)
JUMPN B,CHAQS1
POPJ P, ;NO MATCHES
;THIS ROUTINE RUNS IN THE CORE JOB AND CLEANS UP MEMORY USED BY CHAOS BUFFERS
;SMASHES ALL ACS
CHCLN: SKIPE A,CHTTBF ;SEE IF 2/3 OR MORE OF BUFFERS FREE
SKIPN B,CHFRBF
POPJ P, ;NO BUFFERS OR NONE FREE, NOTHING TO DO
SUBM A,B
IDIV A,B ;GET RATIO OF TOTAL TO USED
CAIGE A,3 ;NOTE IF B IS ZERO A IS UNCHANGED
POPJ P, ; AND AT LEAST 32.
IFL TSYSM-256., MOVEI D,TSYSM-1 ;SCAN MEMORY FOR CHAOS BUFFER PAGES
.ELSE MOVEI D,255.
CHCLN0: LDB A,[MUR,,MEMBLT(D)]
CAIE A,MUCHA
CHCLN4: SOJGE D,CHCLN0
JUMPL D,CPOPJ
MOVE A,D ;QUICKLY DETERMINE IF ANY NON-FREE BUFFERS
LSH A,10. ; ON THIS PAGE
HRLI A,-<2000/PKTBSZ>
MOVE T,[ASCII/LUNCH/]
CHCLN5: CAME T,1(A)
JRST CHCLN4 ;NOT FREE, DON'T BOTHER WITH SLOW STUFF
ADDI A,PKTBSZ-1
AOBJN A,CHCLN5
SETZB C,CHCLNQ ;COLLECT ALL FREE BUFFERS THAT ARE ON THIS PAGE
MOVE E,CHFRBF ;LOOP ABOUT AS MANY TIMES AS THERE ARE FREE BUFFERS
CHCLN1: PUSHJ P,CHABAL ;GET NEXT FREE BUFFER
JUMPE A,CHCLN2
LDB B,[121000,,A]
CAMN B,D
JRST [ MOVEI Q,CHCLNQ ;THIS ONE'S ON THE PAGE, SAVE IT
PUSHJ P,CHAQPL
AOJA C,.+2 ] ;COUNT THEM
PUSHJ P,CHABRT ;NOT ON THE PAGE, PUT BACK
SOJG E,CHCLN1
CHCLN2: CAIE C,<2000/PKTBSZ> ;DID WE GET THE WHOLE PAGE?
JRST [ MOVEI Q,CHCLNQ ? PUSHJ P,CHALFR ? JRST CHCLN4 ]
MOVNS C ;YES, GET RID OF THESE BUFFERS
ADDM C,CHTTBF
MOVE A,D
PUSHJ P,MEMR
JRST CHCLN
OVHMTR CHZ