NEW
  PREFIX
AUTO 4,1
				.LIST OFF
				.OP	65C02
				.OR	$2000
				.TF BIN/RPCDUMP
*--------------------------------------
				.INB INC/MACROS.I
				.INB INC/A2OSX.I
				.INB INC/ETH.I
				.INB INC/LIBTCPIP.I
*--------------------------------------
TIMEOUT.MAX		.EQ 40					40*100ms = 4 sec.
*--------------------------------------
ZPIPCfgPtr		.EQ ZPBIN
ZPFrameBase		.EQ ZPBIN+2
*--------------------------------------
*			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
				.DA #0
				.DA CS.END-CS.START		Code Length To Relocate
				.DA DS.END-DS.START		Data Segment to Allocate
				.DA #16					SS
				.DA #4					ZP
				.DA 0
*--------------------------------------
.1				.DA CS.INIT
				.DA CS.RUN
				.DA CS.DOEVENT		
				.DA	CS.QUIT
L.LIBTCPIP		.DA LIBTCPIP
L.Socket		.DA Socket
L.Socket.Dst.Addr	.DA Socket.Dst.Addr
L.RPC.Request	.DA RPC.Request
L.MSG.USAGE		.DA MSG.USAGE
L.MSG.UNKNOWN	.DA MSG.UNKNOWN
L.MSG.TIMEOUT	.DA MSG.TIMEOUT
L.MSG.DUMP0		.DA MSG.DUMP0
L.MSG.DUMP1		.DA MSG.DUMP1
				.DA 0
*--------------------------------------
CS.INIT			ldy #S.PS.ARGC
				lda (pPs),y
				beq .99

				>LDYA L.LIBTCPIP
				>SYSCALL LoadLib
				sta hLIBTCPIP

				>LIBCALL hLIBTCPIP,LIBTCPIP.GET.IPCFG	is TCPIP loaded ?
				bcs .99
				>STYA ZPIPCfgPtr
				
				lda (ZPIPCfgPtr)		Configured ?
				bpl .99
				
				ldx #3
				ldy #S.IPCFG.IP+3
.1				lda (ZPIPCfgPtr),y
				sta Socket.Src.Addr,x
				dey
				dex
				bpl .1
				
				clc
				rts
				
.99				>LDYA L.MSG.USAGE
				>SYSCALL puts
				lda #E.SYN
				sec
				rts
*--------------------------------------
CS.RUN			jsr Init.Timeout
				
.1				>PUSHW L.Socket.Dst.Addr
				lda #1
				>SYSCALL ArgV
				>PUSHYA
				>LIBCALL hLIBTCPIP,LIBTCPIP.HST.GETBYNAME
				bcc .2

				>SLEEP
				jsr Wait.Timeout
				bcc .1
				
				lda #1
				>SYSCALL ArgV
				>PUSHYA
				
				>PUSHBI 2
				>LDYA L.MSG.UNKNOWN
				>SYSCALL printf
				sec
				rts
				
.2				>PUSHW L.Socket
				>LIBCALL hLIBTCPIP,LIBTCPIP.SKT.New
				bcs .91
				
				>STA.G hSocket
				
				ldx #3
				
.21				lda A2osX.TIMER16,x				
				sta RPC.Request,x
				dex
				bpl .21
				
.3				>PUSHWI RPC.Request.End-RPC.Request
				>PUSHW L.RPC.Request
				>LDA.G hSocket
				>LIBCALL hLIBTCPIP,LIBTCPIP.SKT.Send
				bcc .4
				
				>SLEEP
				jsr Wait.Timeout
				bcc .3
.91				bra .99
				
.4				jsr Init.Timeout

.5				>LDA.G hSocket
				>LIBCALL hLIBTCPIP,LIBTCPIP.SKT.Rcvd
				bcc .6
				
				>SLEEP
				jsr Wait.Timeout
				bcc .5
				bra .99
			
.6				ldy #hFrame
				sta (pData),y
				>SYSCALL GetMemPtr
				>STYA ZPFrameBase
				
				jsr DumpRPCFrame

				ldy #hFrame
				lda (pData),y
				>SYSCALL FreeMem
				
				lda #0
				sec
				rts
				
.99				lda #1
				>SYSCALL ArgV
				>PUSHYA
				>PUSHBI 2
				>LDYA L.MSG.TIMEOUT
				>SYSCALL printf
				sec
				rts
*--------------------------------------
CS.DOEVENT		lda (pEvent)
				bpl .9					is it a TIMER event?

				ldy #TimeOut
				lda (pData),y
				beq .9
				dec 
				sta (pData),y
.9				sec						do not discard TIMER event
				rts
*--------------------------------------
CS.QUIT			ldy #hSocket
				lda (pData),y
				beq .1
				
				>LIBCALL hLIBTCPIP,LIBTCPIP.SKT.Close
				
.1				lda hLIBTCPIP
				beq .8
				>SYSCALL UnloadLib
				
.8				clc
				rts
*--------------------------------------
Init.Timeout	ldy #TimeOut
				lda #TIMEOUT.MAX
				sta (pData),y
				rts
*--------------------------------------
Wait.TimeOut	sec
				ldy #TimeOut
				lda (pData),y
				beq .9
				clc
.9				rts
*--------------------------------------
DumpRPCFrame	lda #S.UDP+24
				clc
				adc ZPFrameBase
				sta ZPFrameBase
				lda /S.UDP+24
				adc ZPFrameBase+1
				sta ZPFrameBase+1

				>LDYA L.MSG.DUMP0
				>SYSCALL puts
				
.1				ldy #3
				lda (ZPFrameBase),y		Value follows?
				beq .9
				
				ldy #18					port
				>PUSHB (ZPFrameBase),y
				iny
				>PUSHB (ZPFrameBase),y

				ldy #15					proto
				>PUSHB (ZPFrameBase),y

				ldy #11					version
				>PUSHB (ZPFrameBase),y
				
				ldy #4					program
.7				>PUSHB (ZPFrameBase),y
				iny
				cpy #8
				bne .7

				>PUSHBI 8
				>LDYA L.MSG.DUMP1
				>SYSCALL printf
				
				lda #20
				clc
				adc ZPFrameBase
				sta ZPFrameBase
				bcc .1
				inc ZPFrameBase+1
				bra .1
				
.9				rts
*--------------------------------------
CS.END
LIBTCPIP		.AZ "libtcpip.o"
hLIBTCPIP		.BS 1
MSG.USAGE		.AZ "Usage : RPCDUMP <ip|host>"
MSG.UNKNOWN		.AZ "%s: Unknown host\r\n"
MSG.TIMEOUT		.AZ "No response from %s\r\n"
MSG.DUMP0		.AZ "Program     Ver Proto:Port"
MSG.DUMP1		.AZ "%10L  %2d     %2d:%D\r\n"
*--------------------------------------
Socket			.DA #S.SOCKET.T.DGRAM
				.BS 3
Socket.Src.Addr	.BS 4
Socket.Src.Port	.DA 0					Dynamic
Socket.Dst.Addr	.BS 4
Socket.Dst.Port	.DA UDP.PORT.PMAP
*--------------------------------------
RPC.Request		.BS 4					XID
				.HS 00000000			0=CALL
				.HS 00000002			RPCVERS
				.HS 000186A0			PROG=portmapper
				.HS 00000002			VERS
				.HS 00000004			PMAPPROC_DUMP
				.HS 00000000			CRED
				.HS 00000000	
				.HS 00000000			VERF
				.HS 00000000
RPC.Request.End	.EQ *
*--------------------------------------
				.DUMMY
				.OR 0
DS.START
hSocket			.BS 1
hFrame			.BS 1
TimeOut			.BS 1
DS.END
				.ED
*--------------------------------------
MAN
SAVE USR/SRC/BIN/RPCDUMP.S
ASM
