1
0
mirror of https://github.com/PDP-10/its.git synced 2026-03-24 17:36:15 +00:00

Ethernet and ARP support from Dave Conroy.

This commit is contained in:
Lars Brinkhoff
2017-01-24 11:48:41 +01:00
parent 1f124047da
commit 93b674f306
3 changed files with 903 additions and 0 deletions

1
src/dcg/-read-.-this- Normal file
View File

@@ -0,0 +1 @@
Files to support an Ethernet interface, from Dave Conroy's ITS.

201
src/dcg/arp.4 Normal file
View File

@@ -0,0 +1,201 @@
;ARP/ETH TABLE MANAGEMENT (CALLED BY ETH)
;DGC 14-SEP-2014
NAI==2
NAO==10
EBLK
;INBOUND (REMOTE TO LOCAL) ARP TABLE (AIIA[X] NON-0 => IN USE)
AIIA: BLOCK NAI ;00..31, HW FMT
AIEA0: BLOCK NAI ;00..31, HW FMT
AIEA1: BLOCK NAI ;32..47, HW FMT
;OUTBOUND (LOCAL TO REMOTE) ARP TABLE (AOIA[X] NON-0 => IN USE)
AOIA: BLOCK NAO ;00..31, HW FMT
AOEA0: BLOCK NAO ;00..31, HW FMT
AOEA1: BLOCK NAO ;32..47, HW FMT
AOSTS: BLOCK NAO ;<0 SEND-REQ, 0 WAIT-ACK, >0 VALID
AOCLK: BLOCK NAO ;IN 0.5 SECOND TICKS
AOCNT: BLOCK NAO ;RETRY COUNT FOR WAIT-ACK
BBLK
;CALLED TO INITIALIZE (FLUSH) THE ARP TABLES
;ONLY THE AIIA/AOIA ENTRIES NEED TO BE SET TO 0, BECAUSE IF THESE
;ENTRIES ARE 0, NOTHING ELSE IN THE TABLE MATTERS AT ALL
;AN ARPCLK IN THE MIDDLE IF THIS IS HARMLESS (AND ETHINI KNOWS THIS)
ARPINI: MOVSI H,-NAI
AINI0: SETZM AIIA(H) ;FREE
AOBJN H,AINI0
MOVSI H,-NAO
AINI1: SETZM AOIA(H) ;FREE
AOBJN H,AINI1
POPJ P,
;CALLED FROM NETCLK EVERY 0.5 SECOND TO AGE ENTRIES
;IN THE OUTBOUND ARP TABLE AND TO REQUEST RETRIES AT THE APPROPRIATE
;TIME. RAISES PI LEVEL TO PROTECT THE ARP TABLES FROM DEVICE PI.
ARPCLK: CONI PI,TT ;TT = SPL(NETLVL)
CONO PI,NETOFF
MOVSI H,-NAO
ACLK0: SKIPN AOIA(H)
JRST ACLK3 ;FREE
SKIPE AOCLK(H)
SOSE AOCLK(H)
JRST ACLK3 ;NOT END-OF-LIFE
;IF A VALID ENTRY HAS EA0/EA1=0/0 (ARP FAIL) FLUSH IT AT END-OF-LIFE
SKIPG AOSTS(H)
JRST ACLK1 ;NOT VALID
SKIPN AOEA0(H)
SKIPE AOEA1(H)
JRST ACLK3
SETZM AOIA(H) ;FREE
JRST ACLK3
;IF A WAIT-ACK ENTRY STILL HAS RETRIES MAKE IT A SEND-REQ
;OTHERWISE MAKE IT VALID, BUT WITH EA0/EA1=0/0, AND A 5 SEC TIME-TO-LIVE (SO
;THAT A PKT ALREADY IN THE XMQ, OR ONE THAT ARRIVES SOON, IS THROWN AWAY)
ACLK1: SKIPE AOSTS(H)
JRST ACLK3 ;NOT WAIT-ACK
PUSHJ P,ETHIOS ;ALWAYS GET OUTPUT SIDE RUNNING
SOSN AOCNT(H)
JRST ACLK2 ;NO MORE WAIT-ACK RETRIES
SETOM AOSTS(H) ;MAKE SEND-REQ
JRST ACLK3
ACLK2: SETZM AOEA0(H) ;0/0 (ARP FAIL)
SETZM AOEA1(H)
MOVEI T,1 ;MAKE VALID
MOVEM T,AOSTS(H)
MOVEI T,2.*5. ;LIVE FOR 5 SEC
MOVEM AOCLK(H)
ACLK3: AOBJN H,ACLK0
ANDI TT,177 ;SPLX(TT)
CONO PI,PICON(TT)
POPJ P,
;CALLED TO FIND AN IA->EA MAPPING IN THE OUTBOUND ARP TABLE
;ON ENTRY C HOLDS THE IA (HW FMT) THAT NEEDS TO BE FOUND
;RTN+1 NOT FOUND
;RTN+2 FOUND, BUT WAITING FOR ARP-ACK
;RTN+3 FOUND, D/E IS EA0/EA1 (WHICH MIGHT BE 0/0)
ARPFND: MOVSI H,-NAO
AFND0: SKIPE T,AOIA(H) ;FIND IA
CAME C,T
AOBJN H,AFND0
JUMPGE H,AFND2 ;NOT FOUND, RTN+1
AOS (P)
SKIPG AOSTS(H) ;VALID ?
JRST AFND2 ;NO, RTN+2
AOS (P)
MOVE D,AOEA0(H) ;GOT EA0/EA1, RTN+3
MOVE E,AOEA1(H)
JUMPN D,AFND1 ;LIVE FOR (ANOTHER) 60 MIN
JUMPE E,AFND2 ;IF EA0/EA1 NOT 0/0
AFND1: MOVEI T,2.*60.*60.
MOVEM T,AOCLK(H)
AFND2: POPJ P,
;CALLED TO ADD AN ENTRY TO THE OUTBOUND ARP TABLE
;THE STS/CLK/CNT ARE RESET, IN ANTICIPATION OF CALLER SENDING AN ARP-REQ
;ON ENTRY C HOLDS THE IA (HW FMT) THAT NEEDS TO BE ADDED (WHICH IS
;ASSUMED TO NOT BE IN THE OUTBOUND ARP TABLE; THE CALLER HAS CHECKED)
;RTN+1 CAN'T ADD AN ENTRY TO THE TABLE
;RTN+2 ENTRY ADDED TO THE TABLE
ARPADD: SETZ TT, ;OLDEST (GE => NO OLDEST)
MOVSI H,-NAO
AADD0: SKIPN AOIA(H) ;IS THIS A FREE ENTRY ?
JRST AADD2 ;YES, RECYCLE
SKIPG AOSTS(H) ;VALID ?
JRST AADD1 ;NO, LEAVE ALONE
SKIPN T,AOCLK(H) ;IS THIS A FULLY AGED ENTRY ?
JRST AADD2 ;YES, RECYCLE
SKIPGE TT ;IF NO OLDEST OR NEW ENTRY
CAMGE T,AOCLK(TT) ;OLDER THAN THE CURRENT OLDEST ?
MOVE TT,H ;YES, NEW OLDEST
AADD1: AOBJN H,AADD0
SKIPL H,TT ;FOUND A REUSABLE OLDEST ?
JRST AADD3 ;NO, RTN+1
AADD2: MOVEM C,AOIA(H) ;FILL IN NEW ENTRY
SETZM AOSTS(H) ;WAIT-ACK
MOVEI T,2.*5. ;WAIT 5 SEC FOR ACK
MOVEM T,AOCLK(H)
MOVEI T,2. ;2 TRIES
MOVEM T,AOCNT(H)
AOS (P) ;RTN+2
AADD3: POPJ P,
;CALLED TO CHECK IF AN ARP-REQ FROM OUTBOUND IS NEEDED
;THE STS/CLK ARE RESET, IN ANTICIPATION OF CALLER SENDING AN ARP-REQ (CNT
;IS LEFT ALONG, BECAUSE IT IS BEING USED TO COUNT THE RETRIES)
;RTN+1 NO ARP-REQ NEEDED
;RTN+2 ARP-REQ NEEDED, C IS IA (HW FMT)
ARPORQ: MOVSI H,-NAO
AORQ0: SKIPE C,AOIA(H) ;FIND NON-FREE ENTRY
SKIPL AOSTS(H) ;IN STATE SEND-REQ (<0)
AOBJN H,AORQ0
JUMPGE H,AORQ1 ;NO NON-FREE ENTRY, RTN+1
SETZM AOSTS(H) ;WAIT-ACK
MOVEI T,2.*5. ;WAIT 5 SEC FOR ACK
MOVEM T,AOCLK(H)
AOS (P) ;RTN+2
AORQ1: POPJ P,
;CALLED TO CHECK IF AN ARP-ACK FROM INBOUND IS NEEDED
;RTN+1 NO ARP-ACK NEEDED
;RTN+2 ARP-ACK NEEDED, C IS IA (HW FMT), D/E IS EA0/EA1 (HW FMT)
ARPOAK: MOVSI H,-NAI
AOAK0: SKIPN C,AIIA(H) ;FIND NON-FREE ENTRY
AOBJN H,AOAK0
JUMPGE H,AOAK1 ;NO NON-FREE ENTRY, RTN+1
SETZM AIIA(H) ;FREE
MOVE D,AIEA0(H)
MOVE E,AIEA1(H)
AOS (P) ;RTN+2
AOAK1: POPJ P,
;CALLED TO PROCESS AN ARP-REQ THAT HAS BEEN RECEIVED
;ON ENTRY A/B HOLD THE FIRST TWO WORDS OF THE ARP PKT (WHICH ARE UNUSED
;BUT WHICH NEED TO BE PRESERVED), C HOLDS THE ARC IA (HW FMT), AND
;D/E HOLD THE SRC EA0/EA1 (FOR WHICH THERE ISN'T A SW FMT)
ARPIRQ: MOVSI H,-NAI
AIRQ0: SKIPE AIIA(H) ;FIND FREE ENTRY
AOBJN H,AIRQ0
JUMPGE H,AIAK2 ;NO FREE ENTRY, DONE
MOVEM C,AIIA(H) ;SRC IA
MOVEM D,AIEA0(H) ;SRC EA
MOVEM E,AIEA1(H)
;IF A REMOTE HOST ASKS FOR MY EA, IT WANTS TO SEND ME SOMETHING,
;AND THERE IS A GOOD CHANCE THAT I WILL WANT TO SEND SOMETHING BACK, SO IF
;IT'S EASY, SAVE THE IA/EA OF THE REMOTE HOST IN THE OUTBOUND ARP TABLE
MOVSI H,-NAO
AIRQ1: SKIPE T,AOIA(H) ;ALREADY KNOWN ?
CAME C,T
AOBJN H,AIRQ1
JUMPL H,AIAK2 ;YES, DONE
MOVSI H,-NAO
AIRQ2: SKIPN AOIA(H) ;NO, LOOK FOR A FREE ENTRY
JRST AIRQ3
SKIPLE AOSTS(H) ;OR A VALID ENTRY THAT HAS AGED OUT
SKIPE AOCLK(H)
AOBJN H,AIRQ2
AIRQ3: JUMPGE H,AIAK2 ;NO ENTRY, DONE
MOVEM C,AOIA(H) ;SRC IA
JRST AIAK1 ;FINISH IN COMMON CODE
;CALLED TO PROCESS AN ARP-ACK THAT HAS BEEN RECEIVED
;ON ENTRY A/B HOLD THE FIRST TWO WORDS OF THE ARP PKT (WHICH ARE UNUSED
;BUT WHICH NEED TO BE PRESERVED), C HOLDS THE ARC IA (HW FMT), AND
;D/E HOLD THE SRC EA0/EA1 (FOR WHICH THERE ISN'T A SW FMT)
ARPIAK: MOVSI H,-NAO
AIAK0: SKIPE T,AOIA(H) ;FIND MATCH
CAME C,T
AOBJN H,AIAK0
JUMPGE H,AIAK2 ;NO ENTRY, IGNORE
;ARPIRQ/ARPIAK COME HERE TO FINISH FILLING IN AN OUTBOUND ARP TABLE ENTRY
AIAK1: MOVEM D,AOEA0(H) ;SRC EA
MOVEM E,AOEA1(H)
MOVEI T,1 ;VALID
MOVEM T,AOSTS(H)
MOVEI T,2.*60.*60. ;LIVE FOR 60 MIN
MOVEM T,AOCLK(H)
AIAK2: POPJ P,

701
src/dcg/kxeth.11 Normal file
View File

@@ -0,0 +1,701 @@
;ETH INTERFACE, PDP-10/X (KX) USING WIZNET W5300
;DGC 26-DEC-2014
;IF KXETH IS IN THE CONFIG, IT BETTER BE DOING SOMETHING
IFE INETHP\CHETHP,.ERR KXETH DOING NOTHING
ETH==600 ;DEVICE ADDRESS
EBCEA0==777777777760 ;BROADCAST HARDWARE ADDRESS
EBCEA1==777774000000 ;FF:FF:FF:FF:FF:FF
NPDLX==64. ;SIZE OF PDL (ETHLVL)
EBLK
ETHUP: 0 ;<0 UP, >=0 DOWN/DEAD
EOBSY: 0 ;<0 BUSY, >=0 IDLE
EOSAV: 0 ;SAVED PKT
EOCHS: 0 ;SAVED PKT TYPE (<0 CHAOS, >=IP)
EACS: BLOCK 16. ;AC SAVE AREA (ETHLVL)
EPDLX: BLOCK NPDLX ;PDL (ETHLVL)
BBLK
IFN INETHP,[
;ORIGINALLY THE NETHST AND NETIMP SYSTEM CALLS WERE ONLY FOR IMP,
;BUT NETHST WITH ARG1 OF -1 IS HOW THE NETWRK LIBRARY EXPECTS TO BE ABLE TO
;GET THE INET ADDRESS OF THE LOCAL SYSTEM, SO ETH INCLUDES A VERSION OF
;NETHST THAT CAN HANDLE THIS CASE (AND ONLY THIS CASE)
;NOTE THAT WE JUST RETURN ETHUP3 AS VAL2, EVEN THOUGH VAL2 IS ACTUALLY IN
;HOSTS2 FORMAT, SIMPLY ASSUMING THAT DOING SO WON'T BE TROUBLESOME
ANETHST:HRRE T,A ;HW -1 => FW -1
AOJN T,OPNL25 ;ONLY ALLOW ARG1 OF -1 (LOCAL HOST)
MOVEI A,0 ;4.2-4.1-00 (DOWN), NO REASON
SKIPGE ETHUP
TLO A,2000 ;4.2-4.1=10 (UP)
MOVE B,[ETHUS3]
JRST POPJ1
]
IFN CHETHP,[
;THESE TABLES ARE USED TO MAP A CHAOS ADDRESS (FOUND IN ECHCA) INTO
;A MATCHING INET ADDRESS (FOUND IN THE MATCHING ENTRY IN ECHIA). TABLE LOOKUP
;SEEMS LIKE THE BEST SCHEME, ALTHOUGH IT MIGHT BE BETTER TO MAP CHAOS
;NETWORKS INTO INET NETWORKS, RATHER THAN CHAOS ADDRESSES INTO INET ADDRESSES,
;IF SOME FUTURE VERSION OF KXETH TRIES TO DO SOMETHING WITH BRD PKTS.
ECHCA: 402 ;TX (1.2)
403 ;N1 (1.3)
NECHCA=.-ECHCA
ECHIA: IPADDR 192,168,1,2 ;TX.LOCAL
IPADDR 192,168,1,3 ;UBUNTU-NUC-01.LOCAL
NECHIA=.-ECHIA
IFN NECHCA-NECHIA,.ERR ECHCA/ECHIA LENGTH MISMATCH
]
;CALLED (SYSJOB) WHEN THE SYSTEM IS STARTED
;CHECK TO SEE IF A W5300 IS ATTCHED TO THE ETH, AND IF IT IS,
;INITIALIZE THE W5300, TURN ON THE PI, AND MARK IT AS UP.
;THIS ROUTINE CAN BE CALLED AT ANY TIME, EVEN THOUGH THE SYSTEM CURRENTLY
;DOES NOT DO SO (THE SYSJOB COULD BE MODIFIED SO THAT "LOCK NET"
;CALLED ETHINI AND DID THE SAME THING ON ETH AS IT CURRENTLY DOES ON IMP).
ETHINI: CONO ETH,0 ;DISABLE ETH PI
SETZM ETHUP ;MARK AS DOWN/DEAD
PUSHJ P,ARPINI ;CLEAR OUT THE ARP TABLES
SETZM EOBSY ;MARK AS IDLE
SKIPN A,EOSAV ;A <- SAVED PKT
JRST EINI1
SETZM EOSAV
SKIPGE EOCHS ;CHECK THE SAVED PKT TYPE
JRST EINI0 ;CHAOS
IFE INETHP,[
;WE HAVE AN IP PKT, BUT INETHP ISN'T TRUE. CAN'T HAPPEN.
BUG HALT,[ETHINI-INETHP]
]
IFN INETHP,[
PUSHJ P,EIPFR ;FREE IP PKT
JRST EINI1
]
IFE CHETHP,[
;WE HAVE A CHAOS PKT, BUT CHETHP ISN'T TRUE. CAN'T HAPPEN.
EINI0: BUG HALT,[ETHINI-CHETHP]
]
IFN CHETHP,[
EINI0: PUSHJ P,ECHFR ;FREE CHAOS PKT
]
;RESET SOME POSSIBLE W5300, THEN LOOK TO SEE IF IT'S THERE
;THE (BADLY DOCUMENTED) PB FLAG TELLS THE W5300 NOT TO RESPOND TO ICMP ECHO PKTS
EINI1: DATAO ETH,[161000,,0] ;MR <- WDF2, WDF1, WDF0, RST
MOVE T,TIME ;1-2 TICK (32-64MS) DELAY TO ENSURE
ADDI T,2 ;PLL LOCKED (10MS IS ENOUGH)
CAMLE T,TIME
PUSHJ P,UFLS
DATAO ETH,[160104,,0] ;MR <- WDF2, WDF1, WDF0, PB, IND
DATAO ETH+4*1,[001770,,0] ;AR <- IDR
DATAI ETH+4*2,T
CAME T,[246000000000]
JRST EINI2 ;NO W5300
;W5300 IS THERE, ENABLE SOCKET 0 INTERRUPTS, LOAD HARDWARE ADDRESS
DATAO ETH+4*1,[000020,,0] ;IMR <- S0INT
DATAO ETH+4*2,[000004,,0]
DATAO ETH+4*1,[000040,,0] ;SHAR <- ETHEA0/ETHEA1
DATAO ETH+4*2,[ETHEA0&777774000000]
DATAO ETH+4*1,[000050,,0]
DATAO ETH+4*2,[<ETHEA0_16.>&777774000000]
DATAO ETH+4*1,[000060,,0]
DATAO ETH+4*2,[ETHEA1&777774000000]
;ALLOCATE ALL OF THE PKT MEMORY TO SOCKET 0 (8K TO TX, 120K TO RX)
DATAO ETH+4*1,[000200,,0] ;TMS01R <- 8K/0K
DATAO ETH+4*2,[020000,,0]
DATAO ETH+4*1,[000210,,0] ;TMS23R <- 0K/0K
DATAO ETH+4*2,[000000,,0]
DATAO ETH+4*1,[000220,,0] ;TMS45R <- 0K/0K
DATAO ETH+4*2,[000000,,0]
DATAO ETH+4*1,[000230,,0] ;TMS67R <- 0K/0K
DATAO ETH+4*2,[000000,,0]
DATAO ETH+4*1,[000240,,0] ;RMS01R <- 120K/0K
DATAO ETH+4*2,[360000,,0]
DATAO ETH+4*1,[000250,,0] ;RMS23R <- 0K/0K
DATAO ETH+4*2,[000000,,0]
DATAO ETH+4*1,[000260,,0] ;RMS45R <- 0K/0K
DATAO ETH+4*2,[000000,,0]
DATAO ETH+4*1,[000270,,0] ;RMS67R <- 0K/0K
DATAO ETH+4*2,[000000,,0]
DATAO ETH+4*1,[000300,,0] ;MTYPER <- 1
DATAO ETH+4*2,[000004,,0]
;ENABLE SOCKET 0 IN LOW-LEVEL ETHERNET (MACRAW) MODE
DATAO ETH+4*1,[004020,,0] ;S0IMR <- SENDOK, RECV
DATAO ETH+4*2,[000120,,0]
DATAO ETH+4*1,[004000,,0] ;S0MR <- MF, MACRAW
DATAO ETH+4*2,[000420,,0]
DATAO ETH+4*1,[004010,,0] ;S0CR <- OPEN
DATAO ETH+4*2,[000004,,0]
DATAO ETH+4*1,[004040,,0] ;SOCK_MACRAW
DATAI ETH+4*2,T
TLZ T,776000
CAME T,[000410000000]
BUG HALT,[NOT SOCK_MACRAW]
SETOM ETHUP ;MARK AS UP
CONO ETH,20+ETHCHN ;ENABLE ETH PI ON ETHCHN
EINI2: POPJ P,
IFN INETHP,[
;CALLED TO FREE THE IP PKT BUF POINTED TO BY A
;IPIODN ONLY USES T/Q, SO THE OLD LEVEL CAN BE HELD IN TT OVER THE CALL
;PKQPF/PKQBL LOOK LIKE THEY PROTECT THEMSELVES, SO IS THIS NEEDED ?
EIPFR: CONI PI,TT ;TT <- SPL(NETLVL)
CONO PI,NETOFF
MOVSI T,(%PKPIL) ;CLR PI-LEVEL LOCK, FREE PKT
ANDCAM T,PK.FLG(A)
PUSHJ P,IPIODN
ANDI TT,177 ;SPLX(TT)
CONO PI,PICON(TT)
POPJ P,
]
IFN CHETHP,[
;CALLED TO FREE THE CHAOS PKT BUF POINTED TO BY A
;THERE IS NO NEED TO HACK PI LEVELS BECAUSE CHABRT DOES A PIOFF/PION
ECHFR: HRROS T,-2(A) ;NOT ON TX LIST (LH=1'S)
AOJN T,ECHFR0 ;IN ANY LIST (LH=1'S, RH=1'S) ?
PUSHJ P,CHABRT ;NO, RETURN TO FREE
ECHFR0: POPJ P,
]
;CALLED (MANY PLACES) TO ENSURE THE OUTPUT SIDE IS RUNNING
;BECAUSE THIS CAN BE CALLED AT MAIN LEVEL AND AT DIFFERENT PI LEVELS IT
;SIMPLY MAKES A SW REQ AND LETS ETHBRK DO ALL THE REAL WORK
;THIS MUST NOT BE CALLED IF ETHUP>=0 (DOWN/DEAD) BECAUSE ETHBRK DOES NOT CHECK
ETHIOS: CONO PI,4000\<200_-ETHCHN>
POPJ P,
;CALLED FROM THE JSR IN LOCATION 40+2*ETHCHN (ETHCHN=6)
;ONLY S0_INT.RECV AND S0_INT.SENDOK SHOULD BE ENABLED IN THE W5300
;NOTE THAT BECAUSE ETHLVL IS LOWER PRIORITY THAN NETLVL CARE MUST BE TAKEN
;WHEN THIS CODE CALLS INTO ANY OF THE COMMON NETWORKING CODE
EBLK
ETHBRK: 0
BBLK
MOVEM 17,EACS+17 ;SAVE REGS
MOVEI 17,EACS
BLT 17,EACS+16
MOVE P,[-NPDLX,,EPDLX-1] ;SET UP ETHLVL'S PDL
CONO PI,20000\<200_-ETHCHN> ;CLR (POSSIBLE) SW REQ ON ETHCHN
DATAO ETH+4*1,[004030,,0] ;T <- S0_IR
DATAI ETH+4*2,T
TLNN T,120 ;RECV OR SENDOK REQ ?
JRST EBRK0 ;NO
DATAO ETH+4*2,T ;CLEAR REQ
TLNE T,100 ;SENDOK, MARK OUTPUT IDLE
SETZM EOBSY
TLNE T,20 ;RECV, INPUT PKTS
PUSHJ P,EIPKT
EBRK0: SKIPL EOBSY ;IF IDLE, TRY AND OUTPUT PKTS
PUSHJ P,EOPKT
MOVSI 17,EACS ;RESTORE REGS
BLT 17,17
JRST 12,@ETHBRK ;DISMISS PI, RETURN
;CALLED (ETHBRK) TO INPUT ALL PKTS IN FIFO
;ARP-REQ AND ARP-ACK PACKETS UPDATE THE ARP TABLES, WHICH MAY HAVE
;THE SIDE EFFECT OF UNBLOCKING THE OUTPUT SIDE
;INET PKTS ARE INPUT, AND FED EITHER TO THE CHAOS STACK (IF THE PROTOCOL
;TYPE IS THAT OF A CHAOS PKT) OR TO THE INET STACK (DEFAULT).
;CHAOS PKTS ARE PROCESSED USING DO-IT-YOURSELF INET CODE BECAUSE IT'S
;LEGAL TO CONFIGURE CHAOS WITHOUT CONFIGURING INET.
;THIS ROUTINE CAN SMASH ALL THE ACS BECAUSE IT'S REALLY JUST A PART OF ETHBRK.
EIPKT: DATAO ETH+4*1,[004250,,0] ;T <- S0_RX_RSR0:S0_RX_RSR2
DATAI ETH+4*2,T
LSH T,-20.
DATAO ETH+4*1,[004240,,0]
DATAI ETH+4*2,TT
TLNE TT,4
TRO T,200000
JUMPE T,EIPKT9 ;0 => DONE
DATAO ETH+4*1,[004300,,0] ;S0_RX_FIFOR
DATAI ETH+4*2,R ;R <- 2-BYTE PKT SIZE
LSH R,-20.
;PULL THE DST-EA AND SRC-EA OUT OF THE RX FIFO
CAIGE R,12. ;ENOUGH FOR 2*ETHADDR
JRST EIPKT6 ;NO, FLUSH
SUBI R,12.
DATAI ETH+4*10+4*2,A ;A/B <- PKT DST ETHADDR
DATAI ETH+4*2,B
DATAI ETH+4*10+4*2,T ;PKT SRC ETHADDR
DATAI ETH+4*2,T
;THIS CHECK IS PURE PARANOIA, SINCE THE HW SHOULD HAVE DONE THE SAME CHECK
CAME A,[ETHEA0] ;DST ETHADDR = ME
JRST EIPKT1 ;NO
CAMN B,[ETHEA1]
JRST EIPKT2 ;YES
EIPKT1: CAME A,[EBCEA0] ;DST ETHADDR = BROADCAST
JRST EIPKT6 ;NO, FLUSH
CAME B,[EBCEA1]
JRST EIPKT6 ;NO, FLUSH
;PULL THE ETHTYPE OUT OF THE RX FIFO
EIPKT2: CAIGE R,2. ;ENOUGH FOR ETHTYPE
JRST EIPKT6 ;NO, FLUSH
SUBI R,2.
DATAI ETH+4*2,A ;A <- ETHTYPE
;CHECK FOR ARP PKTS, AND PROCESS THEM
;WE ONLY UNDERSTAND THE 28-BYTE PKTS THAT MAP AN IP ADDR (V4) TO AN ETH ADDR
CAME A,[20030000000] ;ETHTYPE ARP (HEX 0806) ?
JRST EIPKT3
CAIGE R,28. ;IS THE PKT LONG ENOUGH ?
JRST EIPKT6 ;NO, FLUSH
SUBI R,28.
DATAI ETH+4*10+4*2,A ;HW TYPE, PROTO TYPE
DATAI ETH+4*10+4*2,B ;HW ADDR LEN, PROTO ADDR LEN, OPER
DATAI ETH+4*10+4*2,D ;SRC-EA, SRC-IA
DATAI ETH+4*2,E
DATAI ETH+4*10+4*2,C
DATAI ETH+4*10+4*2,T ;DST-EA (FLUSHED), DST-IA
DATAI ETH+4*2,T
DATAI ETH+4*10+4*2,I
;AN ETH PKT IS AT LEAST 46 BYTES LONG, SO THERE IS PADDING TO FLUSH
ADDI R,1.+4. ;R <- # OF 16-BIT WORDS (PAD+CRC)
LSH R,-1
EIPKTM: DATAI ETH+4*2,T ;FLUSH PAD+CRC
SOJG R,EIPKTM
CAME A,[4100000] ;HW-TYPE=0001 (ETH), SW-TYPE=0800 (IP)
JRST EIPKT ;NO, FLUSH
CAME I,[ETHUS3_4] ;IS THE DST-IA MINE (MAINLY FOR ARP-REQ) ?
JRST EIPKT ;NO, FLUSH
CAMN B,[14020000020] ;06, 04, 0001 (ARP-REQ)
PUSHJ P,ARPIRQ
CAMN B,[14020000040] ;06, 04, 0002 (ARP-ACK)
PUSHJ P,ARPIAK
JRST EIPKT
;CHECK FOR IP (V4) PKTS AND PROCESS THEM
EIPKT3: CAME A,[20000000000] ;ETHTYPE IP (HEX 0800) ?
JRST EIPKT6
CAIGE R,20. ;ENOUGH FOR THE IP HDR ?
JRST EIPKT6 ;NO, FLUSH
SUBI R,12. ;WORDS 0-2 TO C/D/E
DATAI ETH+4*10+4*2,C ;CHOSEN BECAUSE IPGIPT USES A/B
DATAI ETH+4*10+4*2,D
DATAI ETH+4*10+4*2,E
IFN CHETHP,[
;AN IP PKT WITH A PROTOCOL TYPE OF CHAOS, GETS SENT TO THE CHAOS CODE
LDB T,[241000,,E] ;CHAOS PKT ?
CAIN T,16.
JRST EIPKTA ;YES
]
IFN INETHP,[
;AN IP PKT; ALLOCATE A PKT BUF, COPY PKT TO BUF, SEND TO IP
;IPGIPT ONLY USES T/Q, SO THE OLD LEVEL CAN BE HELD IN TT OVER THE CALL
;PKQGF/PKBAL LOOK LIKE THEY PROTECT THEMSELVES, SO IS THIS NEEDED ?
;IPRDGM USES JUST ABOUT EVERYTHING, SO THE OLD PI LEVEL IS SAVED ON THE PDL
MOVE A,R ;A <- PKT LEN (WORDS)
ADDI A,12.+3. ;12. BECAUSE 3. WORDS ALREADY READ
LSH A,-2
CONI PI,TT ;TT <- SPL(NETLVL)
CONO PI,NETOFF
PUSHJ P,IPGIPT ;A <- IP PKT BUF (USES B, T, Q)
MOVEI A,0 ;A <- 0 ON FAILURE (RTN+1)
ANDI TT,177 ;SPLX(TT)
CONO PI,PICON(TT)
JUMPE A,EIPKT6 ;NO PKT BUF, FLUSH
HRRZ T,PK.BUF(A) ;MOVE THE 3 WORDS ALREADY READ
MOVEM C,0(T) ;INTO THE IP PKT BUF
MOVEM D,1(T)
MOVEM E,2(T)
MOVE B,R ;B <- WORDS (AOBJN)
LSH B,-2
MOVN B,B
HRLZ B,B
HRRI B,3(T)
MOVE C,R ;C <- BYTES (0 - 3)
ANDI C,3
JUMPGE B,EIPKT5
EIPKT4: DATAI ETH+4*10+4*2,(B) ;READ WORDS
AOBJN B,EIPKT4
EIPKT5: XCT EIPKT8(C) ;READ FINAL 0-3 BYTES
DATAI ETH+4*10+4*2,T ;FLUSH 4 BYTE CRC
MOVE B,R ;B <- PKT LEN (WORDS)
ADDI B,12.+3. ;12. BECAUSE 3. WORDS ALREADY READ
LSH B,-2
MOVEI C,0 ;C <- IP HDR OFFS INTO PKT
CONI PI,T ;PUSH(SPL(NETLVL))
PUSH P,T
CONO PI,NETOFF
PUSHJ P,IPRDGM ;SEND PKT TO IP STACK
POP P,T ;SPLX(POP())
ANDI T,177
CONO PI,PICON(T)
JRST EIPKT
]
;FLUSH UNKNOWN OR MALFORMED PKT (R = DATA LEN IN FIFO)
EIPKT6: ADDI R,1.+4. ;R <- # OF 16-BIT WORDS (DATA + CRC)
LSH R,-1
EIPKT7: DATAI ETH+4*2,T ;FLUSH DATA + CRC
SOJG R,EIPKT7
JRST EIPKT
;XCT EIPKT8(C) TO READ THE FINAL 0-3 BYTES OF IP OR NORMAL-CHAOS PKT
EIPKT8: JFCL ;0
DATAI ETH+4*2,(B) ;1, READ 2, 0XXX
DATAI ETH+4*2,(B) ;2, READ 2, 01XX
DATAI ETH+4*10+4*2,(B) ;3, READ 4, 012X
;RETURN THROUGH HERE
EIPKT9: POPJ P,
IFN CHETHP,[
;A CHAOS-IN-IP PKT; ALLOCATE A PKT BUF, COPY PKT TO BUF, SEND TO CHAOS
;NO FRAGS BECAUSE 524 BYTES (20+16+488) IS LESS THAN 576 BYTES
;CHABGI PROTECTS ITSELF, SO THERE IS NO NEED TO HACK THE PI LEVELS AT THE CALL
;CHAPII USES JUST ABOUT EVERYTHING, SO THE OLD PI LEVEL IS SAVED ON THE PDL
EIPKTA: SUBI R,8. ;WORDS 3-4 TO I/J
DATAI ETH+4*10+4*2,I
DATAI ETH+4*10+4*2,J
PUSHJ P,EIPCS ;TT <- IP CHECKSUM OF C/D/E/I/J
JUMPN TT,EIPKT6 ;NOT 0, FLUSH
LDB T,[400400,,C] ;IF NOT IP (V4), FLUSH
CAIE T,4
JRST EIPKT6
;BROADCASTS CAN BE IGNORED BECAUSE CURRENTLY NOBODY SENDS THEM ON CHAOS
; CAMN J,[<ETHUS3\<NM%ETH#37777777777>>_4]
; JRST EIPKTB
; CAMN J,[37777777777_4]
; JRST EIPKTB
CAME J,[ETHUS3_4] ;IS THIS SENT TO ME ?
JRST EIPKT6 ;NO, FLUSH
EIPKTB: LDB T,[041600,,D] ;IF FRAG, FLUSH
JUMPN T,EIPKT6
LDB T,[340400,,C] ;IP HEADER LENGTH
SUBI T,5.
JUMPL T,EIPKT6 ;<5 => BAD HDR, FLUSH
JUMPE T,EIPKTD ;=5 => NO OPTIONS
MOVE TT,T
LSH TT,2
CAMGE R,TT ;ARE THE OPTION WORDS THERE ?
JRST EIPKT6 ;NO, FLUSH
SUB R,TT
EIPKTC: DATAI ETH+4*10+4*2,TT ;EAT OPTION WORDS
SOJG T,EIPKTC
EIPKTD: CAIL R,4*%CPKDT ;LEGAL PKT SIZE ?
CAILE R,<4*%CPKDT>+%CPMXC
JRST EIPKT6 ;NO, FLUSH
PUSHJ P,CHABGI ;A <- CH PKT BUF FROM FREE LIST
JRST EIPKT6 ;NONE, FLUSH
SUBI R,4*%CPKDT
DATAI ETH+4*14+4*2,0(A) ;READ IN PKT HDR, ALWAYS BYTE-SWAPPED
DATAI ETH+4*14+4*2,1(A)
DATAI ETH+4*14+4*2,2(A)
DATAI ETH+4*14+4*2,3(A)
MOVE B,R ;B <- AOBJN WORD, 4-BYTE CHUNKS
LSH B,-2
MOVN B,B
HRLZ B,B
HRRI B,%CPKDT(A)
MOVE C,R ;C <- 0-3 BYTES AT THE END
ANDI C,3
PUSHJ P,CHSWAB ;READ PKT IN BYTE-SWAPPED MODE ?
JRST EIPKTG ;RTN+1 => NO, RTN+2 => YES
JUMPGE B,EIPKTF ;READ PKT, BYTE-SWAPPED MODE
EIPKTE: DATAI ETH+4*14+4*2,(B)
AOBJN B,EIPKTE
EIPKTF: XCT EIPKTK(C)
JRST EIPKTJ
EIPKTG: JUMPGE B,EIPKTI ;READ PKT, NORMAL MODE
EIPKTH: DATAI ETH+4*10+4*2,(B)
AOBJN B,EIPKTH
EIPKTI: XCT EIPKT8(C)
EIPKTJ: DATAI ETH+4*10+4*2,T ;FLUSH 4 BYTE CRC
;FLUSH PKT IF SA IS NOT KNOWN, MAKING IT IMPOSSIBLE TO EVER TALK BACK
;ADDING AN NEW ENTRY TO THE ECHCA->ECHIA TABLE MIGHT BE A BETTER THING TO DO
LDB T,[$CPKSA(A)]
MOVSI TT,-NECHCA
EIPKTN: CAME T,ECHCA(TT) ;IS THIS SA KNOWN ?
AOBJN TT,EIPKTN
JUMPL TT,EIPKTO ;YES
PUSHJ P,ECHFR ;FLUSH PKT
JRST EIPKT
;WE KNOW WE CAN TALK BACK, SO SEND THE PKT TO THE CHAOS STACK
EIPKTO: CONI PI,T ;PUSH(SPL(NETLVL))
PUSH P,T
CONO PI,NETOFF
PUSHJ P,CHAPII ;SEND PKT TO CHAOS
POP P,T ;SPLX(POP())
ANDI T,177
CONO PI,PICON(T)
JRST EIPKT
;XCT EIPKTK(C) TO READ THE FINAL 0-3 BYTES OF BYTE-SWAPPED CHAOS PKT
EIPKTK: JFCL ;0
DATAI ETH+4*2,(B) ;1, READ 2, 0XXX
DATAI ETH+4*4+4*2,(B) ;2, READ 2, 10XX
PUSHJ P,EIPKTL ;3, READ 4, 10X2 -> 102X
EIPKTL: DATAI ETH+4*14+4*2,(B)
LDB T,[041000,(B)] ;THIS ISN'T VERY EFFICIENT, BUT
DPB T,[141000,(B)] ;IT'S ALSO VERY UNCOMMON
POPJ P,
]
;CALLED (ETHBRK) WHEN THE OUTPUT SIDE IS IDLE TO ENSURE THAT
;THE OUTPUT SIDE IS RUNNING IF THERE IS ACTUALLY SOMETHING THAT CAN BE OUTPUT
;CHAOS PKTS ARE PROCESSED USING DO-IT-YOURSELF INET CODE BECAUSE IT'S
;LEGAL TO CONFIGURE CHAOS WITHOUT CONFIGURING INET.
;THIS ROUTINE CAN SMASH ALL THE ACS BECAUSE IT'S REALLY JUST A PART OF ETHBRK.
;CHECK IF THERE IS AN ARP-ACK THAT NEEDS TO BE SENT
EOPKT: PUSHJ P,ARPOAK ;IS THERE AN ARP-ACK TO OUTPUT ?
JRST EOPKT0 ;NO
DATAO ETH+4*1,[004270,,0] ;S0_TX_FIFOR
DATAO ETH+4*10+4*2,D ;DST ETH ADDR (REMOTE)
DATAO ETH+4*2,E
DATAO ETH+4*10+4*2,[ETHEA0] ;SRC ETH ADDR (ME)
DATAO ETH+4*2,[ETHEA1]
DATAO ETH+4*2,[20030000000] ;0806 (ARP)
DATAO ETH+4*10+4*2,[4100000] ;0001 (ETH), 0800 (IP)
DATAO ETH+4*10+4*2,[14020000040];06, 04, 0002 (ARP-ACK)
DATAO ETH+4*10+4*2,[ETHEA0] ;SRC ETH/IP ADDRS (ME)
DATAO ETH+4*2,[ETHEA1]
DATAO ETH+4*10+4*2,[ETHUS3_4]
DATAO ETH+4*10+4*2,D ;DST ETH/IP ADDRS (REMOTE)
DATAO ETH+4*2,E
DATAO ETH+4*10+4*2,C
MOVEI R,12.+2.+28. ;SEND PKT
JRST EOPKTS
;CHECK IF THERE IS AN ARP-REQ THAT NEEDS TO BE SENT (RE-SENT)
EOPKT0: PUSHJ P,ARPORQ ;IS THERE AN ARP-REQ TO OUTPUT ?
JRST EOPKT1 ;NO
DATAO ETH+4*1,[004270,,0] ;S0_TX_FIFOR
DATAO ETH+4*10+4*2,[EBCEA0] ;DST ETH ADDR (BROADCAST)
DATAO ETH+4*2,[EBCEA1]
DATAO ETH+4*10+4*2,[ETHEA0] ;SRC ETH ADDR (ME)
DATAO ETH+4*2,[ETHEA1]
DATAO ETH+4*2,[20030000000] ;0806 (ARP)
DATAO ETH+4*10+4*2,[4100000] ;0001 (ETH), 0800 (IP)
DATAO ETH+4*10+4*2,[14020000020];06, 04, 0001 (ARP-REQ)
DATAO ETH+4*10+4*2,[ETHEA0] ;SRC ETH/IP ADDRS (ME)
DATAO ETH+4*2,[ETHEA1]
DATAO ETH+4*10+4*2,[ETHUS3_4]
DATAO ETH+4*10+4*2,[0] ;DST ETH/IP ADDRS (IA=REMOTE, EA=0)
DATAO ETH+4*2,[0]
DATAO ETH+4*10+4*2,C
MOVEI R,12.+2.+28. ;SEND PKT
JRST EOPKTS
;GET A PACKET TO WORK ON, EITHER SAVED FROM LAST TIME, OR FRESH FROM AN XMQ
;IPGXMQ/CHGXMQ ONLY USE T/Q, SO THE OLD LEVEL CAN BE HELD IN TT OVER THE CALL
EOPKT1: SKIPN A,EOSAV ;A <- SAVED PKT
JRST EOPKT2 ;NONE
SETZM EOSAV
SKIPGE B,EOCHS ;B <- SAVED PKT TYPE (<0 CHAOS, >=0 IP)
JRST EOPKT7 ;CHAOS
JRST EOPKT4 ;IP
EOPKT2: CONI PI,TT ;TT <- SPL(NETLVL)
CONO PI,NETOFF
IFN INETHP,[
PUSHJ P,IPGXMQ ;A <- PKT FROM IPXMQ
MOVEI B,0 ;B <- IP (>=0)
JUMPN A,EOPKT3
]
IFN CHETHP,[
PUSHJ P,CHGXMQ ;A <- PKT FROM CHXMQ
MOVNI B,1 ;B <- CHAOS (<0)
JUMPN A,EOPKT3
]
MOVEI A,0 ;A <- NO PKT
EOPKT3: ANDI TT,177 ;SPLX(TT)
CONO PI,PICON(TT)
JUMPE A,EOPKTX ;NO PKT, RETURN
SKIPGE B
JRST EOPKT7 ;CHAOS
IFE INETHP,[
;WE HAVE AN IP PKT, BUT INETHP ISN'T TRUE. CAN'T HAPPEN.
EOPKT4: BUG HALT,[EOPKT-INETHP]
]
IFN INETHP,[
;LOOK UP THE IP IA->EA MAPPING USING ARP
;INET SHOULD HAVE ARRANGED THAT PK.DST(A) IS ON THE LOCAL NET,
;BUT IF IT ISN'T, USE THE GATEWAY (DON'T DISCARD THE PKT OR CRASH THE SYSTEM)
EOPKT4: MOVE T,PK.DST(A) ;T <- DST IA (SW FMT)
MOVE C,T ;C <- HOP IA (DIRECT, HW FMT)
LSH C,4
GETNET T ;T <- NET #
CAME T,[ETHUS3&NM%ETH] ;CHECK IF SAME NET # AS ME
MOVE C,[ETHGW3_4] ;C <- HOP IA (INDIRECT VIA GW, HW FMT)
PUSHJ P,ARPFND ;QUERY IA->EA MAPPING
JRST EOPKTL ;NOT FOUND, SEND ARP-REQ
JRST EOPKTK ;FOUND, BUT MAPPING NOT VALID YET
JUMPN D,EOPKT5 ;FOUND, SEND IF EA NOT 0/0
JUMPN E,EOPKT5
PUSHJ P,EIPFR ;FREE PKT
JRST EOPKT
;SEND A PKT FOR IP, A IS PKT, C IS HOP IA, D/E IS HOP EA0/EA1
EOPKT5: DATAO ETH+4*1,[004270,,0] ;S0_TX_FIFOR
DATAO ETH+4*10+4*2,D ;DST EA
DATAO ETH+4*2,E
DATAO ETH+4*10+4*2,[ETHEA0] ;SRC EA
DATAO ETH+4*2,[ETHEA1]
DATAO ETH+4*2,[20000000000] ;0800 (IP)
HLRZ R,PK.BUF(A) ;R <- # OF 4-BYTE CHUNKS (>=5)
MOVN B,R ;B <- AOBJN WORD (IN 4-BYTE CHUNKS)
HRLZ B,B
HRR B,PK.BUF(A)
EOPKT6: DATAO ETH+4*10+4*2,(B) ;COPY PKT INTO FIFO
AOBJN B,EOPKT6
PUSHJ P,EIPFR ;FREE PKT
LSH R,2 ;R <- # OF BYTES
ADDI R,12.+2.
JRST EOPKTS
]
IFE CHETHP,[
;WE HAVE A CHAOS PKT, BUT CHETHP ISN'T TRUE. CAN'T HAPPEN.
EOPKT7: BUG HALT,[EOPKT-CHETHP]
]
IFN CHETHP,[
;IF THE PKT IS A BRD YOU CAN'T JUST MAP IT'S DA, BUT SINCE NOBODY REALLY
;USES BRD PKTS, IT'S OK TO JUST THROW THEM AWAY (A BETTER IMPLEMENTATION MIGHT
;LOOP OVER THE ECHCA/ECHIA, AND DO THE APPROPRIATE UNICASTS)
EOPKT7: LDB T,[$CPKOP(A)] ;BRD PKT ?
CAIN T,%COBRD
JRST EOPKT9 ;YES, FLUSH
;LOOKUP THE CHAOS CA->IA->EA MAPPING USING THE ECHCA/ECHIA TABLES AND ARP
LDB T,[$CPKDA(A)]
MOVSI TT,-NECHCA
EOPKT8: CAME T,ECHCA(TT) ;SEARCH THE ECHCA TABLE
AOBJN TT,EOPKT8
JUMPGE TT,EOPKT9 ;NOT FOUND, FLUSH
MOVE T,ECHIA(TT) ;T <- DST IA (SW FMT)
MOVE J,T ;J <- DST IA (HW FMT)
LSH J,4
MOVE C,J ;C <- HOP IA (DIRECT, HW FMT)
GETNET T ;T <- NET #
CAME T,[ETHUS3&NM%ETH] ;CHECK IF SAME NET # AS ME
MOVE C,[ETHGW3_4] ;C <- HOP IA (INDIRECT VIA GATEWAY, HW FMT)
PUSHJ P,ARPFND ;HOP IA -> EA
JRST EOPKTL ;NOT FOUND, SEND ARP-REQ
JRST EOPKTK ;FOUND, BUT MAPPING NOT VALID YET
JUMPN D,EOPKTA ;FOUND, SEND IF EA NOT 0/0
JUMPN E,EOPKTA
EOPKT9: PUSHJ P,ECHFR ;FREE PKT
JRST EOPKT
;SEND A PKT FOR CHAOS, A IS PKT, J IS DST IA, C IS HOP IA, D/E IS HOP EA0/EA1
EOPKTA: DATAO ETH+4*1,[004270,,0] ;S0_TX_FIFOR
DATAO ETH+4*10+4*2,D ;DST EA
DATAO ETH+4*2,E
DATAO ETH+4*10+4*2,[ETHEA0] ;SRC EA
DATAO ETH+4*2,[ETHEA1]
DATAO ETH+4*2,[20000000000] ;0800 (IP)
LDB R,[$CPKNB(A)] ;R <- # OF BYTES OF DATA
CAILE R,%CPMXC ;MAKE SURE IT'S NOT TOO LONG
MOVEI R,%CPMXC
;BUILD 5-WORD IP HDR IN C/D/E/I/J, CHECKSUM IT, AND COPY IT INTO TX FIFO
;NOTE THAT J IS DST IA, AND SO WORD 4 OF THE IP HDR IS ALREADY IN THE RIGHT PLACE
MOVE I,[ETHUS3_4] ;WORD 3, SRC IA
MOVSI E,200100 ;WORD 2, TTL=64, CHAOS, CS=0
MOVSI D,000001 ;WORD 1, DF=1
MOVE C,R ;WORD 0, IPV4, 5-WORDS, LEN
ADDI C,20.+16.
LSH C,4
TLO C,212000
PUSHJ P,EIPCS ;COMPUTE CHECKSUM
DPB TT,[042000,,E] ;PUT CHECKSUM IN WORD 2
DATAO ETH+4*10+4*2,C ;COPY INTO TX FIFO
DATAO ETH+4*10+4*2,D
DATAO ETH+4*10+4*2,E
DATAO ETH+4*10+4*2,I
DATAO ETH+4*10+4*2,J
;COPY CHAOS HDR (BYTE-SWAPPED) AND DATA (NORMAL, BYTE-SWAPPED) INTO TX FIFO
DATAO ETH+4*14+4*2,0(A) ;HDR, BYTE-SWAPPED
DATAO ETH+4*14+4*2,1(A)
DATAO ETH+4*14+4*2,2(A)
DATAO ETH+4*14+4*2,3(A)
MOVE B,R ;B <- AOBJN WORD, 4-BYTE WORDS
LSH B,-2
MOVN B,B
HRLZ B,B
HRRI B,%CPKDT(A)
MOVE C,R ;C <- END, 0-3 BYTES
ANDI C,3
PUSHJ P,CHSWAB ;WRITE DATA IN BYTE-SWAPPED MODE ?
JRST EOPKTD ;RTN+1 NO, RTN+2 YES
JUMPGE B,EOPKTC ;WRITE DATA, BYTE-SWAPPED MODE
EOPKTB: DATAO ETH+4*14+4*2,(B)
AOBJN B,EOPKTB
EOPKTC: XCT EOPKTH(C)
JRST EOPKTG
EOPKTD: JUMPGE B,EOPKTF ;WRITE DATA, NORMAL MODE
EOPKTE: DATAO ETH+4*10+4*2,(B)
AOBJN B,EOPKTE
EOPKTF: XCT EOPKTJ(C)
EOPKTG: PUSHJ P,ECHFR ;FREE PKT
ADDI R,12.+2.+20.+16.
JRST EOPKTS
;XCT EOPKTH(C) TO WRITE THE FINAL 0-3 BYTES OF DATA IN BYTE-SWAPPED MODE
EOPKTH: JFCL ;0
DATAO ETH+4*2,(B) ;1, WRITE 2, 0XXX
DATAO ETH+4*4+4*2,(B) ;2, WRITE 2, 10XX
PUSHJ P,EOPKTI ;3, WRITE 4, 102X -> 10X2
EOPKTI: LDB T,[141000,(B)]
DPB T,[041000,(B)]
DATAO ETH+4*14+4*2,(B)
POPJ P,
;XCT EOPKTJ(C) TO WRITE THE FINAL 0-3 BYTES OF DATA IN NORMAL MODE
EOPKTJ: JFCL ;0
DATAO ETH+4*2,(B) ;1, WRITE 2, 0XXX
DATAO ETH+4*2,(B) ;2, WRITE 2, 01XX
DATAO ETH+4*10+4*2,(B) ;3, WRITE 4, 012X
]
;AN ARP-REQ IS ALREADY IN FLIGHT
EOPKTK: MOVEM A,EOSAV ;SAVE PKT FOR NEXT TIME WE ARE HERE
MOVEM B,EOCHS
JRST EOPKTX
;WE KNOW NOTHING ABOUT THIS IA, START GETTING AN IA->EA MAPPING
EOPKTL: MOVEM A,EOSAV ;SAVE PKT FOR NEXT TIME WE ARE HERE
MOVEM B,EOCHS
PUSHJ P,ARPADD ;MAKE AN ENTRY IN THE ARP TABLE
JRST EOPKTX ;CAN'T, TRY AGAIN LATER
DATAO ETH+4*1,[004270,,0] ;S0_TX_FIFOR
DATAO ETH+4*10+4*2,[EBCEA0] ;DST ETH ADDR (BROADCAST)
DATAO ETH+4*2,[EBCEA1]
DATAO ETH+4*10+4*2,[ETHEA0] ;SRC ETH ADDR (ME)
DATAO ETH+4*2,[ETHEA1]
DATAO ETH+4*2,[20030000000] ;0806 (ARP)
DATAO ETH+4*10+4*2,[4100000] ;0001 (ETH), 0800 (IP)
DATAO ETH+4*10+4*2,[14020000020];06 (HW LEN), 04 (SW LEN), 0001 (REQ)
DATAO ETH+4*10+4*2,[ETHEA0] ;SRC ETH/IP ADDRS (ME)
DATAO ETH+4*2,[ETHEA1]
DATAO ETH+4*10+4*2,[ETHUS3_4]
DATAO ETH+4*10+4*2,[0] ;DST ETH/IP ADDRS (IA=REMOTE, EA=0)
DATAO ETH+4*2,[0]
DATAO ETH+4*10+4*2,C
MOVEI R,12.+2.+28. ;SEND PKT
;SEND A PKT. THE DATA IS IN THE TX FIFO. THE LEN IS IN R.
EOPKTS: DATAO ETH+4*1,[004200,,0] ;S0_TX_WRSR0:S0_TX_WRSR2 <- 0:LEN
DATAO ETH+4*2,[0]
DATAO ETH+4*1,[004210,,0]
LSH R,20.
DATAO ETH+4*2,R
DATAO ETH+4*1,[004010,,0] ;S0_CR <- SEND
DATAO ETH+4*2,[000200,,0]
SETOM EOBSY ;MARK OUTPUT SIDE AS BUSY
;EVERYTHING COMES HERE TO RESTORE AND RETURN
EOPKTX: POPJ P,
IFN CHETHP,[
;CALLED TO PUT THE IP CHECKSUM OF C/D/E/I/J (AN IP HDR) INTO TT
;THE WORDS IN C/D/E/I/J ARE IN HW FMT, BUT ARE CONVERTED TO SW FMT BEFORE THEY GET
;ADDED INTO THE CHECKSUM, SO THAT CARRIES CAN PILE UP IN BITS 00..03
EIPCS: MOVE TT,C ;WORD 0
LSH TT,-4
MOVE T,D ;WORD 1
LSH T,-4
ADD TT,T
MOVE T,E ;WORD 2
LSH T,-4
ADD TT,T
MOVE T,I ;WORD 3
LSH T,-4
ADD TT,T
MOVE T,J ;WORD 4
LSH T,-4
EIPCS0: ADD TT,T
CAIG TT,177777 ;FOLD INTO LO HALF
JRST EIPCS1
MOVE T,TT
LSH T,-16. ;HI HALF + CARRIES
ANDI TT,177777 ;LO HALF
JRST EIPCS0
EIPCS1: XORI TT,177777 ;FINAL 1'S COMPLEMENT
POPJ P,
]