A2osX/LIB/LIBTCPIP.S.ARP.txt
2016-01-16 23:04:22 +01:00

356 lines
6.6 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

PR#3
PREFIX /A2OSX.SRC
NEW
INC 1
AUTO 6
.LIST OFF
*--------------------------------------
ARP.IN >PULLW ZPFrameBase1
>PULLW ZPFrameLen1
ldy #S.ARP.TPA
ldx #S.IPCFG.IP
.1 lda (ZPFrameBase1),y
cmp IPCFG,x
bne .9
iny
inx
cpx #S.IPCFG.IP+4
bne .1
ldy #S.ARP.OPERATION+1 HI byte
lda (ZPFrameBase1),y
cmp #S.ARP.OPERATION.REQ
beq ARP.IN.REQ
cmp #S.ARP.OPERATION.REP
beq ARP.IN.REP
.9 clc Discard any other ARP frames
rts
ARP.IN.REP >LDAXI S.ARP.SHA
jsr SetFramePtr1AX
>PUSHW ZPFramePtr1
>LDAXI S.ARP.SPA
jsr SetFramePtr1AX
>PUSHW ZPFramePtr1
jsr ARP.ADD
clc
ARP.IN.RTS rts
ARP.IN.REQ jsr NEW.ARP.FRAME
bcs ARP.IN.RTS
phx
>STYA ZPFrameBase2
ldy #S.ARP.OPERATION+1
lda #S.ARP.OPERATION.REP
sta (ZPFrameBase2),y
>LDAXI S.ARP.SHA
jsr SetFramePtr1AX
>LDAXI S.ETH.DSTMAC
jsr SetFramePtr2AX
ldy #6
jsr CopyFramePtr12
>LDAXI S.ARP.THA
jsr SetFramePtr2AX
ldy #10 IP(4) + MAC(6)
jsr CopyFramePtr12
>PUSHW ZPFramePtr1 still point to SHA
>LDAXI S.ARP.SPA
jsr SetFramePtr1AX
>PUSHW ZPFramePtr1
jsr ARP.ADD
ldx #5
ldy #S.ARP.SHA+5
.4 lda IPCFG+S.IPCFG.MAC,x
sta (ZPFrameBase2),y
dey
dex
bpl .4
ldx #3
ldy #S.ARP.SPA+3
.5 lda IPCFG+S.IPCFG.IP,x
sta (ZPFrameBase2),y
dey
dex
bpl .5
>PUSHW ZPFrameBase2
jsr SEND.ARP.FRAME
pla
>SYSCALL SYS.FreeMemA
clc
rts
*--------------------------------------
* ARP.CLEAR
*--------------------------------------
ARP.CLEAR ldx #K.ARPCACHE.SIZE*S.ARPCACHE
.1 stz ARP.CACHE-1,x
dex
bne .1
clc
rts
*--------------------------------------
* ARP.QUERY
* In:
* PULLW PTR to IP
* PULLW PTR to MAC (to fill)
* Out:
* CC: hit: MAC filled
* CS: missed
*--------------------------------------
ARP.QUERY >PULLW ZPPtrIP IP
>PULLW ZPPtrMAC MAC
jmp ARP.QUERY.I
*--------------------------------------
* ARP.ADD
* In:
* PULLW PTR to IP
* PULLW PTR to MAC
*--------------------------------------
ARP.ADD >PULLW ZPPtrIP IP
>PULLW ZPPtrMAC MAC
lda #S.ARPCACHE.STATUS.RESOLVED
jmp ARP.ADD.I
*--------------------------------------
* ARP.GETCACHE
* Out:
* Y,A = PTR to ARP.CACHE
*--------------------------------------
ARP.GETCACHE >LDYA L.ARP.CACHE
clc
rts
*--------------------------------------
* PRIVATE
*--------------------------------------
ARP.RESOLVE ldy #S.IP.DST
lda (ZPFrameBase1),y
iny
.1 and (ZPFrameBase1),y
iny
cpy #S.IP.DST+4
bne .1
cmp #$FF
bne .3 not a broadcast....
ldy #S.ETH.DSTMAC
.2 sta (ZPFrameBase1),y
iny
cpy #S.ETH.DSTMAC+6
bne .2
clc
rts
.3 ldy #S.IP.DST+3
ldx #3
.4 lda (ZPFrameBase1),y
eor IPCFG+S.IPCFG.IP,x
and IPCFG+S.IPCFG.MASK,x
bne .5
dey
dex
bpl .4
lda ZPFrameBase1 Same network, query ARP for dest IP
clc
adc #S.IP.DST
sta ZPPtrIP
lda ZPFrameBase1+1
adc /S.IP.DST
sta ZPPtrIP+1
bra .6
.5 lda L.IPCFG Not Same network, query ARP for GW
clc
adc #S.IPCFG.GW
sta ZPPtrIP
lda L.IPCFG+1
adc /S.IPCFG.GW
sta ZPPtrIP+1
.6 lda ZPFrameBase1
clc
adc #S.ETH.DSTMAC
sta ZPPtrMAC
lda ZPFrameBase1+1
adc /S.ETH.DSTMAC
sta ZPPtrMAC+1
*--------------------------------------
ARP.QUERY.I ldx #0
.1 phx
lda ARP.CACHE,x
beq .5 empty ARP Cache entry, try next...
ldy #0
.2 lda ARP.CACHE+S.ARPCACHE.IP,x
cmp (ZPPtrIP),y
bne .5 wrong IP, try next...
inx
iny
cpy #4
bne .2
plx
lda ARP.CACHE,x get back status
bpl .4 Pending...
ldy #0 already resolved, get MAC
.3 lda ARP.CACHE+S.ARPCACHE.MAC,x
sta (ZPPtrMAC),y
inx
iny
cpy #6
bne .3
clc
rts
.4 inc ARP.CACHE+S.ARPCACHE.RETRYCNT,x Pending, increase Retry Count
bne .41
stz ARP.CACHE,x reached max retry,mark as free
.41 sec
rts
.5 pla
clc
adc #S.ARPCACHE
tax
cmp #K.ARPCACHE.SIZE*S.ARPCACHE
bne .1
jsr NEW.ARP.FRAME nothing in ARP cache, send ARP request
bcs .9
phx
ldy #S.ARP.OPERATION+1
lda #S.ARP.OPERATION.REQ
sta (ZPFrameBase1),y
ldx #5
ldy #S.ARP.SHA+5
.71 lda IPCFG+S.IPCFG.MAC,x
sta (ZPFrameBase1),y
dey
dex
bpl .71
ldx #3
ldy #S.ARP.SPA+3
.72 lda IPCFG+S.IPCFG.IP,x
sta (ZPFrameBase1),y
dey
dex
bpl .72
ldy #3
.73 lda (ZPPtrIP),y
pha
dey
bpl .73
ldy #S.ARP.TPA
.74 pla
sta (ZPFrameBase1),y
iny
cpy #S.ARP.TPA+4
bne .74
lda #255
ldy #S.ETH.DSTMAC
.75 sta (ZPFrameBase1),y
iny
cpy #S.ETH.DSTMAC+6
bne .75
jsr SEND.ARP.FRAME.I
bcs .76
jsr ARP.ADD.PENDING ZPARPIP still pointing IP
.76 pla
>SYSCALL SYS.FreeMemA
sec
.9 rts
*--------------------------------------
ARP.ADD.PENDING lda #S.ARPCACHE.STATUS.PENDING
ARP.ADD.I sta Status
ldx #0
.1 lda ARP.CACHE,x get status
beq .7 empty ARP cache entry
phx
ldy #0
.2 lda (ZPPtrIP),y
cmp ARP.CACHE+S.ARPCACHE.IP,x
bne .4
inx
iny
cpy #4
bne .2
plx
bra .7 same IP,update MAC
.4 pla get back index in ARP.CACHE
clc
adc #S.ARPCACHE
cmp #K.ARPCACHE.SIZE*S.ARPCACHE
beq .5 Cache is full ?
tax
bra .1
.5 ldx #K.ARPCACHE.SIZE*S.ARPCACHE-S.ARPCACHE
.6 lda ARP.CACHE+S.ARPCACHE-1,x
sta ARP.CACHE-1,x
dex
bne .6
ldx #K.ARPCACHE.SIZE*S.ARPCACHE-S.ARPCACHE
.7 lda Status
sta ARP.CACHE,x mark ARP entry Status
inx
stz ARP.CACHE,x Init retry count
inx
ldy #0
.8 lda (ZPPtrIP),y store IP in cache
sta ARP.CACHE,x
inx
iny
cpy #4
bne .8
lda Status
bpl .82 no MAC if "pending"
ldy #0
.81 lda (ZPPtrMAC),y store MAC in cache
sta ARP.CACHE,x
inx
iny
cpy #6
bne .81
.82 clc
rts
*--------------------------------------
MAN
SAVE LIB/LIBTCPIP.S.ARP
LOAD LIB/LIBTCPIP.S
ASM