Trailing-Edge
-
PDP-10 Archives
-
SRI_NIC_PERM_SRC_3_19910112
-
mit/monitor/new-chaos.mac
There are no other files named new-chaos.mac in the archive.
;*****************************************************************
;** **
;** **
CHSDBG==1 ;Turn on debugging
;** **
;** **
;*****************************************************************
;<BERLIN.M5>CHAOS.MAC.17, 24-Sep-82 02:22:45, Edit by BERLIN
;1032 Comment out unreachable code
;<BERLIN.M5>CHAOS.MAC.16, 22-Sep-82 15:04:32, Edit by BERLIN
;1031 Old (?) way of handling EOF
; Turn off debugging - CHABDP leaves junk in syserr block and
; causes ILLUUO when referenced. Need to fix some bugs soon.
;1017 Also make this bug go away for the time being...
;<BERLIN>CHAOS.MAC.12, 24-Aug-82 21:56:47, Edit by BERLIN
;1016 Turn on debugging for a while...
; The problem is that apparently a connection block is getting
; used after it is released. The latest bughlt (piptr1) came
; at CHIDT9, when CHAPBF was -1, and PKT check wants 0 for empty q
;<BERLIN.M5>CHAOS.MAC.9, 21-Aug-82 23:07:50, Edit by BERLIN
;1014 Real check for empty q (How did this ever work???)
;1005 Force BBNFLG to 0 for MIT, remove gatinc,gattdnc
;<BERLIN.M5>CHAOS.MAC.5, 10-Aug-82 09:36:49, Edit by BERLIN
;1004 Remove support for receiving packets from the Arpanet
;<5.MITMON>CHAOS.MAC.4, 21-Jul-82 19:57:49, Edit by JTW
;1003 MMcM's fix for retrans problem with big packet numbers,
; DCP's fix for input packets sometimes not noticed
;<BERLIN.M5>CHAOS.MAC.3, 5-Jul-82 12:36:11, Edit by BERLIN
;1002 Remove arpa routing again
;<SYS.MONITOR>CHAOS.MAC.429, 5-Jul-82 01:30:36, Edit by BERLIN
;1000 V5 merge
;Fixes and changes from TAPPAN@BBN:
;<BBN-4-MONITOR>CHAOS.MAC.18, 10-Jan-82 17:47:31, Edit by TAPPAN
; Make CHGETP save temporaries to fix problem with T3 getting
; clobbered from GETINP
;<BBN-4-MONITOR>CHAOS.MAC.10, 18-Nov-81 19:00:57, Edit by TAPPAN
; Fixes to internet code, involving the fact that we
; can't call GETBLK while NOSKED
;[BBND]SNARK:<TAPPAN.4>CHAOS.MAC.26, 27-Oct-81 12:39:01, Ed: TAPPAN
; Make internet stuff work, some cleanup to NOSKDP/OKSKDP
; CHXINT cannot send packets if called from schedular context
;<SYS.MONITOR>CHAOS.MAC.427, 9-Apr-82 09:30:26, Edit by BERLIN
;284 Add up to 64 subnets and remove routing to LLL subnets
;284 because it's still buggy and I don't have time to support it.
;<FOONEX>CHAOS.MAC.425, 14-Jan-82 16:31:53, Edit by MMCM
;<SYS.MONITOR>CHAOS.MAC.423, 4-Dec-81 13:29:16, Edit by BERLIN
;255 Add routine GATDNC to tell internet when NFE is down,
;and move call to GATINC so called whenever NFE comes up.
;M:<BERLIN>CHAOS.MAC.418 23-Nov-81 00:15:27, Edit by BERLIN
;Complete conditional so we can assemble without debug code
;<SYS.MONITOR>CHAOS.MAC.412, 14-Sep-81 23:14:48, Edit by MMCM
; Save more registers in arpanet receive routines.
;<SYS.MONITOR>CHAOS.MAC.411, 8-Sep-81 12:43:33, Edit by CPR
; Take out 233, since done in RELCNN (FREE.MAC) now.
; Unify the DTEFLG, NETDTE, CHADTE nonsense a little by replacing
; all DTEFLG references with NETDTE references (NETDTE is now -1
; to signify no DTE support, and 0-3 for the network DTE otherwise.)
;233 Save registers in global routine RELCON
;SRC:<SYS.MONITOR>CHAOS.MAC.409 24-Aug-81 19:02:57, Edit by MMCM
; Add some internet support for BBN
;SRC:<SYS.MONITOR>CHAOS.MAC.407 12-Aug-81 22:16:32, Edit by MMCM
; Fix version skews
;<FOONEX>CHAOS.MAC;406 10-Aug-81 16:03:52, Edit by MMCM
; Several bugs in CHA:.-
;SRC:<SYS.MONITOR>CHAOS.MAC.397 7-May-81 19:35:46, Edit by MMCM
; Check uniquizer too in CHFNDX
;SRC:<SYS.MONITOR>CHAOS.MAC.397 2-May-81 12:42:15, Edit by MMCM
; Bug in arpa routing added by use of single temporary packet
;<FOONEX>CHAOS.MAC;392 21-Apr-81 17:30:08, Edit by MMCM
; Allow interrupts out of GETOUT hang
;SRC:<SYS.MONITOR>CHAOS.MAC.375 9-Apr-81 14:54:02, Edit by CPR
; Merge in HIC's 2020 support.
;<FOONEX>CHAOS.MAC;373 29-Mar-81 21:08:13, Edit by MMCM
; Don't try to use indexing in previous context on byte instructions.
;SRC:<SYS.MONITOR>CHAOS.MAC.371 21-Mar-81 14:11:50, Edit by MMCM
;<FOONEX>CHAOS.MAC;370 14-Mar-81 13:14:08, Edit by MMCM
; Add conditional assembly for Foonly Tenex.
;SRC:<SYS.MONITOR>CHAOS.MAC.329 20-Mar-81 15:16:27, Edit by CPR
; Use temporary packet buffer for ARPA to CHAOS routing instead of
; allocating and freeing a packet each time.
;SRC:<SYS.MONITOR>CHAOS.MAC.327 11-Mar-81 23:29:48, Edit by MMCM
; Fix some bugs with sending over ARPA Net
;SRC:<SYS.MONITOR>CHAOS.MAC.326 25-Feb-81 16:41:15, Edit by CPR
; Add subnet 13 (EECS pseudo-subnet) to routing tables.
;SRC:<SYS.MONITOR>CHAOS.MAC.321 20-Feb-81 20:56:46, Edit by CPR
; Fix throwing away of packets-over-window to still mark an NVT
; connection as needing input attention at TTCH7 time; also fix
; case where foreign NCP violating protocol (by sending over window)
; would choke the connection entirely (at CHIDAT): now we just
; throw away a packet when it arrives if it isn't within the real
; receive window (ie, the last user packet # + receive window size).
;SRC:<SYS.MONITOR>CHAOS.MAC.316 15-Feb-81 18:05:30, Edit by CPR
; Add new form of OPENF: opening "CHA:.-" will get you a connection
; (immediately) through which you can send RFCs to your heart's
; delight, and see all the ANS, FWD, LOS and CLS packets that come
; wafting back in reply.
;SRC:<SYS.MONITOR>CHAOS.MAC.306 8-Feb-81 18:10:14, Edit by CPR
; Disgusting hack to send over window in SNDPKT after waiting for a
; long time for it to open up; see the "to do" section on how to do
; this right (someday). This is a temporary solution to avoid
; infinite hangage when a connection's window never opens up.
;SRC:<SYS.MONITOR>CHAOS.MAC.305 6-Feb-81 00:27:51, Edit by CPR
; When opening a listening connection, note that there's some RFC
; matching to do, potentially, to speed up the common case of a
; RFC coming in, not getting matched, and CHARFC starting up a
; server for it, which then listens for that contact name.
;SRC:<SYS.MONITOR>CHAOS.MAC.304 2-Feb-81 21:25:32, Edit by CPR
; Clear out any references to a connection in CHATTW at RELCON time.
;SRC:<SYS.MONITOR>CHAOS.MAC.299 28-Jan-81 16:54:03, Edit by CPR
; Super-paranoid locking in SNDPK0 to catch screw where a packet
; is ack'ed illegally by foreign NCP even before it's first
; transmitted (yes, it happens).
;SRC:<SYS.MONITOR>CHAOS.MAC.295 26-Jan-81 00:13:33, Edit by CPR
; Add variable transmit and receive window sizes for tuning.
;SRC:<SYS.MONITOR>CHAOS.MAC.264 18-Jan-81 12:19:08, Edit by CPR
; Obey the input "window" for the distinguished RFC handler so that
; if it dies, we won't fill up memory with unhandled-RFC packet copies.
;SRC:<SYS.MONITOR>CHAOS.MAC.214 12-Jan-81 12:35:55, Edit by CPR
; CHAXMT now calls RELPKM to get rid of a packet when done, in
; the case where it didn't make it onto any send lists and we didn't
; queue it for anywhere.
; Add extra checking for a hung Chaosnet main background fork (done
; by the local routing fork, which has little reason to hang), and
; for a wedged front-end (CHNPO1, fe quota, staying too low for too
; long).
;SRC:<SYS.MONITOR>CHAOS.MAC.180 9-Jan-81 16:45:33, Edit by CPR
; Make all calls to SNDPK0/SNDPK1 and CHAXMT ask for block/nonblock
; to allow guarantee of never blocking when don't want to;
; add separate background fork for just local routing;
; move actual server startup and shutdown worrying out of monitor
; (opening "CHA:." will let a privileged fork read copies of all
; unhandled RFCs).
;SRC:<SYS.MONITOR>CHAOS.MAC.168 7-Jan-81 19:53:52, Edit by CPR
; Put back calls to RELPKT for checking's sake only (when debugging,
; will complain if not releasable right away); add "reasons" to RELPKM/T
; calls for debugging; add settable RFC timeout period.
;SRC:<SYS.MONITOR>CHAOS.MAC.162 2-JAN-80 15:55:56, Edit by JIS
; Fix bug in error return from CPYPKZ
;SRC:<SYS.MONITOR>CHAOS.MAC.153 22-Dec-80 16:56:46, Edit by CPR
; Always call RELPKM instead of RELPKT since everyone is now careful to
; maintain the link fields of a packet.
;SRC:<SYS.MONITOR>CHAOS.MAC.108 15-Dec-80 14:32:58, Edit by CPR
; Local routing is now done via background fork (to insulate both sides
; of a connection from each other somewhat).
;SRC:<SYS.MONITOR>CHAOS.MAC.104 15-Dec-80 12:40:13, Edit by CPR
; Give up on efficiency attempt for Chaos NVT handling: put it back the
; way it was (too slow to be acceptable).
;SRC:<SYS.MONITOR>CHAOS.MAC.99 14-Dec-80 18:12:08, Edit by CPR
; Attempt at better Chaos NVT has-output handling
; (start-output now sets CF%TTO in an NVT's connection).
;SRC:<SYS.MONITOR>CHAOS.MAC.78 4-Dec-80 14:08:52, Edit by CPR
; Add debugging code for extra caution in dealing with connections, packets.
; Use HOSTS2.BIN for host table now. General background fork cleanup.
;SRC:<SYS.MONITOR>CHAOS.MAC.61 3-Dec-80 17:00:58, Edit by CPR
; Add local routing for non-ARPA monitors.
;SRC:<SYS.MONITOR>CHAOS.MAC.59 3-Dec-80 16:44:12, Edit by CPR
; Let OKSKDP and NOSKDP be called nestedly; wrap them around local
; routing calls to CHIPKT for safety's sake.
;SRC:<SYS.MONITOR>CHAOS.MAC.58 3-Dec-80 16:25:58, Edit by CPR
; Various changes at EBM's suggestion
;<SYS.MONITOR>CHAOS.MAC.40 18-Oct-80 04:22:00, Edit by Jis
;206 Add in support for chaos-net-user capability
;SRC:<SYS.MONITOR>CHAOS.MAC.28 19-Sep-80 13:31:09, Edit by CPR
; Do Chaos NVT input processing at TTCH7 time.
;<SYS.MONITOR>CHAOS.MAC.22 16-Sep-80 19:50:01, Edit by Jis
; Fix up CPYPKT to have error and nonerror return
;<SYS.MONITOR>CHAOS.MAC.7 8-Aug-80 11:15:17, Edit by Jis
;199 Don't wait for non-open connections to flush output buffers
;<NEW.MONITOR>CHAOS.MAC.5 13-Jul-80 22:59:00, Edit by Jis
;197 Allow user to specify RFC packet contents in OPENF call
;<4.MONITOR>CHAOS.MAC.12 8-Feb-80 15:57:37, Edit by MMCM
;166 CHAOSnet packets over the ARPANET to LLL
;<4.MONITOR>CHAOS.MAC.5, 6-Jan-80 01:46:45, Edit by MT
; Fixed up NVT support
;<4.MONITOR>CHAOS.MAC.1 3-Jan-80 05:53:20, Edit by MMCM
; Merged into release 4 MIT-XX standard system
REPEAT 0,< -- To do --
-- Doesn't currently support both DECnet and Chaosnet over DN20's
(separate, now, of course); in particular, the DEDMCB usage herein
doesn't let the DECnet one get control. Will need work in both
areas of Chaos and DECnet support.
-- The various calls to UNLDIS herein are probably not right: they
have NOINTs after them to re-lock up processarily, but this doesn't
re-lock the JFN they're dealing with. Have to figure how to do that
right in each case.
-- net-independent CVHST, GTHST, etc. (needs thought)
-- at CHAXMT, we now never send a packet when the -11 is over quota,
and this helps solve the problem of the -11 getting a message when it
has no buffer space and crashing (in the case of 20F) or simply
ignoring the message (and thus no ack ever comes back from the -11),
which means we lose track of the -11 status. However, this has the
bad side effect that short control messages generated at interrupt
level (eg, STS to stop duplicate retransmissions) mightn't get out when
they should. A better solution is to reserve some "interrupt level"
space in the -11 as well as normal, process-level packet space, and to
use them separately, with the -11 reporting every second or so on its
space situation to keep the -10 in synch with both types of space.
-- at SNDPKT, we just go ahead and send over-window after a timeout
period, to avoid being locked up there forever (happens alot). The
real solution, of course, is to re-arrange things so that SNDPKT
queues up packets to be sent when the window opens up, and requests a
BLKF (thus unlocking) from its various callers, with the callers
prepared to restart.
-- when someone attempts to listen for a connection name, that really
shouldn't fail if someone else is already listening unless the first
listener requested exclusive access in the OPENF%. Otherwise, it is
hard to have "shelf" jobs, several of which can be waiting, listening
for a connection. This would require reorganizing the RFC-listening
stuff (couldn't use a TBLUK% table any more), but it's worth it.
-- There is still some lossage with performance apropos packet pool
usage: a very active connection can nearly monopolize the interrupt-
level pool, making it hard for other connections to get their work
done; I'm currently playing with maximum window settings to see if
tweaking these can help.
-- There is also lossage in CLSWAT, where, in theory, we should be
able to just wait for the transmit window to totally open up to ensure
all packets got out safely. However, this doesn't work. Figure out
why (it seems to confuse ITS NCPs).
>;REPEAT 0,
SEARCH PROLOG
BBNFLG=0 ;1005 BBNFLG is 0 at MIT
;1000 Setup default parameter switches
DEFINE NDG (SYM,VAL)<
IFNDEF SYM,<
SYM==:VAL>>
NDG ARPAF,0 ; Arpaanet packetizing
NDG CHINET,0 ; Internet packetizing
NDG MNET,0 ; Multinet system
NDG BBNFLG,0 ; BBN monitor mods
NDG F3FLG,0 ; Foonly processor
NDG KLFLG,0 ; KL processor
NDG SMFLG,0 ; 2020 processor
NDG T20FLG,0 ; TOPS-20 monitor
NDG TNXFLG,0 ; TENEX monitor
NDG NETDTE,-1 ;DEFAULT IS NO DTE USAGE
NDG FRNDLY,0 ; friendly host support code
;;;DEBUGGING/METERING SETTINGS
NDG CHSDBG,0 ;DEBUGGING OFF BY DEFAULT
NDG CHSMTR,0 ;METERING OFF BY DEFAULT
;1000 End Addition
IFN ARPAF,<SEARCH IMPPAR>
IFN FRNDLY,<
DEFINE FRIEND (SITE) <
IRP SITE,<
[ASCIZ /SITE/]
>>>
;;;INTERNET INTERFACE SUPPORT
IFNDEF CHINET,<CHINET==0> ;DEFAULT IS OFF
IFNDEF NETDTE,<NETDTE==-1> ;DEFAULT IS NO DTE USAGE
;;;FLAGS DOUBLE-CHECKEROO
IFE <KLFLG+SMFLG+F3FLG>,<PRINTX ?NO CPU TYPE SPECIFIED>
IFG <KLFLG+SMFLG+F3FLG>-1,<PRINTX ?MORE THAN ONE CPU TYPE SPECIFIED>
IFN ARPAF&SMFLG,<PRINTX ?NO ARPA KS10 SUPPORT (YET)>
IFN <KLFLG!SMFLG>&TNXFLG,<PRINTX ?NO TENEX KL OR KS SUPPORT>
IFGE NETDTE,<IFN SMFLG,<PRINTX ?NO KS DTE SUPPORT>>
IFN T20FLG&F3FLG,<PRINTX ?NO F2 TOPS-20 SUPPORT>
IFGE NETDTE-4,<PRINTX ?NETDTE MUST BE 0-3>
IFN T20FLG,<
TTITLE CHAOS
IFN KLFLG,<SEARCH PROKL> ;GET DTE DEFINITIONS
IFN SMFLG,<SEARCH PROKS> ;GET CHAOS UNIBUS ADAPTER DEFINITIONS
IFN CHINET,<
SEARCH INPAR ;GET INTERNET DEFINITIONS
IF1,<IPKT==PKT> ;GET RID OF DUPLICATE DEFINITION
DEFAC(P4,PKT)
>;IFN CHINET
EXTN <MAXCON,CHRFMX,CHST2P,TMSCHR>
DEFINE CHABUG (X,Y) <BUG(X,<Y>)> ;COMPATIBLE BUG MACRO FOR BOTH SYSTEMS
OPDEF XCTUM [XCTU] ;DATA ONLY IN PREVIOUS CONTEXT
>;IFN T20FLG
IFN TNXFLG,<
SEARCH STENEX,MONSYM,MACSYM
TITLE CHAOS
EXTN <ASGJFR,ASGPAG,ASGRES,ASGSWP,BLTMU,BLTUM>
EXTN <CAPMSK,FILBCT,FILBFI,FILBFO,FILCOD,FKINT,FORKX,INSKED>
EXTN <MRETN,PBYTSZ,PSIRQ,RELFRE,RELPAG,RELRES,RELSWP,SK2RET,TODCLK>
EXTN <UNLCKF,.RESNP,.RESP1,.RESP3,LCKTST>
EXTN <MRETNE,RELJFN,NVTPTR,TTNETW,TTOCT,TTECT,NVTCHS>
IFE ARPAF,<
EXTN <NVTINI>
>;IFE ARPAF,
>;IFN TNXFLG
SUBTTL DEFINITIONS
DEFINE DEBUG <IFN CHSDBG>
DEFINE NODEB <IFE CHSDBG>
;EXTERNAL REFERENCES
EXTN <CHPMXC,CHPMXT,CHPMXW> ;CHAOS PACKET LIMITS
EXTN <MXRWIN,MXTWIN,NMWIND,CHAON,CHAONL,CHAONC,CHAFLG,CHAPFG>
EXTN <CHANPO,CHATIM,CHATM1,CHATM2,CHCNLK,CHNPF,CHNPKI,CHNSNS,CHNSTS,CHAFHN>
EXTN <CHNRTR,CHNPOL,CHQRFC,CHRFLK,RFCTAB,CHACON,MYCHAD>
EXTN <CTMSTM,CHNGTM,CHPIOF,CHPIDF,CHATMA,CHAT1A,CHNPO1>
EXTN <CHKCVT,ASNCVT,DETCVT,CHANEG,CHATCS,CVTUPI,CHANPD>
EXTN <CVTPTR,CHNNRS>
EXTN <CHOSTB,CHOSTP,CHANET> ;TABLE, HAVE-TABLE, # PAGES, NET #
EXTN <CHANAO> ;OFFSET IN CHOSTB OF CHAOS ADDRESS TABLE
EXTN <CHQLCL,CHQRFP>
EXTN <CHATTW,CHAPRO,MYHNAM,MYHTIM>
EXTN <CHRFHC>
EXTN <CHABFT,CHNPOW,CHNPWT,CHALRW,CHABFW>
EXTN <CHANOL>
DEBUG,< EXTN <RESFRP,RESFRZ> > ;FOR DEBUGGING ONLY: FREE POOL BEGINNING AND END
IFGE NETDTE,<
EXTN <CHASBS,CHASBL>
;1005 EXTN <GATINC,GATDNC>
>
IFN SMFLG,<
EXTN <CHAACS,CHAIPL,CHAIPS,CHAXPC,CHATXQ>
EXTN <NPKSIN,NPKSOU,NPKSAB,NPKSLS,NPKSER,NPKSRE,NPKSBB,NPKSIG>
>
IFN ARPAF,< ;166
EXTN <CHARPQ>
>;IFN ARPAF
IFN CHINET,<
EXTN <SNDGAT>
>;IFN CHINET
IFN ARPAF!CHINET,<
EXTN <CHATPB>
>;ARPAF!CHINET
DEBUG,<IF1,< PRINTX Debugging support >>
DEFINE CHKCON < ;;;CHECK THE CONNECTION REF'ED BY CONN IF DEBUGGING
DEBUG,< CALL CHKCNB >
>
DEFINE TCHKCN < ;;;CHECK THE CONN REF IN T1; FOR USE IN SCHED TESTS
DEBUG,<
PUSH P,CONN
HRRZI CONN,(T1)
CHKCON
POP P,CONN
>>
DEFINE CHKPKT < ;;;CHECK THE PACKET REF'ED BY PKT IF DEBUGGING
DEBUG,< CALL CHKPKB >
>
DEFINE TCHKPK < ;;;CHECK PACKET REF IN T1; FOR USE IN SCHED TESTS
DEBUG,< PUSH P,PKT
HRRZI PKT,(T1)
CHKPKT
POP P,PKT
>>
DEFINE PKTPTH (PI) < ;;;NOTE PACKET HAS GONE BY THIS POINT IN ITS PATH
DEBUG,< MOVE CX,PI
CALL PKTPTS
>>
DEFINE CONPTH (PI) < ;;;NOTE CONNECTION HAS BEEN BY THIS POINT
DEBUG,< MOVE CX,PI
CALL CONPTS
>>
DEFINE RCALL (RTN,R) < ;;;CALL A ROUTINE WITH A 'REASON' WHEN DEBUGGING
DEBUG,< MOVX CX,R > ;GET THE REASON CODE IN CX FOR THE CALL
CALL RTN
>
DEFINE METER <IFN CHSMTR>
DEFINE NOMET <IFE CHSMTR>
METER,<IF1,< PRINTX Metering support >>
IFGE NETDTE,<
CHADTE==NETDTE ;USE THE NETWORK -11'S DTE IF THERE IS ONE
IFE CHADTE,<EXTN <CHBGPK>> ;THROUGH PRIMARY DTE, NEED ASSEMBLY AREA
IFN CHADTE,<EXTN <NSPQER>> ;SECONDARY DTE: INVALID PROTOCOL CALL
>
IFL NETDTE,<
CHADTE==0
>;IFL NETDTE
;PI CHANNEL ASSIGNMENT
CHACHN==-1 ;BY DEFAULT, NO PI CHANNEL ASSIGNMENT
IFGE NETDTE,< ;1000
IFN T20FLG,< ;BUT UNDER TWENEX, ONE OF:
IFN KLFLG,<CHACHN==DLSCHN> ; KL: CHAOS HANDLING VIA DTE'S (DLS LEVEL)
IFN SMFLG,<CHACHN==UNBCHN&7> ; KS: VIA UNIBUS ADAPTER'S LEVEL
>;IFN T20FLG,
> ;1000 end IFGE NETDTE
;LOCAL AC'S
DEFAC(CONN,Q1)
DEFAC(PKT,Q3)
;FILESYS AC'S
IFN T20FLG,<
DEFAC(STS,P1)
DEFAC(JFN,P2)
DEFAC(DEV,P4)
DEFAC(F1,P5)
>
;FILESYSTEM STORAGE USAGE
FILCON==FILOFN ;LOS ERROR STRING ADDR,,CONNECTION BLOCK
;FILBFO==FILMS1 ;OUTPUT BUFFER POINTER
;FILBFI==FILMS2 ;INPUT BUFFER POINTER
;FILBCT==FILFDB ;BYTE COUNTS OUTPUT,,INPUT
FILOBF==FILCOD ;OUTPUT BUFFER PACKET ADDR
IF1,<
;PACKET HEADER FORMAT (DESCRIBED IN REVERSE FORMAT SINCE IT GROWS BACKWARDS)
DEFINE PHE (E,L) < ;;;PACKET HEADER ENTRY
IFB <L>,<PKTHLN==PKTHLN+1>
IFNB<L>,<PKTHLN==PKTHLN+<L>>
E==-PKTHLN
>
PKTHLN==0 ;INITIALIZE HEADER LENGTH
IFN CHADTE!CHDR11,<
IFN CHADTE,<
PHE PKTTYP ;NEED THIS TYPE FOR TO -11 PTCL
>;IFN CHADTE
IFN CHDR11,<
PHE PKTCDR ;SIZE (16-BIT BYTES),,CDR FOR DR11 MICROCODE
>;IFN CHDR11
IFN ARPAF,< ;UNLESS DOING ARPA ROUTING, WHEN NEED
PHE PKTIMP,3 ; 4 WORDS FOR ARPANET HEADER, SHARING ROOM
>;IFN ARPAF ; WITH TO -11 HEADER
>;IFN CHADTE!CHDR11
IFN CHINET,<
PHE PKTINT,<<MINIHS+3>/4+PKTELI> ;INTERNET HEADERR ROOM
>
DEBUG,<
PHE PKTMAG ;MAGIC WORD FOR EXTRA CHECKING
PHE PKTHSP ;PACKET HISTORY BYTE PTR (MUST PRECEDE PKTHST!)
PHE PKTHST,3 ;PACKET HISTORY: 6-BIT PATH NUMBERS
PHE PKTHDW ;COPY OF ORIGINAL PACKET ASGRES HEADER
>;DEBUG
PHE PKTTIM ;TIME OF LAST ACTIVITY WITH THIS PACKET
IFN SMFLG,<PHE PKTTLK> ;RE-XMISSION COUNT,,LINK TO NEXT PKT TO BE XMITTED
PHE PKTLNK ;LINK WORD: <XMIT ACTIVE IF 1, NOTHING IF -1,
; ELSE LINK TO NEXT ON LOCAL-Q LIST>,,
; <LINK TO NEXT IF ON A LIST (OR NIL), ELSE -1>
PURGE PHE
>;IF1
;PACKET-HANDLING MACRO: ON KS10, WE TRY TO AVOID FREEING AND THEN
;IMMEDIATELY RE-ALLOCATING PACKETS, SO USE GETPKT INSTEAD OF CALLING
;CPYPKI DIRECTLY TO COPY AN INPUT PACKET. IF SIZE ARG IS NOT BLANK,
;THEN T3 HAS NUMBER OF BYTES NEEDED.
;RETURNS +1 ON FAILURE.
DEFINE GETPKT(SIZE) <
IFN SMFLG,<
IFNB <SIZE>,<
CALL CPYPKI
>>
IFE SMFLG,<
IFNB <SIZE>,<STOR T3,CPKNB,(PKT)>
CALL CPYPKT
>>
;MISCELLANEOUS
IFN .CSCLS,<PRINTX ?Some code assumes .CSCLS==0>
;TIME CONSTANTS
CHTRFW==^D<30*1000> ;DEFAULT MS TO WAIT FOR RFC ANSWER
;OTHER PARAMETERS
IFN SMFLG,<
CHARTC==3 ;RETRANSMIT THIS MANY TIMES IF XMIT ABORTS
>
;;STATUS ANS BYTE COUNT
IFN SMFLG,<CHSTBC==^D32+2+2+^D<8*4>> ;KS REPORTS ALL 8 REAL PACKET COUNTERS
IFE SMFLG,<CHSTBC==^D32+2+2+^D<2*4>> ;OTHERS REPORT ONLY IN AND OUT COUNTERS
SUBTTL INITIALIZATION & PTCL VECTORS
;INITIALIZE NETWORK STUFF
SWAPCD ;OK TO BE SWAPPABLE
CHAINI::SETOM CHCNLK ;UNLOCK CONNECTION LOCK
SETOM CHRFLK ;AND RFC TABLE LOCK
SETZM CHQRFC ;EMPTY OUT INCOMING RFC QUEUE
SETOM CHATTW ;EMPTY OUT NVT-CONNECTION-WITH-DATA Q
IFN CHINET,<
SETOM CHPKTI ; Hold off on internet buffer pointer
>
MOVE 1,[CHATTW,,CHATTW+1]
BLT 1,CHATTW+NTTCVT ;CLEAR OUT WHOLE TABLE
SETOM CHPIDF ;SET UP PI LOCKING VARIABLES
IFE TNXFLG,<
SETZM CHAPRO ;206 DEFAULT IS NO NET PROTECTION
>
IFN TNXFLG,<
SETOM CHAPRO ;NO WAY TO CHANGE IT, SO DEFAULT TO ON FOR TENEX
>
SETZM CHOSTP ;NO HOST TABLE BUILT YET
SETZM MYHNAM ;I DON'T HAVE A NAME YET, EITHER
IFG NETDTE,<
SETOM MYCHAD ; WE DON'T KNOW OUR HARDWARE ADDRESS YET
>
SETZM CHQLCL ;CLEAR OUT LOCAL-ROUTING QUEUE
MOVEI T1,^D488 ;LARGEST NUMBER OF BYTES PER PACKET
MOVEM T1,CHPMXC ;SET IT FOR EVERYONE TO FIND
IFE NETDTE,< ;BUT THIS IS LARGEST WE CAN TRANSMIT THROUGH
MOVEI T1,300 ; PRIMARY FRONT END
>;IFE NETDTE
MOVEM T1,CHPMXT ;LARGEST TRANSMITTABLE PACKET SIZE
ADDI T1,3 ;CALCULATE MAXIMUM NUMBER OF WORDS THIS
LSH T1,-2 ; IMPLIES
MOVEM T1,CHPMXW
MOVEI T1,CHRFMX ;MAXIMUM NUMBER OF RFC'S ALLOWED
MOVEM T1,RFCTAB ;INIT TABLE OF CONNECTION NAMES FOR THEM
MOVX T1,5 ;NOMINAL WINDOW SIZE (VARIABLE FOR TWIDDLING)
MOVEM T1,NMWIND
MOVX T1,^D10 ;MAXIMUM WINDOW SIZES
MOVEM T1,MXRWIN ;(KEEP THIS REASONABLE SO WE DON'T LET ONE
MOVX T1,^D15 ; CONNECTION EAT ALL THE INTERRUPT-LEVEL POOL)
MOVEM T1,MXTWIN
IFN TNXFLG,<
IFE ARPAF,<
CALL NVTINI ;CLEAR OUT NVT TABLES IF ARPANET WON'T DO IT
>>
MOVSI T1,(CR%CAP) ;CREATE LOCAL-ROUTING FORK
SETZ T2,
CFORK ;MAKE A JOB0 FORK
CHABUG(CHLFRK)
MOVEI T2,CHALRF ;START IT UP
MSFRK
SETZM CHAFLG ;CLEAR BACKGROUND FORK REQUEST FLAGS
MOVSI T1,(CR%CAP) ;GIVE IT ALL OUR CAPABILITIES
SETZ T2,
CFORK ;MAKE A JOB0 FORK
CHABUG(CHIFRK)
MOVEI T2,CHSFRK ;START IN MONITOR MODE
MSFRK
JRST CHARLD ;AND HANDLE LIKE RELOAD
RESCD ;THIS CALLED FROM DTE INT LEVEL
IFGE NETDTE,<
IFN CHADTE,<
CHADTV::CHAPKT ;DATA IS A PACKET
NSPQER ;SHOULD NEVER REQUEST STATUS
CHSSTS ;HERE IS STATUS
CHADON ;ACK OF PACKET SENT
>;IFN CHADTE
IFE CHADTE,<
;DTE PTCL VECTOR FOR CHAOS INTERFACE
CHADTV::CHAHSD ;STRING DATA (PACKET)
CHADON ;ACK
CHSSTS ;STATUS FROM -11
0 ;SET LINE ALLOCATION
0 ;SYSERR
CHARLD ;-11 RELOAD ACTION
>;IFE CHADTE
>;IFGE NETDTE
SWAPCD ;OK TO BE SWAPPABLE
;CHA: DEVICE DTB
CHADTB::DTBDSP (CHADIR) ;DIRECTORY LOOKUP
DTBDSP (CHANAM) ;NAME LOOKUP
DTBDSP (CHAEXT) ;EXTENSION LOOKUP
DTBDSP (CHAVER) ;VERSION LOOKUP
DTBBAD (DESX9) ;NO PROTECTION
DTBBAD (DESX9) ;NOR ACCOUNT
DTBBAD (DESX9) ;NOR STATUS
DTBDSP (CHAOPN) ;OPENF
DTBDSP (CHASQI) ;SEQUENTIAL INPUT
DTBDSP (CHASQO) ;SEQUENTIAL OUTPUT
DTBDSP (CHACLZ) ;CLOSF
REPEAT 7,<
DTBBAD (DESX9)> ;RANDOM ILLEGAL FUNCTIONS
DTBDSP (CHAMTO) ;MTOPR
DTBDSP (CHASTS) ;GET STATUS
DTBBAD (DESX9) ;SET STATUS
IFN T20FLG,<
DTBDSP (CHASQR) ;SOUTR
DTBDSP (RFTADN) ;NO READ TOD
DTBDSP (SFTADN) ;NOR SET TOD
DTBDSP (CHAINP) ;SET FOR INPUT
DTBDSP (CHAOUP) ;SET FOR OUTPUT
DTBBAD (GJFX49) ;ATTRIBUTES
>;IFN T20FLG
SUBTTL GTJFN AND OPENF DEVICE ROUTINES
;DIRECTORY LOOKUP
CHADIR: TQNE <STEPF> ;STEPPING DIRECTORIES NOT ALLOWED
RETBAD (GJFX17)
NOINT
JRST SK2RET ;SKIP RETURN WITH INTERRUPTS OFF
;VERSION LOOKUP
CHAVER: JUMPGE T1,OKRET
TQNE <STEPF> ;TRYING TO STEP?
RETBAD (GJFX18,<OKINT>) ;YES, ERROR
OKRET: TQNN <UNLKF> ;OK TO UNLOCK?
OKINT ;YES, TURN BACK ON INTERRUPTS
JRST SK2RET
;NAME LOOKUP
CHANAM: JUMPE T1,[RETBAD (GJFX18,<OKINT>)] ;WILDCARDS NOT ALLOWED
CALL HSTNAM ;GET HOSTNAME
RETBAD (GJFX18,<OKINT>) ;NO GOOD
JRST OKRET
;EXTENSION LOOKUP
CHAEXT: JUMPE T1,[RETBAD (GJFX18,<OKINT>)] ;WILDCARDS NOT ALLOWED
IFN TNXFLG,<
SETZM FILCON(JFN) ;NO CONNECTION ALLOCATED YET
>
JRST OKRET ;ELSE LOOKS ALRIGHT
;CHA: DEVICE OPENF
CHAOPN: SKIPL MYCHAD ;DO I KNOW MY HARDWARE ADDRESS YET?
SKIPN CHAON ;IS THE NETWORK IN FACT THERE YET?
RETBAD (OPNX19) ;NO OR NO
SKIPE CHAPRO ;IS NET PROTECTION ON?
JRST [ MOVE T1,CAPMSK ;YES, CHECK POTENTIAL CAPAS
TRNE T1,SC%WHL!SC%OPR!SC%CHA ;DO WE HAVE REQUIRED CAPAS?
JRST .+1 ;YEP, GO ON...
RETBAD(CHAOX5)] ;NO, GIVE ERROR
TQZE <RNDF> ;APPEND
TQO <WRTF> ;BECOMES WRITE
TQNN <READF,WRTF> ;SOME SORT OF ACCESS THERE?
RETBAD (OPNX14) ;NO, BAD OPENF
LDB PKT,PBYTSZ ;GET BYTE SIZE REQUESTED
CAIE PKT,10 ;FOR NOW ONLY ALLOW 8-BIT BYTE CONNECTIONS
CAIN PKT,7 ;OR ASCII FOR SIMPLICITY
CAIA
RETBAD (SFBSX2) ;ILLEGAL BYTE SIZE
IFN TNXFLG,<
SKIPE CONN,FILCON(JFN) ;ALREADY HAVE PARTIAL CONNECTION?
JRST CHOPI4 ;YES, GO BLOCKED AGAIN
>
LOCK CHCNLK,<CALL LCKTST> ;LOCK UP THE CONNECTION LOCK
MOVSI CONN,-MAXCON ;MAXIMUM NUMBER OF NETWORK CONNECTIONS ALLOWED
SKIPGE CHACON(CONN) ;THIS CONNECTION IN USE?
AOBJN CONN,.-1 ;YES, KEEP LOOKING
JUMPGE CONN,CHOPX4 ;INSUFFICIENT RESOURCES
CALL ASGPAG ;GET A FREE PAGE +++SHOULD THIS CALL ASGPGS???
JRST CHOPX4 ;FAILED, UNLOCK LOCK AND RETURN
HRRM T1,FILWND(JFN) ;SAVE IT FOR BUFFER
MOVE T1,[.RESP1,,CONSIZ] ;WHEN DEBUGGING, NEED PAGE-FAULT-FREENESS
MOVEI T2,.RESNP ;FROM THE NETWORK POOL
CALL ASGRES ;ASSIGN ZEROED RESIDENT STORAGE FOR IT
JRST CHOPX3 ;FAILED, UNLOCK LOCK AND RETURN
HLRZ T2,CHACON(CONN) ;GET UNIQUIZER
ANDI T2,400000-1_12 ;JUST UNIQIZER PART
CAIN T2,400000-1_12 ;MAXIMUM?
SETZ T2, ;YES, WRAP AROUND
ADDI T2,1_12(CONN) ;INCREMENT UNIQUIZER AND ADD IN LOCAL IDX
STOR T2,CHAIDX,(T1) ;STORE IN CONNECTION BLOCK
HRLI T1,400000(T2) ;SET CONNECTION IN USE
MOVEM T1,CHACON(CONN) ;SAVE THIS INDEX THEN
UNLOCK CHCNLK ;DONE WITH CONNECTION LOCK
HRRZ CONN,T1 ;AND KEEP CONVENIENT FOR US LATER
DEBUG,< MOVE T2,[CHSMGV] ;SET IN MAGIC VALUE IF DEBUGGING
XORI T2,(CONN) ;MAKE IT KEYED TO CONNECTION IN QUESTION
MOVEM T2,CONMAG(CONN)
MOVEI T1,CONHST(CONN) ;BUILD HISTORY BYTE REF
HRLI T1,331100
MOVEM T1,CONHSP(CONN)
CONPTH [1] ;NOTE GENESIS FOR CONNECTIONS
>;DEBUG
HRRZM CONN,FILCON(JFN) ;SAVE BLOCK WITH JFN
STOR PKT,CHABSZ,(CONN) ;STORE BYTE SIZE AWAY
MOVE T1,MYCHAD ;PUT IN LOCAL HOST ADDRESS
STOR T1,CHALCH,(CONN)
MOVE T1,FORKX ;SAVE OWNING FORK
STOR T1,CHAFRK,(CONN)
SETONE CHAICN,(CONN) ;NO CHANNEL TO INTERRUPT YET
SETONE CHAOCN,(CONN)
MOVE T1,NMWIND ;NOMINAL WINDOW SIZE TO START
HRLM T1,CHAWIN(CONN) ;RECEIVE WINDOW SIZE
MOVX T1,CHTRFW ;DEFAULT RFC WAIT TIMEOUT PERIOD
STOR T1,CHATRF,(CONN)
HLRZ T1,FILNEN(JFN) ;GET POINTER TO NAME STRING
CALL HSTNAM ;LOOKUP HOST NAME
JRST [ MOVEI T1,GJFX18
JRST CHOPX1 ]
JUMPE T1,CHOPIN ;IF NULL, WANTS TO LISTEN
;WANTS TO INITIATE AN RFC TO SOMEPLACE
STOR T1,CHAHST,(CONN) ;SAVE REMOTE HOST DESIRED
MOVE T1,TODCLK ;TIME OF LAST ACTIVITY
MOVEM T1,CHAITM(CONN)
MOVEI T1,.CSRFS ;RFC SENT STATE
HRRM T1,CHASTA(CONN)
MOVEI Q2,.CORFC ;REQUEST FOR CONNECTION
RCALL ASGPKC,30 ;ALLOCATE A PACKET FOR THIS CONNECTION
JRST [ MOVEI T1,MONX01
JRST CHOPX1 ]
HRRZ T2,FILNEN(JFN)
AOJ T2,
MOVE T1,T2
HRLI T1,(<POINT 7,>) ;SAVE CONTACT NAME POINTER
ILDB T1,T1 ;GET FIRST BYTE OF CONTACT NAME
JUMPE T1,[CALL CHOPI3 ;IF ZERO (NULL CONTACT NAME)
JRST [MOVEI T1,CHAOX3 ;FILL IN RFC FROM USER AC3
JRST CHOPX1] ;FAILED
JRST CHOPI0] ;GO SEND IT
CALL PKTSTR ;FILL IN PACKET DATA FROM STRING AND SEND IT
CHOPI0: SETZ T1,
CALL SNDPK0 ;SEND THIS OFF, BLOCKING IS OK
CHOPIR: HRRI T1,RFCST ;RFC SENT HANDLING TEST
CHOPI1: LOAD T2,IOMODE ;GET DATA MODE
CAIE T2,6 ;6 OR 7 IS IMMEDIATE RETURN
CAIN T2,7
RETSKP
CONPTH [2] ;NOTE WE'VE BEEN THIS ROUTE
HRLI T1,(CONN) ;CONNECTION INDEX
CALL CHOWAT ;WAIT FOR OPEN
HRRZ T1,CHASTA(CONN) ;GET CONNECTION STATE NOW
CHOPEN: JUMPE T1,[HLRZ T1,CHAIBF(CONN) ;CLOSED, SEE IF THERE IS ANY DATA
JUMPE T1,CHOPI2
LOAD T1,CPKOP,(T1) ;IS IT A DATA TYPE PACKET
CAIE T1,.COANS ;ANS IS ACCEPTABLE DATA FOR THIS
CAIL T1,.CODAT
RETSKP
JRST CHOPI2] ;NO, MUST BE LOSING
CAIE T1,.CSRFC
CAIN T1,.CSOPN ;OPENED OK?
RETSKP ;YES, RETURN OK
CAIE T1,.CSLOS ;LOS RECEIVED FROM IT?
SKIPA T1,[OPNX20] ;NO, MUST HAVE TIMED-OUT AND GONE INC
CALL GETLOS ;YES, SET UP ERROR MESSAGE FROM THAT
CHOPX1: PUSH P,T1 ;SAVE ERROR CODE
HRRZ T1,FILWND(JFN)
CALL RELPAG ;GET RID OF INPUT WINDOW PAGE
CALL RELCON ;RELEASE THE STORAGE BLOCK
POP P,T1
RET ;ERROR RETURN
;WAIT FOR CONNECTION TO OPEN, MDISMS ARG IN 1
IFN T20FLG,<
CHOWAT: PUSH P,T1 ;SAVE MDISMS ARGUMENT
MOVEI T1,(CONN) ;SETUP FOR CONNECTION TO GET DEALLOCATED IF USER ^C'S
MOVEI T2,STKCD5
CALL JSBSTK
POP P,T1 ;GET BACK MDISMS ARG
CALL UNLDIS ;WAIT FOR THAT STATE TO OCCUR
NOINT ;PROTECT OURSELVES
MOVEI T1,(CONN) ;FLUSH DEALLOCATION RECORD
MOVEI T2,STKCD5
CALLRET JSFRMV ;REMOVE FROM JSB STACK NOW THAT NOINT AGAIN
>;IFN T20FLG
IFN TNXFLG,<
CHOWAT: MDISMS ;WAIT FOR IT
JRST WATRET ;CHECK FOR INTERRUPT AND MAYBE GO TO USER
>;IFN TNXFLG
CHOPI2: MOVEI T1,OPNX21
JRST CHOPX1
;HERE TO FILL IN RFC FROM DATA REF'ED BY USER AC3
CHOPI3: SAVEAC <T1,T2,T3> ;NOT SURE THIS IS NECESSARY
XCTUM [HLRZ T1,3] ;GET USER SUPPLIED BYTE COUNT
CAMLE T1,CHPMXT ;CURRENT BYTE COUNT LIMIT
RET ;PUNT IF TOO MUCH DATA
PUSH P,T1 ;SAVE BYTE COUNT FOR LATER
ADDI T1,3 ;ROUND APPROPRIATELY
LSH T1,-2 ;199 CONVERT TO WORD COUNT
XCTUM [HRRZ T2,3] ;USER ADDRESS TO COPY FROM
XMOVEI T3,CHPKDT(PKT) ;POINTER TO DATA AREA OF PACKET
CALL BLTUM ;COPY AWAY...
POP P,T1 ;RECLAIM BYTE COUNT
STOR T1,CPKNB,(PKT) ;STORE IN PACKET HEADER
RETSKP ;WON
CHOPX3: HRRZ T1,FILWND(JFN)
CALL RELPAG ;GET RID OF INPUT WINDOW PAGE
CHOPX4: UNLOCK CHCNLK ;UNLOCK CONNECTION LOCK
RETBAD (MONX01) ;UNSUFFICIENT RESOURCES
IFN TNXFLG,<
CHOPI4: HRRZ T1,CHASTA(CONN) ;GET CURRENT STATE
CAIN T1,.CSRFS
JRST CHOPIR
CAIN T1,.CSLSN
JRST CHOPIL
JRST CHOPEN ;ALREADY OPEN OR SOMETHING
>
RESCD
RFCST: TCHKCN ;IF DEBUGGING, CHECK CONNECTION
HRRZ T2,CHASTA(T1)
CAIE T2,.CSRFS ;STILL RFC SENT STATE?
JRST 1(4) ;NO, RETURN
IFN T20FLG,<
JRST 0(4)
>;IFN T20FLG
IFN TNXFLG,<
RFCST1: MOVE T3,FKINT(FX) ;LOOK FOR DEFERRED INTERRUPTS
TLNN T3,(1B1)
JRST 0(4) ;NONE, CONTINUE BLOCKED
JRST 1(T4) ;YES, UNBLOCK
>;IFN TNXFLG
SWAPCD
;HERE TO LISTEN FOR A CONNECTION (CHA:.FOO), TO BECOME THE DISTINGUISHED RFC
;HANDLER (CHA:.) OR TO SET UP A RFC/ANS PERMANENT CONNECTION (CHA:.-)
CHOPIN: HRRZ T2,FILNEN(JFN) ;GET CONNECTION NAME TO LISTEN FOR
HRLI T2,(<POINT 7,0,34>)
MOVE T1,T2 ;NOW, SEE IF THIS
ILDB T3,T1 ; NAME IS NULL (WANTS TO LISTEN FOR ALL RFCS)
JUMPE T3,[
IFE BBNFLG,<
MOVX T2,SC%WHL!SC%OPR!SC%NWZ!SC%NAS ;YES, CHECK CAPAS
MOVX T1,NTWZX1 ;ERROR CODE IF NOT PRIVILEGED
TDNN T2,CAPMSK ; (POTENTIAL IS GOOD ENOUGH)
JRST CHOPX1 ;NO, GO CLEAN UP AND RETURN ERROR
>
NOSKED ;ACQUIRE THIS CAREFULLY
MOVX T1,OPNX9 ;INVALID SIMULTANEOUS ACCESS IF ALREADY A LISTENER
SKIPE CHRFHC ;SOMEONE ALREADY THERE?
JRST [ OKSKED ;YES, UNLOCK
JRST CHOPX1 ] ; AND GIVE ERROR
MOVEM CONN,CHRFHC ;NO, WE'RE NOW THE FELLOW IN COMMAND
OKSKED
MOVX T1,^D20 ;THIS SHOULD BE ENOUGH INPUT WINDOW FOR IT,
HRLM T1,CHAWIN(CONN) ; ASSUMING IT'S FAIRLY RESPONSIVE
MOVX T1,.CSLSN ;PRETEND WE'RE LISTENING, BUT
HRRM T1,CHASTA(CONN)
RETSKP ] ; RETURN SUCCESS IMMEDIATELY
CAIN T3,"-" ;PERHAPS WANTS TO SET UP A PERMANENT RFC-SENT
JRST [ ILDB T3,T1 ; CONNECTION? ("CHA:.-")
JUMPN T3,.+1 ;NOPE
MOVX T1,.CSPRF ;YES, SAY SO AND
HRRM T1,CHASTA(CONN) ; SUCCEED
RETSKP ] ; IMMEDIATELY
CALL ADDLSN ;ADD NEW CONNECTION NAME
JRST CHOPX1 ;FAILED: ERROR CODE IN T1 ALREADY
MOVX T1,CH%RFC ;TELL THE BACKGROUND FORK TO CHECK AGAIN
IORM T1,CHAFLG ; FOR POTENTIAL RFC MATCHES
MOVX T1,.CSLSN ;LISTENING STATE
HRRM T1,CHASTA(CONN)
CHOPIL: HRRI T1,RFCRT ;WAIT FOR AN INCOMING RFC
JRST CHOPI1
RESCD
RFCRT: TCHKCN ;IF DEBUGGING, CHECK CONNECTION
HRRZ T2,CHASTA(T1)
CAIE T2,.CSLSN ;STILL LISTENING?
JRST 1(4) ;NO, RETURN
IFN T20FLG,<JRST 0(4)>
IFN TNXFLG,<JRST RFCST1> ;CHECK FOR USER ^C'ING AS WELL
SWAPCD
;ADD STRING REF'ED BY T2 TO THE LISTENING RFC LIST; RETURN NONSKIP WITH
;T1/ ERROR CODE IF THERE ARE PROBLEMS.
ADDLSN: STKVAR <ADLSAD,ADLSCT>
MOVEM T2,ADLSAD ;SAVE STRING
LOCK CHRFLK,<CALL LCKTST> ;GET THE RFC TABLE LOCK
MOVEI T1,RFCTAB ;RFC LISTENING TABLE
TBLUK
ERJMP ADDLSR ;SOME PROBLEM, LUMP UNDER 'NO RESOURCES'
TXNE T2,TL%EXM ;EXACTLY MATCHED SOMETHING ALREADY THERE
JRST ADDLSF ; SO RETURN ERROR
MOVE T2,ADLSAD ;GET BACK STRING POINTER
SETZ T3,
ILDB T1,T2
JUMPE T1,.+2
AOJA T3,.-2 ;COMPUTE LENGTH
MOVEM T3,ADLSCT ;SAVE COUNT
AOJ T3, ;BUMP UP FOR ENDING NULL
MOVEI T1,5+4(T3) ; PLUS ONE WORD FOR HEADER
IDIVI T1,5 ;GET DESIRED LENGTH
CALL ASGSWP ;GET SOME SWAPPABLE SPACE
JRST ADDLSR ;FAILED, RESOURCE PROBLEM
MOVE T3,ADLSCT ;RECOVER COUNT
MOVSI T2,1(T1) ;BUILD STRING REF IN LH FOR TBLUK FORMAT
EXCH T2,ADLSAD ;SAVE ADDRESS, GET ORIGINAL STRING PTR
HRLI T1,(<POINT 7,0,34>)
ILDB PKT,T2
IDPB PKT,T1
SOJG T3,.-2
SETZ PKT,
IDPB PKT,T1 ;TIE OFF TO MAKE ASCIZ
MOVE T2,ADLSAD ;GET BACK CONTACT NAME REF
HRRI T2,(CONN) ;BUILD CONTACT REF,,CONNECTION TO HANDLE THIS RFC
MOVEI T1,RFCTAB ;PUT THIS NEW ENTRY INTO TABLE
TBADD
ERJMP ADDLSR ;IF TABLE FULL, FAIL
UNLOCK CHRFLK
RETSKP
ADDLSR: SKIPA T1,[MONX01] ;RESOURCE PROBLEM HERE
ADDLSF: MOVEI T1,OPNX9 ;NAME ALREADY EXISTS: INVALID SIMULTANEOUS ACCESS
UNLOCK CHRFLK ;FAILED SOMEHOW: UNLOCK
RET ; AND INDICATE FAILURE
;CHAOS NET CLOSF
CHACLZ: HRRZ CONN,FILCON(JFN) ;GET CONNECTION INDEX
CHKCON ;VALIDATE IT IF DEBUGGING
HRRZ Q2,CHASTA(CONN) ;AND STATE
CAIN Q2,.CSRFC ;RFC RECEIVED?
JRST CHACL2 ;YES, STILL NEED TO SEND A CLS FOR IT
CAIE Q2,.CSOPN ;STILL OPEN?
JRST CHACL3 ;NO, SKIP SENDING ANYTHING
CALL CHARTR ;YES, TRY TO RETRANSMIT WHATEVER NEEDS IT
CALL FLSOUT ;SEND OFF LAST PACKET
TQZ <ERRF> ;IGNORE ERROR
UMOVE T1,1
TDNN T1,[1,,400000] ;IF NOT CALLED FROM CLOSF
TLNN T1,(CO%WCL) ;OR NOT REQUESTED
JRST CHACL2 ;DONT WAIT FOR IT TO GET DONE
MOVSI T1,(CONN)
HRRI T1,CLSWAT ;WAIT FOR ALL DATA TO GET SENT OUT
IFN T20FLG,<
CALL UNLDIS
NOINT
>;IFN T20FLG
IFN TNXFLG,<
MDISMS
CALL WATRET ;MAYBE RETURN TO USER IF INTERRUPT PENDING
>;IFN TNXFLG
CHACL2: MOVEI Q2,.COCLS
RCALL ASGPK0,31 ;GET A PACKET FOR CONNECTION WITHOUT DATA
JRST CHACL3
SETZ T1,
CALL SNDPK0 ;SEND IT OFF TOO, BLOCKING OK
CHACL3: CALL RELCON ;RELEASE STORAGE ASSOCIATED WITH THIS CONNECTION
AOS (P) ;WILL SKIP RETURN
CHACL4: SKIPE PKT,FILOBF(JFN) ;HAVE AN OUTPUT BUFFER?
JRST [ RCALL RELPKT,3 ;YES, FREE IT TOO
JRST .+1 ]
HRRZ T1,FILWND(JFN)
SKIPE T1
CALL RELPAG
SETZM FILBFO(JFN)
SETZM FILBFI(JFN)
HLRZ T2,FILCON(JFN) ;LOS ERROR MESSAGE STILL?
JUMPE T2,R ;NO, DONE
HRRZS (T2)
MOVEI T1,JSBFRE
CALL RELFRE ;RELEASE IT
HRRZS FILCON(JFN)
RET
;WAIT UNTIL ALL PACKETS FOR CONNECTION HAVE BEEN SENT OFF
RESCD
CLSWAT: TCHKCN ;IF DEBUGGING, CHECK CONNECTION
HRRZ T2,CHASTA(T1) ;199 CHECK FOR NON-OPEN CONNECTION
CAIE T2,.CSOPN ; BETTER BE OPEN
JRST 1(T4) ; UNBLOCK IF NOT
;+++ THIS APPEARS TO BE WRONG: YOU REALLY WANT TO WAIT UNTIL ALL PACKETS
;+++ HAVE BEEN GIVEN TO THE REMOTE FELLOW, NOT JUST RECEIPTED.
HLRZ T2,CHAOBF(T1) ;GET HEAD OF CONNECTION OUTPUT PACKET LIST
JUMPE T2,1(T4) ;NONE, UNBLOCK
REPEAT 0,< ;+++ HOWEVER, THIS DOESN'T WORK QUITE RIGHT!
HRRZ T2,CHAWIN(T1) ;PICK UP CURRENT XMIT WINDOW
CAMG T2,CHANOS(T1) ;SEE IF STILL THINGS TO BE ACK'ED
JRST 1(T4) ;NO, UNBLOCK
>;REPEAT 0,
IFN T20FLG,<JRST 0(T4)> ;YES, KEEP WAITING
IFN TNXFLG,<JRST RFCST1>
;RELEASE ALL STORAGE ASSOCIATED WITH A CONNECTION; SET THINGS UP SO
;AN INACTIVE CONNECTION WILL BE RECOGNIZED BY THE VARIOUS CONNECTION AND
;QUEUE MUNGING ROUTINES.
RELCON::CHKCON ;POSSIBLY CHECK THIS CONNECTION FOR VALIDITY
CALL NOSKDP
MOVEI Q2,CHAPBF(CONN) ;OUT OF ORDER PACKETS
CALL CHALFR
;1017 SETOM CHAPBF(CONN) ;MARK THIS Q AS INACTIVE NOW
SETZM CHAPBF(CONN) ;1017 MARK THIS Q AS INACTIVE NOW
MOVEI Q2,CHAIBF(CONN) ;INPUT BUFFERS
CALL CHALFR
;1017 SETOM CHAIBF(CONN) ;THIS Q IS INACTIVE
SETZM CHAIBF(CONN) ;1017 THIS Q IS INACTIVE
CALL CHALFO
;1017 SETOM CHAOBF(CONN) ;DITTO
SETZM CHAOBF(CONN) ;1017 DITTO
SETZM CHANBF(CONN)
CAMN CONN,CHRFHC ;IS THIS THE DISTINGUISHED RFC HANDLER?
SETZM CHRFHC ;YES, NO LONGER THERE
CALL CH7CLN ;GET RID OF ANY QUEUED-FOR-INPUT REFS
MOVN T1,RFCTAB ;CHECK THAT IT IS NOT IN THE RFC TABLE
HRRI T1,RFCTAB
AOBJP T1,RELCN2
RELCN1: HRRZ T2,(T1)
CAIN T2,(CONN) ;ONCE WE FIND A MATCHING ENTRY,
JRST [ CALL RFCFRE ; DELETE IT FROM THE RFC TABLE
JRST RELCN2 ] ; AND GO FINISH CLEANUP
AOBJN T1,RELCN1
RELCN2: LOAD T1,CHALDX,(CONN) ;GET CONNECTION INDEX
CAIL T1,MAXCON ;VALID?
CHABUG(CHARBC) ;NO, COMPLAIN ABOUT IT BUT GO ON (SIGH)
MOVE T2,[400000,,-1]
ANDCAM T2,CHACON(T1) ;CLEAR IN USE AND CONNECTION BLOCK POINTER
DEBUG,< SETZM CONMAG(CONN) > ;MAKE SURE IT'S NEVER MISTAKEN AGAIN FOR VALID
CALL OKSKDP
MOVEI T1,(CONN)
JRST RELRES ;RELEASE STORAGE BLOCK ITSELF AND RETURN
IFN TNXFLG,<
;; FLUSH ANY CONNECTIONS BELONGING TO THIS FORK. THIS WILL HAPPEN WHEN
;; THE FORK IS KILLED WHILE PCLSR'ED OUT OF AN OPENF.
CHAKIL::PUSH P,CONN
MOVSI T3,-MAXCON
CHKIL0: SKIPL CONN,CHACON(T3)
JRST CHKIL1
LOAD T1,CHAFRK,(CONN)
CAME T1,FORKX
JRST CHKIL1
PUSH P,T3
CALL RELCON
POP P,T3
CHKIL1: AOBJN T3,CHKIL0
POP P,CONN
RET
>;TNXFLG
SUBTTL NVT SUPPORT
SWAPCD
; ATTACH CONNECTION TO PTY (FROM .ATNVT)
; CALL: T1/ JFN OF OPENED NETWORK CONNECTION WITH CHKJFN DONE
;
; RETURNS
; +1 CANNOT ATTACH
; +2 OK. THE JFN IS RELEASED, AC 1 HAS LINE NUMBER OF ATTACHED PTY.
CATNVT::MOVEI T1,ATNX2 ;ERROR CODE IF TEST SKIPS
TQNE <READF> ;MUST BE OPENED FOR READING AND WRITING
TQNN <WRTF>
JRST ATPER1
MOVEI T1,ATNX3 ;RECEIVE NOT OPEN
TQNN <OPNF> ;IS IT OPEN?
JRST ATPER1
HRRZ CONN,FILCON(JFN) ;GET CONNECTION
CHKCON ;VALIDATE IT IF DEBUGGING
HRRZ T1,CHASTA(CONN) ;GET CONNECTION STATUS
CAIN T1,.CSRFC ;RFC RECEIVED?
JRST ATNVT1
CAIN T1,.CSOPN ;OPENED OK
JRST ATNVT2
MOVEI T1,ATNX6
JRST ATPER1
ATNVT1: CALL SNDOPN ;ACCEPT THE RFC (WAS IN RFC-RECEIVED STATE)
ATNVT2: XCTUM [HLL CONN,1] ;99 GET FLAGS
IFN TNXFLG,<
MOVE T1,CONN ;WHERE ROUTINE EXPECTS CONNECTION INDEX
>
CALL ASNCVT ;ASSIGN NVT TO THESE UNITS
JRST [ MOVEI A,ATNX13 ;CAN'T, NO PTY'S
JRST ATPER1 ]
IFN T20FLG,<
PUSH P,T2 ;SAVE ADDRESS OF DYNAMIC AREA
>
SETONE CHAFRK,(CONN) ;NO FORK OWNS THIS ANY MORE
STOR T1,CHANVT,(CONN) ;SAVE TTY NUMBER
IORI T1,.TTDES ;CONVERT PTY TO TTY DESIGNATOR
UMOVEM T1,1 ;RETURN TO USER
CALL CHACL4 ;RELEASE JFN STORAGE FOR WINDOWS
CALL RELJFN ;RELEASE SEND JFN
IFN T20FLG,<
POP P,T2 ;GET BACK ADDRESS OF DYNAMIC DATA
CALL ULKTTY ;UNLOCK DATA BASE
>
SMRETN ;RETURN SKIPPING
ATPER1: CALL UNLCKF
JRST MRETNE ;SAVE ERROR RETURN IN AC1
;CLOSE THE CONNECTION ASSOCIATED WITH THIS NVT---CANNOT BLOCK (CAN BE CALLED
;WITH DEVICE LOCK LOCKED IF DETACHING MANUALLY!): REQUEST THAT THE
;CHAOS BACKGROUND FORK CLOSE IT.
CVTCLZ::CHKCON ;CHECK CONN REF IF DEBUGGING
MOVX T1,CF%CLS ;MARK IT AS NEEDING
IORM T1,CHASTA(CONN) ; CLOSING SOMETIME SOON
MOVX T1,CH%CLS ;TELL CHAOS FORK THERE'S A CLOSE REQUEST
IORM T1,CHAFLG
RET
;START UP OUTPUT FOR A LINE; JUST ASKS BACKGROUND FORK TO LOOK AT THIS
;TTY NEXT SCAN.
;RETURNS +1 ALWAYS.
; CONN/ CONNECTION IN QUESTION
;+++ UNUSED NOW, SINCE IT WAS TOO SLOW: THE BACKGROUND FORK FLUSHES
;+++ ALL NVT OUTPUT TO THE NET EVERY CYCLE INSTEAD OR WHEN CHAFLG GETS
;+++ SET (EG, WITH CH%TTY).
CHAVSO::CHKCON ;CHECK THIS CONNECTION REF IF DEBUGGING
LOAD T2,CHANVT,(CONN) ;GET NVT LINE
CALL CHKCVT ;MAKE SURE IT'S TRULY A CHAOS NVT
JRST CHAVSB
MOVX T1,CF%TTO ;MARK THIS CONNECTION
IORM T1,CHASTA(CONN) ; AS NEEDING OUTPUT ATTENTION
RET ;DONE
CHAVSB: CHABUG(CHAVSN) ;NO, COMPLAIN AND GET OUT
RET
SUBTTL TTCH7 TIME NVT INPUT PROCESSING
;CALLED FROM SCHEDULER AT TTCH7 TIME TO UNPACK CHARACTERS WAITING IN ANY
;NVT CONNECTIONS' INPUT PACKET LISTS.
RESCD
CHTTC7::SKIPN CHAON ;IS THE CHAOSNET UP YET?
RET ;NO, NOTHING TO DO
SAVEQ ;SAVE CONN, FX, Q2
IFN CHDR11,<
CALL CCHKDR ;CHECK ON THE STATE OF THE DR11 PACKETS
>;IFN CHDR11
STKVAR <CHT7DC,CHT7IX>
MOVEI Q2,NTTCVT+1 ;SAFETY DOWN-COUNTER
MOVEM Q2,CHT7DC
MOVEI Q2,CHATTW ;MARCHES THROUGH Q
MOVEM Q2,CHT7IX ;SAVE IT INITIALLY
CHTC70: SOSL CHT7DC ;BOUNDS CHECK THIS LOOP
CAIL Q2,CHATTW+NTTCVT+1 ; AND THIS REF; BOTH WITHIN BOUNDS?
CHABUG(CHT7QB) ;NOPE, SHOULDN'T HAPPEN
SETO CONN,
EXCH CONN,(Q2) ;PICK UP CONNECTION REF AND RESET ENTRY
CAMN CONN,[-1] ;END OF Q?
JRST CHTCDN ;YES, GET OUT
HRRZ CONN,CONN ;CLEAR OUT LEFT HALF (UNIQUIZER)
CHKCON ;VALIDATE IT IF DEBUGGING
LOAD T2,CHANVT,(CONN) ;GET NVT INDEX
CALL CHKCVT ;IS THIS A VALID NVT (DOUBLE CHECK)?
JRST CHTC7B
CALL CVTUPI ;EMPTY THIS CONNECTION'S DATA TO THE NVT'S INPUT
CHTC79: AOS Q2,CHT7IX ;BUMP TO NEXT Q ENTRY
JRST CHTC70 ;KEEP GOING
;1003 CHTCDN: SETOM CHATTW ;DONE, CLEAR OUT QUEUE
;1003 NOW CLEARED BY EXCH CONN,(Q2) ABOVE
CHTCDN: RET ;1003 SO JUST RETURN
CHTC7B: CHABUG(CHT7IN) ;NO (INVALID NVT INDEX), COMPLAIN
JRST CHTCDN ;AND GET OUT
;CALLED AT RELCON TIME TO CLEAR OUT ANY REFERENCES TO CONN IN CHATTW
;(CALLED NOSKDP, OF COURSE).
CH7CLN: SAVET
MOVEI T1,CHATTW ;SCAN THE QUEUE FOR ANY OCCURENCES
CH7CLL: MOVE T2,(T1) ;PICK UP ENTRY
CAMN T2,[-1] ;DONE?
RET ;YEP, GET OUT
TLZ T2,-1 ;CLEAR OUT ANY JUNK
CAIE T2,(CONN) ;FOUND IT?
AOJA T1,CH7CLL ;NO, KEEP LOOKING
CH7CLR: MOVE T2,1(T1) ;YES, PICK UP NEXT ENTRY
MOVEM T2,(T1) ;MOVE IT IN OVER THIS ONE
CAMN T2,[-1] ;END OF Q?
RET ;YES, GET OUT
AOJA T1,CH7CLR ;NO, MOVE NEXT
SWAPCD
SUBTTL CHAOS NET SEQUENTIAL I/O
;NETWORK INPUT
CHASQI: SOSGE FILCNT(JFN) ;ANY MORE BYTES?
JRST SQI1 ;NO, MUST GO GET SOME MORE FROM NETWORK BUFFERS
ILDB T1,FILBYT(JFN)
RET
SQI1: CALL GETINP ;PROCESS BUFFERS FROM NETWORK
JRST SQIBLK ;GO BLOCK MAYBE
JRST CHASQI ;AND START AGAIN
;HERE IF SHOULD BLOCK
SQIBLK: HRRZ CONN,FILCON(JFN) ;GET CONNECTION BLOCK
CHKCON ;VALIDATE IT IF DEBUGGING
CONPTH [3]
HRRZ T1,CHASTA(CONN)
CAIN T1,.CSPRF ;STILL HAVE A CHANCE OF MAKING DATA?
JRST INPWAT ;YES
CAIE T1,.CSOPN ; ...
CAIN T1,.CSRFS
JRST INPWAT ;WAIT FOR INPUT BUFFERS TO APPEAR
CAIN T1,.CSCLS ;JUST CLOSED NORMALLY?
JRST [ HLRZ T1,CHAIBF(CONN) ;YES, ANY DATA THERE?
JUMPN T1,INPWAT ;OK, GO "WAIT" FOR IT
TQO <EOFF> ;NO, IT'S END-OF-FILE TIME
CONPTH [4]
RET ]
TQO <ERRF> ;ELSE IS AN ERROR TO TRY TO READ FROM IT
CONPTH [5]
RET
INPWAT: TQNE <EOFF> ;SEEN AN EOF FOR CONNECTION?
JRST INPEOF ;YES, DONT GO BLOCKED THEN
CONPTH [6]
MOVSI T1,(CONN)
HRRI T1,INPWTT ;WAIT FOR CHAOSNET INPUT
IFN T20FLG,<
CHAWAT: TQO <BLKF> ;YES, SAY NEED TO GO BLOCKED
RETBAD ()
>;IFN T20FLG
IFN TNXFLG,<
CHAWAT: MOVE P,MPP
MOVE B,0(P) ;GET AND DECREMENT RETURN PC
SOS B
HRRM B,0(P) ;BACK TO RETURN ON STACK
PUSHJ P,UNLCKF ;UNLOCK JFN
JSYS EDISMS ;WAIT FOR EVENT
JRST MRETN ;BACK OUT TO USER
>;IFN TNXFLG
INPEOF: SETZ T1, ;RETURN 0 FOR INPUT BYTE
RET
RESCD
INPWTT: TCHKCN ;IF DEBUGGING, CHECK CONNECTION
HRRZ T2,CHASTA(T1) ;MAKE SURE CONNECTION STILL IN GOOD STATE
CAIE T2,.CSOPN
CAIN T2,.CSRFS
CAIA
JRST 1(T4)
HLRZ T2,CHAIBF(T1) ;SEE IF ANYTHING ON INPUT BUFFER QUEUE
JUMPN T2,1(T4) ;YES, UNBLOCK TO PROCESS IT
JRST 0(T4)
SWAPCD
;UNDO INPUT
CHAUIN: TQZN <FILINP> ;REALLY DOING INPUT AT ALL?
RET ;NO, DONE
SKIPGE T1,FILCNT(JFN)
SETZ T1,
HRRM T1,FILBCT(JFN) ;SAVE CURRENT INPUT COUNT
MOVE T1,FILBYT(JFN)
MOVEM T1,FILBFI(JFN) ;AND CURRENT INPUT BYTE POINTER
RET
;SETUP FOR INPUT
CHAINP::SAVET ;FOR THE SAKE OF TENEX
TQOE <FILINP> ;NOW DOING INPUT
RET
CALL CHAUOU ;UNDO OUTPUT
HRRE T3,FILBCT(JFN) ;GET INPUT COUNT
JUMPG T3,CHAIN2 ;HAVE ANY INPUT ALREADY?
CALL GETINP ;NO, TRY TO GET SOME
JFCL ;IGNORING LOSSAGE
RET
CHAIN2: MOVE T2,FILBFI(JFN) ;INPUT BYTE POINTER
HRRE T1,FILBCT(JFN) ;AND COUNT
CHAIN3: MOVEM T1,FILCNT(JFN) ;SETUP CURRENT COUNT
ADDM T1,FILLEN(JFN) ;UPDATE LENGTH OF WHOLE
MOVEM T2,FILBYT(JFN) ;AND BYTE POINTER
RET
;SETUP FOR OUTPUT
CHAOUP::SAVET ;FOR THE SAKE OF TENEX
TQOE <FILOUP>
RET
CALL CHAUIN ;UNDO INPUT
SKIPN FILOBF(JFN) ;IS THERE A PACKET TO STUFF INTO YET?
JRST GETOUT ;NO, GET ONE
MOVE T2,FILBFO(JFN)
HLRE T1,FILBCT(JFN)
JRST CHAIN3
;UNDO OUTPUT
CHAUOU: TQZN <FILOUP>
RET
SKIPGE T1,FILCNT(JFN)
SETZ T1,
HRLM T1,FILBCT(JFN)
MOVE T1,FILBYT(JFN)
MOVEM T1,FILBFO(JFN)
RET
;GET SOME MORE INPUT FROM THE NETWORK BUFFERS; RETURN NON-SKIP IF NOTHING GOTTEN
;(EG, ERROR)
GETINP: HRRZ CONN,FILCON(JFN) ;GET CONNECTION BLOCK
CHKCON ;VALIDATE IT IF DEBUGGING
CONPTH [7]
HRRZ T3,CHASTA(CONN)
CAIN T3,.CSRFC ;RFC RECEIVED?
JRST SNDOPN ;YES, DOING INPUT IMPLIES ACCEPTING THE CONNECTION
LOAD T3,CHABSZ,(CONN)
HRRZ T1,FILWND(JFN) ;INPUT WINDOW
MOVE PKT,T3 ;MAKE A BYTE POINTER TO THE WINDOW
IORI T3,4400
DPB T3,[POINT 12,T1,11]
MOVEI T2,44
IDIVI T2,(PKT)
LSH T2,PGSFT
MOVEM T1,FILBYT(JFN)
SETZM FILCNT(JFN) ;RESET COUNT OF CHARS GOTTEN THIS TIME
GETIN1: HLRZ PKT,CHAIBF(CONN) ;CHECK FIRST ON INPUT LIST
JUMPE PKT,GETIN4 ;NO MORE, RETURN
CHKPKT ;VALIDATE IF DEBUGGING
PKTPTH [42]
LOAD T3,CPKOP,(PKT)
CAIE T3,.COCLS
CAIN T3,.COLOS ;WAS THIS A LOS?
JRST [ CALL GETLOS ;SET ERROR MESSAGE FROM IT
CONPTH [11]
JRST GETIN4 ]
LOAD T3,CPKNB,(PKT) ;GET BYTE COUNT FOR THIS PACKET
SUBI T2,(T3) ;DECREMENT FREE COUNT
JUMPL T2,GETIN4 ;NO ROOM FOR ALL PACKETS NOW
CALL CHGETP ;GET THIS PACKET, DO ACKING, ETC.
JRST GETIN4 ;1000 CHGETP preserves temps now
JUMPE T3,GETIN3
ADDM T3,FILCNT(JFN)
PUSH P,T2
MOVE T2,[POINT 8,CHPKDT(PKT)]
GETIN2: ILDB T4,T2 ;MOVE THIS BUFFER OVER
IDPB T4,T1
SOJG T3,GETIN2
POP P,T2
GETIN3: RCALL RELPKT,4 ;NO LONGER NEED THIS PACKET
JRST GETIN1 ;TRY TO PROCESS NEXT ONE
GETIN4: SKIPG T1,FILCNT(JFN) ;DID WE GET ANY?
JRST [ MOVX T1,CF%EOF ;HAVE WE SEEN AN EOF PACKET?
TDNE T1,CHASTA(CONN)
TQO <EOFF> ;YES, SET EOF FOR THIS STREAM
CONPTH [12]
SETZ T1, ;SOMETHING VENTURED, NOTHING GAINED
RET ]
ADDM T1,FILLEN(JFN) ;GOT SOME, UPDATE LENGTH OF WHOLE
RETSKP ;SUCCESS RETURN, WITH T1/NUMBER CHARS GOTTEN
;ROUTINE TO CALL TO GET A PACKET FROM A CONNECTION; RETURNS NON-SKIP IF
;NO PACKET THERE BY SURPRISE; THIS NEEDS TO BE LOCKED UP TO AVOID A RACE.
CHGETP: SAVET ;1000 Save temps here
CALL NOSKDP ;LOCK THIS UP
MOVEI Q2,CHAIBF(CONN)
CALL CHAQGF ;GET PACKET OFF LIST SINCE THERE IS ROOM
JUMPE PKT,CHGETE ;NONE THERE, FAIL RETURN
LOAD T1,CPKOP,(PKT)
CAIE T1,.CORFC ;UNLESS READING A RFC
SOS CHANBF(CONN) ;ONE LESS ON LIST
CALL CHPKIA ;HANDLE ACK OF IT IF EOF OR DATA PACKET
AOS (P) ;SUCCESS
CHGETE: CALLRET OKSKDP ;ALL DONE IN ANY CASE
RESCD
;HANDLE ACK OF DATA AND EOF PACKETS;
; REMEMBER WE'VE SEEN AN EOF PACKET IF SO FOR STREAM I/O'S SAKE.
CHPKIA::SAVET ;SAVE AC'S
LOAD T3,CPKOP,(PKT) ;GET OPCODE
CAIE T3,.COEOF ;EOF?
CAIL T3,.CODAT ;OR DATA?
CAIA ;YES
RET ;NOPE, FORGET IT
MOVX T1,CF%EOF ;MARK THIS CONNECTION AS HAVING SEEN AN EOF
CAIN T3,.COEOF
IORM T1,CHASTA(CONN) ; IF WE'RE NOW LOOKING AT ONE
HRRZ T1,CHASTA(CONN) ;THIS CONNECTION STILL OPEN?
CAIE T1,.CSOPN
RET ;NO, DON'T SEND ANY STATI
PUSH P,PKT ;SAVE PKT OVER POTENTIAL CHASTO CALL
LOAD T1,CPKPN,(PKT) ;GET PACKET NUMBER
HRLM T1,CHAPKN(CONN) ;UPDATE LAST GIVEN TO USER
CONPTH [10]
CONPTH T1 ;REMEMBER, IF DEBUGGING, WHAT WE JUST SET
HLRZ T2,CHAACK(CONN) ;GET LAST WE ACK'ED
SUB T1,T2
SKIPGE T1
ADDI T1,200000
IMULI T1,3 ;CHECK AGAINST 1/3 WINDOW SIZE
HLRZ T2,CHAWIN(CONN)
CAIE T3,.COEOF ;IF EOF, OR
CAML T1,T2 ; NEED ACKING,
CALL CHASTO ;SEND STATUS NOW
POP P,PKT
RET
SWAPCD
;ACCEPT AN RFC
SNDOPN: HLRZ PKT,CHAIBF(CONN) ;GET HEAD OF INPUT QUEUE
JUMPE PKT,SNDOP1 ;NONE THERE
LOAD T1,CPKOP,(PKT) ;GET THE OPCODE
CAIE T1,.CORFC ;THE RFC STILL HANGING AROUND?
JRST SNDOP1 ;NO
MOVEI Q2,CHAIBF(CONN) ;YES, REMOVE IT THEN
CALL CHAQGF
JUMPE PKT,SNDOP1 ;IF NOT THERE (?), DON'T FLUSH IT
RCALL RELPKT,5 ;AND FLUSH IT
SNDOP1: MOVEI T1,.CSOPN ;MAKE CONNECTION BE OPENED
HRRM T1,CHASTA(CONN)
CONPTH [13]
MOVEI Q2,.COOPN ;OPN OPCODE
JRST CHASO2 ;SEND LIKE A STS PACKET
;SEQUENTIAL OUTPUT
CHASQO: PUSH P,T1 ;SAVE CHARACTER
CHASQ1: SOSL FILCNT(JFN)
JRST CHASQ2
SETZM FILCNT(JFN) ;DIDNT REALLY PUT IN ANOTHER CHARACTER
CALL FLSOUT ;FORCE OUT THIS BUFFER
JRST [POP P,(P)
RET] ;ERROR RETURN
CALL GETOUT ;AND GET NEW ONE
JRST CHASQ1
CHASQ2: POP P,T1
IDPB T1,FILBYT(JFN)
RET
;FORCE OUT THE REST OF THIS BUFFER
CHASQR: MTOSND: ;I GUESS FOR NOW
FLSOUT: HRRZ CONN,FILCON(JFN)
CHKCON ;VALIDATE IT IF DEBUGGING
CONPTH [14]
HRRZ PKT,FILOBF(JFN)
JUMPE PKT,RSKP ;NONE THERE NOW, FORGET IT
CHKPKT ;VALIDATE PACKET IF DEBUGGING
PKTPTH [43]
MOVE T1,CHPMXT
SUB T1,FILCNT(JFN) ;GET SIZE OF PACKET DATA
STOR T1,CPKNB,(PKT)
SETZM FILCNT(JFN)
SETZM FILOBF(JFN)
CALL SNDPKT ;SEND OFF AS A DATA PACKET
TQOA <ERRF>
RETSKP
MOVEI T1,IOX5 ;ERROR RETURN
RET
;GET ANOTHER OUTPUT BUFFER
GETOUT: HRRZ CONN,FILCON(JFN) ;GET CONNECTION BLOCK
CHKCON ;VALIDATE IT IF DEBUGGING
HRRZ T1,CHASTA(CONN) ;GET STATE OF CONNECTION
CAIN T1,.CSRFC ;RFC RECEIVED?
CALL SNDOPN ;YES, ACCEPT CONNECTION THEN
MOVEI Q2,.CODAT ;RANDOM DATA OPCODE
RCALL ASGPKC,32 ;GET PACKET FOR THIS CONNECTION
JRST [ CALL OUTWAT ;WAIT A LITTLE BIT
JRST GETOUT] ;AND TRY AGAIN
HRRZM PKT,FILOBF(JFN)
ADD PKT,[POINT 8,CHPKDT] ;MAKE BYTE POINTER TO DATA PORTION
MOVEM PKT,FILBYT(JFN)
MOVE T1,CHPMXT
MOVEM T1,FILCNT(JFN)
RET
;; SYSTEM OUT OF STORAGE, DELAY A LITTLE WHILE
OUTWAT: MOVEI T1,^D100
DISMS
CONPTH [15]
IFN T20FLG,<
RET
>
IFN TNXFLG,<
WATRET: MOVE T1,FORKX
MOVE T1,FKINT(T1)
TLNN T1,(1B1) ;CHECK MANUALLY FOR INTERRUPT
RET
CALL UNLCKF ;UNLOCK THE FILE
MOVE P,MPP ;AND UNWIND IF THERE IS ONE
MOVE B,(P)
SOS B
HRRM B,(P)
JRST MRETN
>
;HANDLE A LOS PACKET, MOVE THE STRING OF THE DATA INTO THE JSB SOMEPLACE;
;RETURN "LOS RECEIVED FOR CONNECTION" ERROR CODE IN T1 FOR USE BY CALLER.
GETLOS: MOVEI Q2,CHAIBF(CONN) ;GET PACKET FROM CONNECTION
CALL CHAQGF
JUMPE PKT,R ;NONE THERE
CHKPKT
LOAD T3,CPKOP,(PKT)
CAIE T3,.CSCLS
CAIN T3,.COLOS ;FIND THE LOS
JRST GETLS1
RCALL RELPKT,6 ;I DONT THINK THERE SHOULD EVER BE ANY OF THESE
JRST GETLOS
GETLS1: HLRZ T2,FILCON(JFN)
JUMPE T2,GETLS2
HRRZS (T2)
MOVEI T1,JSBFRE
CALL RELFRE ;RETURN OLD STRING TO FREE STORAGE IF ANY
HRRZS FILCON(JFN)
GETLS2: LOAD T2,CPKNB,(PKT) ;GET BYTE SIZE OF THIS PACKET
JUMPE T2,GETLS4 ;NOTHING THERE, FORGET IT
MOVEI T2,4+1+3(T2) ;PLUS ONE WORD FOR HEADER AND ONE BYTE FOR NULL
LSH T2,-2 ;NUMBER OF WORDS
NOINT ;UNTIL WHERE IT WILL BE REMEMBERED
CALL ASGJFR
JRST [ OKINT
JRST GETLS4] ;CAN'T, GO CLEAN UP AND REPORT ERROR
HRLM T1,FILCON(JFN) ;SAVE STRING FOR ERROR REPORTING
OKINT
HRLI T1,(<POINT 8,0,32>)
MOVE T2,[POINT 8,CHPKDT(PKT)]
LOAD T3,CPKNB,(PKT)
JUMPE T3,GETLS3
ILDB T4,T2 ;MOVE OVER STRING OF DATA
IDPB T4,T1
SOJG T3,.-2
GETLS3: IDPB T3,T1 ;AND A NULL FOR GOOD MEASURE
GETLS4: RCALL RELPKT,7
MOVEI T1,CHAOX1
RET
;CHA: DEVICE STATUS
CHASTS:
IFN TNXFLG,<
TEST (NN,OPNF)
JRST [ SETZ T1, ;PRETEND STATE IS CLOSED IF NOT OPENED
RET]
>
HRRZ CONN,FILCON(JFN)
CHKCON ;VALIDATE IT IF DEBUGGING
HRRZ T1,CHASTA(CONN) ;WILL END UP IN USER AC2
HRR T2,CHANBF(CONN)
HRL T2,CHANOS(CONN) ;AC3: AVAILABLE OUTPUT WINDOW,,
UMOVEM T2,3 ; NUMBER OF PKTS WAITING IN RCV END
RET
SUBTTL CHAOS NET MTOPRS
CHAMTO: HRRZ CONN,FILCON(JFN)
CHKCON ;VALIDATE IT IF DEBUGGING
XCTUM [HRRZ T2,2]
MOVSI T1,-NCHMTS
CHAMT1: HLRZ PKT,CHAMTB(T1)
CAIN PKT,(T2)
JRST CHAMT2
AOBJN T1,CHAMT1
RETBAD (MTOX1)
CHAMT2: HRRZ T2,CHAMTB(T1)
IFN T20FLG,<
JRST (T2)
>
IFN TNXFLG,<
MOVEI T3,CHAWAT ;SUPPLY WAIT COROUTINE
CALL (T2) ;CALL ROUTINE
SKIPA
RET
MOVEM T1,LSTERR## ;SAVE FOR GETER
CALL UNLCKF ;UNLOCK FILE
ITERR() ;SINGLE RETURN MEANS ERROR, GIVE PSI
>
CHAMTB: .MOACN,,MTOACN ;SET INTERRUPT CHANNEL
.MOERR,,MTOERR ;GET ERROR MESSAGE
.MOSND,,MTOSND ;SEND OUT ANY BUFFERED OUTPUT
.MOPKS,,MTOPKS ;SEND A SINGLE DATA PKT
.MOPKR,,MTOPKR ;RECV A SINGLE DATA PKT
.MOSWS,,MTOSWS ;SET WINDOW SIZE
.MOOPN,,MTOOPN ;ACCEPT AN RFC
.MOEOF,,MTOEOF ;SEND EOF FOR CONNECTION
.MONOP,,MTONOP ;WAIT FOR DATA TO GET SENT
.MOAWS,,MTOAWS ;AVAILABLE WINDOW SIZE
.MOFHS,,MTOFHS ;FOREIGN HOST
.MOSIZ,,MTOSIZ ;MAXIMUM SIZE OF PACKET AVAILABLE
.MORWS,,MTORWS ;READ THE CURRENT WINDOW SIZES
.MOUAC,,MTOUAC ;READ THE NUMBER OF UNACK'ED PKTS
.MOSRT,,MTOSRT ;SET RFC TIMEOUT PERIOD IN MS
IFN FRNDLY,<
.MOFRH,,MTOFRH ;CHECK FOR FRIENDLY HOST
>
NCHMTS==.-CHAMTB
IFN FRNDLY,<
FRHTAB: FRENDS
FRHTBL==.-FRHTAB
;CHECK HOST FOR JFN FOR BEING FRIENDLY
MTOFRH: XCTUM [SKIPN T2,3] ;GET HOST IF SPEC'ED
LOAD T2,CHAHST,(CONN) ;ELSE GET FOREIGN HOST FOR CONN
CALL NAMHST ;GET NAME INTO T1
JRST MTOFR0 ;NO NAME, UNFRIENDLY
MOVE T4,T1 ;SAVE AWAY
MOVSI T3,-FRHTBL
MTOFR2: HRRO T1,FRHTAB(T3) ;CHECK AGAINST THIS FRIENDLY HOST
HRRO T2,T4
STCMP
JUMPE T1,MTOFR1 ;A WINNER
AOBJN T3,MTOFR2
MTOFR0: TDZA T3,T3
MTOFR1: SETO T3,
UMOVEM T3,3 ;RETURN TO USER
RETSKP
>
;SET TIMEOUT PERIOD (IN MS) FOR RFC WAITING VIS A VIS THIS CONNECTION
MTOSRT: UMOVE T3,3 ;PICK UP TIMEOUT
STOR T3,CHATRF,(CONN) ;SET IT IN (MAX ~256 SECS SINCE ONLY HALFWD)
RETSKP
;NOTE: BY "UNACK'ED" PACKETS, I MEAN UNDELIVERED, IN DISTINCTION FROM UNRECEIPTED
;PACKETS. THIS ISN'T CONSISTENT WITH OTHER COMMENTS IN THIS FILE; SIGH.
MTOUAC: CALL NOSKDP ;LOCK OUT WINDOW HACKING FOR A JIFFY
HRRZ T3,CHAWIN(CONN) ;GET TRANSMIT WINDOW
SUB T3,CHANOS(CONN) ; SUBTRACT OUT AVAILABLE WINDOW
CALL OKSKDP ;UNLOCK
UMOVEM T3,3 ;RETURN THIS AS NUMBER OF UNACKNOWLEDGED PACKETS
RETSKP
MTORWS: SKIPA T3,CHAWIN(CONN) ;GET CURRENT RECEIVE,,TRANSMIT WINDOW SETTINGS
MTOSIZ: MOVE T3,CHPMXT ;GET MAXIMUM SIZE IN BYTES OF PACKET WE CAN HANDLE
UMOVEM T3,3
RETSKP
;ASSIGN INTERRUPT CHANNELS FOR STATE CHANGE NOTIFICATION
MTOACN: XCTUM [HRRZ T3,3]
STOR T3,CHAICN,(CONN)
XCTUM [HLRZ T3,3]
STOR T3,CHAOCN,(CONN)
MOVE T3,FORKX ;JUST IN CASE SOME OTHER FORK OPENED THIS UP
STOR T3,CHAFRK,(CONN)
RETSKP
;GET AN ERROR STRING FROM A LOS OR CLS
MTOERR: HLRZ T2,FILCON(JFN) ;GET ERROR BYTE POINTER
JUMPE T2,[RETBAD (CHAOX4)]
HRLI T2,(<POINT 8,0,32>)
UMOVE T3,3
TLC T3,-1
TLCN T3,-1
HRLI T3,(<POINT 7,>) ;STANDARDIZE BYTE POINTER FROM USER
MTOER1: ILDB T1,T2
JUMPE T1,MTOER2
XCTBU [IDPB T1,T3]
JRST MTOER1
MTOER2: UMOVEM T3,3 ;RETURN USER UPDATED BYTE POINTER
XCTBU [IDPB T1,3] ;AND APPEND A NULL FOR GOOD MEASURE
RETSKP
;SET RECEIVE WINDOW SIZE
MTOSWS: UMOVE T1,3 ;GET NEW SIZE
CAMLE T1,MXRWIN ;RANGE CHECK IT
MOVE T1,MXRWIN
SKIPG T1 ;IS IT UNREASONABLE?
MOVE T1,1 ;YES, LESS THAN 1 IS USELESS
HRLM T1,CHAWIN(CONN)
AOS (P) ;CAN'T FAIL FROM NOW ON
HRRZ T1,CHASTA(CONN) ;GET STATE NOW
CAIE T1,.CSOPN ;OPEN CONNECTION THERE?
RET ;NO, DONT TRY TO SEND ANYTHING
JRST CHASO1 ;YES, SEND A STS RIGHT AWAY SO IT TAKES EFFECT
;RETURN AVAILABLE WINDOW SIZE FOR SENDING
MTOAWS: MOVE T3,CHANOS(CONN)
UMOVEM T3,3
RETSKP
MTOFHS: LOAD T3,CHAHST,(CONN) ;GET FOREIGN HOST
UMOVEM T3,3 ;+++SHOULD ADD IN NETWORK NUMBER, I GUESS
RETSKP
;SEND A SINGLE DATA PACKET
MTOPKS:
IFN KLFLG!SMFLG,<
XCTBU [LOAD Q2,CPKOP,(3)] ;GET OPCODE
>
IFN F3FLG,<
UMOVE T3,3
HRLI T3,(<POINTR (0,CPKOP)>)
XCTBU [LDB Q2,T3]
>
HRRZ T3,CHASTA(CONN) ;AND CONNECTION STATE
CAIN T3,.CSPRF ;IN PERMANENT-RFC-SENT STATE?
CAIE Q2,.CORFC ; AND TRYING TO SEND A RFC?
CAIA ;NO
JRST MTPKS4
CAIN T3,.CSOPN ;CONNECTION OPEN?
JRST MTPKS1 ;YES, GO SEND THE PACKET AS DATA
CAIE T3,.CSRFC ;RFC RECEIVED?
RETBAD(CHAOX2) ;NO, NOT IN THE RIGHT STATE
CAIE Q2,.COANS ;LET USER HAVE SIMPLE CONNECTIONS
CAIN Q2,.COCLS ;OR SPECIFY A REASON FOR REFUSAL
JRST MTPKS2
PUSH P,Q2 ;SAVE OPCODE
CALL SNDOPN ;DOING OUTPUT IMPLIES ACCEPTING THE CONNECTION
POP P,Q2
MTPKS1: CAIN Q2,.COEOF ;SENDING AN EOF?
JRST MTOEOF ;YES, HANDLE IT CANONICALLY OUR WAY
CAIE Q2,.COLOS
CAIN Q2,.COCLS ;SPECIFYING REASON FOR FLUSHING?
JRST MTPKS2
CAIGE Q2,.CODAT
MOVEI Q2,.CODAT ;MAKE IT LEGAL DATA OPCODE
CALL MTPKS3 ;SETUP THE PACKET
RET ;ERROR
JRST SNDPKT ;GO SEND IT OFF
MTPKS2: CALL MTPKS3 ;SETUP THE ANS OR CLS PACKET
RET ;FAILED
SETZ T1,
CALL SNDPK1 ;SEND IT OFF, BLOCKING OK
CALL CHACL4 ;FLUSH DATA, ETC.
MOVEI T1,.CSCLS ;NOW CLOSED
HRRM T1,CHASTA(CONN)
RETSKP
LOAD T1,CPKNB,(3) ;GET NUMBER OF BYTES
MTPKS3: XCTBU .-1
CAMLE T1,CHPMXT
RETBAD(CHAOX3)
PUSH P,T1
ADDI T1,3 ;ROUND UP
LSH T1,-2 ;INTO WORDS
PUSH P,T1 ;SAVE FOR LATER
RCALL ASGPK1,33 ;GET A PACKET FROM LENGTH IN 1 AND OPCODE IN Q2
JRST [ ADJSP P,-2
CALL OUTWAT ;WAIT A LITTLE BIT
JRST MTPKS3] ;AND TRY AGAIN
POP P,T1 ;WORD COUNT
XCTUM [HRRZ T2,3] ;ADDR IN USER SPACE OF BUFFER
ADDI T2,CHPKDT
XMOVEI T3,CHPKDT(PKT)
CALL BLTUM ;MOVE IT OVER
POP P,T1
STOR T1,CPKNB,(PKT) ;SET UP BYTE COUNT
RETSKP ;PACKET ALL SET UP NOW
;SEND PACKET ON .CSPRF CONNECTION
LOAD T1,CPKDA,(3) ;GET DESTINATION ADDRESS
MTPKS4: XCTBU .-1 ;LOSING TENEX MACRO
STOR T1,CHAHST,(CONN) ;PUT INTO CONNECTION BLOCK
CALL MTPKS3 ;YES, LET HER SEND IT; SET UP THE PACKET
RET ;FAILED; MIMIC
SETZ T1, ;SEND OFF, BLOCKING (ON THE FE) IS OK
CALL SNDPK0
RETSKP ;SUCCESS
;GIVE THE USER THE NEXT PACKET
MTOPKR: HRRZ T3,CHASTA(CONN)
CAMN CONN,CHRFHC ;IS THIS THE DISTINGUISHED RFC HANDLER?
JRST MTOPKP ;YES, GO GIVE IT ANY UNHANDLED RFCS
HLRZ PKT,CHAIBF(CONN) ;LOOK AT FIRST ON INPUT QUEUE
JUMPE PKT,SQIBLK ;NONE THERE, WAIT FOR ONE TO APPEAR
CHKPKT ;CHECK THIS IF DEBUGGING, BEFORE USING IT
PKTPTH [44]
CALL CHGETP ;GET THIS PACKET
JRST SQIBLK ;OUCH, NOTHING THERE NOW, GO WAIT AGAIN
MTOPR1: LOAD T1,CPKNB,(PKT) ;GET BYTE COUNT
ADDI T1,3+CHPKDT*4
LSH T1,-2 ;INTO WORDS
MOVEI T2,(PKT)
XCTUM [HRRZ T3,3] ;DEST
CALL BLTMU ;MOVE INTO USER SPACE
RCALL RELPKT,10 ;RID OF THIS PACKET
RETSKP
;HERE TO HANDLE A PACKET-READ REQUEST FROM THE DISTINGUISHED RFC HANDLER:
;HAND IT THE NEXT PACKET ON ITS INPUT LIST, WHICH IS A COPY OF AN UNHANDLED
;RFC, OR WAIT TILL SOME APPEAR IF NECESSARY.
MTOPKP: SKIPN CHAIBF(CONN) ;ANYTHING IN THE INPUT QUEUE?
JRST MTOPPW ;NO, GO WAIT FOR SOMETHING TO APPEAR
MOVEI Q2,CHAIBF(CONN) ;YES, PULL OF FIRST PACKET
CALL CHAQGF
JUMPE PKT,MTOPPW ;OOPS, NOTHING THERE; GO WAIT FOR WORK
SOS CHANBF(CONN) ;NOTE WE'VE TAKE THIS OFF THE INPUT LIST
CHKPKT ;CHECK IT IF DEBUGGING
PKTPTH [45]
JRST MTOPR1 ;ELSE, GIVE IT TO THE REQUESTING RFC HANDLER FORK
MTOPPW: MOVEI T1,MTOPWT ;WAIT FOR SOMETHING TO APPEAR
HRLI T1,(CONN) ; ON THIS CONNECTION
JRST CHAWAT
RESCD
MTOPWT: TCHKCN
SKIPN CHAIBF(T1) ;ANY NEW PACKETS FOR US TO LOOK AT?
JRST 0(T4) ;NO, KEEP WAITING
JRST 1(T4) ;YES, GO GET 'EM
SWAPCD
;ACCEPT A CONNECTION EXPLICITY
MTOOPN: AOS (P) ;WILL SKIP RETURN
JRST SNDOPN ;ACCEPT THE RFC
;SEND AN EOF PACKET ON A CONNECTION
MTOEOF: CALL FLSOUT ;SEND ANY BUFFERED STREAM OUTPUT
JFCL
MOVEI Q2,.COEOF ;SEND AN EOF
RCALL ASGPK0,34 ;GET A PACKET FOR CONNECTION
RETBAD(MONX01)
SETZRO CPKNB,(PKT) ;ZERO BYTE COUNT
JRST SNDPKT ;AND GO SEND IT OFF
;NOP: FLUSH ANY OUTPUT AND WAIT FOR IT TO GET SENT
MTONOP: PUSH P,T3 ;SAVE BLOCK PATH SUPPLIED BY .MTOPR
CALL FLSOUT ;SEND ANY BUFFERED OUTPUT
JFCL
;1031 Someboy changed this without an edit history. I don't know which works.
repeat 0,<
HRRZ T2,CHASTA(CONN)
CAIE T2,.CSOPN ;STILL OPEN?
JRST MTONO1 ;NO, DON'T WAIT
HLRZ T2,CHAOBF(CONN) ;GET HEAD OF CONNECTION OUTPUT PACKET LIST
JUMPE T2,MTONO1 ;EMPTY, DON'T WAIT
>
repeat 1,<
HRRZ T2,CHAWIN(CONN) ;PICK UP CURRENT XMIT WINDOW
CAMG T2,CHANOS(CONN) ;SEE IF STILL THINGS TO BE ACK'ED
JRST MTONO1 ;NO, DON'T WAIT
>
;1031 End of ambiguity
MOVSI T1,(CONN) ;WAIT FOR EVERYTHING TO GET ACKNOWLEDGED
HRRI T1,CLSWAT
POP P,T3 ;USE BLOCK PATH SUPPLIED BY .MTOPR
JRST (T3)
MTONO1: ADJSP P,-1 ;GET OUT
RETSKP
SUBTTL LOCAL ROUTING FORK
CHALRF:
IFN TNXFLG,<
MOVSI 1,UMODF ;FAKE UP SLOW JSYS ENTRY
MOVEM 1,FPC ; ..
>;IFN TNXFLG
MCENTR ;START HERE: ENTER MONITOR CONTEXT
IFE BBNFLG,<
MOVEI T1,1 ;WE NEED PRIORITY, STAY IN HIGHEST Q
MOVEM T1,JOBBIT
>
IFN BBNFLG,<
CALL SETSPQ ; Special Q for high priority
>
MOVE T1,TODCLK ;INIT BACKGROUND FORK WATCHDOG TIMER
ADDI T1,^D<5*1000> ;(GIVE IT SOME TIME TO GET GOING)
MOVEM T1,CHABFT
CHALRL: CALL CHALCR ;DO SOME ROUTING IF ANY TO DO
MOVE T1,TODCLK
ADDI T1,^D5000 ;RESET OUR WAKEUP TIMER
MOVEM T1,CHALRW
MOVEI T1,CHLTST ;WAIT FOR SOME MORE WORK
HDISMS (^D500) ;TRY TO STAY AROUND IN BALSET FOR SOME TIME
JRST CHALRL
RESCD
CHLTST: MOVE T1,CHALRW ;TIME TO WAKE UP?
SKIPN CHQLCL ;IF ANY WORK WAITING FOR US
CAMG T1,TODCLK ; OR IF TIME IS UP
JRST 1(T4) ; UNBLOCK
JRST 0(T4) ;NOTHING TO DO YET
SWAPCD
;DO SOME MAIN-BACKGROUND-FORK AND NFE-11 WEDGEDNESS CHECKING EVERY SO OFTEN
;THEN DO ANY LOCAL ROUTING THAT NEEDS BE DONE.
CHALCR: MOVE T2,CHABFW ;WHERE THE BACKGROUND FORK IS,
MOVE T3,CHATIM ; WHEN IT THINKS IT SHOULD RUN NEXT,
MOVE T4,CHAFLG ; WHAT ITS REQUESTS ARE,
MOVE Q2,TODCLK ; AND WHAT TODCLK IS NOW
IFGE NETDTE,<
MOVE T1,Q2 ;GET NOW
SUB T1,CHABFT ;FIND OUT WHEN THE MAIN BACKGROUND FORK LAST CYCLED
CAILE T1,^D<5*1000> ;IF MORE THAN A FEW SECONDS,
JRST CHALCB
CHALC0: MOVE T1,TODCLK ;GET NOW
SKIPE T2,CHNPWT ;FIGURE OUT WHEN WE NEED TO CHECK FOR 11 WEDGEDNESS
JRST CHLTS1 ;INITIALIZE FIRST TIME THROUGH
MOVE T2,T1
ADDI T2,^D<5*1000>
MOVEM T2,CHNPWT
SETZM CHNPOW ;AND ASK TO SEE CHNPO1 DROP BELOW EMPTY
CHLTS1: CAML T2,T1 ;TIME'S UP?
JRST CHLTS3 ;NO, DON'T CHECK NOW
ADDI T1,^D<5*1000>
MOVEM T1,CHNPWT ;YES, UPDATE TIME OF NEXT CHECK
SKIPGE CHNPO1 ;HOW'S THE -11 QUOTA DOING?
JRST CHLTS2 ;IT'S OK
SKIPG CHNPOW ;NO ROOM, HAS ANYONE SEEN ROOM IN PAST FEW SECS?
SKIPN CHAON ;-11 STILL UP?
CAIA ;YES OR NO
CHABUG(CHA11S) ;NO, COMPLAIN ABOUT IT
CHLTS2: SETZM CHNPOW ;IN ANY CASE, ASK TO SEE IT DROP BELOW EMPTY AGAIN
CHLTS3:
>;IFGE NETDTE
SKIPN CHQLCL ;IF LOCAL-Q IS NON-EMPTY, HANDLE IT
RET
CHSLC1: CALL NOSKDP ;LOCK OUT OTHER DIDDLERS OF THE LOCAL ROUTING Q
DEBUG,< MOVEI Q2,CHQLCL ;CHECK THIS QUEUE HEADER
CALL CHAQCK
JFCL ;ANY PROBLEM ALREADY REPORTED
>;DEBUG
HLRZ PKT,CHQLCL ;GET A PACKET FROM LOCAL Q
JUMPE PKT,OKSKDP ;NO MORE, GET OUT AFTER UNLOCKING THINGS
CHKPKT ;CHECK IT IF DEBUGGING
PKTPTH [46]
HLRZ T1,PKTLNK(PKT) ;PICK UP LOCAL-Q LINK FROM THIS PACKET
;1032 Note that CHSLCR is unreachable!
;1032 CAIN T1,1 ;SOME PHONY XMIT-ACTIVE FLAG?
;1032 CAIE T1,-1 ; OR NON-LINKED MARKER?
;1032 CAIA ;NO AND NO
;1032 CHABUG(CHSLCR) ;YES, COMPLAIN (JUST IN CASE)
HRROS PKTLNK(PKT) ;MARK AS NOT ON LOCAL-Q LIST ANY MORE
HRLM T1,CHQLCL ;MAKE NEXT THE NEW FIRST
SKIPN T1 ;WAS IT THE LAST?
SETZM CHQLCL ;YES, Q IS NOW EMPTY
PUSH P,PKT ;SAVE THIS PACKET OVER CHIPKT CALL
XMOVEI T1, ;REMEMBER OUR SECTION
JUMPE T1,[CALL CHIPKT ;ALREADY SECTION 0, DON'T DO ANY
JRST CHSLC2] ; SWITCHING
SE0ENT ;CHIPKT WANTS TO RUN IN SECTION 0
CALL CHIPKT ;HERE'S A PACKET FROM MYSELF
SE1ENT ;BACK TO 1 IF WE WERE ALREADY THERE
CHSLC2: POP P,PKT ;GET BACK ORIGINAL PACKET
RCALL RELPKM,11 ;GET RID OF IT IF IT'S NOT ON OTHER LISTS
CALL OKSKDP ;UNLOCK THINGS
JRST CHSLC1 ;BACK FOR MORE
IFGE NETDTE,<
CHALCB: CHABUG(CHATBF,<<T2,WHAT>,<T3,WHEN>,<T4,FLAGS>,<Q2,NOW>>)
MOVE T1,TODCLK ;COMPLAIN AND UPDATE SO WE DON'T BARF TOO OFTEN
MOVEM T1,CHABFT
JRST CHALC0
>;IFGE NETDTE
SUBTTL CHAOS NETWORK FORK
DEFINE WCALL (R) < ;;;FOR DEBUGGING: NOTE WHAT WE'RE DOING
DEBUG,< MOVEI T1,R
MOVEM T1,CHABFW
CALL R
>;DEBUG
NODEB,< CALL R >
>
CHSFRK:
IFN TNXFLG,<
MOVSI 1,UMODF ;FAKE UP SLOW JSYS ENTRY
MOVEM 1,FPC ; ..
>;IFN TNXFLG
MCENTR
MOVE T1,FORKX ;SAVE OUR FORK INDEX
MOVEM T1,CHAFHN
IFE BBNFLG,<
MOVEI T1,1 ;SAY WE SHOULD ALWAYS STAY IN HIGHEST-PRIORITY
MOVEM T1,JOBBIT ; QUEUE
>
IFN BBNFLG,<
CALL SETSPQ ; Special Q us
>
MOVE T1,CHAON
MOVEM T1,CHAONL ;REMEMBER LAST VALUE OF CHAON
SETZM CHNPWT ;INITIALIZE -11 WEDGENESS TIMER
SETZM CHATIM ;CLEAR OUR CYCLE CLOCKS: BASIC CYCLE,
SETZM CHATM1 ; TIMEOUT CYCLE
SETZM CHATM2 ; RFC CHECK CYCLE
SETZM CHNGTM ; NEGOTIATION TIMEOUTS FOR NVT'S
CALL CHSINI ;BUILD OUR HOST TABLE FROM HOSTS2 NOW
IFN CHINET,<
MOVEI T1,^D5000 ; Sleep for a little
DISMS ; to let the Internet initialize
SETZM CHPKTI ; Now allow us to get an internet buffer
>
;BASIC CYCLE: PROCESS REQUESTS, AND HANDLE ALARMS FOR TIMEOUTS, ETC.
;EACH ROUTINE WORRIES ABOUT SEEING IF IT'S TIME TO HANDLE ITS PARTICULAR
;TASK, AND, IF SO, SETTING UP THE TIME TO RUN NEXT TIME.
CHIFRF: MOVE T1,TODCLK ;UPDATE WHEN WE LAST RAN OUR BASIC CYCLE
MOVEM T1,CHABFT
SETZ T1, ;NOW, PICK UP FLAGS
EXCH T1,CHAFLG ; AND RESET THEM
MOVEM T1,CHAPFG ;SET LAST FLAG VALUE (WHAT WE USE BELOW)
SETZM CHAONC ;ASSUME NET HASN'T CHANGED ON US
MOVE T1,CHAON
CAME T1,CHAONL ;ANY CHANGE IN NET STATUS?
JRST [ SETO T2, ;NO, ASSUME IT JUST WENT DOWN
SKIPE CHAON ;DID IT?
MOVEI T2,1 ;NO, JUST CAME UP
MOVEM T2,CHAONC ;TELL WHAT HAPPENED
JRST .+1 ]
MOVEM T1,CHAONL ;REMEMBER WHAT WE JUST SAW FOR NEXT TIME THROUGH
WCALL CHFCC ;DO SOME CONSISTENCY CHECKS
WCALL CHATTS ;HANDLE ANY NVTS THAT NEED IT
WCALL CHFCNS ;UPDATE BASIC CYCLE CLOCKS, SCAN CONNECTIONS
WCALL CHFRFC ;DO ANY RFC HANDLING
WCALL CHANEG ;DO ANY NVT NEGOTIATION TIMEOUTS
MOVE T1,CHATIM
SKIPN CHAFLG ;IF ANY FLAGS ARE SET AGAIN
CAMG T1,TODCLK ; OR IF BASIC CYCLE ALARM TIME IS HERE ALREADY
JRST CHIFRF ; GO HANDLE IT
DEBUG,< MOVEI T1,. ;NOTE WE'RE WAITING HERE
MOVEM T1,CHABFW ; FOR DEBUGGING PURPOSES
>;DEBUG
MOVEI T1,CHFTST ;NO, WAIT UNTIL OUR TIME
HDISMS (^D500) ; COMES OR UNTIL SOMETHING HAPPENS WE CARE ABOUT
JRST CHIFRF ; (THE HDISMS IS TO STAY IN THE BALANCE SET)
RESCD
CHFTST: MOVE T1,CHATIM ;GET TIME FOR NEXT FULL FORK RUN
SKIPN CHAFLG ;IF ANY REQUESTS FOR WORK, OR
CAMG T1,TODCLK ; IF TIME IS UP
JRST 1(T4) ;UNBLOCK
JRST 0(T4) ;ELSE, NOTHING TO DO
SWAPCD
;UPDATE BASIC CYCLE CLOCKS (RETRANSMISSION AND TIMEOUT CLOCKS) AND
;DO A FULL CONNECTION SCAN FOR VARIOUS KINDS OF LOVING CARE.
;(NOTE: DON'T DISTURB BASIC ORDER HERE UNLESS YOU UNDERSTAND THE IMPLICATIONS)
CHFCNS: SETZM CHATMA ;ALARMS HAVEN'T GONE OFF YET
SETZM CHAT1A
MOVE T1,TODCLK ;GET "NOW"
SKIPL CHAONC ;IF NET HAS JUST GONE DOWN, OR IF IT'S
CAMLE T1,CHATIM ; TIME TO SET OFF THE BASIC CYCLE TIME ALARM
CAIA ;THEN DO SO
JRST CHFCSS ;NO, MUST JUST BE SOME REQUEST TO PROCESS
SETOM CHATMA ;MARK OUR BASIC-CYCLE ALARM AS BEING TRIPPED
ADDI T1,^D500 ;TRY TO LOOP THRU EVERY 500 MS
MOVEM T1,CHATIM ;THIS IS OUR NEXT TARGET WAKEUP TIME
SUBI T1,^D500 ;GET BACK TODCLK WITHOUT POTENTIAL CHANGE
CAMG T1,CHATM1 ;TIME FOR TIMEOUT CYCLE TOO?
JRST CHFCSS ;NO
SETOM CHAT1A ;YES, TURN ON TIMEOUT CYCLE ALARM
ADDI T1,^D<5*1000> ;REMEMBER WHEN NEXT TIMEOUT CYCLE IS DUE
MOVEM T1,CHATM1
CHFCSS: MOVE T1,CHAPFG ;GET POSSIBLE LIST OF KINDS OF WORK AHEAD OF US
SKIPN CHATMA ;IF NO BASIC-CYCLE WORK TO DO
TXNE T1,CH%IIN!CH%OIN!CH%DIN!CH%CLS!CH%STS ; AND IF NO PER-CONN REQUESTS
CAIA
RET ;JUST GET OUT
MOVSI F1,-MAXCON ;ELSE, SCAN ALL CONNECTIONS
;SCAN LOOP
CHFCSL: SKIPL CONN,CHACON(F1) ;IS THIS IN USE?
JRST CHFCSE ;NO, SKIP IT
HRRZS CONN ;CLEAR OUT UNIQUIZER (FOR NON-ZERO SECTIONS)
CHKCON ;VALIDATE CONN IF DEBUGGING
;RETRANSMIT EVERY BASIC CYCLE
SKIPE CHATMA ;DID THE BASIC CYCLE ALARM GO OFF?
CALL CHARTR ;YES, TRY TO RETRANSMIT STUFF FROM THIS CONNECTION
;TIMEOUT IDLE CONNECTIONS (AND HANDLE NET GOING DOWN CLEANLY)
SKIPL CHAONC ;DID THE NET GO DOWN RECENTLY
SKIPE CHAT1A ;OR IS IT TIME FOR A TIMEOUT CYCLE?
CAIA ;YES
JRST CHIF21 ;NO, TRY NEXT THEORY
HRRZ T2,CHASTA(CONN) ;GET STATE OF CONNECTION
CAIE T2,.CSRFS ;RFC-SENT STATE?
JRST CHIF19 ;NO, CHECK FURTHER
LOAD T2,CHATRF,(CONN) ;YES, PICK UP RFC TIMEOUT
JRST CHIF9A ; AND GO JOIN TIMEOUT TEST
CHIF19: CAIE T2,.CSOPN ;OPENED NOW?
JRST CHIF21 ;NO, SKIP THIS ONE
MOVX T2,^D<90*1000> ;YES, USE OPEN CONNECTION TIMEOUT LIMIT
CHIF9A: MOVE T1,TODCLK
SUB T1,CHAITM(CONN) ;GET TIME SINCE LAST ACTIVITY ON THIS CONNECTION
SKIPL CHAONC ;DID THE NET JUST GO DOWN, OR HAS IT BEEN
CAML T1,T2 ; MORE THAN OUR LIMIT?
CAIA ;YES OR YES
JRST CHIF20 ;NO, GO ON
MOVEI Q2,.CSINC ;INCOMPLETE TRANSMISSION: CONNECTION IS LOST
CALL CHAINT ;POSSIBLY NOTIFY SOMEONE OF CONNECTION STATE CHANGE
JUMPN CONN,CHIF21 ;IF STILL HAVE CONNECTION REF, TRY SOME MORE
SKIPL CONN,CHACON(F1) ;ELSE, GET BACK CONNECTION
JRST CHFCSE ; (NO CONNECTION ENTRY??? SKIP REST, THEN)
HRRZS CONN ;CLEAR OUT UNIQUIZER
JRST CHIF21 ;AND TRY NEXT THEORY
;REQUEST STATUS FOR DELINQUENT CONNECTIONS
CHIF20: HRRZ T2,CHASTA(CONN) ;STILL OPEN?
CAIE T2,.CSOPN
JRST CHIF21 ;NO, SKIP IT
MOVEI Q2,.COSNS ;WILL WANT A SNS PACKET IF LOSING
HRRZ T2,CHAACK(CONN)
HRRZ T3,CHAPKN(CONN)
CAMN T2,T3 ;OUTSTANDING PACKETS?
CAIL T1,^D<60*1000> ;NO, NOTHING IN MORE THAN A MINUTE?
CAIA
JRST CHIF21 ;NOTHING TO DO HERE
RCALL ASGPK0,35 ;YES, GET A PACKET WITHOUT DATA
JRST CHIF21 ;NO PACKET AVAILABLE
SETO T1,
CALL SNDPK0 ;SEND OFF PACKET, BUT NOT IF REQUIRES BLOCKING
SKIPE T1
AOS CHNSNS ;ONE MORE SNS SENT IF IT GOT OUT
CHIF21:
;PARANOIC CHECKING, THEN NVT-UNWEDGING IF NECESSARY
LOAD T2,CHANVT,(CONN) ;GET NVT INDEX, IF ANY
MOVE T1,CHASTA(CONN) ;ALSO PICK THIS UP FOR EXTRA INFO
SKIPN T2 ;IS THERE ANYTHING THERE?
JRST CHIF22 ;NO
CALL CHKCVT ;YES, IS THIS A CVT?
CHABUG(CHANCV,<<CONN,CONREF>,<T1,CHASTA>>) ;NO, COMPLAIN FOR KICKS
CHIF22:
;CHECK STATUS REQUEST
MOVX T1,CF%STS ;NEED STATUS DONE?
TDNE T1,CHASTA(CONN)
CALL CHASO1 ;YES, SEND THAT OUT
;CHECK INTERRUPT REQUESTS
MOVX T1,CF%IIN ;INPUT INTERRUPT REQUESTED?
TDNN T1,CHASTA(CONN)
JRST CHIF11 ;NO
ANDCAM T1,CHASTA(CONN) ;YES, CLEAR REQUEST
LOAD T1,CHAICN,(CONN) ;GET INTERRUPT CHANNEL
LOAD T2,CHAFRK,(CONN) ;AND OWNING FORK
CAIGE T1,^D36 ;HAVE A VALID CHANNEL?
CALL PSIRQ ;YES, INTERRUPT THE FORK
CHIF11: MOVX T1,CF%OIN ;OUTPUT INTERRUPT?
TDNN T1,CHASTA(CONN)
JRST CHIF10 ;NO
ANDCAM T1,CHASTA(CONN) ;YES, CLEAR REQUEST
LOAD T1,CHAOCN,(CONN)
LOAD T2,CHAFRK,(CONN)
CAIGE T1,^D36
CALL PSIRQ
CHIF10: MOVX T1,CF%DIN ;MARKED FOR DETACHMENT?
TDNN T1,CHASTA(CONN)
JRST CHIF12 ;NO
ANDCAM T1,CHASTA(CONN) ;CLEAR REQUEST
LOAD T2,CHANVT,(CONN) ;YES, DETACH NVT THEN
PUSH P,CONN ;SAVE CONNECTION INDEX JUST IN CASE
CALL DETCVT ; (THIS REQUESTS A CLOSE; HANDLED BELOW)
JFCL ;IGNORE ANY FAILURE
POP P,CONN
CHIF12:
;HANDLE CLOSE REQUESTS FOR NVTS
MOVX T1,CF%CLS ;DID SOMEONE REQUEST A FAST CLOSE?
TDNN T1,CHASTA(CONN)
JRST CHRDC9 ;NOT HERE, TRY NEXT THEORY
LOAD T2,CHANVT,(CONN) ;GET NVT NUMBER
CALL CHKCVT ;IS IT AN NVT?
CHABUG(CHAMCR) ;NOPE, MISBEGOTTEN CLOSE REQUEST: NOTE IT
HRRZ T1,CHASTA(CONN) ;GET CURRENT STATE
CAIE T1,.CSOPN ;STILL OPEN?
JRST CHRDC8 ;NO LONGER IN USEFUL STATE, GET RID OF IT
MOVEI Q2,.COCLS ;SEND A CLS
RCALL ASGPK0,36
JRST CHRDC8 ;CAN'T, BE RUDE AND FORGET ABOUT THE CONNECTION
SETO T1,
CALL SNDPK0 ;SHIP CLS OFF, BUT NOT IF IT REQUIRES BLOCKING
CHRDC8: CALL RELCON ;WE CAN THROW OUT THIS CONNECTION NOW
JRST CHFCSE ;AND GO ON TO NEXT; CAN'T HELP ANY MORE HERE
;GET RID OF DEAD NVTS HERE
CHRDC9: HRRZ T1,CHASTA(CONN) ;GET CONNECTION STATE
CAIN T1,.CSLOS ;LOSING?
JRST CHRDCO ;YES, GET RID OF IT
CAIE T1,.CSINC ;INCOMPLETE?
CAIN T1,.CSCLS ; OR CLOSED?
CAIA ;YES
JRST CHFDC0 ;NO, CAN'T BE WHAT WE'RE LOOKING FOR
CHRDCO: MOVE T1,TODCLK ;GET TIME SINCE LAST ACTIVITY ON THIS CONN
SUB T1,CHAITM(CONN)
CAIG T1,^D<60*1000> ;MORE THAN A MINUTE SINCE ANY ACTIVITY?
JRST CHFDC0 ;NO, FORGET IT
LOAD T2,CHANVT,(CONN) ;YES, GET POTENTIAL NVT INDEX FROM THIS CONNECTION
CALL CHKCVT ;IS IT A CHAOS NVT?
JRST CHFDC0 ;NO, DONE
CALL RELCON ;YES, GET RID OF THIS CONNECTION
CHABUG(CHADNV) ;AND TELL ABOUT THIS DEAD NVT
JRST CHFCSE ;NOTHING MORE TO DO WITH THIS CONNECTION
CHFDC0:
CHFCSE: AOBJN F1,CHFCSL ;LOOP OVER ALL CONNECTIONS
RET ;DONE
;TRY MATCHING UP INCOMING RFC'S WITH LSN'S; IF NO MATCH, PUT A COPY
;ON THE DISTINGUISHED RFC HANDLER'S INPUT QUEUE FOR IT TO WORRY ABOUT.
CHFRFC: MOVX T1,CH%RFC ;ANY WORK FOR US TO DO?
TDNE T1,CHAPFG
JRST CHIF29 ;YES, GO TO IT
MOVE T1,TODCLK ;NO,
CAMG T1,CHATM2 ; TIME TO DO RFC CHECKS PERIODICALLY?
RET ;NO, THAT'S IT
ADDI T1,^D<5*1000> ;YES, REMEMBER WHEN TO MAKE NEXT CHECK
MOVEM T1,CHATM2
CHIF29: SETZ F1, ;WHAT WE LAST SAW
CHIF30: MOVEI Q2,CHQRFC ;GET RFC LIST
CALL NOSKDP ;PREVENT INTERRUPT CODE FROM LOOKING
CALL CHAQGF ;GET FIRST PKT
MOVEM PKT,CHQRFP ;TELL INTERRUPT LEVEL WE OWN THIS PACKET
CALL OKSKDP ;GET INTERRUPTS BACK
JUMPE PKT,R ;Q WAS EMPTY
CAIN F1,(PKT) ;IS THIS AS FAR AS WE GO ON Q?
JRST [ CALL NOSKDP ;YES, LOCK UP
SETZM CHQRFP ; AND CLEAR OUT THIS PACKET
CALL CHAQPF ; PUT PACKET BACK
CALLRET OKSKDP ] ;UNLOCK AND LEAVE
MOVEI T2,CHPKDT(PKT)
HRLI T2,(<POINT 8,>) ;MAKE BYTE POINTER TO CONNECTION NAME
MOVE T3,T2
ILDB T4,T3 ;LOOK FOR A SPACE IN IT
CAIE T4," "
JUMPN T4,.-2 ;NOTE THAT CONTACT NAME WAS MADE ASCIZ
MOVEI T1,0
DPB T1,T3 ;PUT IN A NULL THERE JUST IN CASE
PUSH P,T3 ;SAVE WHERE TO RESTORE STRING
PUSH P,T2 ;SAVE REF TO START OF STRING
HRROI T1,[ASCIZ /STATUS/] ;REQUEST FOR STATUS?
STCMP
JUMPE T1,[ADJSP P,-2 ;YES, FLUSH TEMPS
JRST CHIRFS] ; AND HANDLE THAT OURSELVES
POP P,T2 ;GET BACK ASCIZ REF
MOVEI T1,RFCTAB
TBLUK
POP P,T3
DPB T4,T3 ;PUT BACK IN THE SPACE OR NULL
TXNE T2,TL%EXM ;MATCHES?
JRST CHIF33 ;YES, INTRODUCE THEM
MOVE T1,TODCLK ;NO,
SKIPN T2,PKTTIM(PKT) ; IS THIS THE FIRST TIME FOR THIS PACKET?
JRST CHIF37 ;YES, SEE IF SHOULD START UP A SERVER
SUB T1,T2 ;NO, SEE WHEN THIS WENT ONTO THE QUEUE
CAIG T1,^D<30*1000> ;BEEN AROUND A REASONABLE AMOUNT OF TIME?
JRST CHIF35 ;NO, OK
PUSH P,PKT ;YES,
DEBUG,< DMOVE T1,CHPKDT(PKT) ;NOW, TELL ABOUT THIS UNHANDLED RFC
LOAD T3,CPKNB,(PKT) ;TELL ITS LENGTH
CHABUG(CHAUHR,<<T1,CONTC1>,<T2,CONTC2>,<T3,LENGTH>>)
>;DEBUG
MOVEI T2,[ASCIZ /Timeout: no such server at this site/]
CHIF3A: CALL CHALS2 ; SEND A CLS TO IT
CHIF3B: POP P,PKT
IFE SMFLG,< ;ON KS10, WE'VE ALREADY RECYCLED THE COPY IF ANY
RCALL RELPKT,12 ;FREE THIS PKT (WHAT WAS SENT WAS COPY)
>;IFE SMFLG,
JRST CHIF30
CHIF37: MOVEM T1,PKTTIM(PKT) ;FIRST UPDATE TIME OF PACKET
SKIPN CONN,CHRFHC ;IS THERE A RFC HANDLER HARD AT WORK?
JRST CHIF35 ;NO
PUSH P,PKT ;SAVE THIS OVER POTENTIAL CPYPKT
HRRZ T1,CHANBF(CONN) ;YES, PUT A COPY ON THE UNHANDLED RFC QUEUE
HLRZ T2,CHAWIN(CONN) ; IF THERE'S STILL ROOM IN ITS "WINDOW"
CAIGE T1,(T2)
CALL CPYPKT ;THERE'S ROOM IN THE WINDOW; TRY TO COPY IT
JRST CHIF3U ;NO ROOM OR CAN'T, COMPLAIN
MOVEI Q2,CHAIBF(CONN) ;PUT THIS COPY ON THE INPUT LIST
CALL CHAQPL ; FOR OUR RFC HANDLER (DON'T NEED TO COUNT IT)
AOS CHANBF(CONN) ;ACCOUNT FOR THIS NEW PACKET
CHIF36: POP P,PKT ;GET BACK ORIGINAL RFC PACKET
CHIF35: JUMPE F1,[MOVE F1,PKT ;REMEMBER WE HAVE SEARCHED THIS FAR
JRST .+1]
MOVEI Q2,CHQRFC ;PUT PACKET BACK ON RFC LIST FOR
; LISTENING SERVER TO FIND EVENTUALLY
CALL CHAQPL
JRST CHIF30
CHIF3U: CHABUG(CHANRU) ;COMPLAIN
JRST CHIF36 ;NO ROOM IN WINDOW OR FOR PACKET; GIVE UP
;STATUS RFC
CHIRFS: PUSH P,PKT
MOVX T3,CHSTBC ;THIS IS BYTE COUNT FOR STATUS ANSWER
GETPKT T ;GET A PACKET C(T3) BYTES LONG
JRST CHIF39 ;CAN'T DO THE COPY; DON'T BOTHER WITH IT
MOVE T1,[BYTE (8) .COANS,0,0,CHSTBC]
MOVEM T1,(PKT)
MOVE T1,CHPKS(PKT) ;EXCHANGE SOURCE AND DESTINATION
EXCH T1,CHPKD(PKT)
MOVEM T1,CHPKS(PKT)
MOVEI T1,CHPKDT(PKT)
HRLI T1,(<POINT 8,>)
MOVE T2,[POINT 7,MYHNAM]
MOVEI T3,^D32
CHIRS1: ILDB Q2,T2
JUMPE Q2,CHIRS2
IDPB Q2,T1
SOJA T3,CHIRS1
CHIRS2: MOVEI Q2,200 ;PAD WITH 200'S
IDPB Q2,T1
SOJG T3,.-1
MOVE T2,MYCHAD ;DTE SUBNET NUMBER: HIGH 8 BITS OF MY ADDRESS
LSH T2,-8
IORI T2,400 ;MARK AS NEW FORMAT STATUS ANS
CALL SWB16B
IFE SMFLG,< ;IF DON'T HAVE DIRECT HARDWARE CONNECTION,
MOVEI T2,4 ;4 MORE WORDS:
CALL SWB16B
MOVE T2,CHNPKI ; PACKETS IN
CALL SWB32B
MOVE T2,CHANPO ; AND OUT
CALL SWB32B
>;IFE SMFLG,
IFN SMFLG,< ;ELSE, ON KS DRIVE THE INTERFACE OURSELVES:
MOVEI T2,^D16 ;16 MORE WORDS
CALL SWB32B
SETZ T4,
CHIRS3: MOVE T2,NPKSIN(T4)
CALL SWB32B ;OUTPUT WORD OF STATUS
CAIE T4,7 ;OUTPUT EXACTLY 16 WORDS
AOJA T4,CHIRS3
>;IFN SMFLG,
SETO T1,
CALL CHAXMT ;AND GO ACTUALLY SEND IT, BUT DON'T BLOCK
CHIF39: JRST CHIF3B ;GO RESTORE AND FREE UP THE ORIGINAL PACKET
SWB32B: CALL SWB16B ;LOW 16-BITS FIRST
LSH T2,-8
SWB16B: IDPB T2,T1 ;OUTPUT A 16-BIT NUMBER, SWAB'ED
LSH T2,-8
IDPB T2,T1
RET
;THIS RFC MATCHES A LSN, PUT THEM TOGETHER
CHIF33: HRRZ CONN,(T1) ;GET CONNECTION INDEX
NOINT
CALL RFCFRE ;REMOVE ENTRY FROM RFCTAB
OKINT
CHKCON ;VALIDATE CONN IF DEBUGGING
CHKPKT ;VALIDATE PKT, TOO, IF NEEDS BE
LOAD T1,CPKPN,(PKT) ;GET PACKET NUMBER
HRLM T1,CHAPKN(CONN)
MOVE T1,CHPKS(PKT) ;AND FOREIGN HOST STUFF
MOVEM T1,CHAFRN(CONN)
MOVE T1,TODCLK ;SAVE THIS AS LAST TIME OF INPUT
MOVEM T1,CHAITM(CONN)
SETOM PKTLNK(PKT) ;MARK AS NOT TRANSMIT ACTIVE, ON NO LISTS
MOVEI Q2,CHAIBF(CONN) ;PUT ON LIST SO USER CAN SEE CONTACT NAME
CALL CHAQPL
MOVEI Q2,.CSRFC
CALL CHAINT ;INTERRUPT PROCESS MAYBE
JRST CHIF30 ;GO LOOK FOR MORE WORK
;RELEASE RCTAB ENTRY POINTED TO BY T1
RFCFRE: MOVEI T2,(T1) ;GET ADDRESS OF ENTRY
PUSH P,(T2) ;SAVE ENTRY
MOVEI T1,RFCTAB
TBDEL ;REMOVE FROM LIST OF GUYS NEEDED
ERJMP RFFREB
RFFRE1: POP P,T2
HLRZ T1,T2 ;GET ADDRESS OF CONNECTION NAME
SUBI T1,1 ;POINT TO HEADER
HRRZ T2,(T1) ;GET LENGTH
JRST RELSWP ;FREE IT UP
RFFREB: CHABUG(CHARFB) ;JUST IN CASE
JRST RFFREB
;SCAN NET TTY LINES EVERY BACKGROUND CYCLE OR WHEN CH%TTY GETS SET.
CHATTS:
IFN T20FLG,<
MOVE STS,CVTPTR ;COUNT THRU NVT LINES
CHATS1: HRR T2,STS ;GET TERMINAL NUMBER IN T2
PUSH P,STS ;+++SEE IF STS IS GETTING CLOBBERED
CALL LCKTTY ;GET ADDRESS OF DYNAMIC DATA
JUMPLE T2,CHATS2 ;IF NON-STANDARD BLOCK CHECK FOR OUTPUT
PUSH P,T2 ;SAVE ADDRESS OF DYNAMIC DATA
CALL TTSOBE ;ANY OUTPUT?
CALL CHATCS ;YES, PROCESS IT
POP P,T2 ;GET BACK ADDRESS OF DYNAMIC DATA
CHATS2: CALL ULKTTY ;UNLOCK TTY DATABASE
POP P,STS ;+++
AOBJN STS,CHATS1
SKIPN T2,CTMSTM ;ANY TTMSG'S OUT
RET ;NOTHING TO DO RETURN
CAMLE T2,TODCLK ;TIME TO FLUSH YET?
RET ;NO, RETURN
NOSKED ;PREVENT ANYONE ELSE FROM CHANGING DATA
CALL TMSCHR ;FLUSH ALL TTMSG'S TO NVT'S
OKSKED
SETZM CTMSTM ;CLEAR TIMER
RET
>;IFN T20FLG
IFN TNXFLG,<
PUSH P,10
MOVE 10,NVTPTR ; COUNT THRU NVT LINES
CHATS1: MOVEI 2,(10)
MOVSI 1,NVTCHS
TDNN 1,TTNETW(2)
JRST CHATS2 ; ONLY WHEN CHAOSNET TTY
SKIPN TTOCT(2) ; Output ready?
SKIPE TTECT(2)
CALL CHATCS ; Yes
CHATS2: AOBJN 10,CHATS1
POP P,10
RET
>;IFN TNXFLG
SUBTTL CONSISTENCY CHECKING EVERY CYCLE
CHFCC: SKIPL CHAONC ;DID THE NET JUST GO DOWN?
JRST CHFCC1
IFGE NETDTE,<
;; CALL GATDNC ;255 yes, poke internet
>
CHABUG(CHADWN) ;YES, NOTE THAT FACT FOR FUN
RET
CHFCC1: SKIPG CHAONC ;OR JUST COME UP?
RET
IFGE NETDTE,<
;; CALL GATINC ;255 up now, poke internet
>
CHABUG(CHAUPN) ;YES
RET ;THAT'S ALL FOR NOW
SUBTTL HOST TABLE SUPPORT
;GET IN HOSTS2.BIN IMAGE FOR OUR HOST TABLE. ALSO SETS UP MYHNAM TO
;BE MY OFFICIAL NAME (WAITS FOR OUR HARDWARE ADDRESS TO APPEAR FROM
;THE -11 BEFORE DOING SO).
;The format of the compiled HOSTS2 file is:
HSTSID==0 ; wd 0 SIXBIT /HOSTS2/
NAMPTR==10 ; wd 10 Address in file of NAME table.
SITPTR==11 ; wd 11 Address in file of SITE table.
NETPTR==12 ; wd 12 Address in file of NETWORK table.
;NETWORK table
; wd 0 Number of entries in table.
; wd 1 Number of words per entry. (2)
NETNUM==0 ; wd 0 network number
NTLNAM==1 ; wd 1 LH - address in file of name of network
NTRTAB==1 ; wd 1 RH - address in file of network's address table
;ADDRESS table(s)
; wd 0 Number of entries in table.
; wd 1 Number of words per entry. (2)
ADDADR==0 ; wd 0 Network address of this entry including network number
ADD%NW==377000000000 ;Network number portion of address
ADD%CA==000000177777 ;Chaosnet hardware address portion
ADLSIT==1 ; wd 1 LH - address in file of SITE table entry
ADRCDR==1 ; wd 1 RH - address in file of next ADDRESS entry for this site
; 0 = end of list
;SITE table
; wd 0 Number of entries in table.
; wd 1 Number of words per entry. (3)
STLNAM==0 ; wd 0 LH - address in file of official host name
STRADR==0 ; wd 0 RH - address in file of first ADDRESS table entry for
; this site. Successive entries are threaded
; together through ADRCDR.
;NAMES table:
; wd 0 Number of entries
; wd 1 Number of words per entry. (1)
NMLSIT==0 ; lh address in file of SITE table entry for this host.
NMRNAM==0 ; rh address in file of host name
; All names are ASCIZ strings, all letters upper case.
; The strings are stored before, after and between the tables.
; All strings are word-aligned, and fully zero-filled in the last word.
;Network addresses are defined as follows, for purposes of this table:
; 4.9 0
; 4.8-4.1 network number
; Chaos net (number 7):
; 3.9-2.8 0
; 2.7-1.1 address (2.7-1.9 subnet, 1.8-1.1 host)
; ARPANET (number 12): (note, old-format ARPANET addresses
; 3.9-3.8 0 never appear in the host table.)
; 3.7-2.1 IMP
; 1.9 0
; 1.8-1.1 Host
; Dialnet (number 26):
; 3.9-3.1 0
; 2.9-1.1 address in file of ASCIZ string of phone number
NOMNAM: MYNAME ;NOMINAL HOST NAME AT BUILD TIME
IFE NETDTE,<
RESCD
CHWHST: MOVE T1,MYHTIM ;GET LIMIT OF WAIT
CAMLE T1,TODCLK ;IS TIME UP YET?
SKIPL MYCHAD ; OR HAS MY ADDRESS APPEARED YET?
JRST 1(T4) ;YES, UNBLOCK
JRST 0(T4) ;NO
SWAPCD
>;IFE NETDTE,
CHSINI: STKVAR <CINERR,CINHFJ,CINFAD> ;ERROR FLAG, HOSTS2.BIN JFN, MY FULL CHAOS ADDRESS
SETZM CINERR ;NO ERROR YET
SETOM CINHFJ ;NO JFN YET
SETZM MYHNAM ;MAKE SURE WE KNOW WE DON'T KNOW OUR NAME YET
IFE NETDTE,< ;THIS ONLY WORKS WITH PRIMARY FE CHAOS SUPPORT
MOVE T1,TODCLK ;GET "NOW"
ADDI T1,^D<10*1000> ;WAIT UP TO 10 SECONDS FOR
MOVEM T1,MYHTIM ; MY HARDWARE ADDRESS TO APPEAR FROM -11
MOVEI T1,CHWHST ;WAIT FOR MY ADDRESS
SKIPL MYCHAD ;UNLESS IT'S ALREADY HERE
JRST CHSIN1 ;YEP
HDISMS(^D500) ;WAIT
CHSIN1: SKIPGE MYCHAD ;DID IT ACTUALLY ARRIVE?
CHABUG(CHAINH) ;NO, COMPLAIN ABOUT IT
>;IFE NETDTE
MOVX T1,GJ%OLD!GJ%SHT ;NOW, TRY TO FIND HOSTS2.BIN
IFN T20FLG,<
HRROI T2,[ASCIZ/SYSTEM:HOSTS2.BIN/]
>
IFN TNXFLG,<
HRROI T2,[ASCIZ/<SYSTEM>HOSTS2.BIN/]
>
GTJFN
ERJMP [MOVEI T1,0 ;CAN'T, COMPLAIN AND GET OUT
JRST CHSIER] ; WITH ERROR TYPE
MOVEM T1,CINHFJ ;GOT IT, REMEMBER THIS JFN
MOVE T2,[2,,.FBBYV] ;GET THE BYTE SIZE INFO AND NUMBER OF BYTES
MOVEI T3,T3 ; TO T3, T4
GTFDB
ERJMP [MOVEI T1,1 ;CAN'T, GIVE UP
JRST CHSIER]
EXCH T3,T4 ;T3/ NUMBER OF BYTES, T4/.FBBYV INFO
LDB T2,[POINTR(T4,FB%BSZ)] ;GET ACTUAL BYTE SIZE
LSH T2,<^D35-POS(OF%BSZ)> ;SHIFT IT INTO PLACE FOR OPENF
IORX T2,OF%RD ;WE SIMPLY WANT TO READ THE FILE
OPENF ;GET IT OPEN
ERJMP [MOVEI T1,2 ;FAILED; GIVE UP
JRST CHSIER]
LDB T2,[POINTR(T4,FB%PGC)] ;GET PAGE COUNT
CAILE T2,CHST2P ;WILL IT FIT?
JRST [ MOVEI T1,3 ;NOPE, GIVE UP
JRST CHSIER]
LDB T2,[POINTR(T4,FB%BSZ)] ;GET BACK BYTE SIZE
LSH T2,^D35-POS(<007700,,0>) ;SHIFT IT INTO PLACE FOR BP SIZE FIELD
TLO T2,440000 ;BUILD BYTE REF TO OUR HOST TABLE START
HRRI T2,CHOSTB
MOVNS T3 ;NOW, GET SET TO SIN IT ALL IN
SIN ;TRY IT
ERJMP [MOVEI T1,4 ;SOMETHING FAILED,
JRST CHSIER] ; NOTE IT
MOVE T1,CHOSTB+HSTSID ;PICK UP PURPORTED SELF-ID
CAME T1,[SIXBIT/HOSTS2/] ;IS IT OK?
JRST [ MOVEI T1,5 ;NO, FAIL
JRST CHSIER]
MOVE T1,CHOSTB+NETPTR ;YES, GET REF TO START OF NETWORK TABLE
DMOVE T2,CHOSTB(T1) ;NUMBER OF ENTRIES AND SIZE OF EACH
MOVEI T1,CHOSTB+2(T1) ;FIRST ENTRY ADDRESS (REAL)
CHSIN2: HLRZ T4,NTLNAM(T1) ;GET REF TO NAME OF THIS NET
MOVE T4,CHOSTB(T4) ;GET NAME
CAME T4,[ASCII/CHAOS/] ;THIS US?
SOJG T2,[ADDI T1,(T3) ;NO, BUMP TO NEXT ENTRY IF ANY MORE
JRST CHSIN2] ; AND TRY IT
JUMPLE T2,[MOVEI T1,6 ;COULDN'T FIND OUR NET NUMBER, COMPLAIN
JRST CHSIER]
MOVE T2,NETNUM(T1) ;GOT IT, PICK UP OUR NUMBER
MOVEM T2,CHANET ;SAVE IT HERE
SETOM CHOSTP ;NOW HAVE A TOTALLY KOSHER HOST TABLE READY
SKIPGE MYCHAD ;HAVE OUR ADDRESS?
JRST CHSIN4 ;NO, TRY TO WORK THE OTHER WAY (FROM OUR NAME)
LSH T2,<^D35-POS(ADD%NW)> ;PUT IT IN THE NETWORK FIELD
IOR T2,MYCHAD ;BUILD MY FULL HOSTS2 ADDRESS HERE
MOVEM T2,CINFAD ;SAVE IT FOR SCAN BELOW
HRRZ T1,NTRTAB(T1) ;GET OFFSET OF ADDRESS TABLE FOR CHAOSNET
MOVEM T1,CHANAO ;REMEMBER IT FOR LATER LOOKUPS
DMOVE T2,CHOSTB(T1) ;GET NUMBER OF ENTRIES AND SIZE OF EACH
MOVEI T1,CHOSTB+2(T1) ;GET REAL REF TO FIRST ENTRY
CHSIN3: MOVE T4,ADDADR(T1) ;GET THIS ENTRY'S ADDRESS
CAME T4,CINFAD ;IS IT I?
SOJG T2,[ADDI T1,(T3) ;NO, BUMP TO NEXT IF ANY MORE
JRST CHSIN3] ; AND KEEP LOOKING
JUMPLE T2,[MOVEI T1,7 ;COULDN'T FIND MY NAME
JRST CHSIER]
HLRZ T1,ADLSIT(T1) ;GET OFFSET OF SITE ENTRY FOR ME
HLRZ T1,CHOSTB+STLNAM(T1) ;GET OFFICIAL HOST NAME OFFSET
ADD T1,[POINT 7,CHOSTB] ;TURN INTO BP
SKIPA ;HAVE OUR NAME REF IN T1
CHSIN4: MOVE T1,[POINT 7,NOMNAM] ;DON'T KNOW OUR ADDRESS, USE NOMINAL NAME
MOVE T2,[POINT 7,MYHNAM]
ILDB T3,T1 ;MOVE IN MY ASCIZ OFFICIAL HOSTS2 NAME
IDPB T3,T2
JUMPN T3,.-2
SKIPL MYCHAD ;STILL IN THE DARK ABOUT MY ADDRESS?
JRST CHSIDN ;NO, GET OUT
MOVEI T1,MYHNAM-1 ;YES, FIND OUR ADDRESS THE OTHER WAY
CALL HSTNAM
SKIPA ;IF FAILS,
SKIPN T1 ; OR IF OUR NAME ISN'T FOUND
JRST [ MOVEI T1,10 ;REMEMBER THIS PROBLEM
JRST CHSIER ]
MOVEM T1,MYCHAD ;ELSE, REMEMBER MY HOST ADDRESS
JRST CHSIDN ;ALL SET, GO CLEAN UP
;HERE ON ERROR
CHSIER: MOVEM T1,CINERR ;NOTE SOME PROBLEM
;HERE WHEN DONE,TO CLEAN UP
CHSIDN: SKIPL T1,CINHFJ ;GET JFN IF ANY
CLOSF ; AND TRY TO CLOSE IT
ERJMP .+2 ;IF FAILS, TRY TO JUST RELEASE IT
JRST CHSIED ;NO JFN OR CLOSF WORKED, SKIP THE RELEASE
RLJFN ;GET RID OF THE JFN
ERJMP .+1 ;AGAIN, IGNORE FILE ERRORS
CHSIED: SKIPE T1,CINERR ;ANY REAL PROBLEMS ABOVE?
CHABUG(CHANHT,<<T1,PROB>>) ;YES, COMPLAIN APPROPRIATELY
RET
;CONVERT HOSTNAME STRING (JFN NAME BLOCK REF IN T1) TO NUMBER
HSTNAM: JUMPE T1,RSKP ;RETURN 0 (BUT OK) IF NO STRING
SAVEAC <T2,T3,T4,Q2,F1> ;SAVE WORK REGS
STKVAR <OHSTNT,<HSTNS,^D50/5>,LHSTNS> ;ORIGINAL STRING, COPY OF STRING, WD LENGTH
HRLI T1,(<POINT 7,0,34>)
MOVEM T1,OHSTNT ;SAVE NAME REF FOR LATER USE
ILDB T1,T1 ;GET FIRST
JUMPE T1,RSKP ;IF NULL STRING, RETURN NULL (BUT OK)
SKIPN CHOSTP ;HAVE A HOST TABLE?
JRST HSTNM1 ;NONE, TRY NUMBER SPEC
MOVEI T1,HSTNS ;CLEAR OUR
SETZM (T1)
MOVSI T2,(T1) ; LOCAL HOST FELLOW FOR WORD COMPARISON PURPOSES
HRRI T2,1(T1)
MOVEI T1,^D50/5-1(T1)
BLT T2,(T1)
MOVE T1,OHSTNT ;GET BACK ORIGINAL HOST SPEC
MOVNI T3,^D100 ;LIMIT COUNTER
MOVEI T2,HSTNS ;WHERE WE BUILD OUR WORD-COMPARABLE HOSTNAME
HRLI T2,440700
HSTNM0: ILDB T4,T1
CAIL T4,"a"
CAILE T4,"z"
CAIA
TRZ T4,40 ;UPPER-CASIFY ALPHABETICS FOR SAFETY
IDPB T4,T2
SKIPE T4
AOJL T3,HSTNM0
JUMPGE T3,HSTNM1 ;TOO LONG, TRY NUMBER JUST FOR SPITE
SETZ T4,
TLNN T2,760000 ;FILL OUT TO FULL WORD
JRST .+3
IDPB T4,T2
JRST .-3
HRRZS T2 ;GET ADDRESS OF LAST WORD STORED
SUBI T2,HSTNS ;GET LENGTH IN WORDS-1
MOVEI T2,1(T2) ;ADJUST
MOVNM T2,LHSTNS ;SAVE NEGATIVE FOR AOBJN USE BELOW
MOVE T1,CHOSTB+NAMPTR ;GET OFFSET OF NAMES TABLE
DMOVE T2,CHOSTB(T1) ;NUMBER OF ENTRIES AND SIZE OF EACH
MOVEI T1,CHOSTB+2(T1) ;REAL REF TO FIRST ENTRY
HSTNM7: HRRZ T4,NMRNAM(T1) ;PICK UP NAME OFFSET
MOVEI T4,CHOSTB(T4) ;TURN INTO REAL ADDRESS
MOVEI F1,HSTNS ;THIS IS COMPARAND
HRL F1,LHSTNS ;MAKE LOOP CONTROLLER
HSTNM8: MOVE Q2,(F1) ;SEE IF WORD-EQUAL
CAME Q2,(T4)
JRST [ ADDI T1,(T3) ;NO, BUMP TO NEXT ENTRY
SOJG T2,HSTNM7 ; AND GO ON IF ANY MORE
JRST HSTNM1 ] ;NO MORE, TRY NUMBER
MOVEI T4,1(T4)
AOBJN F1,HSTNM8 ;COMPARE ALL WORDS
HLRZ T1,NMLSIT(T1) ;FOUND IT; PICK UP SITE OFFSET FOR THIS GUY
HRRZ T1,CHOSTB+STRADR(T1) ;PICK UP FIRST ADDRESS ENTRY OFFSET FOR THIS SITE
HSTNM9: JUMPE T1,HSTNM1 ;RAN OUT OF ENTRIES, TRY NUMBER SPEC
MOVE T2,CHOSTB+ADDADR(T1) ;GET THIS ADDRESS
LDB T3,HNMPNW ;PICK OUT NETWORK NUMBER
CAME T3,CHANET ;IS THIS A CHAOS HOST ADDRESS?
JRST [ HRRZ T1,CHOSTB+ADRCDR(T1) ;NO, CDR DOWN LIST OF ADDRESSES
JRST HSTNM9 ] ;AND KEEP LOOKING
LDB T1,HNMPCA ;GET REAL HARDWARE ADDRESS
RETSKP ;DONE
HNMPNW: POINTR T2,ADD%NW
HNMPCA: POINTR T2,ADD%CA
;TRY FOR A NUMBER SPEC IF THE ABOVE HAIR FAILS
HSTNM1: SETZ T1, ;BUILD HOST NUMBER HERE
MOVE T2,OHSTNT ;GET BACK ORIGINAL SPEC REF
HSTNM2: ILDB T3,T2
JUMPE T3,RSKP
CAIL T3,"0"
CAILE T3,"7"
RET
LSH T1,3
ADDI T1,-"0"(T3)
JRST HSTNM2
;HOST NUMBER INTO HOST, NUMBER IN T2, RETURN SKIP IN T1 IF FOUND
NAMHST: SAVEQ
MOVE T1,CHANET
DPB T1,HNMPNW ;SET NETWORK AS CHAOS
PUSH P,T2 ;SAVE HOST ADDRESS
MOVE T1,CHOSTB+NETPTR ;POINTER TO NETWORK TABLE
DMOVE CONN,CHOSTB(T1)
ADDI T1,2
LSH T2,-^D27 ;JUST NETWORK NUMBER
NAMHS1: CAMN T2,CHOSTB+NETNUM(T1) ;FOUND THAT NETWORK
JRST NAMHS2
ADD T1,CONN+1
SOJG CONN,NAMHS1
ADJSP P,-1
POPJ P, ;NETWORK NOT FOUND
NAMHS2: HRRZ T1,CHOSTB+NTRTAB(T1) ;POINTER TO NETWORK'S ADDRESS TABLE
DMOVE CONN,CHOSTB(T1)
ADDI T1,2
POP P,T2 ;GET BACK HOST
NAMHS3: CAMN T2,CHOSTB+ADDADR(T1)
JRST NAMHS4
ADD T1,CONN+1
SOJG CONN,NAMHS3
RET
NAMHS4: HLRZ T1,CHOSTB+ADLSIT(T1) ;SITE ENTRY
HLRZ T1,CHOSTB+STLNAM(T1) ;NAME
ADDI T1,CHOSTB ;MAKE ABSOLUTE
RETSKP
RESCD ;HARDWARE SUPPORT ROUTINES
IFGE NETDTE,<
SUBTTL DTE SERVICE
IFN CHADTE,<
;FROM -11 STATUS
CHSSTS: MOVE T1,[-CHASBS,,CHASBL] ;POINT TO STATUS BLOCK
CHSST1: ILDB T3,T2
MOVEM T3,(T1)
AOBJN T1,CHSST1
SETOM CHAON ;SAY NET IS ON
;255 CALL GATINC ;POKE INTERNET GATEWAY ;255 moved
RET
;ACK FROM -11
CHADON: SOS T1,CHNPO1 ;ONE LESS PACKET OUTSTANDING IN -11
MOVEI T2,1 ;FOR CHNPOW RESET
CAMGE T1,CHNPOW ;DID WE GET BELOW SOMEONE'S WATCHDOG LIMIT?
MOVEM T2,CHNPOW ;YES, NOTE THAT FACT
RET
;-11 CRASHED, TURN OFF NET; THIS WILL EVENTUALLY CAUSE ALL CONNECTIONS TO GO .CSINC
DEDMCB::SETZM CHAON
RET
;-11 RELOAD ACTION, ALSO CALLED ONCE AT STARTUP
NODINI::
CHARLD: SETZM CHAON ;NETWORK OFF FOR NOW
MOVNI T1,^D10 ;NUMBER OF PACKETS TO ALLOW OUTSTANDING IN -11
MOVEM T1,CHNPO1
MOVEI T1,CHADTE
MOVE T2,[POINT 16,[BYTE (16) 0,1]]
MOVEI T3,2
CALL DTEQ
JFCL ;WILL GET SENT EVENTUALLY
RET
;PACKET FROM -11
CHAPKT: MOVEI PKT,1(T2) ;FALL INTO CHIPKT WITH PACKET SET UP
IF2,<IFN .-CHIPKT,<PRINTX ?CHIPKT MUST FOLLOW CHAPKT DIRECTLY>> ;DOUBLE-CHECK
>;IFN CHADTE
IFE CHADTE,<
;FROM -11 STATUS
CHSSTS: MOVE T1,[-CHASBS,,CHASBL] ;POINT TO STATUS BLOCK
CHSST1: ILDB T2,T4
LSH T2,8
ILDB T3,T4
IORI T2,(T3)
MOVEM T2,(T1)
AOBJN T1,CHSST1
SETOM CHAON ;SAY NET IS ON
MOVEI T1,
; CALL GATINC ;POKE INTERNET GATEWAY ;255 moved
RET
;ACK FROM -11
CHADON: JUMPL T2,R ;IGNORE ACK ALL
SOS T1,CHNPO1 ;ONE LESS PACKET OUTSTANDING IN -11
MOVEI T2,1 ;FOR CHNPOW RESET
CAMGE T1,CHNPOW ;DID WE GET BELOW SOMEONE'S WATCHDOG LIMIT?
MOVEM T2,CHNPOW ;YES, NOTE THAT FACT
RET
;-11 RELOAD ACTION, ALSO CALLED ONCE AT STARTUP
CHARLD: SETZM CHAON ;NETWORK OFF FOR NOW
MOVNI T1,^D10 ;NUMBER OF PACKETS TO ALLOW OUTSTANDING IN -11
MOVEM T1,CHNPO1
MOVSI T1,0 ;GET HOSTNUMBER AND RELATED INFO FROM -11
MOVE T2,[.DFRDS,,.FECHA] ;REQUEST DEVICE STATUS
SETZB T3,T4
CALL DTEQ
JFCL
RET
;STRING DATA FROM -11
CHAHSD: MOVE T3,(T4) ;FIRST WORD IS BYTE OFFSET INTO PACKET
LSH T3,-24 ;INTO T3
MOVE T2,(T4) ;NEXT IS NUMBER OF BYTES STILL TO COME
LSH T2,-4
ANDI T2,177777 ;INTO T2
SUBI T1,4 ;ACCOUNT FOR OUR HEADER
JUMPN T2,CHAHS1 ;IF BYTES STILL TO COME THIS PACKET
JUMPE T3,CHAHS2 ;OR IT IS OFFSET ANY
CHAHS1: ADDI T1,3(T3) ;LAST DESTINATION BYTE, AND READY TO ROUND UP
LSH T3,-2 ;MAKE WORD OFFSET (NOTE OFFSET REM 4 = 0)
LSH T1,-2 ;AND THIS ALSO
MOVEI T3,CHBGPK(T3) ;POINT INTO THE BIG PACKET
HRLI T3,1(T4) ;SOURCE IS DTE BUFFER WITH PACKET IN IT
BLT T3,CHBGPK(T1) ;COPY INTO BIG PACKET
JUMPN T2,R ;DONE IF MORE DATA TO COME
SKIPA PKT,[CHBGPK] ;HAVE ROUTINES PROCESS THE BIG PACKET
CHAHS2: MOVEI PKT,1(T4) ;THIS IS A SHORT PACKET, USE DTE BUFFER ITSELF
JRST CHIPKT
>;IFE CHADTE
>;IFGE NETDTE
IFN SMFLG,<
SUBTTL KS10-CHAOS INTERFACE SUPPORT
;;; HERE TO REINITIALIZE THE HARDWARE
CHARLD: SETZM CHAON ;ASSUME CHAOSNET IS OFF
MOVE T1,[CHAADR] ;CHECK FOR EXISTANCE OF CHAOS INTERFACE
CALL UBGOOD
RET ;IT'S NOT THERE, SO CHAOSNET IS OFF
SETZM CHAXPC+2 ;SETUP XPCW BLOCK
MOVEI T1,CHAHIN
MOVEM T1,CHAXPC+3
MOVE T1,[XPCW CHAXPC] ;THIS IS THE INTERRUPT INSTRUCTION
MOVE T2,SMTEPT+CHAUBN ;INTERRUPT VECTOR FOR OUR UNIBUS ADAPTOR
ADDI T2,CHAVEC/4 ;OFFSET BASED ON OUR INTERRUPT VECTOR
MOVEM T1,(T2) ;PLANT INTERRUPT INSTRUCTION
MOVE T1,[CHAADR]
MOVEI T2,CHSRST ;RESET THE INTERFACE
WRIO T2,CHACSR(T1)
RDIO T2,CHAMYN(T1) ;READ OUR HOST NUMBER
MOVEM T2,MYCHAD ;AND REMEMBER IT
SETZM CHATXQ ;CLEAR TRANSMIT QUEUE
SETOM CHAON ;SAY NETWORK IS ON
MOVEI T2,CHSTCL+CHSRCL+CHSREN
WRIO T2,CHACSR(T1) ;CLEAR TRANSMITTER AND RECEIVER, AND ENABLE
; RECEIVER INTERRUPTS
RET
CHAHIN: MOVEM 17,CHAACS+17 ;SAVE AC 17
MOVEI 17,CHAACS ;THEN SAVE REMAINDER WITH A BLT
BLT 17,CHAACS+16
MOVE 17,[-CHAIPS,,CHAIPL] ;INTERRUPT LEVEL PDL
MOVE T1,[CHAADR] ;CHAOSNET I/O ADDRESS
RDIO T2,CHACSR(T1) ;GET CURRENT DEVICE STATUS
TRNE T2,CHSRDN ;RECEIVE DONE -- GO HANDLE INTERRUPT
JRST CHAIRV
TRNE T2,CHSTEN ;TRANSMITTER INTERRUPT EXPECTED?
JRST CHAITX ;YES, CHECK TO SEE IF THAT'S IT
CHASPU: CHABUG(CHASPI,<<T2,D>>) ;SPURIOUS INTERRUPT, SHOULDN'T HAPPEN
CALL CHARLD ;THIS KNOWS HOW TO REALLY RESET THE WORLD
;;; RETURN FROM INTERRUPT
CHAIRT: MOVSI 17,CHAACS ;RESTORE ALL AC'S BUT 17
BLT 17,16
MOVE 17,CHAACS+17 ;NOW RESTORE 17
XJEN CHAXPC ;THEN RETURN FROM WHENCE WE CAME...
;;; HERE WHEN WE SUSPECT THE TRANSMITTER
CHAITX: TRNN T2,CHSTDN ;TRANSMIT DONE?
JRST CHASPU ;NOPE, SPURIOUS INTERRUPT
PIOFF ;WILL BE HACKING THE QUEUE
HRRZ PKT,CHATXQ ;THIS IS THE PACKET WE JUST TRANSMITTED
TRNE T2,CHSTAB ;TRANSMIT ABORTED?
JRST CHATXA ;YES, HANDLE DIFFERENTLY
CHATXB: HRRZ T1,PKTTLK(PKT) ;NEXT PACKET TO GO
SETZM PKTTLK(PKT) ;MAKE SURE NOBODY LOOKS AT THIS INFO
HLRZ T2,CHATXQ ;GET LAST PACKET ON QUEUE FOR ERROR CHECK
JUMPN T1,CHATX0 ;SOMETHING THERE, TRANSMIT IT
SETZM CHATXQ ;CLEAR THE QUEUE
PION ;DONE HACKING WITH IT ALSO
CAME T2,PKT ;IS QUEUE CONSISTENT?
CHATX1: CHABUG(CHATQF) ;TRANSMIT QUEUE IS INCONSISTENT
CALL CHAXIN ;PACKET IS DONE BEING TRANSMITTED
MOVE T1,[CHAADR]
MOVEI T2,CHSTEN
BCIO T2,CHACSR(T1) ;TURN OFF TRANSMITTER INTERRUPT ENABLE
JRST CHAIRT ;DISMISS INTERRUPT
CHATX0: CAMN T2,PKT ;THE PACKET WE JUST SENT BETTER NOT HAVE BEEN
; THE LAST ONE!
JRST [SETZM CHATXQ ;ERROR, REPORT IT AND FLUSH QUEUE
PION
JRST CHATX1]
HRRM T1,CHATXQ ;THIS PACKET IS THE NEXT TO GO
PUSH P,T1 ;SAVE FOR LATER
PION ;DONE WITH QUEUE FOR NOW
CALL CHAXIN ;REPORT PACKET AS TRANSMITTED
POP P,PKT ;GET THAT PACKET BACK
CALL CHATXP ;SEND IT OFF
JRST CHAIRT ;THEN DISMISS INTERRUPT
;;; HERE IF TRANSMIT ABORTED (PI SYSTEM IS OFF)
CHATXA: AOS NPKSAB ;COUNT THE ABORT
HLRZ T1,PKTTLK(PKT) ;GET THE RETRANSMISSION COUNT
AOS T1 ;ONE MORE TIME
CAILE T1,CHARTC ;OK TO RETRANSMIT
JRST CHATXB ;NOPE, SO TREAT AS IF SUCCESFUL
HRRZ T2,PKTTLK(PKT) ;GET NEXT PACKET
HRLZM T1,PKTTLK(PKT) ;REMEMBER THE NUMBER OF TIMES
;;; *** THIS IS A CROCK -- IT SHOULD WAIT 1/60 OF A SEC OR SO, BUT THAT'S
;;; *** TOO HARD FOR NOW SO IT'LL WORK THIS WAY
JUMPE T2,CHATXC ;WE ARE THE ONLY ONE, SO SEND US OFF RIGHT NOW
HRRM T2,CHATXQ ;PROMOTE NEW PACKET TO THE HEAD OF THE QUEUE
HLRZ T1,CHATXQ ;LAST PACKET ON QUEUE
HRRM PKT,PKTTLK(T1) ;LINK US IN
HRLM PKT,CHATXQ ;AND MAKE US LAST
MOVEI PKT,(T2)
CHATXC: PION ;QUEUES ARE CONSISTENT, TRANSMIT THE NEXT PKT
CALL CHATXP ;SEND IT OFF
JRST CHAIRT ;THEN DISMISS THE INTERRUPT
;;; HERE TO TRANSMIT PACKET IN PKT. THE INTERFACE BETTER BE READY FOR ONE!
CHATXP: MOVE T1,[CHAADR]
MOVEI T2,CHSTCL
BSIO T2,CHACSR(T1) ;CLEAR TRANSMITTER
MOVE T4,[<442000,,0>(PKT)] ;BYTE POINTER TO BEGINNING OF PACKET
REPEAT 10,< ;OUTPUT THE 16 HEADER BYTES
ILDB T2,T4
WRIO T2,CHAWBF(T1)
>
LOAD T3,CPKNB,(PKT) ;NUMBER OF DATA BYTES
AOS T3
LSH T3,-1 ;ROUND OFF TO NUMBER OF 16 BIT WORDS
JUMPE T3,CHATP1 ;ONLY HEADER, SKIP DATA TRANSMISSION STUFF
LOAD T2,CPKOP,(PKT) ;GET THE OPCODE
CAIE T2,.COOPN ;16 BIT CONTROL OPCODE?
CAIN T2,.COSTS
JRST CHATP2
CAIN T2,.CORUT
JRST CHATP2
CAIGE T2,.CODAT+100 ;BINARY DATA?
JRST CHATP0 ;NOPE, USE THE SLOW LOOP
CHATP2: ILDB T2,T4
WRIO T2,CHAWBF(T1) ;WRITE DATA WORD TO INTERFACE
SOJG T3,CHATP2
CHATP1:
;;; *** HERE IT SHOULD ROUTE, BUT FOR NOW JUST SEND IT OUT TO THE SPECIFIED
;;; *** HOST ON SUBNET 1 (OUR OWN SUBNET)
LOAD T2,CPKDA,(PKT)
WRIO T2,CHAWBF(T1)
RDIO T2,CHAXMT(T1) ;TRANSMIT THE THING
MOVEI T2,CHSTEN ;AND ENABLE TRANSMITTER INTERRUPTS
BSIO T2,CHACSR(T1)
RET
;;; HERE WHEN NEED TO DO BYTE SWAPPING ON OUTPUT
CHATP0: MOVE T4,[<441000,,CHPKDT>(PKT)] ;8 BIT BYTE POINTER
CHATP4: ILDB T2,T4 ;GET NEXT BYTE
ILDB Q2,T4 ;THIS NEEDS TO BE HIGH ORDER BYTE
DPB Q2,[101000,,T2] ;SO PLANT IT IN AC
WRIO T2,CHAWBF(T1) ;WORD OUT TO INTERFACE
SOJG T3,CHATP4
JRST CHATP1
;;; HERE TO RECEIVE A PACKET, T2 HAS HARDWARE CSR, T1 HAS CHAOS BASE ADDRESS
CHAIRV: AOS NPKSIN ;COUNT THIS AS ANOTHER PACKET IN FORM INTERFACE
TRNE T2,CHSERR ;CRC ERROR?
JRST CHARV5 ;YES, COUNT IT, FLUSH THE PACKET, THEN PROCEED
RDIO Q2,CHARBF(T1) ;GET FIRST 16 BIT WORD, WHICH CONTAINS OPCODE
LSH Q2,-8 ;SHIFT OPCODE INTO POSITION
RDIO T2,CHARBF(T1) ;NEXT WORD IS FORWARDING COUNT AND LENGTH
MOVEI T1,3(T2) ;GET NUMBER OF BYTES IN PACKET + 3 TO ROUND
LSH T1,-2 ;CONVERT TO NUMBER OF PDP-10 WORDS
PUSH P,T2 ;SAVE T2 OVER CALL TO ASGPKI
CAIG T1,CHPMXW ;DON'T READ HARDWARE IF PACKET TOO LARGE
CALL ASGPKI ;GET APPROPRIATLY SIZED PACKET
JRST [POP P,T2
AOS NPKSIG ;COUNT THIS PACKET IGNORED FOR "OTHER REASONS"
CALL CHARVR ;RESET RECEIVER
JRST CHAIRT] ;PUNT RECEIVE -- RESET HARDWARE AND DISMISS INT
POP P,T2 ;RESTORE BYTE COUNT
HRLZI T4,042000 ;POINT TO SIZE/FORWARDING COUNT FIELD
HRRI T4,(PKT)
DPB T2,T4 ;THEN STORE 16 BITS
MOVE T1,[CHAADR] ;GET BACK CHAOS INTERFACE ADDRESS
REPEAT 6,<
RDIO T2,CHARBF(T1) ;READ NEXT WORD
IDPB T2,T4
>;END REPEAT
LOAD T3,CPKNB,(PKT) ;BYTE COUNT
JUMPE T3,CHARV2 ;NO DATA, SKIP READING ANY
AOS T3
LSH T3,-1 ;NUMBER OF 16 BIT WORDS
ANDI Q2,377 ;OPCODE PART
CAIE Q2,.COOPN ;16 BIT CONTORL OPCODE?
CAIN Q2,.COSTS
JRST CHARV0
CAIE Q2,.CORUT
CAIL Q2,.CODAT+100 ;BYTE SWAP NECESSARY?
JRST CHARV0 ;NOPE, JUST READ THEM IN FAST
MOVE CONN,[201000,,T2] ;BYTE POINTER FOR REVERSING BYTES
CHARV1: RDIO T2,CHARBF(T1) ;READ NEXT 16 BIT WORD
DPB T2,CONN ;DUPLICATE LOW ORDER BYTE
LSH T2,-10 ;THEN FLUSH EXTRA COPY OF LOW ORDER BYTE
IDPB T2,T4 ;AND STORE WORD IN MEMORY
SOJG T3,CHARV1 ;LOOP UNTIL NO MORE
CHARV2: RDIO T2,CHARBF(T1) ;THIS IS THE HARDWARE DESTINATION
RDIO T3,CHARBF(T1) ;THIS IS THE HARDWARE SOURCE
RDIO T4,CHARBF(T1) ;THIS IS THE CHECKSUM
RDIO T4,CHARBC(T1) ;THE BIT COUNT
CAIE T4,7777 ;IS THE BIT COUNT CORRECT?
JRST CHARV3 ;NO, BAD BIT COUNT -- FLUSH THE PACKET
RDIO T4,CHACSR(T1) ;CHECK IF GOT CRC ERROR AFTER READING OUT
TRNE T4,CHSERR
JRST CHARV4 ;YES, COUNT IT AND RETURN PACKET
CALL CHARVR ;RESET RECEIVER
CALL CHIPKT ;HANDLE THIS PACKET
JRST CHAIRT ;DISMISS INTERRUPT
;;; FAST(ER) DATA LOOP
CHARV0: RDIO T2,CHARBF(T1) ;GET 16 BIT BYTE
IDPB T2,T4 ;PLANT IN PACKET
SOJG T3,CHARV0 ;LOOP UNTIL NO MORE
JRST CHARV2
;;; ERROR ROUTINES
CHARV5: AOS NPKSER ;CRC ERROR BEFORE READING
CALL CHARVR ;RESET RECEIVER
JRST CHAIRT ;THEN RETURN FROM INTERRUPT
CHARV3: AOSA NPKSBB ;BAD BIT COUNT
CHARV4: AOS NPKSRE ;CRC ERROR AFTER READOUT
CALL RELPKT ;RETURN PKT TO FREE POOL
CALL CHARVR ;RESET RECEIVER
JRST CHAIRT ;THEN DISMISS INTERRUPT
;;; RESET RECEIVER
CHARVR: MOVE T1,[CHAADR]
RDIO T2,CHACSR(T1) ;ACCOUNT FOR LOST PACKETS
LDB T3,[110400,,T2]
ADDM T3,NPKSLS
MOVEI T3,CHSRCL ;THEN CLEAR THE RECEIVER
BSIO T3,CHACSR(T1)
RET
;;;NORMAL-ROUTING PACKET OUTPUT FOR KS10 (CALLED FROM CHAXMT)
CHXNOR: AOS NPKSOU ;ONE MORE OUTPUT TO HARDWARE
SKIPN CHAON ;IF NET ISN'T REALLY ON, DON'T SEND PACKET
JRST CHAXIN ;SO MAKE BELIEVE IT MADE IT OUT
AOS CHANPO
PIOFF ;HACK QUEUES UNINTERRUPTABLY
SKIPN T1,CHATXQ ;ARE WE CURRENTLY TRANSMITTING?
JRST [MOVEI T1,(PKT) ;NOPE, SO QUEUE UP THE PACKET
HRLI T1,(PKT)
MOVEM T1,CHATXQ
SETZM PKTTLK(PKT) ;LAST PACKET IN QUEUE
PION ;TURN PI SYSTEM BACK ON
JRST CHATXP] ;THEN SEND THE PACKET OUT THE INTERFACE
HLRZ T1,T1 ;GET LAST PACKET ON QUEUE
HRRM PKT,PKTTLK(T1) ;LINK US TO IT
HRLM PKT,CHATXQ ;WE ARE NOW LAST PACKET ON QUEUE
SETZM PKTTLK(PKT) ;FLAG THAT IN PACKET AS WELL
PION ;DONE HACKING QUEUES
RET
>;END IFN SMFLG
IFN CHDR11,<
SUBTTL FOONLY DR11 SUPPORT
;SPECIAL LOCATIONS TO INTERFACE TO MICROCODE
DRINPD=2000 ;INPUT DONE LIST
DROUTD=2001 ;OUTPUT DONE LIST
DRINPR=2002 ;INPUT READY LIST
DROUTR=2003 ;OUTPUT READY LIST
DRINPP=2004 ;INPUT PACKET IN PROGRESS
DROUTP=2005 ;OUTPUT PACKET IN PROGRESS
;SPECIAL INSTRUCTIONS FOR HACKING DR11
OPDEF DR11R [744000,,0] ;RESET STATE
OPDEF DR11WI [744040,,0] ;WAKE UP INPUT MICROCODE
OPDEF DR11WO [744100,,0] ;WAKE UP OUTPUT MICROCODE
OPDEF DR11O [745000,,0] ;EFFECTIVE ADDRESS TO PDP-11
;INITIALIZE DR11 INTERFACE
CHARLD: DR11R 60 ;TURN OFF MICRO-INTERRUPTS
MOVE T1,[DRINPD,,DRINPD+1]
SETZM -1(T1)
BLT T1,DROUTP ;CLEAR OUT SPECIAL LOCATIONS
DR11O 0 ;SEND 0 TO 11
MOVEI Q2,^D5 ;MAKE SOME INPUT PACKETS
CDRIN1: MOVE T1,[.RESP1,,^D128]
MOVEI T2,.RESNP
CALL ASGRES
CHABUG(CHDR1F)
MOVSI T3,^D254
MOVEM T3,(T1)
MOVEI T2,DRINPR
CALL DR11Q ;PUT ON END OF INPUT QUEUE
SOJG Q2,CDRIN1
DR11WI ;INPUT WAKEUP
SETOM CHAON ;NOW CAN DO THINGS
RET
;CALLED FROM CLOCK LEVEL TO CHECK ON THINGS
CCHKDR:
CKDRIN: SETZ T1,
EXCH T1,DRINPD ;GET INPUT DONE LIST
JUMPE T1,CKDRIR ;NO INPUT, CHECK OUTPUT
HLRZ T1,T1 ;GET HEAD OF LIST
CKDRI1: PUSH P,T1 ;SAVE ADDRESS
MOVEI PKT,1(T1) ;POINT TO PACKET DATA
CALL CHIPKT ;HANDLE IT
POP P,T1
MOVSI T3,^D254 ;MAXIMUM NUMBER OF INPUT BYTES
EXCH T3,(T1) ;GET CDR AND RESET SIZE AND CDR
MOVEI T2,DRINPR ;PUT BACK ON INPUT READY LIST
CALL DR11Q
DR11WI ;LET IT GET FULL
MOVEI T1,(T3) ;GET CDR
JUMPN T1,CKDRI1 ;AND PROCESS IT IF NECESSARY
CKDRIR:
;CHECK ON OUTPUT
CKDROU: SETZ T1,
EXCH T1,DROUTD
JUMPE T1,CKDROR
HLRZ T1,T1 ;GET HEAD OF LIST
CKDRO1: PUSH P,T1 ;SAVE IT
MOVEI PKT,1(T1) ;POINT TO PACKET ITSELF
PKTPTH [61] ;NOTE WE GOT HERE WHEN DEBUGGING
DEBUG,< HLRZ T1,PKTLNK(PKT) ;PICK UP XMIT ACTIVE FLAG
MOVE T2,PKTMAG(PKT) ;GET MAGIC FIELD IF DEBUGGING
CAIE T1,1 ;BETTER BE WHAT WE LEFT IT AT
CHABUG(CHAXIB,<<T1,WHAT>,<PKT,PKTREF>,<T2,MAGIC>>) ;NO, COMPLAIN
>;DEBUG
HRROS PKTLNK(PKT) ;CLEAR TRANSMIT ACTIVE
RCALL RELPKM,16
POP P,T1 ;GET BACK PACKET
HRRZ T1,(T1) ;GET CDR
JUMPN T1,CKDRO1 ;AND PROCESS IT
CKDROR: RET ;ALL DONE
;TRANSMIT A PACKET
CHXNOR:
CHXDR1: AOS CHANPO
NOSKD1 ;LOCK OUT ANY OTHERS
PKTPTH [60] ;REMEMBER WE'VE BEEN HERE
MOVE T1,TODCLK ;SET TIME OF LAST REAL
MOVEM T1,PKTTIM(PKT) ; XMISSION FOR RE-XMISSION CHECKING
LOAD T1,CPKNB,(PKT) ;GET BYTE COUNT
ADDI T1,CHPKDT*4+1 ;PLUS HEADER AND ROUND UP
LSH T1,-1 ;INPUT 16-BIT BYTES
HRLZM T1,PKTCDR(PKT) ;STORE AND CLEAR CDR
MOVEI T1,PKTCDR(PKT) ;POINT THERE
MOVEI T2,DROUTR ;PUT ON OUTPUT READY LIST
CALL DR11Q
DR11WO ;WAKE UP MICROCODE
OKSKD1
RETSKP ;WE ALWAYS SUCCEED
;PUT PACKET IN T1 ONTO END OF DR11 READY LIST IN T2
DR11Q: SETZ T4,
EXCH T4,(T2) ;GET LIST AND ZERO
JUMPE T4,[HRLI T4,(T1) ;IF PREVIOUSLY EMPTY, THIS IS HEAD AS WELL
JRST .+2]
HRRM T1,(T4) ;STORE PACKET AS CDR(LAST)
HRRI T4,(T1) ;MAKE IT NEW LAST
MOVEM T4,(T2) ;SAVE UPDATED LIST
RET
>;IFN CHDR11
SUBTTL PACKET INPUT
CHIPKT: SKIPN CHAON ;IS NET FULLY ON?
JRST [ ;NOPE
IFN SMFLG,< CALL RELPKT > ;ON KS, FIRST GET RID OF THIS PACKET
JRST CHARLD ]
LOAD T2,CPKDA,(PKT) ;GET DESTINATION ADDRESS
CAME T2,MYCHAD ;MATCHES MINE?
JRST CHAPFW ;NO, FORWARD PACKET
LOAD T2,CPKSA,(PKT) ;GET SOURCE ADDRESS
CAME T2,MYCHAD ;FROM MYSELF (LOCALLY ROUTED)?
AOS CHNPKI ;NO, COUNT NUMBER OF REAL PACKETS INPUT
MOVEI T2,[ASCIZ /Byte count too large/]
LOAD T3,CPKNB,(PKT) ;GET BYTE COUNT
CAMLE T3,CHPMXC ;SEE IF WITHIN LEGAL RANGE
JRST CHALOS ;NO, SEND A LOS BACK THEN
SKIPGE (PKT) ;< SEE IF DATA OPCODE (>= 200)
JRST CHIDAT ;YES, HANDLE DATA PACKET THEN
MOVEI T2,[ASCIZ /Illegal opcode/]
LOAD T3,CPKOP,(PKT) ;GET OPCODE
CAIL T3,.COMAX ;WITHIN RANGE?
SETZ T3, ;NO, HANDLE WITH LOS RESPONSE
JRST @CHAHSO(T3) ;YES, GO HANDLE IT
CHAHSO: CHALOS ;ZERO?
CHIRFC ;.CORFC
CHIOPN ;.COOPN
CHICLS ;.COCLS
CHIANS ;.COFWD
CHIANS ;.COANS
CHISNS ;.COSNS
CHISTS ;.COSTS
IGNPKT ;.CORUT
CHILOS ;.COLOS
CHALOS ;.COLSN
IGNPKT ;.COMNT
CHIDAT ;.COEOF
;FORWARDING
CHAPFW: JUMPE T2,IGNPKT ;0 FOR DESTINATION, JUST FLUSH IT
IFN ARPAF,<
LOAD T2,CPKDS,(PKT) ;CHECK FOR BAD ADDRESS ON SUBNET
CAILE T2,MAXSBN ;RANGE CHECK
JRST IGNPKT ;OUT OF RANGE, DISCARD
HLRZ T2,SBNRUT(T2) ;GET ROUTING METHOD
CAIN T2,CHXLCL ;LOCAL SUBNET?
JRST IGNPKT ;YES, DISCARD
>;IFN ARPAF
LOAD T2,CPKFC,(PKT) ;GET FORWARDING COUNT
AOJ T2,
CAIL T2,20 ;CHECK FOR FORWARDING LOOP
JRST IGNPKT ;AND DISCARD IF SO
STOR T2,CPKFC,(PKT)
GETPKT ;GET PACKET COPY
RET ;CANNOT DO THE COPY, PUNT
AOS CHNPF ;ONE MORE PACKET FORWARDED
SETO T1, ;DON'T BLOCK
JRST CHAXMT ;AND GO SEND THIS PACKET OFF AGAIN
;RFC RECEIVED: SEE IF IT IS A DUPLICATE; IF NOT PUT ON LIST TO BE HANDLED.
CHIRFC: MOVE T2,CHPKS(PKT) ;GET THE SOURCE OF THIS PACKET
HLRZ T1,CHQRFC ;LOOK DOWN RFC LIST FOR POSSIBLE ONES
JUMPE T1,CHIRF3
CHIRF1: CAMN T2,CHPKS(T1) ;FROM THE SAME SOURCE?
JRST IGNPKT ;YES, JUST FORGET THIS NEW ONE
HRRZ T1,PKTLNK(T1) ;GET THE NEXT IN LIST
CAIE T1,-1 ;JUST IN CASE, MAKE SURE NOT EMPTY MARKER
JUMPN T1,CHIRF1
SKIPE T1,CHQRFP ;FORK CODE HAVE HANDLE ON A PACKET?
CAME T2,CHPKS(T1) ;YES, DOES IT MATCH?
CAIA ;NOPE, SEE IF DUPLICATE CONNECTION
JRST IGNPKT ;ELSE FLUSH DUPLICATE RFC
CHIRF3: MOVSI T1,-MAXCON
CHIRF4: SKIPL CONN,CHACON(T1) ;IS THERE A CONNECTION HERE?
JRST CHIRF5 ;NO
HRRZS CONN ;CLEAR UNIQUIZER
CAMN T2,CHAFRN(CONN) ;THE SAME?
JRST IGNPKT ;YES, FLUSH THIS DUPLICATE
CHIRF5: AOBJN T1,CHIRF4 ;NO, KEEP LOOKING
CALL CPYPKZ ;MAKE AN ASCIZ COPY OF THE PACKET
JRST IGNPKT ;CANNOT MAKE COPY, PUNT
SETZM PKTTIM(PKT) ;NOTE THAT WE'VE NOT SEEN IT YET
MOVEI Q2,CHQRFC ;RFC RECEIVED LIST
CALL CHAQPF ;ADD TO LIST
MOVX T1,CH%RFC ;MARK ANOTHER RFC AS NEEDING HANDLING
IORM T1,CHAFLG
RET
;SNS RECEIVED
CHISNS: CALL CHFNDX ;FIND OUR INDEX FOR THIS CONNECTION
JRST CHALOS
CAIE Q2,.CSOPN ;IS IT NOW OPEN?
JRST IGNPKT ;NO, IGNORE REQUEST
IFN SMFLG,<CALL RELPKT> ;ON KS10, RETURN SNS PACKET TO FREE POOL
JRST CHASTO ;TRY TO SEND STATUS NOW FOR THIS CONNECTION
;STS RECEIVED
CHISTS: CALL CHFNDX ;FIND CONNECTION
JRST CHALOS
CAIE Q2,.CSOPN ;MUST BE OPEN
JRST CHALOS
CHIST1: LDB T1,[POINT 16,CHPKDT(PKT),31] ;GET WINDOW SIZE FROM PACKET
CAMLE T1,MXTWIN ;RANGE CHECK
MOVE T1,MXTWIN
JUMPLE T1,CHISTB
CHIST2: HRRM T1,CHAWIN(CONN) ;STORE TRANSMIT WINDOW SIZE
LDB T2,[POINT 16,CHPKDT(PKT),15] ;GET PACKET NUMBER BEING RECEIPTED
CALL CHIAK0 ;REMOVE THOSE PACKETS FROM HIS LIST
IFN SMFLG,<CALL RELPKT> ;ON KS, RETURN THE STS PACKET
JRST CHARTR ;AND RETRANSMIT OTHERS LEFT ON IT FOR TOO LONG
CHISTB: CHABUG(CHAZWN,<<T1,WINSIZ>,<CONN,CONREF>>) ;NO, COMPLAIN
MOVX T1,1 ;YES, SET IT TO MINIMUM
JRST CHIST2
;FWD OR ANS RECEIVED
CHIANS: CALL CHFNDX ;FIND INDEX FOR THIS CONNECTION
JRST IGNPKT ;NONE, NO CONN ON OTHER END TO TELL PRESUMABLY
CAIN Q2,.CSRFS ;IN RFC-SENT STATE?
JRST CHICL1 ;CLOSE CONNECTION, SETUP BUFFER W/ ERROR MESSAGE
CAIE Q2,.CSPRF ;IN PERMANENT RFC-SENT STATE?
JRST IGNPKT ;NO, JUST IGNORE IT
CHIAN0: HRRZ T1,CHANBF(CONN) ;YES, GET NUMBER OF UNEATEN INPUT PACKETS
HLRZ T2,CHAWIN(CONN) ;GET INPUT WINDOW SIZE
CAIGE T1,(T2) ;IF WINDOW ISN'T FULL,
GETPKT ; COPY PACKET INTO RESIDENT STORAGE IF NECESSARY
RET ;WINDOW FULL OR CAN'T COPY, GIVE UP
SKIPN CHAIBF(CONN) ;PREVIOUSLY EMPTY?
CALL CHAIN1 ;YES, PERHAPS INTERRUPT AN INTERESTED FORK
AOS CHANBF(CONN) ;ONE MORE ON INPUT LIST
MOVEI Q2,CHAIBF(CONN) ;PUT IT ON THE IN-ORDER LIST
CALL CHAQPL
RET ;DONE
;OPN RECEIVED
CHIOPN: CALL CHFNDX ;FIND CONNECTION
JRST CHALOS
CAIE Q2,.CSRFS ;MUST BE RFC SENT
JRST IGNPKT ;ELSE JUST IGNORE IT
LOAD T2,CPKPN,(PKT) ;GET PACKET NUMBER
HRLM T2,CHAPKN(CONN) ;SETUP RECEIVE PACKET NUMBERS FOR CONNECTION
MOVE T2,CHPKS(PKT) ;GET SOURCE
MOVEM T2,CHAFRN(CONN) ;THAT IS FOREIGN HOST FOR CONNECTION
CALL CHIST1 ;PROCESS WINDOW SIZE AND RECEIPT AS STS
CALL CHASTO ;SEND BACK STATUS
MOVEI Q2,.CSOPN ;STATE FOR CONNECTION NOW OPEN
JRST CHAINT ;MAYBE WAKE UP SOME FORK
;LOS RECEIVED
CHILOS: CALL CHFNDX ;TRY TO FIND CONNECTION
JRST IGNPKT ;IGNORE IT IF NOT
JUMPE Q2,IGNPKT ;OR IS CLOSED
CAIN Q2,.CSPRF ;PERMANENT-RFC STATE?
JRST CHIAN0 ;YES, JUST GIVE THIS PACKET TO THE FELLOW
PUSH P,PKT ;SAVE INCOMING PACKET
CALL CHALFO ;FREE UP OUTPUT BUFFERS
POP P,PKT
MOVEI Q2,.CSLOS ;PUT INTO LOS STATE
JRST CHICL2 ;GIVE USER ERROR MESSAGE
;CLS RECEIVED
CHICLS: CALL CHFNDX
JRST CHALOS
CAIN Q2,.CSPRF ;PERMANENT-RFC STATE?
JRST CHIAN0 ;YES, JUST GIVE THIS PACKET TO THE FELLOW
CAIE Q2,.CSOPN ;STATE SHOULD BE OPEN
CAIN Q2,.CSRFS ;OR RFC SENT
CHICL1: TDZA Q2,Q2 ;NEW STATE IS CLOSED
JRST CHALOS
CHICL2: CALL CHAINT ;MAYBE INTERRUPT SOMEBODY
JUMPE CONN,IGNPKT ;IF THIS KILLED THE CONNECTION, FORGET PKT
PUSH P,PKT ;SAVE INCOMING PACKET
MOVEI Q2,CHAPBF(CONN) ;POINTER TO OUT OF ORDER PACKETS
CALL CHALFR ;FREE THEM ALL
HRRZS CHANBF(CONN) ;NO MORE ON THAT LIST
POP P,PKT
JRST CHIDT1 ;RETURN LOS PACKET AS DATA
;DATA PACKET RECEIVED
CHIDAT: CALL CHFNDX
JRST CHALOS
CAIE Q2,.CSOPN ;MUST BE OPENED
JRST CHALOS
CALL CHIACK ;PROCESS THE ACKNOWLEDGEMENT FIELD
HLRZ T2,CHAPKN(CONN) ;GET LAST PACKET GIVEN TO USER
LOAD T1,CPKPN,(PKT) ; AND GET NEW PACKET'S NUMBER
HLRZ T4,CHAWIN(CONN) ;GET WINDOW SIZE
ADDI T4,(T2) ;FIGURE THE HIGHEST LEGAL PACKET NUMBER
SUB T4,T1
TRNE T4,100000 ;IS THIS WITHIN THE WINDOW SIZE (T4 LEQ T1)?
JRST [ CONPTH [20] ;NO, REMEMBER AND IGNORE THIS PACKET
CALL CHINVT ; AFTER NOTING THAT THIS NVT MAY NEED ATTN
JRST IGNPKT ]
HRRZ T2,CHAIBF(CONN) ;ANY INPUT BUFFERS ASSOCIATED WITH THIS?
JUMPN T2,[LOAD T2,CPKPN,(T2) ;YES, GET PACKET NUMBER FOR LAST ON LIST
JRST .+2]
HLRZ T2,CHAPKN(CONN) ;NO, GET LAST PACKET GIVEN TO USER
CAIL T2,177777 ;INCREMENT THIS PACKET NUMBER
TDZA T2,T2
ADDI T2,1
CAMN T1,T2 ;THIS THE NEXT PACKET IN THE SEQUENCE?
JRST CHIDT1 ;YES, QUEUE IT ONTO THE END OF THE LIST
SUB T2,T1
TRNN T2,100000 ;COMPARE MOD 2^16
JRST CHIDTD ;LAST SEEN GREATER, DISCARD DUPLICATE PKT
MOVEI T3,0 ;AT FRONT OF LIST
HLRZ Q2,CHAPBF(CONN) ;GET FIRST PACKET IN OUT OF ORDER LIST
JUMPE Q2,CHIDT4 ;THIS IS THE FIRST
CHIDT3: LOAD T2,CPKPN,(Q2) ;GET ITS PACKET NUMBER
SUB T2,T1
JUMPE T2,CHIDTD ;SAME AS THIS NEW ONE, DISCARD
TRNN T2,100000
JRST CHIDT4 ;T1 LESS, THIS IS WHERE IT GOES
MOVE T3,Q2 ;T2 LESS, KEEP LOOPING
HRRZ Q2,PKTLNK(T3)
JUMPN Q2,CHIDT3 ;UNLESS REACHED END
CHIDT4: GETPKT ;ELSE SAVE THE PACKET IF NECESSARY
JRST [ CONPTH [21]
CONPTH T1 ;REMEMBER THE PACKET NUMBER WHEN WE PUNTED
RET ] ;CANNOT COPY, PUNT FOR NOW
DEBUG,< PKTPTH [53] ;IF DEBUGGING, REMEMBER WHERE WE STARTED
CONPTH [22]
CONPTH T1 ; AND REMEMBER THE PACKET NUMBER AT THIS POINT
>;DEBUG
SKIPE T3
HRRM PKT,PKTLNK(T3) ;THREAD ONTO PREVIOUS PACKET
SKIPN Q2
HRRM PKT,CHAPBF(CONN) ;THREAD ONTO BACK OF LIST
SKIPN T3
HRLM PKT,CHAPBF(CONN) ;THREAD ONTO FRONT OF LIST
HRRM Q2,PKTLNK(PKT)
MOVSI T3,1
ADDM T3,CHANBF(CONN) ;ONE MORE ON OUT OF ORDER LIST
RET
;HERE IF IT GOES ONTO THE END OF THE REGULAR LIST; T2/ PACKET NUMBER.
CHIDT1: GETPKT ;MOVE PACKET INTO RESIDENT STORAGE IF NECESSARY
JRST [ CONPTH [23]
CONPTH T2
RET ] ;CANNOT DO THE COPY, PUNT
PKTPTH [54] ;WHEN DEBUGGING, REMEMBER OUR ROOTS
CONPTH [24]
CONPTH T2 ;NOTE THIS PACKET NUMBER
SKIPN CHAIBF(CONN) ;PREVIOUSLY EMPTY?
CALL CHAIN1 ;WAKE UP FORK MAYBE
CHIDT2: AOS CHANBF(CONN) ;ONE MORE ON IN ORDER LIST
MOVEI Q2,CHAIBF(CONN)
CALL CHAQPL ;PUT ONTO END OF LIST
CHIDT9: HLRZ PKT,CHAPBF(CONN) ;GET TOP OF OUT OF ORDER LIST
JUMPE PKT,CHINVT ;NO MORE, GO UPDATE NVT BUFFERS IF ANY
LOAD T3,CPKPN,(PKT) ;GET ITS PACKET NUMBER
CAIL T2,177777
TDZA T2,T2
ADDI T2,1
CAME T3,T2 ;IS THIS THE NEXT ONE TO GO?
JRST CHINVT ;NO, SEE IF THIS BELONGS TO AN NVT
CONPTH [25]
CONPTH T3
MOVEI Q2,CHAPBF(CONN)
CALL CHAQGF ;YES, PULL OFF OUT OF ORDER LIST
JUMPE PKT,CHIDTB
MOVSI T3,-1
ADDM T3,CHANBF(CONN) ;ONE LESS ON THAT LIST
JRST CHIDT2 ;AND ONE MORE FOR IN ORDER LIST
CHIDTB: CHABUG(CHAOOL) ;OUCH, NOT THERE NOW? COMPLAIN
RET ; AND GET OUT
;HERE IF HAVE TO DISCARD A PACKET, ALSO SEND RECEIPT TO STOP RETRANSMISSION SOON
CHIDTD: AOS CHANPD ;ONE MORE PACKET DISCARDED
CONPTH [26]
IFN SMFLG,<CALL RELPKT> ;ON KS, FREE UP THIS DISCARD
JRST CHASTO ;AND GO MAKE SURE DO ACK
;IF THIS INPUT WAS FOR AN NVT, QUEUE UP THIS CONNECTION AS NEEDING ATTENTION
CHINVT: LOAD T2,CHANVT,(CONN) ;GET NVT NUMBER
CALL CHKCVT ;IS IT AN NVT?
JRST CHINVR ;NOPE
SETZ T3, ;EMPTY SLOT REF EVENTUALLY
MOVEI T1,CHATTW ;SCAN Q FOR THIS CONNECTION
CHNVT0: CAIL T1,CHATTW+NTTCVT ;CHECKED ALL OF Q?
JRST CHNVT2 ;YES, GO STORE NEW ENTRY
JUMPN T3,CHNVT1 ;ALREADY HAVE EMPTY SLOT
MOVE T2,(T1) ;GET THIS ELEMENT
CAMN T2,[-1] ;END OF Q MARKER?
MOVEI T3,(T1) ;YES, REMEMBER IT
CHNVT1: CAMN CONN,(T1) ;IS THIS CONNECTION ALREADY MARKED AS NEEDING HELP?
JRST CHINVR ;YES, NOTHING TO DO
AOJA T1,CHNVT0 ;NO, KEEP LOOKING
CHNVT2: SKIPN T3 ;NON-ZERO MEANS FOUND A FREE SLOT
CHABUG(CHNVBQ) ;WOW BAD Q: GIVE UP
MOVEM CONN,(T3) ;STASH THIS NEW ELEMENT
CHINVR: RET ;DONE
;HANDLE RECEIVED PACKET ACKNOWLEDGEMENT
CHIACK: LOAD T2,CPKAN,(PKT) ;GET PACKET NUMBER BEING RECEIPTED
CHIAK0: LOAD T3,CPKAN,(PKT)
HRRZ T1,CHAACK(CONN) ;GET MAX OF THIS AND PREVIOUS ACKNOWLEDGED
SUB T1,T3
TRNE T1,100000
HRRM T3,CHAACK(CONN)
PUSH P,PKT
HLRZ PKT,CHAOBF(CONN) ;GO DOWN CONNECTION SEND LIST
JUMPE PKT,CHIAK2
CHIAK1: CHKPKT ;VALIDATE PACKET IF DEBUGGING
LOAD T1,CPKOP,(PKT) ;GET OPCODE
CAIE T1,.CORFC ;RFC OR
CAIN T1,.COOPN ;OPN THAT WE ARE RETRANSMITTING?
JRST CHIAK3 ;YES, CAN FLUSH IT NOW
LOAD T1,CPKPN,(PKT) ;GET THIS PACKET'S NUMBER
SUBM T2,T1
TRNE T1,100000
JRST CHIAK2
CHIAK3: HRRZ Q2,PKTLNK(PKT) ;GET NEXT PACKET
HLLOS PKTLNK(PKT) ;MARK PKT AS NOT ON ANY SEND LIST
RCALL RELPKM,14 ;RELEASE PACKET IF NOT BEING SENT NOW
CHIAK4: HRLM Q2,CHAOBF(CONN)
SKIPE PKT,Q2
JRST CHIAK1 ;KEEP TRYING REST OF SEND LIST
SETZM CHAOBF(CONN) ;NOTHING ON SEND LIST NOW
CHIAK2: MOVE T2,CHANOS(CONN) ;GET PREVIOUS STATE
HRRZ T3,CHAACK(CONN)
HRRZ Q2,CHAPKN(CONN)
SUB T3,Q2
SKIPLE T3
SUBI T3,200000
ADD T3,CHAWIN(CONN)
HRREM T3,CHANOS(CONN)
JUMPG T2,CHIAK5 ;ALREADY HAD WINDOW?
LOAD T1,CHAOCN,(CONN)
SKIPLE CHANOS(CONN) ;AND SOME NOW?
CAIL T1,^D36
JRST CHIAK5 ;SKIP IT
MOVX T1,CF%OIN ;GENERATE OUTPUT INTERRUPT
IORM T1,CHASTA(CONN) ;NOTE THIS NEED
MOVX T1,CH%OIN ; AND TELL BACKGROUND FORK THERE'S WORK HERE
IORM T1,CHAFLG
CHIAK5: POP P,PKT
RET
;FIND INDEX FOR THIS CONNECTION INTO CONN, STATE INTO Q2
CHFNDX: MOVEI T2,[ASCIZ /Connection does not exist at this end/] ;HANDY MESSAGE
LOAD CONN,CPKD1,(PKT) ;GET DESTINATION INDEX
CAIGE CONN,MAXCON ;WITHIN RANGE
SKIPL CONN,CHACON(CONN) ;AND IN USE
RET ;NO, FAIL
HRRZS CONN ;CLEAR OUT UNIQUIZER
CHKCON ;VALIDATE IT IF DEBUGGING, REGARDLESS OF OUTCOME
HRRZ Q2,CHASTA(CONN)
MOVE T1,CHPKS(PKT)
MOVE T3,CHPKD(PKT)
CAIN Q2,.CSRFS ;IF IN RFC SENT, DONT CARE ABOUT INDEX
AND T1,[BYTE (16) -1, 0]
CAMN T3,CHALCL(CONN) ;LOCAL AND
CAME T1,CHAFRN(CONN) ;FOREIGN THE SAME?
RET ;NO, NO GOOD
MOVE T1,TODCLK
MOVEM T1,CHAITM(CONN) ;TIME OF LAST INPUT ON THIS CONNECTION
MOVEI T2,[ASCIZ /Connection not in right state at this end/]
RETSKP ;OK, BUT HANDY MESSAGE IN T2 IF ANYONE NEEDS IT
SUBTTL PACKET MUNGING SUPPORT
;GET STORAGE FOR PACKET, OPCODE IN Q2; WHEN DEBUGGING, REASON IS IN CX
ASGPKI: ADD T1,[.RESP1,,CHPKDT+PKTHLN] ;ASSIGN A PACKET AT INTERRUPT LEVEL
JRST ASGPK2 ; WITH LENGTH IN T1
ASGPK0: TDZA T1,T1 ;NO DATA NEEDED
ASGPKC: MOVE T1,CHPMXW ;MAXIMUM NUMBER OF WORDS OF DATA
ASGPK1::ADD T1,[.RESP3,,CHPKDT+PKTHLN] ;PACKET HEADER PLUS HEADER WORDS
ASGPK2: MOVEI T2,.RESNP ;FROM THE NETWORK POOL
DEBUG,< PUSH P,CX > ;SAVE REASON CODE (FOR WHEN DEBUGGING)
CALL ASGRES
JRST [ DEBUG,<ADJSP P,-1> ;IF DEBUGGING, FLUSH REASON
RET ] ;FAIL RETURN
MOVEI PKT,PKTHLN(T1) ;RETURN ADDRESS OF PACKET IN PKT
SETOM PKTLNK(PKT) ;NOT ON ANY TRANSMIT QUEUES YET
MOVE T1,TODCLK ;SET IN PACKET-CREATION TIME
MOVEM T1,PKTTIM(PKT)
STOR Q2,CPKOP,(PKT) ;SET IN OPCODE GIVEN
DEBUG,< MOVE T1,[CHSMGV] ;BUILD MAGIC VALUE
XORI T1,(PKT) ; KEYED TO CURRENT PACKET
MOVEM T1,PKTMAG(PKT) ;SET IT
MOVE T1,-PKTHLN-1(PKT) ;GET ASGRES HEADER WORD
MOVEM T1,PKTHDW(PKT) ;SAVE IT HERE FOR DUAL-CHECKING
MOVEI T1,PKTHST(PKT) ;BUILD BYTE REF TO HISTORY TRAIL
HRLI T1,360600 ; (DPB REF)
POP P,T2 ;PICK UP ASSIGN-PACKET REASON
DPB T2,T1 ; AND DROP IT IN
IBP T1 ;BUMP AND
MOVEM T1,PKTHSP(PKT) ; SAVE REF
>;DEBUG
RETSKP
IFN SMFLG,<
;ON KS, MAKE COPY OF PACKET ONLY IF HAVE TO; T3/ BYTE COUNT.
;ONCE COPIED, WE FREE ORIGINAL.
CPYPKI: SAVET
LOAD T1,CPKNB,(PKT) ;GET BYTE COUNT
CAML T1,T3 ;IF PACKET IS BIG ENOUGH
RETSKP ; JUST RETURN IT
MOVE T1,T3 ;ELSE, GET NUMBER OF BYTES WE NEED
PUSH P,PKT ;SAVE ORIGINAL PACKET REF
CALL CPYPK1 ;DO THE WORK
CAIA
AOS -1(P) ;MIMIC SUCCESS
EXCH PKT,(P) ;GET ORIGINAL PACKET AND SAVE NEW REF
CALL RELPKT ; AND FREE UP ORIGINAL
POP P,PKT ;GET BACK NEW PACKET REF
RET ;RETURN SUCCESS OR FAILURE
>;IFN SMFLG,
;MAKE A COPY OF THE PACKET IN PKT IN RESIDENT STORAGE,
;SINCE IT IS JUST A DTE BUFFER NOW. NON-SKIP RETURN ON FAILURE.
CPYPKT: SAVET ;SAVE TEMP ACS
LOAD T1,CPKNB,(PKT) ;GET BYTE COUNT
CPYPK1: ADDI T1,3 ;ROUND TO WORD
LSH T1,-2 ;TURN INTO INTO WORDS
PUSH P,T1 ;SAVE SIZE
PUSH P,PKT ; AND ORIGINAL PACKET REF
RCALL ASGPKI,37 ;GET A PACKET FROM INTERRUPT-LEVEL POOL
JRST [ AOS CHNNRS ;JUST COUNT THESE NOW: PERFECTLY NORMAL
JRST CPYPK9 ]
MOVE T3,-1(P) ;GET BACK SIZE OF ORIGINAL PACKET'S DATA IN WORDS
ADDI T3,CHPKDT-1(PKT) ; AND REF TO END OF NEW PACKET
HRL T2,(P) ;GET BACK ORIGINAL PACKET REF AS SOURCE,,
HRRI T2,(PKT) ; THEN ADD DESTINATION
BLT T2,(T3) ;MOVE DATA
AOS -2(P) ;INDICATE WINNAGE (ISN'T OBSCURITY WONDERFUL?)
CPYPK9: ADJSP P,-2 ;FLUSH TWO TEMPS
RET ;GET OUT; SKIP OR NON-SKIP ALREADY SET
;MAKE A COPY WITH AN ASCIZ CONTACT NAME; ON KS, ORIGINAL PACKET IS FREED UP,
;UNLESS THE COPYING FAILS.
CPYPKZ: LOAD T1,CPKNB,(PKT) ;GET BYTE COUNT
PUSH P,T1 ;SAVE FOR LATER
IFN SMFLG,<PUSH P,PKT> ;SAVE THIS PACKET REF, TOO, ON KS
AOJ T1, ;MAKE ROOM FOR THE NULL
CALL CPYPK1 ;GO DO THIS SIZE COPY THEN
JRST [ ADJSP P,-1 ;MIMIC FAILURE, FLUSHING TEMPS ON THE WAY
IFN SMFLG,< POP P,PKT>
RET]
IFN SMFLG,< ;ON KS, HAVE TO FLUSH OLD PACKET
EXCH PKT,(P) ;SAVE AND GET OLD PACKET
CALL RELPKT ;GET RID OF IT
POP P,PKT ;GET BACK COPY REF
>;IFN SMFLG,
POP P,T1 ;GET BACK COUNT
IFN KLFLG!SMFLG,<
ADJBP T1,[POINT 8,CHPKDT(PKT)] > ;REF LAST BYTE
IFN F3FLG,<
IDIVI T1,4 ;BYTES PER WORD
ADD T1,[POINT 8,CHPKDT(PKT)]
SOJL T2,.+3
IBP T1
JRST .-2
>;IFN F3FLG,
MOVEI T2,0
IDPB T2,T1 ;APPEND A NULL TO IT
RETSKP
;TOTALLY IGNORE AN INPUT PACKET (WHICH, ON THE KS, IS A FULL-BLOWN PACKET, AS
;ALL ARE, AND ON OTHER SYSTEMS, IS A VESTIGIAL PACKET WHICH DOESN'T NEED
;ANY FURTHER HANDLING).
IGNPKT:
IFE SMFLG,<RET> ;NOOP ON NON-KS
IFN SMFLG,<CALLRET RELPKT> ;KS NEEDS TO FREE IT UP
;RELEASE A PACKET IF IT IS NOT RETRANSMITTABLE (IE, IF NOT TRANSMITTING OR
;QUEUED UP FOR OURSELVES, AND NOT ON ANY LISTS NOW, AS INDICATED BY ITS
;LINK WORD). IF DEBUGGING, THE REASON CODE IS IN CX.
;CALL RELPKT WHEN YOU EXPECT THE PACKET TO BE FREEABLE RIGHT NOW.
RELPKT::
DEBUG,< PUSH P,T1
MOVE T1,PKTLNK(PKT) ;PICK UP LINK WORD
CAME T1,[-1,,-1] ;FREEABLE NOW?
CHABUG(CHANFP,<<PKT,PKTREF>>) ;NO, COMPLAIN
POP P,T1 ;GET BACK TEMP AND FALL INTO RELPKM
>;DEBUG
RELPKM::PUSH P,T1 ;SAVE TEMPS
CHKPKT ;CHECK PACKET IF DEBUGGING
MOVE T1,PKTLNK(PKT) ;GET XMIT-ACTIVE FLAG,,LINK HALF-WORD
CAME T1,[-1,,-1] ;IF EITHER ACTIVE OR QUEUED LOCALLY OR ON A LIST
JRST RELPKD ; THEN DON'T BOTHER IT: WILL GET FREED LATER
PUSH P,T2 ;SAVE FURTHER TEMPS NOW THAT WE HAVE WORK TO DO
PUSH P,T3
PUSH P,T4
DEBUG,< MOVEI T3,(CX) ;GET REASON CODE
MOVEM T3,PKTMAG(PKT) ;CLEAR OUT MAGIC AND SET IN REASON FOR RELEASE
PKTPTH T3 ;SET THIS IN ITS HISTORY, TOO
>;DEBUG
MOVEI T1,-PKTHLN(PKT) ;POINT TO START OF ACTUAL BLOCK FOR RELRES
SETZ PKT, ;INDICATE GONE
CALL RELRES ;RELEASE IT
POP P,T4 ;GET BACK TEMPS
POP P,T3
POP P,T2
RELPKD: POP P,T1
RET
;SEND BACK A LOS FOR PACKET REF'ED BY PKT; ASCIZ REF TO REASON IN T2
CHALOS: SKIPA T1,[.COLOS]
CHALS2: MOVEI T1,.COCLS ;RECEIVED A LOSING RFC
MOVEI T3,100
GETPKT T ;JUST A DTE BUFFER OR RFC PKT THAT WE SHOULD COPY
RET ;CAN'T? JUST IGNORE IT THEN
PKTPTH [55]
STOR T1,CPKOP,(PKT) ;SETUP OPCODE FIELD
MOVE T1,CHPKS(PKT) ;EXCHANGE SOURCE AND DESTINATION
EXCH T1,CHPKD(PKT)
MOVEM T1,CHPKS(PKT)
CALL PKTSTR ;PUT THE ASCIZ STRING FROM T2 INTO THE DATA PORTION
SETO T1,
JRST CHAXMT ; OF THE PKT AND GO ACTUALLY SEND IT
PKTSTR: SETZ T3, ;EVENTUAL COUNT
TLNN T2,-1 ;MIGHT BE AN 8-BIT BYTE POINTER ALREADY
HRLI T2,(<POINT 7,>)
MOVE T1,[POINT 8,CHPKDT(PKT)]
PKTST1: ILDB Q2,T2
CAIN Q2,"_"
MOVEI Q2," " ;CONVERT _'S TO SPACES IN CONTACT NAMES
IDPB Q2,T1
JUMPE Q2,PKTST2
AOJA T3,PKTST1
PKTST2: STOR T3,CPKNB,(PKT) ;SETUP BYTE COUNT
RET
;SEND A STS PACKET OR MARK FOR NETWORK FORK TO DO IT
CHASTO: MOVEI T1,1 ;JUST NEED 4 BYTES OF DATA (1 WORD)
MOVEI Q2,.COSTS
RCALL ASGPKI,40 ;GET PACKET FROM INTERRUPT POOL
JRST [ MOVX T1,CF%STS ;FAILED:
IORM T1,CHASTA(CONN) ;MARK THIS ONE AS NEEDING STS
MOVX T1,CH%STS ;AND TELL CHAOS FORK THERE'S ANOTHER TO HANDLE
IORM T1,CHAFLG
RET ]
CHSTO2: MOVEI T1,4 ;FOUR BYTES OF DATA
STOR T1,CPKNB,(PKT)
HLRZ T1,CHAWIN(CONN)
DPB T1,[POINT 16,CHPKDT(PKT),31] ;PUT IN THE RECEIVE WINDOW SIZE
HLRZ T2,CHAPKN(CONN) ;GET LAST PACKET SEEN BY USER
HRRZ T1,CHAIBF(CONN)
SKIPE T1
LOAD T2,CPKPN,(T1) ;OR THAT GOT INTO THE IN-ORDER QUEUE
DPB T2,[POINT 16,CHPKDT(PKT),15] ;STORE AWAY AS RECEIPT PACKET NUMBER
CONPTH [30] ;WHEN DEBUGGING, REMEMBER WE SEND THIS STS
CONPTH T2
AOS CHNSTS ;ONE MORE STS SENT
SETO T1,
CALLRET SNDPK0 ;AND HANDLE LIKE DATA (BUT DON'T BLOCK FOR IT)
;SEND STS OR OPN PACKET FROM PROCESS LEVEL
SWAPCD
CHASO1: MOVEI Q2,.COSTS
CHASO2: HRRZ T1,CHASTA(CONN) ;MAKE SURE STILL WORTH DOING
CAIE T1,.CSOPN
RET ;NOPE, JUST IGNORE
MOVEI T1,1 ;(ENTER HERE WITH Q2/ OPCODE) ONE WORD OF DATA
RCALL ASGPK1,41 ;GET A PACKET FOR THIS CONNECTION
RET ;FAILED, LET NORMAL MECHANISMS DO IT LATER
MOVX T1,CF%STS ;NOTE WE'VE HANDLED THIS NEED FOR STATUS
ANDCAM T1,CHASTA(CONN)
JRST CHSTO2 ;GO SEND IT OFF
RESCD
;RETRANSMIT ANYTHING LYING AROUND FOR TOO LONG FOR THIS CONNECTION.
CHARTR: HRRZ T1,CHASTA(CONN) ;MAKE SURE STILL IN VALID STATE FOR RETRANSMISSION
CAIE T1,.CSOPN
CAIN T1,.CSRFS
CAIA
RET
HLRZ PKT,CHAOBF(CONN) ;IS THERE ANY WORK HERE?
JUMPE PKT,R ;NO
DEBUG,< PUSH P,Q2 ;COUNT OF PACKETS RE-XMITTED
SETZ Q2, ; FOR DEBUGGING
>;DEBUG
CALL NOSKDP ;PREVENT TAMPERING WITH QUEUE
HRRZ T1,CHAACK(CONN) ;1003 LAST PACKET NUMBER WE RE-XMITTED
CHART1: HLRZ PKT,CHAOBF(CONN)
CAIA
CHART2: HRRZ PKT,PKTLNK(PKT)
JUMPE PKT,CHARTD ;NO MORE, DONE
CHKPKT
LOAD T2,CPKPN,(PKT) ;GET PACKET NUMBER
SUBM T1,T2
TRNN T2,100000
JRST CHART2 ;ALREADY RETRANSMITTED, TRY NEXT
MOVE T1,PKTTIM(PKT) ;TRANSMIT TIME
ADDI T1,^D33 ;DON'T RETRANSMIT IF SENT IN LAST 30TH SEC
HLRZ T2,PKTLNK(PKT) ;XMIT ACTIVE FLAG
CAMGE T1,TODCLK
CAIE T2,-1 ;IF -1, NOTHING GOING ON WITH IT (ELSE, COULD BE
; XMIT ACTIVE, OR ROUTED TO OURSELVES LOCALLY)
JRST CHARTD ;FORGET IT IF TOO SOON, OR ALREADY BEING XMITTED
PKTPTH [50]
LOAD T1,CPKPN,(PKT) ;SAVE PACKET NUMBER
PUSH P,T1
SETO T1,
CALL CHAXMT ;REXMIT IT WITHOUT BLOCKING
SKIPE T1 ;DID IT GET SENT?
AOS CHNRTR ;YES, ONE MORE RETRANSMISSION
DEBUG,< AOS Q2 >
POP P,T1 ;GET BACK PACKET NUMBER
JRST CHART1
;HERE WHEN DONE WITH RETRANSMISSION: UNLOCK AND GET OUT
CHARTD: CALL OKSKDP ;DONE
DEBUG,< CONPTH [31]
CONPTH Q2
POP P,Q2
>;DEBUG
RET
;SEE ABOUT TELLING SOMETHING THAT THERE HAS BEEN A STATE CHANGE
;FOR THIS CONNECTION:
; Q2/ NEW CONNECTION STATE
;RETURNS
; CONN/ 0 IF IT HAS BEEN ESSENTIALLY FLUSHED, ELSE NOT CHANGED
CHAINT: HRRM Q2,CHASTA(CONN) ;SAVE NEW CONNECTION STATE
CONPTH [32]
CONPTH Q2
MOVE T1,TODCLK
MOVEM T1,CHAITM(CONN) ;SET LAST INPUT ACTIVITY FOR THIS CONNECTION
LOAD T2,CHANVT,(CONN)
CAIE Q2,.CSOPN ;IS THIS ANY STATE OTHER THAN OPENED?
CALL CHKCVT ;AND ASSOCIATED WITH AN NVT?
JRST CHAIN1 ;NO, SEE IF THERE IS A FORK TO INTERRUPT
MOVX T1,CF%DIN ;YES, TELL CHAOS FORK TO DO DETACH AND FLUSH
IORM T1,CHASTA(CONN)
MOVX T1,CH%DIN
IORM T1,CHAFLG ;AND NOTE A DETACH INTERRUPT REQUEST PENDING
SETZ CONN, ;TELL CALLER CONNECTION IS ESSENTIALLY FLUSHED
RET
CHAIN1: LOAD T1,CHAICN,(CONN) ;GET INTERRUPT CHANNEL
CAIL T1,^D36
RET
MOVX T1,CF%IIN ;MARK THIS CONNECTION AS NEEDING AN
IORM T1,CHASTA(CONN) ; INPUT INTERRUPT
MOVX T1,CH%IIN
IORM T1,CHAFLG ;TELL BACKGROUND FORK ABOUT IT, TOO
RET
;SEND A DATA PACKET ON CONNECTION IN CONN; RETURNS NONSKIP ON FAILURE
SNDPKT: HRRZ T1,CHASTA(CONN) ;GET CONNECTION STATUS
CAIE T1,.CSOPN ;OPENED?
JRST SNDPKE ;NO, COMPLAIN AND FAIL
SKIPLE CHANOS(CONN) ;ROOM WITHIN WINDOW SIZE?
JRST SNDPKW ;YEP, GO ON
MOVE T1,TODCLK ;NO, REMEMBER WHEN WE BLOCKED
MOVEM T1,CHAOTM(CONN)
MOVSI T1,(CONN) ;BLOCK UNTIL ROOM APPEARS
HRRI T1,SNPKBT
NOINT ;CANCEL OUT NOINT GIVEN ON UNLDIS
IFN T20FLG,<
CALL UNLDIS ;WAIT FOR IT, LOCKED
>;IFN T20FLG
IFN TNXFLG,<
CALL UNLCKF
MDISMS
>;IFN TNXFLG
HRRZ T1,CHASTA(CONN) ;CONNECTION
CAIN T1,.CSOPN ; STILL IN VALID STATE?
JRST SNDPKW ;YES, GO ON, REGARDLESS OF WINDOW STATE
SNDPKE: RCALL RELPKM,15 ;RELEASE THE PACKET IF NOT OPEN
RETBAD(CHAOX2) ;AND RETURN ERROR
SNDPKW: AOS (P) ;CAN'T FAIL FROM THIS POINT ON; RETURN SUCCESS
SETZ T1, ;BLOCKING IS OK FROM HERE
;SEND A DATA PACKET WITHOUT CHECKING CONNECTION STATUS OR AVAIL XMIT WINDOW;
;RETURNS NON-SKIP ALWAYS. T1/ NON-ZERO MEANS DON'T BLOCK.
SNDPK1::HRRZ T2,CHAPKN(CONN) ;GET NEXT PACKET NUMBER TO USE
CAIL T2,177777
TDZA T2,T2
ADDI T2,1
HRRM T2,CHAPKN(CONN)
STOR T2,CPKPN,(PKT)
;LIKE SNDPK1, BUT DON'T WORRY ABOUT PACKET NUMBER (EG, FOR SNS PACKETS)
SNDPK0: MOVE T4,T1 ;SAVE BLOCKING-OK ARG
DEBUG,<
MOVE T1,PKTLNK(PKT) ;MAKE SURE THIS PACKET HAS NO STRINGS ATTACHED
CAME T1,[-1,,-1] ;SHOULD BE TOTALLY VANILLA
CHABUG(CHASPS,<<PKT,PKTREF>,<T1,LINK>>) ;OOPS
>;DEBUG
HLRZ T1,CHAPKN(CONN) ;PACKET NUMBER TO ACKNOWLEDGE
HRLM T1,CHAACK(CONN) ;REMEMBER WE DID SO
STOR T1,CPKAN,(PKT) ;FILL IN ACK FIELD
SETZRO CPKFC,(PKT) ;CLEAR FORWARDING COUNT
MOVE T1,CHALCL(CONN)
MOVEM T1,CHPKS(PKT) ;SOURCE
MOVE T1,CHAFRN(CONN)
MOVEM T1,CHPKD(PKT) ;DESTINATION
HRRZ T1,CHASTA(CONN)
CAIN T1,.CSPRF ;ALWAYS RFC-SENT?
JRST SNDPK3 ;YES, WE DO NOT RETRANSMIT THEN
LOAD T1,CPKOP,(PKT) ;GET THE OPCODE
CAIE T1,.CORFC ;RFC AND OPN GET RETRANSMITTED
CAIN T1,.COOPN
JRST SNDPK2 ; BUT DON'T COUNT TOWARD THE WINDOW
CAIN T1,.COEOF ;AS DOES EOF
JRST SNDPK4
CAIGE T1,.CODAT ; OR DATA
JRST SNDPK3 ;NO, GUESS ONLY SEND IT ONCE THEN
SNDPK4: SOSGE CHANOS(CONN) ;ONE LESS AVAILABLE WINDOW SLOT (DATA AND EOF ONLY)
SETZM CHANOS(CONN) ;DON'T LET IT DROP BELOW ZERO, THOUGH
SNDPK2: MOVEI Q2,CHAOBF(CONN) ;PUT ONTO END OF SEND LIST
CALL NOSKDP ;HAVE TO LOCK UP JUST IN CASE IT'S ILLEGALLY
CALL CHAQPL ; ACKED BEFORE WE EVEN GET AROUND TO XMITTING IT
XMOVEI T1,OKSKDP ;***KLUDGE*** UNLOCK WHEN LEAVING
PUSH P,T1
SNDPK3: MOVE T1,T4 ;GET BACK BLOCKING-OK ARG
DEBUG,< CALL CHAXMT ;SEND THIS PACKET OFF, WHEN DEBUGGING
CONPTH [34]
CONPTH T1 ;REMEMBER WHAT HAPPENED
RET
>;DEBUG
;SEND THE PACKET IN PKT; T1/ NON-ZERO MEANS JUST RETURN IF NEED TO BLOCK;
;RETURNS T1/ NON-ZERO IFF SHIPPED THE PACKET OFF SOMEWHERE.
CHAXMT: STKVAR <CHXMNB,CHXRTM>
MOVEM T1,CHXMNB ;SAVE ARGUMENT
CHKPKT ;CHECK PACKET IF DEBUGGING
PKTPTH [51]
MOVE T1,TODCLK ;SET TIME OF LAST TRANSMISSION, EVEN IF WE DON'T
MOVEM T1,PKTTIM(PKT) ; XMIT IT RIGHT AWAY, FOR CHECKING PURPOSES
CALL CHXRUT ;FIND OUT HOW IT'S GOING TO BE SENT
MOVEM T2,CHXRTM ;REMEMBER
IFGE NETDTE,<
CAIE T2,CHXDTE ;IF NOT THROUGH FE-11,
JRST CHAXM1 ; DON'T WORRY ABOUT -11 STATUS
SKIPL CHNPO1 ;TOO MANY PACKETS OUTSTANDING IN -11?
CONSZ PI,177B27 ;OR PI IN PROGRESS?
JRST CHAXM1 ;NO, ROOM EXISTS, OR AT PI LEVEL, GO ON
SKIPN INSKED ;IF WE ARE IN THE SCHEDULER
SKIPE NSKED ;OR CANNOT GO BLOCKED
JRST CHAXM1 ;SEND IT ANYWAY
SETZ T1, ;ASSUME NOT OK
EXCH T1,CHXMNB ;OK TO BLOCK? (SAY WE DIDN'T SEND, IF NOT)
JUMPN T1,CHXDN1 ;NOPE, GET OUT
MOVEI T1,CHXMTT ;ELSE WAIT FOR ROOM
HRLI T1,(PKT) ;PACKET REF IS DATA TO CHXMTT FOR TIMEOUT CHECK
NOINT ;CANCEL OUT OKINT GIVEN IN UNLDIS
CALL UNLDIS ;WAIT FOR ROOM TO APPEAR IN -11
PKTPTH [52] ;REMEMBER WE WAITED FOR IT
>;IFGE NETDTE
CHAXM1: SETZM CHXMNB ;ASSUME THE WORST ABOUT SENDING THE PACKET
CALL NOSKDP ;LOCK UP HERE SO WE DON'T SEND AN XMIT-ACTIVE PKT
CHKPKT ;MAKE SURE THIS PACKET IS STILL OK AFTER WAITING
HLRZ T1,PKTLNK(PKT)
CAIE T1,-1 ;MUST BE TOTALLY QUIESCED FOR US TO DEAL W/IT
JRST CHXDON ;YEP, ALREADY ACTIVE IN SOME WAY, SO FORGET IT
MOVSI T1,1
HLLM T1,PKTLNK(PKT) ;FLAG XMIT ACTIVE NOW
MOVE T2,CHXRTM ;GET ROUTING METHOD
CALL (T2) ;CALL THE ROUTER WE'VE CHOSEN
JRST [ HRROS PKTLNK(PKT) ;FAILED: NO LONGER XMIT ACTIVE, REMEMBER THAT
PKTPTH [56] ;(NOTE FAILURE WHEN DEBUGGING)
JRST CHXDON ] ; AND RETURN "NOT SENT"
SETOM CHXMNB ;ELSE, SAY WE'VE SENT THIS PACKET
CHXDON: CALL OKSKDP ;UNLOCK
CHXDN1: SKIPE T1,CHXMNB ;FIND OUT IF WE ACTUALLY SENT THIS PKT OR NOT
RET ;YES, ALL DONE
RCALL RELPKM,22 ;ELSE, THIS GUY WASN'T QUEUED TO GO, SO IF IT'S
RET ; NO LISTS, GET RID OF IT
SUBTTL SNDPKT SUPPORT ROUTINES
;WAIT FOR ROOM TO APPEAR IN THE FE -11
CHXMTT::SKIPE CHAON ;NET STILL UP?
SKIPGE CHNPO1 ;ANY ROOM IN -11?
JRST 1(T4) ;NO, OR YES, UNBLOCK TO DISCOVER THE TRUTH
TCHKPK ;CHECK THIS PACKET REF IF DEBUGGING
MOVE T2,PKTTIM(T1) ;NET UP, AND NO ROOM IN -11, GET TIME OF XMIT START
ADDI T2,^D<5*1000> ;IF WE'RE WAITING ON THE -11 FOR THIS LONG
CAMG T2,TODCLK
JRST CHXMTB
JRST 0(T4) ;KEEP WAITING
CHXMTB: CHABUG(CHAXOD) ;SOMETHING'S PROBABLY WRONG: COMPLAIN
MOVE T2,TODCLK ;AND RESET THE TIME SO WE WON'T COMPLAIN TOO MUCH
MOVEM T2,PKTTIM(T1)
JRST 0(T4)
;DTEQ PACKET SENT TO -11 OK; IF IT ISNT ON ANY TRANSMIT LIST, IT CAN BE
;DEALLOCATED
CHAXIN:
IFE SMFLG,<MOVEI PKT,(T1)> ;ON KS, PKT IS ALREADY PROPERLY SET UP
PKTPTH [61] ;NOTE WE GOT HERE WHEN DEBUGGING
DEBUG,< PUSH P,T2
HLRZ T1,PKTLNK(PKT) ;PICK UP XMIT ACTIVE FLAG
MOVE T2,PKTMAG(PKT) ;GET MAGIC FIELD IF DEBUGGING
CAIE T1,1 ;BETTER BE WHAT WE LEFT IT AT
CHABUG(CHAXIB,<<T1,WHAT>,<PKT,PKTREF>,<T2,MAGIC>>) ;NO, COMPLAIN
>;DEBUG
HRROS PKTLNK(PKT) ;CLEAR TRANSMIT ACTIVE
RCALL RELPKM,16
DEBUG,< POP P,T2 >
RET
;SCHEDULER TEST FOR WINDOW TO OPEN UP ON A CONNECTION
SNPKBT: TCHKCN ;IF DEBUGGING, CHECK CONNECTION
HRRZ T2,CHASTA(T1) ;GET STATE OF CONNECTION
CAIE T2,.CSOPN ;VERIFY STILL OPENED
JRST 1(T4)
SKIPLE CHANOS(T1) ;ANY WINDOW AVAILABLE?
JRST 1(T4) ;YES, UNBLOCK
MOVE T2,TODCLK ;NO, GET NOW
SUB T2,CHAOTM(T1) ;FIND OUT HOW LONG WE'VE BEEN WAITING
CAIL T2,^D<10*1000> ;IF OVER SOME RATHER LONG TIME,
JRST 1(T4) ; UNBLOCK TO SEND OVER WINDOW
JRST 0(T4) ;ELSE, KEEP WAITING
SUBTTL ROUTING SUPPORT
;CHOOSE A ROUTING METHOD; RETURNS T2/ ROUTINE TO USE
CHXRUT: SETZ T2, ;ASSUME NORMAL (THROUGH FE -11) ROUTING
IFN ARPAF,< ;166
LOAD T1,CPKDS,(PKT) ;GET DESTINATION SUBNET
CAIG T1,MAXSBN ;RANGE CHECK
HLRZ T2,SBNRUT(T1) ;OK, GET ROUTING METHOD
>
LOAD T1,CPKDA,(PKT) ;BUT ALSO CHECK DESTINATION HOST ADDRESS
CAMN T1,MYCHAD ;IS IT I?
MOVEI T2,CHXLCL ;YES, SEND LOCALLY
SKIPN T2 ;ANY ROUTING CHOSEN YET?
MOVEI T2,CHXNOR ;NO, GO THROUGH NORMAL ROUTE
TLZ T2,-1 ;MAKE SURE NO SECTION FUNNINESSES
RET
;ROUTE TO OURSELVES; DON'T EVEN HACK ANY HARDWARE (LET BACKGROUND FORK DO IT)
CHXLCL: AOS CHNPOL ;COUNT THIS LOCAL ROUTING
PKTPTH [57]
HRRZS PKTLNK(PKT) ;THIS WILL BE THE END OF LOCAL-Q LIST
HRRZ T1,CHQLCL ;GET CURRENT TAIL
HRRM PKT,CHQLCL ; AND MAKE THIS THE NEW TAIL
JUMPN T1,[HRLM PKT,PKTLNK(T1) ;IF NON-NIL OLD TAIL, MAKE IT REF NEW TAIL
JRST .+2]
HRLM PKT,CHQLCL ;ELSE, WAS EMPTY, ON BOTH ENDS, MAKE IT TAIL, TOO
RETSKP ;NO PROBLEMS
IFGE NETDTE,<
;ROUTE NORMALLY THROUGH THE (PRIMARY OR SECONDARY) FRONT END
CHXNOR:
CHXDTE: SKIPN CHAON ;IF NETWORK ISN'T UP,
RET ; THIS IS FUTILE, FAIL RETURN
AOS CHANPO ;ONE MORE PACKET REALLY OUTPUT TO -11
AOSLE CHNPO1 ;ONE MORE PACKET OUTSTANDING IN -11
JRST [ SETZM CHNPO1 ;OOPS, WENT TOO FAR: PUT IT BACK
AOS CHANOL ;COUNT OVERESTIMATIONS
RET ] ; AND FAIL RETURN TO SAY WE DIDN'T SEND IT
PKTPTH [60] ;REMEMBER WE'VE BEEN HERE
MOVE T1,TODCLK ;SET TIME OF LAST REAL
MOVEM T1,PKTTIM(PKT) ; XMISSION FOR RE-XMISSION CHECKING
PUSH P,F
MOVEI F,(PKT) ;UNIQUE CODE IS PACKET POINTER
MOVSI A,CHAXIN ;WHERE TO GO WHEN -11 GETS IT
LOAD C,CPKNB,(PKT) ;BYTE SIZE
IFE CHADTE,<
ADDI C,CHPKDT*4+3 ;PLUS PACKET HEADER
TRZ C,3 ;MAKING EVEN NUMBER OF WORDS
MOVE B,[.DFHSD,,.FECHA]
MOVEI D,(PKT)
HRLI D,(<POINT 8,>)
>;IFE CHADTE
IFN CHADTE,<
ADDI C,<CHPKDT-PKTTYP>*4+3 ;PLUS PACKET HEADER AND INTERNAL HEADER
TRZ C,3 ;MAKING EVEN NUMBER OF WORDS
LSH C,-1 ;MAKE 16 BIT BYTE COUNT
HRRI A,CHADTE ;DTE NUMBER TO SEND TO
MOVEI B,PKTTYP(PKT)
SETZM (B) ;CLEAR TYPE FIELD
HRLI B,(<POINT 16,>)
>;IFN CHADTE
CALL DTEQ
SKIPA ;I GUESS WILL RETRANSMIT SOMETIME SOON IF NECESSARY
AOS -1(P) ;WORKED: RETURN SUCCESS
POP P,F
RET
>;IFGE NETDTE
IFN ARPAF,<
;ROUTING TABLE: ROUTING ROUTINE,,GATEWAY HOST (IF ANY)
SBNRUT: CHXNOR,,0 ;SUBNET 0, NOT USED
CHXDTE,,0 ;SUBNET 1, MAIN CAMPUS LOOP
CHXDTE,,0 ;SUBNET 2, ETHERNET
CHXDTE,,0 ;SUBNET 3, MC
CHXDTE,,0 ;SUBNET 4, AI
CHXDTE,,0 ;SUBNET 5, XX
CHXDTE,,0 ;SUBNET 6, 9TH FLOOR OF TECH SQUARE
CHXNOR,,0 ;SUBNET 7, NOT USED
CHXDTE,,0 ;SUBNET 10, LCSNET
CHXIMP,,0 ;SUBNET 11, ARPANET
0 ;SUBNET 12, NOT USED
CHXDTE,,0 ;SUBNET 13, EECS
REPEAT 4,<0> ;SUBNETS 14-17 NOT USED
repeat 14,<0> ;284 can't get to LLL any more
;284 REPEAT 14,<CHXIMI,,137> ;SUBNETS 20-33, LLL
REPEAT 4,<0> ;SUBNETS 34-37 NOT USED
REPEAT 24,<0> ;284 SUBNETS 40-63 also not used yet
MAXSBN==.-SBNRUT-1
;ROUTE TO SUBNET THROUGH ARPANET HOST
CHXIMI: LOAD T1,CPKDS,(PKT) ;GET DESTINATION SUBNET
SKIPA T1,SBNRUT(T1) ;GET GATEWAY ADDRESS FOR THAT
CHXIMP: LOAD T1,CPKDA,(PKT) ;GET DESTINATION ADDRESS
HRLZM T1,PKTIMP(PKT) ;SAVE AWAY FIRST STEP DESTINATION
PIOFF
HLRZ T1,CHARPQ ;END OF ARPANET QUEUE
JUMPE T1,[HRRM PKT,CHARPQ ;HEAD OF QUEUE TOO IF EMPTY
JRST .+2]
HRRM PKT,PKTIMP(T1) ;LINK IN
HRLM PKT,CHARPQ ;TAIL OF QUEUE
PION
RETSKP ;ALL DONE FOR NOW
>;IFN ARPAF,
;PUT PACKET AS FIRST ON Q
CHAQPF: CALL NOSKDP
CHKPKT ;CHECK IF DEBUGGING
DEBUG,< CALL CHAQCK ;CHECK Q HEADER FOR VALIDITY
JRST OKSKDP ;NO GOOD, GET OUT
>;DEBUG
HLRZ T1,(Q2) ;GET PRESENT HEAD
HRRM T1,PKTLNK(PKT) ;PUT AS SECOND
HRLM PKT,(Q2) ;PUT US AS HEAD
SKIPN T1 ;AND IF EMPTY
HRRM PKT,(Q2) ;AS TAIL TOO
JRST OKSKDP
;PUT AS LAST ON Q
CHAQPL: CALL NOSKDP
CHKPKT ;CHECK PKT IF DEBUGGING
DEBUG,< CALL CHAQCK ;CHECK Q HEADER
CALLRET OKSKDP ;NO GOOD, JUST GET OUT
>;DEBUG
HLLZS PKTLNK(PKT) ;THIS WILL BE THE END OF A LIST
HRRZ T1,(Q2)
HRRM PKT,(Q2)
JUMPN T1,[HRRM PKT,PKTLNK(T1)
CALLRET OKSKDP]
HRLM PKT,(Q2) ;WAS EMPTY, ON BOTH ENDS
CALLRET OKSKDP
;GET FIRST OFF LIST
CHAQGF::CALL NOSKDP
DEBUG,< CALL CHAQCK ;CHECK Q HEADER
JRST [ SETZ PKT, ;NO GOOD, RETURN NIL PKT REF
JRST CHAQG0 ] ;JOIN EXIT CODE
>;DEBUG
HLRZ PKT,(Q2)
CAMN PKT,[777777] ;1014 IS Q EMPTY?
SETZ PKT, ;1014 WAS EMPTY, USE CANONICAL FORM
SKIPN PKT ;1014 MAYBE 0, MAYBE -1?
JRST CHAQG0 ;1014 YES, EMPTY
HRRZ T1,PKTLNK(PKT)
HLLOS PKTLNK(PKT) ;MARK AS NOT ON ANY LIST
HRLM T1,(Q2)
JUMPN T1,CHAQG0
SETZM (Q2) ;NOW EMPTY
CHAQG0: JRST OKSKDP
;FREE RESIDENT BUFFERS
CHALFR: CALL CHAQGF ;GET FIRST FROM LIST
JUMPE PKT,R
RCALL RELPKT,17
JRST CHALFR
;FREE RESIDENT OUTPUT BUFFERS, BUT NOT ANY THAT ARE XMIT ACTIVE
CHALFO: MOVEI Q2,CHAOBF(CONN)
CHALF1: CALL CHAQGF ;GET FIRST FROM LIST
JUMPE PKT,R ;END OF LIST
RCALL RELPKM,20 ;FREE PACKET
JRST CHALF1
;LOCK OUT SCHEDULING AND PI INTERRUPTS; CAN BE CALLED NESTEDLY.
NOSKDP: CONSZ PI,177B27 ; IF AT PI LEVEL, DO NOTHING
RET
NOSKD1 ;NO SCHEDULING PLEASE (CAN BE IN SCHEDULER)
IFGE CHACHN,<
AOSG CHPIOF ; CHNOFF if we haven't already
CHNOFF CHACHN
>;IFGE CHACHN,
RET
OKSKDP: CONSZ PI,177B27 ; IF at PI level
RET ; DO NOTHING
IFGE CHACHN,<
SOSGE CHPIOF ; Are we the top level ?
CHNON CHACHN ; Yes, all interrupts again also
>;IFGE CHACHN,
OKSKD1
IFN CHINET,<
;;; The following code is because we cannot call GETBLK while
;;; NOSKED (since it might block on the free storage lock)
;;; and CHXINT is always called while NOSKED.
;;; Therefore we try to keep an internet buffer on tap
SKIPN INSKED ; We can't work in schedular
SKIPE NSKED ; or if NOSKED
RET ; so give up
PIOFF ; Steal machine for a moment
SKIPE CHPKTI ; Have we a buffer already?
JRST [ PION ; yes, do nothing
RET]
SETOM CHPKTI ; make others leave it alone
PION ; and give back the machine
STKVAR <FROMS1> ; Flag of the section we're in
XMOVEI T1,0 ; Get section number
MOVEM T1,FROMS1 ; Save
SKIPN T1 ; If in section 0
SE1CAL ; enter section 1
MOVEI T1,PKTELI+<MINIHS+3>/4+CHPKDT+<^D488>/4+2
; allocate space for maximum possible packet
CALL GETBLK ; get a block of Internet free storage
MOVEM T1,CHPKTI ; Save buffer if we got it
SKIPN FROMS1 ; If we came from section 0
SE0ENT ; return to it
>
RET
SUBTTL ARPANET ROUTING SUPPORT
repeat 0,< ;1002 remove arpa routing support
IFN ARPAF,< ;166
;GET NEXT ENTRY FOR CHAOSNET ARPANET OUTPUT QUEUE
; RETURNS +1 QUEUE EMPTY
; +2 IMP BUFFER POINTER IN A
CHRIMQ::HRRZ A,CHARPQ
JUMPE A,R ;NONE, RETURN EMPTY
HRRZ B,PKTIMP(A) ;GET LINK
JUMPE B,[SETZM CHARPQ ;WAS END, QUEUE NOW EMPTY
JRST .+2]
HRRM B,CHARPQ ;NEW HEAD OF QUEUE
HLRZ C,PKTIMP(A) ;GET ARPANET DESTINATION ADDRESS
MOVEI A,PKTIMP(A) ;POINT TO IMP HEADER
SETZM .NBLD0(A) ;CLEAR SPACE FOR THE 96 BIT LEADER
SETZM .NBLD1(A)
SETZM .NBLD2(A)
MOVEI B,ITY%LL ;SET LONG LEADER FLAG
STOR B,IHFTY,(A)
MOVEI B,HTY%NP ;SET CONNECTION SIZE
STOR B,IHHTY,(A)
MOVEI B,(C) ;DESTINATION
ANDI B,77 ;SIX BITS OF IMP
STOR B,IHIMP,(A)
LSH C,-6
ANDI C,3 ;TWO BITS OF HOST
STOR C,IHHST,(A)
MOVEI B,CHSLNK ;LINK
STOR B,IHLNK,(A)
LOAD B,CPKNB,-PKTIMP(A) ;GET BYTE COUNT
ADDI B,3+<CHPKDT-PKTIMP>*4 ;INCLUDE LENGTH OF HEADER
LSH B,-2 ;INTO WORDS
STOR B,NBBSZ,(A) ;AND STORE
RETSKP
;MESSAGE DONE TO ARPANET INTERFACE
CHIMDN::SAVEQ
MOVEI PKT,-PKTIMP(A) ;IF NOT RETRANSMITTABLE
HRROS PKTLNK(PKT) ;CLEAR TRANSMIT ACTIVE
RCALL RELPKM,21 ;CAN DEALLOCATE IT NOW
RET
>;166 IFN ARPAF
>;1002 End repeat 0 (remove arpa routing support)
IFN ARPAF!CHINET,<
;SUPPORT FOR RECEIVING PACKETS FROM ANOTHER MODULE IN ANOTHER SECTION
REPEAT 0,< ;1004
IFN ARPAF,<
;INPUT MESSAGE FROM THE ARPANET, MAY BE IN NON-ZERO SECTION, SO
;WE CANNOT JUST CALL CPYPKT
CHIIMP::SAVEQ
MOVE T2,IMIB ;GET POINTER TO IMP BUFFER
ADDI T2,.NBHHL ;POINT TO ACTUAL DATA
HRRZ T4,IMPINP ;GET NEXT WORD TO READ
SUB T4,T2 ;FIGURE LENGTH TO IMP
ANDI T4,-1 ;ONLY RH MEANINGFUL
>;IFN ARPAF
>;Repeat 0
;;;
;;; Here with T2 pointing to Chaosnet packet, T4 holding amount
;;; of data received, copy packet to primary section and
;;; give it to packet receiver
;;;
CHIIM1: LOAD T1,CPKNB,(T2) ;GET BYTE COUNT
ADDI T1,3 ; Round up
LSH T1,-2 ;TURN INTO WORDS
CAMLE T1,CHPMXW ;COMPARE SIZE AGAINST MAXIMUM
RET ; Bad
ADDI T1,CHPKDT ;PLUS PACKET HEADER
CAILE T1,(T4) ;COMPARE THE TWO SIZES
RET ; Bad
MOVEI T3,CHATPB ;THIS TEMP PACKET IS THE DESTINATION
MOVEI PKT,(T3) ; AND LEAVE HERE FOR CHIPKT
CALL XBLTA ;COPY IN THE PACKET FROM IMP BUFFER
SE0ENT ;MAKE LIFE EASIER ON DTE CODE
CALL NOSKDP ;LOCK THINGS APPROPRIATELY FOR CHIPKT
CALL CHIPKT ;PROCESS INPUT OF IT
CALL OKSKDP ;UNLOCK
SE1ENT ;BACK TO SECTION 1 FOR IMP CODE
RET
>;IFN ARPAF!CHINET
IFN CHINET,<
; Input message from INTERNET module, again may be in non-zero section.
CHIINT::SAVEQ
MOVE T2,IPKT ; Pointer to INTERNET packet
LOAD T1,PIDO,(IPKT) ; Data offset
LOAD T4,PIPL,(IPKT) ; Data size
ADDI T2,PKTELI(T1) ; Add offset to pointer
SUB T4,T1 ; subtract header from size
JRST CHIIM1 ; And enter CHAOSNet
IFL NETDTE,<
CHARLD: SETOM CHAON ;ANYTHING ELSE?
RET
CHXNOR:
>;IFL NETDTE
;OUTPUT PACKET TO INTERNET, CALLED WITH CHAOSNET PACKET IN PKT
CHXINT: STKVAR <FROMS1> ; flag of the section we're called from
XMOVEI T1,0 ; Get section number
MOVEM T1,FROMS1 ; save
SKIPN T1 ; Don't enter if we're already there
SE1CAL ; enter section 1
PUSH P,IPKT ; Save Internet packet register
SKIPE INSKED ; Called from the schedular?
JRST CHXINX ; Can't send packet if so
; (because can't lock down memory)
SKIPG IPKT,CHPKTI ; Is there an internet buffer on tap?
JRST CHXINX ; No, must drop packet
SETZM CHPKTI ; clear pointer
SETZRO PFLGS,(IPKT) ; clear all flags
SETZM .IPKVR(IPKT)
MOVEI T1,.INTVR ;INTERNET VERSION
STOR T1,PIVER,(IPKT)
MOVEI T1,<MINIHS/4> ;DATA COMES RIGHT AFTER OBLIGATORY HEADER
STOR T1,PIDO,(IPKT)
MOVEI T1,10 ; reasonable TTL
STOR T1,PITTL,(IPKT) ; save in packet
LOAD T1,CPKNB,(PKT) ; get data size
ADDI T1,CHPKDT*4 ; Size of CHAOS header
PUSH P,T1 ; save for later
ADDI T1,MINIHS ; + Size of inet leader
STOR T1,PIPL,(IPKT) ; Store as packet size
SETZM .IPKSG(IPKT) ; No fragmentation
SETZM .IPKPR(IPKT) ; ...
MOVEI T1,.CHAFM ; CHAOSNET protocol
STOR T1,PIPRO,(IPKT)
MOVE T1,DEFADR ; get default address
STOR T1,PISH,(IPKT) ; set as source host
LOAD T1,CPKDA,(PKT) ; destination host
IOR T1,[CHINTM] ; mask in internet
STOR T1,PIDH,(IPKT) ; and set internet destination
XMOVEI T3,PKTELI+<MINIHS+3>/4(IPKT) ; Point to Data area
MOVE T2,PKT ; transfer from here
POP P,T1 ; Number of bytes to transfer
LSH T1,-2 ; convert to words
AOS T1 ; in case of non-integer
CALL XBLTA ; ....
CALL SNDGAT ; send it off
CHXINX: POP P,IPKT ; restore register
HRROS PKTLNK(PKT) ; Packet is no longer XMIT active
RCALL RELPKM,22 ; Packet is not in use, so release it
SKIPN FROMS1 ; don't return to sc 0 if we came from 1
SE0ENT ; return to section 0
RETSKP ; and return
>;IFN CHINET
SUBTTL DEBUGGING SUPPORT
DEBUG,<
;CHECK THE CONNECTION REF'ED BY CONN FOR VALIDITY (USING MAGIC VALUE)
CHKCNB: PUSH P,T2
PUSH P,T1 ;GET WORK REGISTERS
MOVE T2,-2(P) ;GET CALLER'S ADDRESS+1
MOVE T1,CONMAG(CONN) ;GET MAGIC VALUE
XORI T1,(CONN) ;TURN BACK INTO VANILLA MAGIC VALUE, HOPEFULLY
CAME T1,[CHSMGV] ;IS IT OK?
CHABUG(CHABDC,<<CONN,CONREF>,<T2,WHERE>>) ;NO, COMPLAIN LOUDLY
POP P,T1
POP P,T2
RET
;CHECK PACKET REF'ED BY PKT FOR VALIDITY
CHKPKB: PUSH P,T2
HRRZ T2,-1(P) ;GET CALLER'S ADDRESS+1 (NO SECTION, FLAGS)
SOS T2 ; BUMP BACK TO CHKPKB CALL POINT
PUSH P,T1
PUSH P,T3
PUSH P,T4
PUSH P,Q2
MOVE T1,PKTMAG(PKT) ;GET KEYED MAGIC VALUE
MOVE T4,PKTLNK(PKT) ;GET THIS FOR LATER REPORTING
MOVE Q2,PKTHDW(PKT) ;GET PURPORTED ASGRES HEADER WORD
MOVE T3,T1 ;SAVE IT HERE
XORI T1,(PKT) ;TURN BACK INTO VANILLA VERSION
CAMN Q2,-PKTHLN-1(PKT) ;IS THE HEADER WORD OK
CAME T1,[CHSMGV] ; AND THE MAGIC VALUE OK?
CHABUG(CHABDP,<<PKT,PKTREF>,<T2,WHERE>,<T3,WHY>,<T4,LINKS>>) ;NO TO EITHER
HLRZ T1,T4 ;CHECK LH OF LINK WORD
CAIE T1,-1 ;THIS IS OK (INACTIVE)
CAIN T1,0 ;AS IS THIS (END OF LOCAL-Q LIST)
JRST CHKPBN
CAIN T1,1 ;THIS IS OK (XMIT ACTIVE)
JRST CHKPBN
CAIL T1,RESFRP ;ELSE, MUST BE REF: CHECK RES FREE POOL
CAILE T1,RESFRZ ; BOUNDS
JRST CHKPBE ;OUCH, NO GOOD: COMPLAIN
CHKPBN: HRRZ T1,T4 ;NOW, CHECK RH
CAIE T1,-1 ;THIS IS OK (INACTIVE)
CAIN T1,0 ;AS IS THIS (END OF SOME LIST)
JRST CHKPBD
CAIL T1,RESFRP ;ELSE, MUST BE REF: CHECK W/IN FREE POOL
CAILE T1,RESFRZ ; BOUNDS
CHKPBE: CHABUG(CHABDR,<<PKT,PKTREF>,<T2,WHERE>,<T3,WHY>,<T4,LINKS>>) ;BAD, BARF
CHKPBD: POP P,Q2
POP P,T4 ;GET BACK TEMPS
POP P,T3
POP P,T1
POP P,T2
RET
;MAKE SURE WE'RE LOCKED UP: EITHER AT PI LEVEL OR HAVE CALLED NOSKDP.
CHKLCK:
IFGE CHACHN,<
SKIPGE CHPIOF ;HAS NOSKDP BEEN CALLED?
>
IFL CHACHN,<
SKIPN NSKED ; are we safe from pre-emption?
>
CONSZ PI,177B27 ;NO, AT PI LEVEL?
RET ;YES, WE'RE LOCKED UP
CHABUG(CHALCK) ;OOPS, UNPROTECTED
RET
;SET UP A PACKET HISTORY PATH ENTRY (CX HAS ENTRY)
PKTPTS: PUSH P,CX ;SAVE THIS OVER POTENTIAL NOSKD1 CALL
CALL NOSKDP ;DON'T LET ANYONE ELSE HACK THIS
POP P,CX
DPB CX,PKTHSP(PKT) ;DROP THIS IN
IBP PKTHSP(PKT) ;BUMP TO NEXT
HRRZ CX,PKTHSP(PKT) ;PICK UP HISTORY BYTE REF (ADDRESS ONLY)
CAIL CX,PKTHSP(PKT) ;IF WE'VE GOTTEN TO THE BOTTOM,
JRST [ MOVEI CX,PKTHST(PKT) ;WRAP AROUND
HRLI CX,360600
MOVEM CX,PKTHSP(PKT) ;RESET IT TO TOP
JRST .+1 ]
CALLRET OKSKDP ;UNLOCK AND GET OUT
;SET UP A CONNECTION HISTORY ENTRY
CONPTS: PUSH P,CX ;SAVE THIS OVER NOSKD1 CALL
CALL NOSKDP ;DON'T LET ANYONE ELSE HACK THIS
POP P,CX
DPB CX,CONHSP(CONN) ;DROP THIS IN
IBP CONHSP(CONN) ;BUMP TO NEXT
HRRZ CX,CONHSP(CONN) ;PICK UP HISTORY BYTE REF (ADDRESS ONLY)
CAIL CX,CONHSP(CONN) ;IF WE'VE GOTTEN TO THE BOTTOM,
JRST [ MOVEI CX,CONHST(CONN) ;WRAP AROUND
HRLI CX,331100
MOVEM CX,CONHSP(CONN) ;RESET IT TO TOP
JRST .+1 ]
CALLRET OKSKDP ;UNLOCK AND GET OUT
;CHECK A PACKET QUEUE HEADER TO MAKE SURE IT'S NOT MARKED AS INACTIVE
CHAQCK: MOVE T1,(Q2) ;GET HEADER WORD
SKIPN T1 ;OK IF NOTHING THERE
RETSKP
CAME T1,[-1] ;MARKED AS EMPTY?
JRST [ HLRZ T1,(Q2) ;NO, PICK UP FIRST
TCHKPK ; AND MAKE SURE IT'S OK
HRRZ T1,(Q2) ;AND LAST
TCHKPK
RETSKP ] ;OK, ANYWAY
CHABUG(CHAQHI) ;YES, COMPLAIN
RET ;FAIL RETURN
>; Long DEBUG conditional
IFN T20FLG,<TNXEND>
END