PR#3 PREFIX /DATA/A2OSX 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