NEW
  AUTO 3,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 50					5 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

hSocket			.BS 1
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 #64					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.CONNECT	.DA MSG.CONNECT
L.MSG.SKTKO		.DA MSG.SKTKO
L.MSG.CONNECTED	.DA MSG.CONNECTED
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 L.MSG.UNKNOWN
				>PUSHW ZPHostPtr
				>PUSHBI 2
				>SYSCALL printf
				bra CS.RUN.ESYN

.9				>PUSHW L.MSG.USAGE
				>PUSHBI 0
				>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 #'a'
				bcc .11
				cmp #'z'+1
				bcs .11
				
				eor #$20
				
.11				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 .9

				pha
				>PUSHWZ				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 L.MSG.CONNECT
				ldx #0

.1				>PUSHB SA.REMOTE+S.SOCKADDR.ADDR,x
				inx
				cpx #4
				bne .1

				>PUSHW SA.REMOTE+S.SOCKADDR.PORT
				>PUSHW ZPHostPtr			
				
				>PUSHBI 8
				>SYSCALL printf

CS.RUN.OPENSKT	>PUSHBI 0				no protocol
				lda #S.SOCKET.T.STREAM
				>LIBCALL hLIBTCPIP,LIBTCPIP.Socket
				bcs .9

				sta hSocket

				>PUSHW L.SA.LOCAL
				lda hSocket
				>LIBCALL hLIBTCPIP,LIBTCPIP.Bind
				bcc .1

.9				pha
				>LDYA L.MSG.SKTKO
				>SYSCALL puts
				pla
				sec
.99				rts

.1				jsr Init.Timeout

.2				>SLEEP

				>PUSHW L.SA.REMOTE
				lda hSocket
				>LIBCALL hLIBTCPIP,LIBTCPIP.Connect
				bcc .3

				cmp #ERR.SKT.NOCONN
				bne .9

				jsr Wait.Timeout
				bcc .2
				lda #ERR.SKT.NOCONN
				bra .9

.3				>LDYA L.MSG.CONNECTED
				>SYSCALL puts

				>LDYAI RESP.BUFSIZE
				>SYSCALL getmem
				bcs .99

				>STYA ZPRespBufPtr
				txa
				>STA.G hRespBuf

				>SLEEP
				
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
				>PUSHW L.MSG.SKTERR
				pla
				pha
				>PUSHA
				>PUSHBI 1
				>SYSCALL printf
				pla
				sec
				rts
*--------------------------------------
CS.RUN.IOERR	pha
				>PUSHW L.MSG.IOERR
				pla
				pha
				>PUSHA
				>PUSHBI 1
				>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

				>PUSHWI HTTP.GET1.LEN
				>PUSHW L.HTTP.GET1
				jsr .8
				bcs .99

				>PUSHW ZPEncodedBufLen
				>PUSHW ZPEncodedBufPtr
				jsr .8
				bcs .9

				>PUSHWI HTTP.GET2.LEN
				>PUSHW L.HTTP.GET2
				jsr .8
.99				bcs .9

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

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

.8				lda #'!'
				>SYSCALL putchar
				
				lda hSocket
				>LIBCALL hLIBTCPIP,LIBTCPIP.Write
.9				rts
*--------------------------------------
CS.RUN.RESPONSE jsr Init.Timeout

.1				>SLEEP
				>PUSHWI RESP.BUFSIZE
				>PUSHW ZPRespBufPtr

				lda hSocket
				>LIBCALL hLIBTCPIP,LIBTCPIP.Read
				bcc .2
				
				cmp #E.NODATA
				bne .8
				
				jsr Wait.Timeout
				bcs .80
				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 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.CONNECT		.AZ "Connecting to %d.%d.%d.%d:%D (%s)..."
MSG.SKTKO		.AZ "Failed to Open Socket."
MSG.CONNECTED	.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
TimeOut			.BS 1
DS.END
				.ED
*--------------------------------------
MAN
SAVE USR/SRC/BIN/HTTPGET.S
ASM
