NEW
PREFIX
AUTO 4,1
				.LIST OFF
				.OP	65C02
				.OR	$2000
				.TF BIN/HTTPGET
*--------------------------------------
				.INB INC/MACROS.I
				.INB INC/A2OSX.I
				.INB INC/MLI.I
				.INB INC/MLI.E.I
				.INB INC/ETH.I
				.INB INC/LIBTCPIP.I
				.INB INC/NET.HTTP.I
*--------------------------------------
RESP.BUFSIZE	.EQ 1024
TIMEOUT.MAX		.EQ 100					10 sec.
*--------------------------------------
				.DUMMY
				.OR ZPBIN
ZS.START
ZPIPCfgPtr		.BS 2
ZPHostPtr		.BS 2
ZPPtr			.BS 2
ZPReqBufPtr		.BS 2
ZPReqBufLen		.BS 2
ZPEncodedBufPtr	.BS 2
ZPEncodedBufLen	.BS 2
ZPRespBufPtr	.BS 2
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 Length To Relocate
				.DA DS.END-DS.START		Data Segment to Allocate
				.DA #16					SS
				.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.SA.LOCAL		.DA SA.LOCAL
L.SA.REMOTE		.DA SA.REMOTE
L.SA.REMOTE.AD	.DA SA.REMOTE+S.SOCKADDR.ADDR
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.SKTOK		.DA MSG.SKTOK
L.MSG.SKTERR	.DA MSG.SKTERR
L.MSG.IOERR		.DA MSG.IOERR
L.HTTP.GET1		.DA HTTP.GET1
L.HTTP.GET2		.DA HTTP.GET2
L.HTTP.GET3		.DA HTTP.GET3
				.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 CS.RUN.IPOK
				
				>LDYA L.MSG.IPKO
				>SYSCALL puts
				lda #E.SYN
				sec
				rts
				
CS.RUN.IPOK		ldy #S.IPCFG.IP+3
				ldx #3
				
.1				lda (ZPIPCfgPtr),y
				sta SA.LOCAL+S.SOCKADDR.ADDR,x
				dey
				dex
				bpl .1
				
				>INC.G ArgIndex
				>SYSCALL ArgV
				bcs .9

				>STYA ZPHostPtr
				jsr Init.Timeout

.2				>PUSHW L.SA.REMOTE.AD
				
				>PUSHW ZPHostPtr
				>LIBCALL hLIBTCPIP,LIBTCPIP.HST.GETBYNAME
				bcc CS.RUN.HOSTOK
				>SLEEP
				jsr Wait.Timeout
				bcc .2

				>PUSHW ZPHostPtr
				>PUSHBI 2
				>LDYA L.MSG.UNKNOWN
				>SYSCALL printf
				bra CS.RUN.ESYN
				
.9				>PUSHBI 0
				>LDYA L.MSG.USAGE
				>SYSCALL printf

CS.RUN.ESYN		lda #E.SYN
				sec				
CS.RUN.RTS		rts

CS.RUN.HOSTOK	>INC.G ArgIndex
				>SYSCALL ArgV
				bcc .10
				jmp CS.RUN.PORTOK
				
.10				>STYA ZPPtr
				lda (ZPPtr)
				cmp #'-'
				beq .1
				
				>LDYA ZPPtr							
				>SYSCALL atoi
				bcs CS.RUN.RTS
				>STYA SA.REMOTE+S.SOCKADDR.PORT
				
				>INC.G ArgIndex
				>SYSCALL ArgV
				bcs .8
				
				>STYA ZPPtr
				lda (ZPPtr)
				cmp #'-'
				bne CS.RUN.ESYN
				
.1				ldy #1
				lda (ZPPtr),y
				cmp #'U'
				bne .2
				
				>INC.G ArgIndex
				>SYSCALL ArgV
.9				bcs CS.RUN.ESYN

				>STYA ZPReqBufPtr
				>SYSCALL strlen
				>STYA ZPReqBufLen
.8				bra CS.RUN.PORTOK
				
.2				cmp #'F'
				bne CS.RUN.ESYN
				
				>INC.G ArgIndex
				>SYSCALL ArgV
				bcs CS.RUN.RTS
				pha
				
				>PUSHWI 0				Aux type
				>PUSHBI S.FI.T.TXT
				>PUSHBI	O.RDONLY
				pla
				>SYSCALL LoadTxtFile
				bcs .9
				
				>STYA ZPReqBufLen
				txa
				>STA.G hReqBuf
				>SYSCALL GetMemPtr
				>STYA ZPReqBufPtr
				
CS.RUN.PORTOK	>PUSHW ZPHostPtr			
				>PUSHW SA.REMOTE+S.SOCKADDR.PORT

				ldx #3
				
.1				>PUSHB SA.REMOTE+S.SOCKADDR.ADDR,x
				dex
				bpl .1
				
				>PUSHBI 8
				>LDYA L.MSG.HOSTOK
				>SYSCALL printf
		
CS.RUN.OPENSKT	>PUSHBI 0				no protocol
				lda #S.SOCKET.T.STREAM
				>LIBCALL hLIBTCPIP,LIBTCPIP.Socket
				bcs .9

				>STA.G hSocket
				pha
				>PUSHW L.SA.LOCAL
				pla
				>LIBCALL hLIBTCPIP,LIBTCPIP.Bind
				bcc .2
				
.9				>LDYA L.MSG.SKTKO
				>SYSCALL puts
				lda #E.SYN
				sec				
				rts
				
.2				>PUSHW L.SA.REMOTE
				>LDA.G hSocket
				>LIBCALL hLIBTCPIP,LIBTCPIP.Connect
				bcs .9
				
				>LDYA L.MSG.SKTOK
				>SYSCALL puts
				
				>LDYAI RESP.BUFSIZE
				>SYSCALL getmem
				bcs .9
				>STYA ZPRespBufPtr
				txa
				>STA.G hRespBuf

CS.RUN.GET		jsr CS.RUN.ENCODE
				bcs .99
				
*				>PUSHW ZPEncodedBufLen
*				>PUSHW ZPEncodedBufPtr
*				ldy #S.PS.hStdOut
*				lda (pPs),y
*				>SYSCALL fwrite
				
				jsr CS.RUN.REQUEST
				bcs .99

				jsr CS.RUN.RESPONSE
				bcs .99
				
.9				lda #0
				sec
.99				rts
*--------------------------------------
CS.RUN.SKTERR	pha
				>PUSHA
				>PUSHBI 1
				>LDYA L.MSG.SKTERR
				>SYSCALL printf
				pla
				sec
				rts
*--------------------------------------
CS.RUN.IOERR	pha
				>PUSHA
				>PUSHBI 1
				>LDYA L.MSG.IOERR
				>SYSCALL printf
				pla
				sec
				rts
*--------------------------------------
CS.RUN.CONNECT
*--------------------------------------
CS.RUN.ENCODE	>LDYA ZPReqBufPtr
				>STYA ZPPtr

.10				lda (ZPPtr)
				beq .4

				inc ZPEncodedBufLen
				bne .1
				inc ZPEncodedBufLen+1
				
.1	            inc ZPPtr
				bne .11
				inc ZPPtr+1
				
.11				jsr CS.RUN.TOENCODE
				bcc .10
				
.3				lda ZPEncodedBufLen
				clc
				adc #2
				sta ZPEncodedBufLen
				bcc .10
				inc ZPEncodedBufLen+1
				bra .10

.4				>LDYA ZPEncodedBufLen
				>SYSCALL GetMem
				bcs .9
				
				>STYA ZPEncodedBufPtr
				>STYA ZPPtr
				txa
				>STA.G hEncodedBuf

.5				lda (ZPReqBufPtr)
				beq .8
				
				inc ZPReqBufPtr
				bne .6
				inc ZPReqBufPtr+1
				
.6				jsr CS.RUN.TOENCODE
				bcc .7
				
				jsr CS.RUN.ADDBYTETOBUF
				bra .5
				
.7				jsr CS.RUN.ADDTOBUF
				bra .5
				
.8				clc
.9				rts				
*--------------------------------------
CS.RUN.TOENCODE	ldx #URI.ToEncode.Cnt-1
				
.1				cmp URI.ToEncode,x
				beq .9					CS
				dex
				bpl .1
				clc
.9				rts
*--------------------------------------
CS.RUN.ADDBYTETOBUF
				pha
				lda #'%'
				jsr CS.RUN.ADDTOBUF
				pla
				pha
				lsr
				lsr
				lsr
				lsr
				ora #$30
				cmp #$3A
				bcc .1
				adc #6
.1				jsr CS.RUN.ADDTOBUF
				pla
				and #$0F
				ora #$30
				cmp #$3A
				bcc CS.RUN.ADDTOBUF
				adc #6
*--------------------------------------
CS.RUN.ADDTOBUF	sta (ZPPtr)
				inc ZPPtr
				bne .8
				inc ZPPtr+1
.8				rts				
*--------------------------------------
CS.RUN.REQUEST	jsr Init.Timeout
				
.10				>PUSHWI HTTP.GET1.LEN
				>PUSHW L.HTTP.GET1

				jsr .8
				bcc .1
				tay
				bne .99
				
				>SLEEP
				jsr Wait.TimeOut
				bcc .10
				
.99				lda #MLI.E.IO
				sec
				rts

.1				>PUSHW ZPEncodedBufLen
				>PUSHW ZPEncodedBufPtr
				jsr .8
				bcs .9
				
				>PUSHWI HTTP.GET2.LEN
				>PUSHW L.HTTP.GET2
				jsr .8
				bcs .9

				>LDYA ZPHostPtr
				>SYSCALL strlen
				>PUSHYA
				>PUSHW ZPHostPtr
				jsr .8
				bcs .9

				>PUSHWI HTTP.GET3.LEN
				>PUSHW L.HTTP.GET3

.8				>LDA.G hSocket
				>LIBCALL hLIBTCPIP,LIBTCPIP.Write
.9				rts
*--------------------------------------
CS.RUN.RESPONSE jsr Init.Timeout

.1				>SLEEP
				
				>PUSHWI RESP.BUFSIZE
				>PUSHW ZPRespBufPtr
				>LDA.G hSocket
				>LIBCALL hLIBTCPIP,LIBTCPIP.Read
				bcc .2

				tay
				bne .8
				
				>LDA.G bResponse
				bne .81
				
				jsr Wait.Timeout
				bcs .99
				
				bra .1
				
.2				>PUSHYA					len
				>PUSHW ZPRespBufPtr
				ldy #S.PS.hStdOut
				lda (pPs),y
				>SYSCALL fwrite
				bcs .9

				>INC.G bResponse
				bra .1
				
.8				cmp #MLI.E.IO			SKT Close ?
				bne .9
				
.80				>LDA.G bResponse
				beq .99
.81				clc
				rts
				
.99				lda #MLI.E.IO
.9				sec

				rts
*--------------------------------------
CS.DOEVENT		lda (pEvent)
				bpl .9					is it a TIMER event?
				
				>LDA.G TimeOut
				beq .9
				
				dec
				sta (pData),y
				
.9				sec						do not discard TIMER event
				rts
*--------------------------------------
CS.QUIT			>LDA.G hSocket
				beq .1

				>LIBCALL hLIBTCPIP,LIBTCPIP.Shutdown
				
.1				>LDA.G hReqBuf
				beq .2
				
				>SYSCALL freemem
				
.2				>LDA.G hEncodedBuf
				beq .3
				
				>SYSCALL freemem
				
.3				>LDA.G hRespBuf
				beq .4
				
				>SYSCALL freemem
				
.4				lda hLIBTCPIP
				beq .8
				>SYSCALL UnloadLib
				
.8				clc
				rts
*--------------------------------------
Init.Timeout	lda #TIMEOUT.MAX
				>STA.G TimeOut
				rts
*--------------------------------------
Wait.TimeOut	sec
				>LDA.G TimeOut
				beq .9

				clc
.9				rts
*--------------------------------------
CS.END
LIBTCPIP		.AZ "libtcpip"
hLIBTCPIP		.BS 1
MSG.IPKO		.AZ "TCP/IP Not Loaded/Configured."
MSG.USAGE		.AS "Usage : HTTPGET <ip|host> [port]\r\n"
				.AS "        -U Url\r\n" 
				.AZ "        -F UrlFile\r\n" 
MSG.UNKNOWN		.AZ "%s: Unknown host\r\n"
MSG.HOSTOK		.AZ "Connecting to %d.%d.%d.%d:%D (%s)..."
MSG.SKTKO		.AZ "Failed to Open Socket."
MSG.SKTOK		.AZ "Connected."
MSG.SKTERR		.AZ "Socket Error : $%h\r\n"
MSG.IOERR		.AZ "I/O Error : $%h\r\n"
*--------------------------------------
SA.LOCAL		.DA #AF.INET			S.SOCKADDR.AF
				.BS 1
				.BS 4					S.SOCKADDR.ADDR
				.BS 2					S.SOCKADDR.PORT
*--------------------------------------
SA.REMOTE		.DA #AF.INET			S.SOCKADDR.AF
				.BS 1
				.BS 4					S.SOCKADDR.ADDR
				.DA TCP.PORT.HTTP
*--------------------------------------
URI.ToEncode	.DA #C.LF,#C.CR,#C.SPACE,#'"'
				.AS "%-.\^_`{|}~"
URI.ToEncode.Cnt	.EQ	*-URI.ToEncode
*--------------------------------------
HTTP.GET1		.AS "GET /"
HTTP.GET1.LEN	.EQ *-HTTP.GET1
HTTP.GET2		.AS " HTTP/1.1"
				.DA #C.CR,#C.LF
				.AS "User-Agent: A2osX.HTTPGET"
				.DA #C.CR,#C.LF
				.AS "Host: "
HTTP.GET2.LEN	.EQ *-HTTP.GET2
HTTP.GET3		.DA #C.CR,#C.LF
				.AS "Connection: close"
				.DA #C.CR,#C.LF
				.DA #C.CR,#C.LF
HTTP.GET3.LEN	.EQ *-HTTP.GET3
*--------------------------------------
				.DUMMY
				.OR 0
DS.START
ArgIndex		.BS 1
hReqBuf			.BS 1
hEncodedBuf		.BS 1
hRespBuf		.BS 1
bResponse		.BS 1
hSocket			.BS 1
TimeOut			.BS 1
DS.END
				.ED
*--------------------------------------
MAN
SAVE USR/SRC/BIN/HTTPGET.S
ASM
