Trailing-Edge
-
PDP-10 Archives
-
SRI_NIC_PERM_SRC_1_19910112
-
7/ft3/monitor/stanford/pup.red
There are no other files named pup.red in the archive.
REDIT 1(103) COMPARE by user OPERATOR, 23-Jun-88 14:27:41
File 1: SRC:<6.1.MONITOR.AP16.STANFORD>PUP.MAC.1
File 2: SRC:<6.1.MONITOR.AP16.STANFORD>PUP.MAC.2
***** CHANGE #1; PAGE 1, LINE 1; PAGE 1, LINE 1
---------------------------------
;[MACBETH.STANFORD.EDU]AP16:<6.1.MONITOR.STANFORD.MARS>PUP.MAC.2, 17-Dec-87 15:41:07, Edit by A.ALDERSON
; Insert SC30-M (NI/EI) code under SC30SW. Modify PUPINI appropriately.
;[SIERRA.STANFORD.EDU]SRC:<6.1.MONITOR.STANFORD.MARS>PUP.MAC.50, 1-May-87 10:10:45, Edit by ALDERSON
; Still seeing SMGETX's--increase size of small-packet buffers without
; increasing size needed to REQUEST one
;[SIERRA.STANFORD.EDU]SRC:<6.1.MONITOR.STANFORD.MARS>PUP.MAC.47, 29-Apr-87 11:15:50, Edit by ALDERSON
; Remove losing change of 21-May-85: Wrong way to go about that--leads to
; SMGETX bughlts.
;[SU-SCORE.ARPA]PS:<6-1-MONITOR>PUP.MAC.747, 6-Dec-85 23:27:19, Edit by BILLW
; Fix call to SETPOF referencing wrong section.
***** CHANGE #2; PAGE 2, LINE 2; PAGE 2, LINE 2
; Rework funky blocking done in JFN code: use BLKF instead of restarting.
; Clean up some of the JSYSA/F routines (DOBE%, DIBE%, SOBE%, SIBE%, SOBF%)
; Flush previous edit history
SEARCH PROLOG,PHYPAR,ANAUNV,PUPSYM
TTITLE PUP
---------------------------------
; Rework funky blocking done in JFN code: use BLKF instead of restarting.
; Clean up some of the JSYSA/F routines (DOBE%, DIBE%, SOBE%, SIBE%, SOBF%)
; Flush previous edit history
SEARCH PROLOG,PHYPAR,ANAUNV,PUPSYM,NIPAR
TTITLE PUP
***** CHANGE #3; PAGE 11, LINE 24; PAGE 11, LINE 24
TAIL==1 ;Second word is tail
NSMPKT==1 ;No. of small packets in our ratio
NBGPKT==1 ;No. of large packets in our ratio
SMPBLN==MNPBLX+7 ;Words per small packet buffer (note that a
; minimum sized 10MB pkt must fit)
---------------------------------
TAIL==1 ;Second word is tail
NSMPKT==1 ;No. of small packets in our ratio
NBGPKT==1 ;No. of large packets in our ratio
smpbln==100 ;Guaranteed fit for 10mb packets
;SMPBLN==MNPBLX+7 ;Words per small packet buffer (note that a
; minimum sized 10MB pkt must fit)
***** CHANGE #4; PAGE 12, LINE 35; PAGE 12, LINE 35
RS PRTLCK ;Lock for changes to port tables
RS LSKNDL ;Count of deleted entries in local socket table
RS PUPFRK ;FORKX of Pup background process
RS SYNTIM ;Time for next sync timeout check
RS DEFTIM ;Timeout for doing deferred task scan
---------------------------------
RS PRTLCK ;Lock for changes to port tables
RS LSKNDL ;Count of deleted entries in local socket table
RS PUPFRK ;FORKX of Pup background process
RS SYNTIM ;Time for next sync timeout check
RS DEFTIM ;Timeout for doing deferred task scan
IFN STANSW&SC30SW,<
RS PUPPID ;PUP's NISRV portal ID
RS PUPRBC ;Total number of receive buffers PUP has
;posted to NISRV.
RSI PUPDRB,^D10 ;Number of buffers we want to keep posted
>;IFN STANSW&SC30SW
***** CHANGE #5; PAGE 27, LINE 9; PAGE 27, LINE 9
;resident since we can't risk page faulting with the I/O turned off.
;May be called from process or scheduler context.
XRESCD
PILOCK:
---------------------------------
;resident since we can't risk page faulting with the I/O turned off.
;May be called from process or scheduler context.
XRESCD
IFN STANSW&SC30SW,<NIPIA==DLSCHN>
PILOCK:
***** CHANGE #6; PAGE 27, LINE 17; PAGE 27, LINE 19
CONSZ PI,1B<PHYCHN+^D20> ;At interrupt level?
BUG.(HLT,PILCKX,PUP,SOFT,<PUP - invalid call to PILOCK>)
>;IFN DEBUGF
NOSKD1 ;Go NOSKED
IOPIOFF ;Interlock by turning off I/O channel
CALL @(P) ;Call coroutine
TRNA ;Single return
AOS -1(P) ;Skip return, bump return address
IOPION ;Unlock
OKSKD1 ;Resume scheduling
---------------------------------
CONSZ PI,1B<PHYCHN+^D20> ;At interrupt level?
BUG.(HLT,PILCKX,PUP,SOFT,<PUP - invalid call to PILOCK>)
>;IFN DEBUGF
NOSKD1 ;Go NOSKED
IOPIOFF ;Interlock by turning off I/O channel
IFN STANSW&SC30SW,<
CHNOFF NIPIA ;Disable the NI interrpt level also
>;IFN STANSW&SC30SW
CALL @(P) ;Call coroutine
TRNA ;Single return
AOS -1(P) ;Skip return, bump return address
IOPION ;Unlock
IFN STANSW&SC30SW,<
CHNON NIPIA ;Enable the NI interrupt level
>;IFN STANSW&SC30SW
OKSKD1 ;Resume scheduling
***** CHANGE #7; PAGE 94, LINE 10; PAGE 94, LINE 10
PUPINI: MOVEI T1,BSPBEG ;Get address of start of BSP free storage
MOVEM T1,PUPPAR+.PPSTG ;Stash in PUPPAR GETAB% table
HRRZ T1,PUPPAR+.PPPNV ;Get TTY number of first PNV
MOVEM T1,PNVTTY ;Remember it
MOVX T1,PP%TNX!PP%MMD ;32-bit mode headers, all data modes
SKIPN MEIMDF ;Does this system allow all data modes?
TXZ T1,PP%MMD ;No, clear that flag
XMOVEI T2,NCTVT ;Set up pointer to NCT vector table
PUPIN0: LOAD T2,NTLNK,(T2) ;Get NCT pointer
JUMPE T2,PUPIN1 ;If nil, then done
LOAD T3,NTTYP,(T2) ;Get network type code
CAIN T3,NT.ETH ;10MB Ethernet?
TXO T1,PP%10M ;Yes, set the flag
JRST PUPIN0 ;Loop over all NCT's
PUPIN1: IORM T1,PUPPAR+.PPFLG ;Set flags
XMOVEI T2,PBQEND-1 ;Last address of double-word queues
---------------------------------
PUPINI: MOVEI T1,BSPBEG ;Get address of start of BSP free storage
MOVEM T1,PUPPAR+.PPSTG ;Stash in PUPPAR GETAB% table
HRRZ T1,PUPPAR+.PPPNV ;Get TTY number of first PNV
MOVEM T1,PNVTTY ;Remember it
IORM T1,PUPPAR+.PPFLG ;Set flags
XMOVEI T2,PBQEND-1 ;Last address of double-word queues
***** CHANGE #8; PAGE 94, LINE 30; PAGE 94, LINE 20
PUPIN2: MOVEM T1,HEAD(T1) ; ...
MOVEM T1,TAIL(T1) ; ...
ADDI T1,2 ;Move on to next queue
CAMGE T1,T2 ;More?
JRST PUPIN2 ;Yes, repeat for all
MOVSI UNIT,-NPUPUN ;Initialize all ports
CALL INIPRT
AOBJN UNIT,.-1
---------------------------------
PUPIN2: MOVEM T1,HEAD(T1) ; ...
MOVEM T1,TAIL(T1) ; ...
ADDI T1,2 ;Move on to next queue
CAMGE T1,T2 ;More?
JRST PUPIN2 ;Yes, repeat for all
CALL STGINI ;Initialize queue of permanent packet buffers
***** CHANGE #9; PAGE 94, LINE 40; PAGE 94, LINE 27
MOVX T1,INACCF ;Initialize routing table to all empty
MOVEM T1,PUPROU
MOVE T1,[XWD PUPROU,PUPROU+1]
BLT T1,PUPROU+NPNETS-1
CALL STGINI ;Initialize queue of permanent packet buffers
CALL GATINI ;Initialize gateway data structures
---------------------------------
MOVX T1,INACCF ;Initialize routing table to all empty
MOVEM T1,PUPROU
MOVE T1,[XWD PUPROU,PUPROU+1]
BLT T1,PUPROU+NPNETS-1
MOVX T1,PP%TNX!PP%MMD ;32-bit mode headers, all data modes
SKIPN MEIMDF ;Does this system allow all data modes?
TXZ T1,PP%MMD ;No, clear that flag
XMOVEI T2,NCTVT ;Set up pointer to NCT vector table
PUPIN0: LOAD T2,NTLNK,(T2) ;Get NCT pointer
JUMPE T2,PUPIN1 ;If nil, then done
LOAD T3,NTTYP,(T2) ;Get network type code
CAIN T3,NT.ETH ;10MB Ethernet?
TXO T1,PP%10M ;Yes, set the flag
IFN STANSW&SC30SW,<
LOAD T3,NTDEV,(T2) ;Get the device type
CAIN T3,NT.NIP ;An NI?
CALL INPUNI ;Yes, init PUP for the NI
>;IFN STANSW&SC30SW
JRST PUPIN0 ;Loop over all NCT's
PUPIN1: MOVSI UNIT,-NPUPUN ;Initialize all ports
CALL INIPRT
AOBJN UNIT,.-1
CALL GATINI ;Initialize gateway data structures
***** CHANGE #10; PAGE 96, LINE 2; PAGE 96, LINE 2
IORM T1,PUPFLG ; ...
SETOM PUPON ;PUP is up
RET ;Return to caller
;GATINI - Initialize gateway data structures
---------------------------------
IORM T1,PUPFLG ; ...
SETOM PUPON ;PUP is up
RET ;Return to caller
IFN STANSW&SC30SW,<
;INPUNI - Initialize PUP for the NI
;Called from PUPINI with T2 pointing at the NCT address
;Takes no arguments, preserves all AC's
DEFSTR ETHHST,,35,8 ;Ethernet subnet host number (all classes)
OFFETH==<PKTELI-4-LCLPKT> ;Offset of start of 10MB encapsulation
INPUNI: SAVEAC <T1,T2,T3,T4> ;Transparent w/respect to T1-T4
TRVAR (<<UNBLOK,UN.LEN>>) ;Arg block for NISRV
SETZM PUPRBC ;Reset the number of buffers posted
STOR T2,UNUID,+UNBLOK ;Save the NCT address as the user ID
MOVE T3,NTLADR(T2) ;Get our Internet address
TXNN T3,.NETCA ;Class A network?
JRST [ LDB T1,[POINT 8,T3,19]
JRST .+2] ;Yes, get the subnet number
LDB T1,[POINT 8,T3,27] ;No, must be class B or C
TXNE T3,.NETCA ;Test for a Class A address
TXNN T3,.NETCB ;Test for a Class B address
TRNA ;Class A or B, subnets are possible
SETO T1, ;Can't have subnets for Class C addresses
SKIPN SUBNTF## ;Allowing the use of subnets?
SETO T1, ;No, say not possible
MOVEM T1,NTSUBN(T2) ;Stash subnet number or -1 in the NCT
CAILE T1,NPNETS ;Within range?
IFSKP.
LOAD T3,DEFNET ;Yes, get default PUP subnet number
SKIPN T3 ;Skip if already set
STOR T1,DEFNET ;Else set the default now
ENDIF.
LOAD T1,ETHHST,NTLADR(T2) ;Get our subnet (3MB Ethernet) host number
MOVEM T1,NTHSTN(T2) ;Stash it in the NCT
SETOM NTETHR(T2) ;Set to -1 for testing convenience
SKIPGE T1,NTSUBN(T2) ;Pick out our Ethernet subnet number
JRST INPUN1 ;Strange. PUP, but no subnets.
MOVE T3,NTHSTN(T2) ;Pick out our PUP (3MB) host number
TXO T3,1B1 ;Broadcasts allowed on local subnet
MOVEM T3,PUPROU-1(T1) ;Set PUP routing entry for this host
INPUN1: MOVEI T1,OFFETH ;Offset from LCLPKT (start of encaps.)
MOVEM T1,NTOFF(T2) ; ...
MOVEI T1,^D8 ;Need 8 16-bit words for 10MB encapsulation
MOVEM T1,NTCAPC(T2) ;Stash in NCT
LSH T1,1 ;Compute number of encapsulation bytes
MOVEM T1,NTCAPB(T2) ;Remember that number as well
ADDI T1,4 ;Four bytes into IP is minimum for sniffing
MOVEM T1,NTIPMN(T2) ; ...
ADDI T1,^D20+^D20+^D8-4 ;IP header + TCP header + data is max for sniff
MOVEM T1,NTIPMX(T2) ; ...
SETZRO <UNCHN,UNPAD>,+UNBLOK ;Use channel number 0, no padding
MOVX T1,ET%PUP ;Get the PUP protocol type
STOR T1,UNPRO,+UNBLOK ;Put it in the arg block
XMOVEI T1,PUPCBK ;Get the callback address
STOR T1,UNCBA,+UNBLOK ;Put callback address in the arg block
MOVX T1,NU.OPN ;Get the NISRV function code
XMOVEI T2,UNBLOK ;Get the address of the arg block
CALL DLLUNI ;Open the portal
RET ;Sigh
LOAD T1,UNPID,+UNBLOK ;Get the portal ID
MOVEM T1,PUPPID ;Put it in a safe place
SETONE UNDAD,+UNBLOK ;Setup high order multicast address
SETONE UNDAD,+1+UNBLOK ;Setup low order multicast address
MOVX T1,NU.EMA ;Get NISRV function code
XMOVEI T2,UNBLOK ;Get NISRV arg block address
CALL DLLUNI ;Enable the broadcast address
RET ; Sigh...
MOVX T1,NU.RCI ;Get NISRV function code
XMOVEI T2,UNBLOK ;Get UN block address
CALL DLLUNI ;Read the NI's addresses
RET ; Sigh...
OPSTR <DMOVE T1,>,UNCAR,+UNBLOK ;Get the current address
LSH T1,-4 ;Close the gap
LOAD T3,UNUID,+UNBLOK ;Get the NCT address back
STOR T1,HRDW0,(T3) ;Put the high order in the NCT
LSH T2,-^D20 ;Close the gap
STOR T2,HRDW1,(T3) ;Put the low order in the NCT
CALLRET PUPPST ;Post some buffers
;PUPPST - Post NI buffers for the PUP protocol
;Has no args, smashes all Ts.
XRESCD
PUPPST: MOVE T1,PUPDRB ;Get the number of receive buffers desired
CAMG T1,PUPRBC ;Are enough posted?
RET ; Yes, don't add any more
SAVEAC <PB>
TRVAR (<<UNBLOK,UN.LEN>>) ;NISRV arg block
MOVE T1,PUPPID ;Get our portal ID
STOR T1,UNPID,+UNBLOK ;Put it in the arg block
PSTLOP: SZPI 177B27 ;At interrupt level?
IFSKP. ;No, call BGGETP
CALL BGGETP ; Get a buffer at non-int level
RET ; Couldn't get it. Maybe try later
ELSE. ;We're at interrupt level
CALL BGGET ; Get a buffer at interrupt level
RET ; Couldn't get it. Try again later
ENDIF.
STOR PB,UNRID,+UNBLOK ; Setup request ID to be buffer address
MOVX T1,MXPBLN*4 ; Get the length of the buffer
STOR T1,UNBSZ,+UNBLOK ; Put it in the arg block
XMOVEI T1,PBHEAD(PB) ; Get start address of user data portion
; of buffer
TXO T1,OWGP.(8) ; Make it a byte pointer
STOR T1,UNBFA,+UNBLOK ; Put it in the NISRV arg block
MOVX T1,UNA.EV ;Get address space indicator
STOR T1,UNADS,+UNBLOK ;Buffer is in Exec virtual address space
MOVX T1,NU.RCV ; Get function code for NISRV
XMOVEI T2,UNBLOK ; Setup arg block address
CALL DLLUNI ; Post a receive buffer
JRST PUPPS1 ; Failed, clean up nicely
AOS T1,PUPRBC ; Account for this buffer
CAMGE T1,PUPDRB ; Do we have enough buffers?
JRST PSTLOP ; No, do some more
RET ; Yes, all done
PUPPS1: BUG.(CHK,PUPNPF,PUP,SOFT,<PUP - Post receive buffer failed>)
SZPI 177B27 ;At interrupt level?
IFSKP. ;No, call BGGETP
CALL RELPKT ; Release a buffer at non-int level
ELSE. ;We're at interrupt level
CALL RELPBI ; Release a buffer at interrupt level
ENDIF.
RET ;All done!
>;IFN STANSW&SC30SW
;GATINI - Initialize gateway data structures
***** CHANGE #11; PAGE 96, LINE 9; PAGE 98, LINE 8
;Called from PUPINI
;PUPIBQ, PUPIBC, PUPSTS must be NPUPUN+1 ports long.
;Returns +1 always
;Clobbers T1, UNIT
GATINI: MOVEI UNIT,2*GATPRT ;We have a special port =) GATPRT = NPUPUN
---------------------------------
;Called from PUPINI
;PUPIBQ, PUPIBC, PUPSTS must be NPUPUN+1 ports long.
;Returns +1 always
;Clobbers T1, UNIT
XSWAPCD
GATINI: MOVEI UNIT,2*GATPRT ;We have a special port =) GATPRT = NPUPUN
***** CHANGE #12; PAGE 216, LINE 10; PAGE 218, LINE 10
; +2 success, PB/ buffer pointer
XRESCD
ASGPBI:
;; CAILE T1,^D20+^D8 ;If very few bytes, use a small buffer
CAILE T1,^D46 ;If very few bytes, use a small buffer.
; 46. is the number of data bytes in a minimum
---------------------------------
; +2 success, PB/ buffer pointer
XRESCD
ASGPBI:
CAILE T1,^D20+^D8 ;If very few bytes, use a small buffer
;; CAILE T1,^D46 ;If very few bytes, use a small buffer.
; 46. is the number of data bytes in a minimum
***** CHANGE #13; PAGE 233, LINE 27; PAGE 235, LINE 27
CALL ENCAPS ;Encapsulate the datagram
IFNSK.
JUMPE T1,[RETBAD(ETHRX2)] ;Failure, T1/0 means we tried ARP
RETBAD(PUPX6) ;Else we have a hard failure.
ENDIF.
CALL ASGIRB ;Get iorb pointer in T1
RETBAD(MONX01) ;Pup fork tried to block, take error return
CALL BLDIOW ;Build the IORB, ret pointer in T1
LOAD T2,PUCHK
STOR T2,IRCHK,(T1) ;Set up Pup checksum
SETONE IRTRF,(T1) ;Set flag that we are writing a checksum
MOVE T2,NTENCU(P1) ;Set up CDB,,UDB for this NCT
NOSKED ;Turn off scheduling
CALL PHYSIO ;Pass iorb to PHYMEI routines
OKSKED ;Resume scheduling
AOS STAXMT ;Count another pup queued for output
---------------------------------
CALL ENCAPS ;Encapsulate the datagram
IFNSK.
JUMPE T1,[RETBAD(ETHRX2)] ;Failure, T1/0 means we tried ARP
RETBAD(PUPX6) ;Else we have a hard failure.
ENDIF.
IFN STANSW&SC30SW,<
LOAD T1,NTDEV,(P1) ;Get the device type
CAXN T1,NT.NIP ;Is it an NI?
IFSKP. ;No, do MEIS stuff
>;IFN STANSW&SC30SW
CALL ASGIRB ;Get iorb pointer in T1
RETBAD(MONX01) ;Pup fork tried to block, take error return
CALL BLDIOW ;Build the IORB, ret pointer in T1
LOAD T2,PUCHK
STOR T2,IRCHK,(T1) ;Set up Pup checksum
SETONE IRTRF,(T1) ;Set flag that we are writing a checksum
MOVE T2,NTENCU(P1) ;Set up CDB,,UDB for this NCT
NOSKED ;Turn off scheduling
CALL PHYSIO ;Pass iorb to PHYMEI routines
OKSKED ;Resume scheduling
IFN STANSW&SC30SW,<
ELSE. ;Do NI stuff
TRVAR(<<UNBLOK,UN.LEN>>) ;Get room for NISRV arg block
MOVE T1,PUPPID ;Get our NISRV portal ID
STOR T1,UNPID,+UNBLOK ;Put it in the NISRV arg block
STOR PB,UNRID,+UNBLOK ;Save packet buffer address
DMOVE T1,PBPHYS+1(PB) ;Get the destination Ethernet address
LSH T1,-4 ;Close the gap
LSHC T1,^D16 ;Get two more bytes
LSH T1,4 ;Open the gap again
OPSTR <DMOVEM T1,>,UNDAD,+UNBLOK ;Put it in the arg block
SETZRO UNPTR,+UNBLOK ;Indicate that we supplied an immediate address
XMOVEI T2,PBHEAD(PB) ;Get the start address of datagram
TXO T2,OWGP.(8) ;Make a byte pointer to the destination addr
STOR T2,UNBFA,+UNBLOK ;Setup pointer to the real data
LOAD T1,PUPLEN ;Get the length of this PUP
SUBI T1,1 ;Backup by one
TRZ T1,1 ;Make it even
ADJBP T1,T2 ;Make pointer to checksum
LOAD T2,PUCHK ;Get the checksum
ROT T2,-8 ;Get the high order byte
IDPB T2,T1 ;Store the high order byte
ROT T2,8 ;Get the low order byte
IDPB T2,T1 ;Store the low order byte
MOVX T1,UNA.EV ;Get address space indicator
STOR T1,UNADS,+UNBLOK ;Buffer is in Exec virtual address space
LOAD T1,PUPLEN ;Get the length of the datagram
CAIGE T1,^D46 ;Is it long enough?
MOVX T1,^D46 ; Nope. Now it is
TRNE T1,1 ;Is the length odd?
ADDI T1,1 ; Yes, make it even
STOR T1,UNBSZ,+UNBLOK ;Setup the datagram size
MOVX T1,NU.XMT ;Get NISRV function code
XMOVEI T2,UNBLOK ;Get arg block address
CALL DLLUNI ;Transmit the datagram
BUG. (CHK,PUPNXF,PUP,SOFT,<PUP - NI transmit failed>)
ENDIF.
>;IFN STANSW&SC30SW
AOS STAXMT ;Count another pup queued for output
***** CHANGE #14; PAGE 234, LINE 20; PAGE 236, LINE 20
LOAD PB,IRBUF,(T1) ;Get virtual address of packet buffer
MOVE T2,IRBSTS(T1) ;Get status flags
TXNE T2,IS.ERR ;Any error during the transfer?
AOS STAXBD ;Yes, just count it
CALL RELIRB ;Put iorb back on free queue
SKIPN PBLINK(PB) ;Does this packet belong to BSP?
---------------------------------
LOAD PB,IRBUF,(T1) ;Get virtual address of packet buffer
MOVE T2,IRBSTS(T1) ;Get status flags
TXNE T2,IS.ERR ;Any error during the transfer?
AOS STAXBD ;Yes, just count it
CALL RELIRB ;Put iorb back on free queue
IFN STANSW&SC30SW,<NIXMD1:>
SKIPN PBLINK(PB) ;Does this packet belong to BSP?
***** CHANGE #15; PAGE 234, LINE 26; PAGE 236, LINE 27
CALL RELPBI ;No, release the packet now
POP P,PB ;Restore preserved register
RET ;Return to caller
XSWAPCD
---------------------------------
CALL RELPBI ;No, release the packet now
POP P,PB ;Restore preserved register
RET ;Return to caller
IFN STANSW&SC30SW,<
; Here on transmit complete interrupt from NISRV.
NIXMDN: SKIPE T3 ;Any errors?
AOS STAXBD ; Yes, count them up
PUSH P,PB ;Must use this AC
LOAD PB,UNRID,(T2) ;Get the packet buffer address
JRST NIXMD1 ;Continue with common code
>;IFN STANSW&SC30SW
XSWAPCD
***** CHANGE #16; PAGE 237, LINE 35; PAGE 239, LINE 35
;If we have no free iorbs, we can't read the packet. Drop it.
PUPIOX: AOS STAIOB ;No free iorbs
CALL RELPBI ;Release the buffer
RET ;Flush the packet
---------------------------------
;If we have no free iorbs, we can't read the packet. Drop it.
PUPIOX: AOS STAIOB ;No free iorbs
CALL RELPBI ;Release the buffer
RET ;Flush the packet
IFN STANSW&SC30SW,<
; Here upon receipt of a packet from the NI
NIRCDN: SAVEAC <P1,JFN,UNIT,PB>
MOVE JFN,T2 ;Put NISRV arg block address in a safe place
LOAD P1,UNUID,(JFN) ;Setup the NCT address
LOAD PB,UNRID,(JFN) ;Setup pointer to data
SOS PUPRBC ;One less receive buffer posted
CALL PUPPST ;Go post more if necessary
AOS STARCV ;Count the interrupt
LOAD T1,UNBSZ,(JFN) ;Get data length seen by hardware
; addi t1,4 ;*****ACCOUNT FOR SC NI LOSSAGE*******
LOAD T2,PUPLEN ;Get data length claimed by packet (plus chksm)
SKIPE NTETHR(P1) ;If 10MB interface and the software length...
CAIL T2,MNPLEN+MINDAT ;...is less than the minimum hardware length
TRNA ;Neither, sanity test is valid
JRST NIRRC0 ;Then skip the usual sanity test
SUBI T1,(T2) ;Compute hardware and software count difference
CAILE T1,1 ;Zero or one is good (may have garbage byte)
CALL PUPRCX ;Anything else is a bad packet, drop it
NIRRC0: CAIL T2,MNPLEN ;Check for legal length
CAILE T2,MXPLEN ; ...
CALL PUPRCX ;Bad protocol length, drop it
SUBI T2,1 ;Compute offset to checksum
TRZ T2,1 ;Round down to an even number
OPSTR <ADJBP T2,>,UNBFA,(JFN) ;Point to checksum
ILDB T1,T2 ;Get high order checksum byte
ILDB T3,T2 ;Get low order checksum byte
LSH T1,10 ;Make room for low order
IOR T1,T3 ;Form the checksum
STOR T1,PUCHK ;Store the checksum
CALL NETDFT ;Default networks, update checksum if necessary
CALL PUPRCX ;A bad network number
;NIRRCI (cont'd)
LOAD T1,PUPDN ;Get destination network
LOAD T3,NETADR,(T1) ;Get our host address on destination net
LOAD T2,PUPDH ;Get Pup destination host
CAIN T2,(T3) ;Pup sent to us?
IFSKP.
AOS STAGAT ;No, count a gateway pup
SKIPL PUPPAR+.PPFLG ;Skip if we're a gateway
JRST PUPWAI ;Else quietly flush buffer and datagram.
MOVEI UNIT,GATPRT ;Set up our special gateway "port"
ELSE.
CALL GETPDS ;Yes, get destination socket in T1
MOVE T2,T1 ;PRTLUK wants the socket in T2
LOAD T1,PUPDH ;Get destination host
LOAD T3,PUPDN ;Get destination net
HRLI T1,(T3) ;Form net,,host
SETZ UNIT, ;No special flags
CALL PRTLUK ;Lookup local port, set UNIT
JRST PUPWAI ;No port, dump the waif
ENDIF.
MOVE T1,PUPIBC(UNIT) ;Get count of packets already queued
CAIGE T1,MAXQDI ;Within range?
IFSKP.
AOS STAIQL ;No, count a miss
JRST RELPBI ;And flush this packet
ENDIF.
CALL GETMOD ;Determine pup's data mode
LOAD T1,PUPLEN ;Get pup length
SUBI T1,MNPLEN ;Subtract off header and checksum bytes
AOS STASHT ;Count a short datagram
CALLRET PUPNR0 ;Go append pup to queue, etc.
;(we join the code in PUPRIN)
>;IFN STANSW&SC30SW
***** CHANGE #17; PAGE 243, LINE 33; PAGE 246, LINE 33
JRST PU7PS0 ;Go look at the word again
PU7PS2: AOBJN E,PU7PS0 ;Advance to next word in the bit table
RET ;All done, return to caller
XSWAPCD
---------------------------------
JRST PU7PS0 ;Go look at the word again
PU7PS2: AOBJN E,PU7PS0 ;Advance to next word in the bit table
RET ;All done, return to caller
IFN STANSW&SC30SW,<
;PUPCBK - Callback routine for NISRV
;This routine gets invoked whenever NISRV has something interesting to tell
;PUP. This includes things like completion of a transmit, or the receipt of
;a datagram. This code (and everything it calls) may run at NI interrupt
;level.
XRESCD
PUPCBK: JRST @1+.-NU.OPN(T1) ; Do the dispatch
TABBEG NU.OPN,NU.MAX,<IFIW RTN>
TABENT NU.XMT,<IFIW NIXMDN> ;Transmit done
TABENT NU.RCV,<IFIW NIRCDN> ;Receive done
TABENT NU.RCI,<IFIW NISTAT> ;Status change
TABEND
NISTAT: OPSTR <DMOVE T3,>,UNCAR,(T2) ;Get the current address
LSH T3,-4 ;Close the gap
LOAD T1,UNUID,(T2) ;Get the NCT address back
STOR T3,HRDW0,(T1) ;Put the high order in the NCT
LSH T4,-^D20 ;Close the gap
STOR T4,HRDW1,(T1) ;Put the low order in the NCT
RET
>;IFN STANSW&SC30SW
XSWAPCD