NEW AUTO 3,1 .LIST OFF .OP 65C02 .OR $2000 .TF bin/ping *-------------------------------------- .INB INC/MACROS.I .INB INC/A2OSX.I .INB INC/ETH.I .INB INC/LIBTCPIP.I *-------------------------------------- TIMEOUT.MAX .EQ 100 10 sec. *-------------------------------------- .DUMMY .OR ZPBIN ZS.START ZPIPCfgPtr .BS 2 ZPTmpPtr .BS 2 Identifier .BS 2 Sequence .BS 2 TimeOut.ms .BS 2 ArgIndex .BS 1 ArgHostName .BS 1 hSocket .BS 1 hFrame .BS 1 PingCount .BS 1 TimeOut .BS 1 IP.Remote .BS 4 ZS.END .ED *-------------------------------------- * File Header (16 Bytes) *-------------------------------------- CS.START cld jmp (.1,x) .DA #$61 6502,Level 1 (65c02) .DA #1 BIN Layout Version 1 .DA #S.PS.F.EVENT S.PS.F .DA #0 .DA CS.END-CS.START Code Size (without Constants) .DA DS.END-DS.START Data SegmentSize .DA #64 Stack Size .DA #ZS.END-ZS.START Zero Page Size .DA 0 *-------------------------------------- .1 .DA CS.INIT .DA CS.RUN .DA CS.DOEVENT .DA CS.QUIT L.LIBTCPIP .DA LIBTCPIP L.MSG.IPKO .DA MSG.IPKO L.MSG.USAGE .DA MSG.USAGE L.MSG.UNKNOWN .DA MSG.UNKNOWN L.MSG.HOSTOK .DA MSG.HOSTOK L.MSG.SKTKO .DA MSG.SKTKO L.MSG.REPLY .DA MSG.REPLY L.MSG.UNREACH .DA MSG.UNREACH .DA 0 *-------------------------------------- CS.INIT >LDYA L.LIBTCPIP >SYSCALL LoadLib bcs .9 sta hLIBTCPIP .9 rts *-------------------------------------- CS.RUN >LIBCALL hLIBTCPIP,LIBTCPIP.GETCFG is TCPIP loaded ? >STYA ZPIPCfgPtr lda (ZPIPCfgPtr) Configured ? bmi .1 >LDYA L.MSG.IPKO >SYSCALL puts lda #E.SYN sec rts .1 ldy #DATA.Len-1 .2 lda ICMP.Request,y sta (pData),y dey bpl .2 CS.RUN.IPOK inc ArgIndex lda ArgIndex >SYSCALL ArgV bcs .8 >STYA ZPTmpPtr lda (ZPTmpPtr) cmp #'-' bne .1 ldy #1 lda (ZPTmpPtr),y beq .9 cmp #'0' bcc .9 cmp #'9'+1 bcs .9 and #$0F sta PingCount bra CS.RUN.IPOK .1 lda #TIMEOUT.MAX sta Timeout .2 >PUSHEA.G SA.REMOTE+S.SOCKADDR.ADDR >PUSHW ZPTmpPtr >LIBCALL hLIBTCPIP,LIBTCPIP.HST.GETBYNAME bcc .3 >SLEEP lda Timeout bne .2 >PUSHW ZPTmpPtr >PUSHBI 2 >LDYA L.MSG.UNKNOWN bra .99 .3 lda ArgIndex sta ArgHostName bra CS.RUN.IPOK .8 >LDA.G SA.REMOTE+S.SOCKADDR.ADDR bne CS.RUN.ARGSOK .9 >PUSHBI 0 >LDYA L.MSG.USAGE .99 >SYSCALL printf lda #E.SYN sec rts CS.RUN.ARGSOK lda ArgHostName >SYSCALL ArgV >PUSHYA ldx #3 ldy #SA.REMOTE+S.SOCKADDR.ADDR+3 .1 lda (pData),y >PUSHA dey dex bpl .1 >PUSHBI 6 >LDYA L.MSG.HOSTOK >SYSCALL printf CS.RUN.OPENSKT ldx #3 ldy #S.IPCFG.IP+3 .1 lda (ZPIPCfgPtr),y sta IP.Remote,x dey dex bpl .1 ldx #3 ldy #SA.LOCAL+S.SOCKADDR.ADDR+3 .2 lda IP.Remote,x sta (pData),y dey dex bpl .2 lda A2OSX.RANDOM16 eor A2osX.TIMER16+1 >STA.G SA.LOCAL+S.SOCKADDR.PORT >STA.G SA.REMOTE+S.SOCKADDR.PORT sta Identifier lda A2OSX.RANDOM16+1 eor A2osX.TIMER16 >STA.G SA.LOCAL+S.SOCKADDR.PORT+1 >STA.G SA.REMOTE+S.SOCKADDR.PORT+1 sta Identifier+1 >PUSHBI S.IP.PROTOCOL.ICMP lda #S.SOCKET.T.RAW >LIBCALL hLIBTCPIP,LIBTCPIP.socket bcs .9 sta hSocket >PUSHEA.G SA.LOCAL lda hSocket >LIBCALL hLIBTCPIP,LIBTCPIP.Bind bcs .9 >PUSHEA.G SA.REMOTE lda hSocket >LIBCALL hLIBTCPIP,LIBTCPIP.Connect bcc CS.RUN.SEND.ECHO .9 >LDYA L.MSG.SKTKO >SYSCALL puts lda #E.SYN sec rts CS.RUN.SEND.ECHO >SLEEP lda Identifier >STA.G Request-S.IP+S.ICMP.IDENTIFIER+1 lda Identifier+1 dey sta (pData),y inc Sequence bne .1 inc Sequence+1 .1 lda Sequence >STA.G Request-S.IP+S.ICMP.SEQUENCE+1 lda Sequence+1 dey sta (pData),y >PUSHWI ICMP.RequestLen >PUSHW pData lda hSocket >LIBCALL hLIBTCPIP,LIBTCPIP.send bcs CS.RUN.ERR lda #TIMEOUT.MAX sta Timeout CS.RUN.WAIT.REPLY >SLEEP ldy #S.PS.hStdIn lda (pPS),y >SYSCALL feof bcs CS.RUN.ERR tay bne .1 >SYSCALL GetChar bcs CS.RUN.ERR cmp #3 Ctrl-C beq CS.RUN.ERR CS .1 lda hSocket >LIBCALL hLIBTCPIP,LIBTCPIP.Recv bcc .2 lda Timeout bne CS.RUN.WAIT.REPLY jsr CS.Print.UNREACH bcs CS.RUN.ERR bra .7 .2 sta hFrame >SYSCALL GetMemPtr >STYA ZPTmpPtr jsr CS.Print.REPLY bcs CS.RUN.ERR lda hFrame >SYSCALL FreeMem stz hFrame .7 lda PingCount beq .8 dec PingCount dec A=0 beq .80 .8 jmp CS.RUN.SEND.ECHO .80 sec CS.RUN.ERR rts *-------------------------------------- CS.DOEVENT lda (pEvent) bpl .9 is it a TIMER event? lda TimeOut beq .9 dec TimeOut .9 sec do not discard TIMER event rts *-------------------------------------- CS.Print.UNREACH ldx #3 ldy #SA.REMOTE+S.SOCKADDR.ADDR+3 .1 lda (pData),y >PUSHA dey dex bpl .1 >PUSHBI 4 >LDYA L.MSG.UNREACH >SYSCALL printf rts *-------------------------------------- CS.Print.REPLY lda #TIMEOUT.MAX sec sbc TimeOut stz TimeOut.ms stz TimeOut.ms+1 tax beq .3 .1 lda TimeOut.ms clc adc #100 sta TimeOut.ms bcc .2 inc TimeOut.ms+1 .2 dex bne .1 .3 >PUSHW TimeOut.ms ldy #S.IP.TTL >PUSHB (ZPTmpPtr),y ldy #S.ICMP.SEQUENCE >PUSHB (ZPTmpPtr),y iny >PUSHB (ZPTmpPtr),y ldx #4 ldy #S.IP.SRC+3 .4 >PUSHB (ZPTmpPtr),y dey dex bne .4 >PUSHBI 9 >LDYA L.MSG.REPLY >SYSCALL printf rts *-------------------------------------- CS.QUIT lda hFrame beq .1 >SYSCALL FreeMem .1 lda hSocket beq .2 >LIBCALL hLIBTCPIP,LIBTCPIP.Shutdown .2 lda hLIBTCPIP beq .8 >SYSCALL UnloadLib .8 clc rts *-------------------------------------- CS.END LIBTCPIP .AZ "libtcpip" MSG.IPKO .AZ "TCP/IP Not Loaded/Configured." MSG.USAGE .AS "Usage : PING \r\n" .AZ " -1-9 : Ping Count\r\n" MSG.UNKNOWN .AZ "%s: Unknown host\r\n" MSG.HOSTOK .AZ "PING %d.%d.%d.%d (%s)\r\n" MSG.SKTKO .AZ "Failed to Open Socket." MSG.UNREACH .AZ "%d.%d.%d.%d: TimeOut/Host unreachable\r\n" MSG.REPLY .AZ "32 bytes from %d.%d.%d.%d, icmp_seq=%D, ttl=%d, time=%D ms\r\n" hLIBTCPIP .BS 1 *-------------------------------------- ICMP.Request .DA #S.ICMP.TYPE.ECHOREQ .DA #0 CODE .DA 0 CHECKSUM .BS 2 ID .BS 2 DQ .AS "ABCDEFGHIJKLMNOP" .AS "QRSTUVWXYZ012345" ICMP.RequestLen .EQ *-ICMP.Request *-------------------------------------- .DA #AF.INET S.SOCKADDR.AF .BS 1 .BS 4 S.SOCKADDR.ADDR .BS 2 S.SOCKADDR.PORT *-------------------------------------- .DA #AF.INET S.SOCKADDR.AF .BS 1 .BS 4 S.SOCKADDR.ADDR .BS 2 DATA.Len .EQ *-ICMP.Request *-------------------------------------- .DUMMY .OR 0 DS.START Request .BS ICMP.RequestLen SA.LOCAL .BS S.SOCKADDR SA.REMOTE .BS S.SOCKADDR DS.END .ED *-------------------------------------- MAN SAVE USR/SRC/BIN/PING.S ASM