A2osX/LIB/LIBTCPIP.S.ARP.txt

267 lines
5.0 KiB
Plaintext
Raw Normal View History

2015-03-14 21:48:35 +00:00
PR#3
2015-03-15 22:00:40 +00:00
PREFIX /A2OSX.BUILD
2015-03-14 21:48:35 +00:00
NEW
INC 1
AUTO 6
.LIST OFF
.OP 65C02
*--------------------------------------
* 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 ZPARPIP IP
>PULLW ZPARPMAC MAC
jmp ARP.QUERY.I
*--------------------------------------
* ARP.ADD
* In:
* PULLW PTR to IP
* PULLW PTR to MAC
*--------------------------------------
ARP.ADD >PULLW ZPARPIP IP
>PULLW ZPARPMAC 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 ZPARPIP
lda ZPFrameBase1+1
adc /S.IP.DST
sta ZPARPIP+1
bra .6
.5 lda L.IPCFG Not Same network, query ARP for GW
clc
adc #S.IPCFG.GW
sta ZPARPIP
lda L.IPCFG+1
adc /S.IPCFG.GW
sta ZPARPIP+1
.6 lda ZPFrameBase1
clc
adc #S.ETH.DSTMAC
sta ZPARPMAC
lda ZPFrameBase1+1
adc /S.ETH.DSTMAC
sta ZPARPMAC+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 (ZPARPIP),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 (ZPARPMAC),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 (ZPARPIP),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 (ZPARPIP),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 (ZPARPIP),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 (ZPARPMAC),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